OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 19 matching lines...) Expand all Loading... |
30 #include <math.h> | 30 #include <math.h> |
31 | 31 |
32 #include "bignum-dtoa.h" | 32 #include "bignum-dtoa.h" |
33 | 33 |
34 #include "bignum.h" | 34 #include "bignum.h" |
35 #include "double.h" | 35 #include "double.h" |
36 | 36 |
37 namespace WTF { | 37 namespace WTF { |
38 | 38 |
39 namespace double_conversion { | 39 namespace double_conversion { |
40 | 40 |
41 static int NormalizedExponent(uint64_t significand, int exponent) { | 41 static int NormalizedExponent(uint64_t significand, int exponent) { |
42 ASSERT(significand != 0); | 42 ASSERT(significand != 0); |
43 while ((significand & Double::kHiddenBit) == 0) { | 43 while ((significand & Double::kHiddenBit) == 0) { |
44 significand = significand << 1; | 44 significand = significand << 1; |
45 exponent = exponent - 1; | 45 exponent = exponent - 1; |
46 } | 46 } |
47 return exponent; | 47 return exponent; |
48 } | 48 } |
49 | 49 |
50 | 50 |
51 // Forward declarations: | 51 // Forward declarations: |
52 // Returns an estimation of k such that 10^(k-1) <= v < 10^k. | 52 // Returns an estimation of k such that 10^(k-1) <= v < 10^k. |
53 static int EstimatePower(int exponent); | 53 static int EstimatePower(int exponent); |
54 // Computes v / 10^estimated_power exactly, as a ratio of two bignums, numer
ator | 54 // Computes v / 10^estimated_power exactly, as a ratio of two bignums, numer
ator |
55 // and denominator. | 55 // and denominator. |
56 static void InitialScaledStartValues(double v, | 56 static void InitialScaledStartValues(double v, |
57 int estimated_power, | 57 int estimated_power, |
58 bool need_boundary_deltas, | 58 bool need_boundary_deltas, |
59 Bignum* numerator, | 59 Bignum* numerator, |
60 Bignum* denominator, | 60 Bignum* denominator, |
(...skipping 18 matching lines...) Expand all Loading... |
79 static void BignumToFixed(int requested_digits, int* decimal_point, | 79 static void BignumToFixed(int requested_digits, int* decimal_point, |
80 Bignum* numerator, Bignum* denominator, | 80 Bignum* numerator, Bignum* denominator, |
81 Vector<char>(buffer), int* length); | 81 Vector<char>(buffer), int* length); |
82 // Generates 'count' digits of numerator/denominator. | 82 // Generates 'count' digits of numerator/denominator. |
83 // Once 'count' digits have been produced rounds the result depending on the | 83 // Once 'count' digits have been produced rounds the result depending on the |
84 // remainder (remainders of exactly .5 round upwards). Might update the | 84 // remainder (remainders of exactly .5 round upwards). Might update the |
85 // decimal_point when rounding up (for example for 0.9999). | 85 // decimal_point when rounding up (for example for 0.9999). |
86 static void GenerateCountedDigits(int count, int* decimal_point, | 86 static void GenerateCountedDigits(int count, int* decimal_point, |
87 Bignum* numerator, Bignum* denominator, | 87 Bignum* numerator, Bignum* denominator, |
88 Vector<char>(buffer), int* length); | 88 Vector<char>(buffer), int* length); |
89 | 89 |
90 | 90 |
91 void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits, | 91 void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits, |
92 Vector<char> buffer, int* length, int* decimal_point) { | 92 Vector<char> buffer, int* length, int* decimal_point) { |
93 ASSERT(v > 0); | 93 ASSERT(v > 0); |
94 ASSERT(!Double(v).IsSpecial()); | 94 ASSERT(!Double(v).IsSpecial()); |
95 uint64_t significand = Double(v).Significand(); | 95 uint64_t significand = Double(v).Significand(); |
96 bool is_even = (significand & 1) == 0; | 96 bool is_even = (significand & 1) == 0; |
97 int exponent = Double(v).Exponent(); | 97 int exponent = Double(v).Exponent(); |
98 int normalized_exponent = NormalizedExponent(significand, exponent); | 98 int normalized_exponent = NormalizedExponent(significand, exponent); |
99 // estimated_power might be too low by 1. | 99 // estimated_power might be too low by 1. |
100 int estimated_power = EstimatePower(normalized_exponent); | 100 int estimated_power = EstimatePower(normalized_exponent); |
101 | 101 |
102 // Shortcut for Fixed. | 102 // Shortcut for Fixed. |
103 // The requested digits correspond to the digits after the point. If the | 103 // The requested digits correspond to the digits after the point. If the |
104 // number is much too small, then there is no need in trying to get any | 104 // number is much too small, then there is no need in trying to get any |
105 // digits. | 105 // digits. |
106 if (mode == BIGNUM_DTOA_FIXED && -estimated_power - 1 > requested_digits
) { | 106 if (mode == BIGNUM_DTOA_FIXED && -estimated_power - 1 > requested_digits
) { |
107 buffer[0] = '\0'; | 107 buffer[0] = '\0'; |
108 *length = 0; | 108 *length = 0; |
109 // Set decimal-point to -requested_digits. This is what Gay does. | 109 // Set decimal-point to -requested_digits. This is what Gay does. |
110 // Note that it should not have any effect anyways since the string
is | 110 // Note that it should not have any effect anyways since the string
is |
111 // empty. | 111 // empty. |
112 *decimal_point = -requested_digits; | 112 *decimal_point = -requested_digits; |
113 return; | 113 return; |
114 } | 114 } |
115 | 115 |
116 Bignum numerator; | 116 Bignum numerator; |
117 Bignum denominator; | 117 Bignum denominator; |
118 Bignum delta_minus; | 118 Bignum delta_minus; |
119 Bignum delta_plus; | 119 Bignum delta_plus; |
120 // Make sure the bignum can grow large enough. The smallest double equal
s | 120 // Make sure the bignum can grow large enough. The smallest double equal
s |
121 // 4e-324. In this case the denominator needs fewer than 324*4 binary di
gits. | 121 // 4e-324. In this case the denominator needs fewer than 324*4 binary di
gits. |
122 // The maximum double is 1.7976931348623157e308 which needs fewer than | 122 // The maximum double is 1.7976931348623157e308 which needs fewer than |
123 // 308*4 binary digits. | 123 // 308*4 binary digits. |
124 ASSERT(Bignum::kMaxSignificantBits >= 324*4); | 124 ASSERT(Bignum::kMaxSignificantBits >= 324*4); |
125 bool need_boundary_deltas = (mode == BIGNUM_DTOA_SHORTEST); | 125 bool need_boundary_deltas = (mode == BIGNUM_DTOA_SHORTEST); |
(...skipping 20 matching lines...) Expand all Loading... |
146 case BIGNUM_DTOA_PRECISION: | 146 case BIGNUM_DTOA_PRECISION: |
147 GenerateCountedDigits(requested_digits, decimal_point, | 147 GenerateCountedDigits(requested_digits, decimal_point, |
148 &numerator, &denominator, | 148 &numerator, &denominator, |
149 buffer, length); | 149 buffer, length); |
150 break; | 150 break; |
151 default: | 151 default: |
152 UNREACHABLE(); | 152 UNREACHABLE(); |
153 } | 153 } |
154 buffer[*length] = '\0'; | 154 buffer[*length] = '\0'; |
155 } | 155 } |
156 | 156 |
157 | 157 |
158 // The procedure starts generating digits from the left to the right and sto
ps | 158 // The procedure starts generating digits from the left to the right and sto
ps |
159 // when the generated digits yield the shortest decimal representation of v.
A | 159 // when the generated digits yield the shortest decimal representation of v.
A |
160 // decimal representation of v is a number lying closer to v than to any oth
er | 160 // decimal representation of v is a number lying closer to v than to any oth
er |
161 // double, so it converts to v when read. | 161 // double, so it converts to v when read. |
162 // | 162 // |
163 // This is true if d, the decimal representation, is between m- and m+, the | 163 // This is true if d, the decimal representation, is between m- and m+, the |
164 // upper and lower boundaries. d must be strictly between them if !is_even. | 164 // upper and lower boundaries. d must be strictly between them if !is_even. |
165 // m- := (numerator - delta_minus) / denominator | 165 // m- := (numerator - delta_minus) / denominator |
166 // m+ := (numerator + delta_plus) / denominator | 166 // m+ := (numerator + delta_plus) / denominator |
167 // | 167 // |
(...skipping 10 matching lines...) Expand all Loading... |
178 delta_plus = delta_minus; | 178 delta_plus = delta_minus; |
179 } | 179 } |
180 *length = 0; | 180 *length = 0; |
181 while (true) { | 181 while (true) { |
182 uint16_t digit; | 182 uint16_t digit; |
183 digit = numerator->DivideModuloIntBignum(*denominator); | 183 digit = numerator->DivideModuloIntBignum(*denominator); |
184 ASSERT(digit <= 9); // digit is a uint16_t and therefore always pos
itive. | 184 ASSERT(digit <= 9); // digit is a uint16_t and therefore always pos
itive. |
185 // digit = numerator / denominator (integer division). | 185 // digit = numerator / denominator (integer division). |
186 // numerator = numerator % denominator. | 186 // numerator = numerator % denominator. |
187 buffer[(*length)++] = digit + '0'; | 187 buffer[(*length)++] = digit + '0'; |
188 | 188 |
189 // Can we stop already? | 189 // Can we stop already? |
190 // If the remainder of the division is less than the distance to the
lower | 190 // If the remainder of the division is less than the distance to the
lower |
191 // boundary we can stop. In this case we simply round down (discardi
ng the | 191 // boundary we can stop. In this case we simply round down (discardi
ng the |
192 // remainder). | 192 // remainder). |
193 // Similarly we test if we can round up (using the upper boundary). | 193 // Similarly we test if we can round up (using the upper boundary). |
194 bool in_delta_room_minus; | 194 bool in_delta_room_minus; |
195 bool in_delta_room_plus; | 195 bool in_delta_room_plus; |
196 if (is_even) { | 196 if (is_even) { |
197 in_delta_room_minus = Bignum::LessEqual(*numerator, *delta_minus
); | 197 in_delta_room_minus = Bignum::LessEqual(*numerator, *delta_minus
); |
198 } else { | 198 } else { |
(...skipping 28 matching lines...) Expand all Loading... |
227 // loop would have stopped earlier. | 227 // loop would have stopped earlier. |
228 // We still have an assert here in case the preconditions we
re not | 228 // We still have an assert here in case the preconditions we
re not |
229 // satisfied. | 229 // satisfied. |
230 ASSERT(buffer[(*length) - 1] != '9'); | 230 ASSERT(buffer[(*length) - 1] != '9'); |
231 buffer[(*length) - 1]++; | 231 buffer[(*length) - 1]++; |
232 } else { | 232 } else { |
233 // Halfway case. | 233 // Halfway case. |
234 // TODO(floitsch): need a way to solve half-way cases. | 234 // TODO(floitsch): need a way to solve half-way cases. |
235 // For now let's round towards even (since this is what Ga
y seems to | 235 // For now let's round towards even (since this is what Ga
y seems to |
236 // do). | 236 // do). |
237 | 237 |
238 if ((buffer[(*length) - 1] - '0') % 2 == 0) { | 238 if ((buffer[(*length) - 1] - '0') % 2 == 0) { |
239 // Round down => Do nothing. | 239 // Round down => Do nothing. |
240 } else { | 240 } else { |
241 ASSERT(buffer[(*length) - 1] != '9'); | 241 ASSERT(buffer[(*length) - 1] != '9'); |
242 buffer[(*length) - 1]++; | 242 buffer[(*length) - 1]++; |
243 } | 243 } |
244 } | 244 } |
245 return; | 245 return; |
246 } else if (in_delta_room_minus) { | 246 } else if (in_delta_room_minus) { |
247 // Round down (== do nothing). | 247 // Round down (== do nothing). |
248 return; | 248 return; |
249 } else { // in_delta_room_plus | 249 } else { // in_delta_room_plus |
250 // Round up. | 250 // Round up. |
251 // Note again that the last digit could not be '9' since this wo
uld have | 251 // Note again that the last digit could not be '9' since this wo
uld have |
252 // stopped the loop earlier. | 252 // stopped the loop earlier. |
253 // We still have an ASSERT here, in case the preconditions were
not | 253 // We still have an ASSERT here, in case the preconditions were
not |
254 // satisfied. | 254 // satisfied. |
255 ASSERT(buffer[(*length) -1] != '9'); | 255 ASSERT(buffer[(*length) -1] != '9'); |
256 buffer[(*length) - 1]++; | 256 buffer[(*length) - 1]++; |
257 return; | 257 return; |
258 } | 258 } |
259 } | 259 } |
260 } | 260 } |
261 | 261 |
262 | 262 |
263 // Let v = numerator / denominator < 10. | 263 // Let v = numerator / denominator < 10. |
264 // Then we generate 'count' digits of d = x.xxxxx... (without the decimal po
int) | 264 // Then we generate 'count' digits of d = x.xxxxx... (without the decimal po
int) |
265 // from left to right. Once 'count' digits have been produced we decide weth
er | 265 // from left to right. Once 'count' digits have been produced we decide weth
er |
266 // to round up or down. Remainders of exactly .5 round upwards. Numbers such | 266 // to round up or down. Remainders of exactly .5 round upwards. Numbers such |
267 // as 9.999999 propagate a carry all the way, and change the | 267 // as 9.999999 propagate a carry all the way, and change the |
268 // exponent (decimal_point), when rounding upwards. | 268 // exponent (decimal_point), when rounding upwards. |
269 static void GenerateCountedDigits(int count, int* decimal_point, | 269 static void GenerateCountedDigits(int count, int* decimal_point, |
270 Bignum* numerator, Bignum* denominator, | 270 Bignum* numerator, Bignum* denominator, |
271 Vector<char>(buffer), int* length) { | 271 Vector<char>(buffer), int* length) { |
272 ASSERT(count >= 0); | 272 ASSERT(count >= 0); |
(...skipping 21 matching lines...) Expand all Loading... |
294 buffer[i] = '0'; | 294 buffer[i] = '0'; |
295 buffer[i - 1]++; | 295 buffer[i - 1]++; |
296 } | 296 } |
297 if (buffer[0] == '0' + 10) { | 297 if (buffer[0] == '0' + 10) { |
298 // Propagate a carry past the top place. | 298 // Propagate a carry past the top place. |
299 buffer[0] = '1'; | 299 buffer[0] = '1'; |
300 (*decimal_point)++; | 300 (*decimal_point)++; |
301 } | 301 } |
302 *length = count; | 302 *length = count; |
303 } | 303 } |
304 | 304 |
305 | 305 |
306 // Generates 'requested_digits' after the decimal point. It might omit | 306 // Generates 'requested_digits' after the decimal point. It might omit |
307 // trailing '0's. If the input number is too small then no digits at all are | 307 // trailing '0's. If the input number is too small then no digits at all are |
308 // generated (ex.: 2 fixed digits for 0.00001). | 308 // generated (ex.: 2 fixed digits for 0.00001). |
309 // | 309 // |
310 // Input verifies: 1 <= (numerator + delta) / denominator < 10. | 310 // Input verifies: 1 <= (numerator + delta) / denominator < 10. |
311 static void BignumToFixed(int requested_digits, int* decimal_point, | 311 static void BignumToFixed(int requested_digits, int* decimal_point, |
312 Bignum* numerator, Bignum* denominator, | 312 Bignum* numerator, Bignum* denominator, |
313 Vector<char>(buffer), int* length) { | 313 Vector<char>(buffer), int* length) { |
314 // Note that we have to look at more than just the requested_digits, sin
ce | 314 // Note that we have to look at more than just the requested_digits, sin
ce |
315 // a number could be rounded up. Example: v=0.5 with requested_digits=0. | 315 // a number could be rounded up. Example: v=0.5 with requested_digits=0. |
(...skipping 27 matching lines...) Expand all Loading... |
343 return; | 343 return; |
344 } else { | 344 } else { |
345 // The requested digits correspond to the digits after the point. | 345 // The requested digits correspond to the digits after the point. |
346 // The variable 'needed_digits' includes the digits before the point
. | 346 // The variable 'needed_digits' includes the digits before the point
. |
347 int needed_digits = (*decimal_point) + requested_digits; | 347 int needed_digits = (*decimal_point) + requested_digits; |
348 GenerateCountedDigits(needed_digits, decimal_point, | 348 GenerateCountedDigits(needed_digits, decimal_point, |
349 numerator, denominator, | 349 numerator, denominator, |
350 buffer, length); | 350 buffer, length); |
351 } | 351 } |
352 } | 352 } |
353 | 353 |
354 | 354 |
355 // Returns an estimation of k such that 10^(k-1) <= v < 10^k where | 355 // Returns an estimation of k such that 10^(k-1) <= v < 10^k where |
356 // v = f * 2^exponent and 2^52 <= f < 2^53. | 356 // v = f * 2^exponent and 2^52 <= f < 2^53. |
357 // v is hence a normalized double with the given exponent. The output is an | 357 // v is hence a normalized double with the given exponent. The output is an |
358 // approximation for the exponent of the decimal approimation .digits * 10^k
. | 358 // approximation for the exponent of the decimal approimation .digits * 10^k
. |
359 // | 359 // |
360 // The result might undershoot by 1 in which case 10^k <= v < 10^k+1. | 360 // The result might undershoot by 1 in which case 10^k <= v < 10^k+1. |
361 // Note: this property holds for v's upper boundary m+ too. | 361 // Note: this property holds for v's upper boundary m+ too. |
362 // 10^k <= m+ < 10^k+1. | 362 // 10^k <= m+ < 10^k+1. |
363 // (see explanation below). | 363 // (see explanation below). |
364 // | 364 // |
(...skipping 16 matching lines...) Expand all Loading... |
381 // Optimization: since we only need an approximated result this computat
ion | 381 // Optimization: since we only need an approximated result this computat
ion |
382 // can be performed on 64 bit integers. On x86/x64 architecture the spee
dup is | 382 // can be performed on 64 bit integers. On x86/x64 architecture the spee
dup is |
383 // not really measurable, though. | 383 // not really measurable, though. |
384 // | 384 // |
385 // Since we want to avoid overshooting we decrement by 1e10 so that | 385 // Since we want to avoid overshooting we decrement by 1e10 so that |
386 // floating-point imprecisions don't affect us. | 386 // floating-point imprecisions don't affect us. |
387 // | 387 // |
388 // Explanation for v's boundary m+: the computation takes advantage of | 388 // Explanation for v's boundary m+: the computation takes advantage of |
389 // the fact that 2^(p-1) <= f < 2^p. Boundaries still satisfy this requi
rement | 389 // the fact that 2^(p-1) <= f < 2^p. Boundaries still satisfy this requi
rement |
390 // (even for denormals where the delta can be much more important). | 390 // (even for denormals where the delta can be much more important). |
391 | 391 |
392 const double k1Log10 = 0.30102999566398114; // 1/lg(10) | 392 const double k1Log10 = 0.30102999566398114; // 1/lg(10) |
393 | 393 |
394 // For doubles len(f) == 53 (don't forget the hidden bit). | 394 // For doubles len(f) == 53 (don't forget the hidden bit). |
395 const int kSignificandSize = 53; | 395 const int kSignificandSize = 53; |
396 double estimate = ceil((exponent + kSignificandSize - 1) * k1Log10 - 1e-
10); | 396 double estimate = ceil((exponent + kSignificandSize - 1) * k1Log10 - 1e-
10); |
397 return static_cast<int>(estimate); | 397 return static_cast<int>(estimate); |
398 } | 398 } |
399 | 399 |
400 | 400 |
401 // See comments for InitialScaledStartValues. | 401 // See comments for InitialScaledStartValues. |
402 static void InitialScaledStartValuesPositiveExponent( | 402 static void InitialScaledStartValuesPositiveExponent( |
403 double v, int estimated
_power, bool need_boundary_deltas, | 403 double v, int estimated
_power, bool need_boundary_deltas, |
404 Bignum* numerator, Bign
um* denominator, | 404 Bignum* numerator, Bign
um* denominator, |
405 Bignum* delta_minus, Bi
gnum* delta_plus) { | 405 Bignum* delta_minus, Bi
gnum* delta_plus) { |
406 // A positive exponent implies a positive power. | 406 // A positive exponent implies a positive power. |
407 ASSERT(estimated_power >= 0); | 407 ASSERT(estimated_power >= 0); |
408 // Since the estimated_power is positive we simply multiply the denomina
tor | 408 // Since the estimated_power is positive we simply multiply the denomina
tor |
409 // by 10^estimated_power. | 409 // by 10^estimated_power. |
410 | 410 |
411 // numerator = v. | 411 // numerator = v. |
412 numerator->AssignUInt64(Double(v).Significand()); | 412 numerator->AssignUInt64(Double(v).Significand()); |
413 numerator->ShiftLeft(Double(v).Exponent()); | 413 numerator->ShiftLeft(Double(v).Exponent()); |
414 // denominator = 10^estimated_power. | 414 // denominator = 10^estimated_power. |
415 denominator->AssignPowerUInt16(10, estimated_power); | 415 denominator->AssignPowerUInt16(10, estimated_power); |
416 | 416 |
417 if (need_boundary_deltas) { | 417 if (need_boundary_deltas) { |
418 // Introduce a common denominator so that the deltas to the boundari
es are | 418 // Introduce a common denominator so that the deltas to the boundari
es are |
419 // integers. | 419 // integers. |
420 denominator->ShiftLeft(1); | 420 denominator->ShiftLeft(1); |
421 numerator->ShiftLeft(1); | 421 numerator->ShiftLeft(1); |
422 // Let v = f * 2^e, then m+ - v = 1/2 * 2^e; With the common | 422 // Let v = f * 2^e, then m+ - v = 1/2 * 2^e; With the common |
423 // denominator (of 2) delta_plus equals 2^e. | 423 // denominator (of 2) delta_plus equals 2^e. |
424 delta_plus->AssignUInt16(1); | 424 delta_plus->AssignUInt16(1); |
425 delta_plus->ShiftLeft(Double(v).Exponent()); | 425 delta_plus->ShiftLeft(Double(v).Exponent()); |
426 // Same for delta_minus (with adjustments below if f == 2^p-1). | 426 // Same for delta_minus (with adjustments below if f == 2^p-1). |
427 delta_minus->AssignUInt16(1); | 427 delta_minus->AssignUInt16(1); |
428 delta_minus->ShiftLeft(Double(v).Exponent()); | 428 delta_minus->ShiftLeft(Double(v).Exponent()); |
429 | 429 |
430 // If the significand (without the hidden bit) is 0, then the lower | 430 // If the significand (without the hidden bit) is 0, then the lower |
431 // boundary is closer than just half a ulp (unit in the last place). | 431 // boundary is closer than just half a ulp (unit in the last place). |
432 // There is only one exception: if the next lower number is a denorm
al then | 432 // There is only one exception: if the next lower number is a denorm
al then |
433 // the distance is 1 ulp. This cannot be the case for exponent >= 0
(but we | 433 // the distance is 1 ulp. This cannot be the case for exponent >= 0
(but we |
434 // have to test it in the other function where exponent < 0). | 434 // have to test it in the other function where exponent < 0). |
435 uint64_t v_bits = Double(v).AsUint64(); | 435 uint64_t v_bits = Double(v).AsUint64(); |
436 if ((v_bits & Double::kSignificandMask) == 0) { | 436 if ((v_bits & Double::kSignificandMask) == 0) { |
437 // The lower boundary is closer at half the distance of "normal"
numbers. | 437 // The lower boundary is closer at half the distance of "normal"
numbers. |
438 // Increase the common denominator and adapt all but the delta_m
inus. | 438 // Increase the common denominator and adapt all but the delta_m
inus. |
439 denominator->ShiftLeft(1); // *2 | 439 denominator->ShiftLeft(1); // *2 |
440 numerator->ShiftLeft(1); // *2 | 440 numerator->ShiftLeft(1); // *2 |
441 delta_plus->ShiftLeft(1); // *2 | 441 delta_plus->ShiftLeft(1); // *2 |
442 } | 442 } |
443 } | 443 } |
444 } | 444 } |
445 | 445 |
446 | 446 |
447 // See comments for InitialScaledStartValues | 447 // See comments for InitialScaledStartValues |
448 static void InitialScaledStartValuesNegativeExponentPositivePower( | 448 static void InitialScaledStartValuesNegativeExponentPositivePower( |
449 double v,
int estimated_power, bool need_boundary_deltas, | 449 double v,
int estimated_power, bool need_boundary_deltas, |
450 Bignum* nu
merator, Bignum* denominator, | 450 Bignum* nu
merator, Bignum* denominator, |
451 Bignum* de
lta_minus, Bignum* delta_plus) { | 451 Bignum* de
lta_minus, Bignum* delta_plus) { |
452 uint64_t significand = Double(v).Significand(); | 452 uint64_t significand = Double(v).Significand(); |
453 int exponent = Double(v).Exponent(); | 453 int exponent = Double(v).Exponent(); |
454 // v = f * 2^e with e < 0, and with estimated_power >= 0. | 454 // v = f * 2^e with e < 0, and with estimated_power >= 0. |
455 // This means that e is close to 0 (have a look at how estimated_power i
s | 455 // This means that e is close to 0 (have a look at how estimated_power i
s |
456 // computed). | 456 // computed). |
457 | 457 |
458 // numerator = significand | 458 // numerator = significand |
459 // since v = significand * 2^exponent this is equivalent to | 459 // since v = significand * 2^exponent this is equivalent to |
460 // numerator = v * / 2^-exponent | 460 // numerator = v * / 2^-exponent |
461 numerator->AssignUInt64(significand); | 461 numerator->AssignUInt64(significand); |
462 // denominator = 10^estimated_power * 2^-exponent (with exponent < 0) | 462 // denominator = 10^estimated_power * 2^-exponent (with exponent < 0) |
463 denominator->AssignPowerUInt16(10, estimated_power); | 463 denominator->AssignPowerUInt16(10, estimated_power); |
464 denominator->ShiftLeft(-exponent); | 464 denominator->ShiftLeft(-exponent); |
465 | 465 |
466 if (need_boundary_deltas) { | 466 if (need_boundary_deltas) { |
467 // Introduce a common denominator so that the deltas to the boundari
es are | 467 // Introduce a common denominator so that the deltas to the boundari
es are |
468 // integers. | 468 // integers. |
469 denominator->ShiftLeft(1); | 469 denominator->ShiftLeft(1); |
470 numerator->ShiftLeft(1); | 470 numerator->ShiftLeft(1); |
471 // Let v = f * 2^e, then m+ - v = 1/2 * 2^e; With the common | 471 // Let v = f * 2^e, then m+ - v = 1/2 * 2^e; With the common |
472 // denominator (of 2) delta_plus equals 2^e. | 472 // denominator (of 2) delta_plus equals 2^e. |
473 // Given that the denominator already includes v's exponent the dist
ance | 473 // Given that the denominator already includes v's exponent the dist
ance |
474 // to the boundaries is simply 1. | 474 // to the boundaries is simply 1. |
475 delta_plus->AssignUInt16(1); | 475 delta_plus->AssignUInt16(1); |
476 // Same for delta_minus (with adjustments below if f == 2^p-1). | 476 // Same for delta_minus (with adjustments below if f == 2^p-1). |
477 delta_minus->AssignUInt16(1); | 477 delta_minus->AssignUInt16(1); |
478 | 478 |
479 // If the significand (without the hidden bit) is 0, then the lower | 479 // If the significand (without the hidden bit) is 0, then the lower |
480 // boundary is closer than just one ulp (unit in the last place). | 480 // boundary is closer than just one ulp (unit in the last place). |
481 // There is only one exception: if the next lower number is a denorm
al | 481 // There is only one exception: if the next lower number is a denorm
al |
482 // then the distance is 1 ulp. Since the exponent is close to zero | 482 // then the distance is 1 ulp. Since the exponent is close to zero |
483 // (otherwise estimated_power would have been negative) this cannot
happen | 483 // (otherwise estimated_power would have been negative) this cannot
happen |
484 // here either. | 484 // here either. |
485 uint64_t v_bits = Double(v).AsUint64(); | 485 uint64_t v_bits = Double(v).AsUint64(); |
486 if ((v_bits & Double::kSignificandMask) == 0) { | 486 if ((v_bits & Double::kSignificandMask) == 0) { |
487 // The lower boundary is closer at half the distance of "normal"
numbers. | 487 // The lower boundary is closer at half the distance of "normal"
numbers. |
488 // Increase the denominator and adapt all but the delta_minus. | 488 // Increase the denominator and adapt all but the delta_minus. |
489 denominator->ShiftLeft(1); // *2 | 489 denominator->ShiftLeft(1); // *2 |
490 numerator->ShiftLeft(1); // *2 | 490 numerator->ShiftLeft(1); // *2 |
491 delta_plus->ShiftLeft(1); // *2 | 491 delta_plus->ShiftLeft(1); // *2 |
492 } | 492 } |
493 } | 493 } |
494 } | 494 } |
495 | 495 |
496 | 496 |
497 // See comments for InitialScaledStartValues | 497 // See comments for InitialScaledStartValues |
498 static void InitialScaledStartValuesNegativeExponentNegativePower( | 498 static void InitialScaledStartValuesNegativeExponentNegativePower( |
499 double v,
int estimated_power, bool need_boundary_deltas, | 499 double v,
int estimated_power, bool need_boundary_deltas, |
500 Bignum* nu
merator, Bignum* denominator, | 500 Bignum* nu
merator, Bignum* denominator, |
501 Bignum* de
lta_minus, Bignum* delta_plus) { | 501 Bignum* de
lta_minus, Bignum* delta_plus) { |
502 const uint64_t kMinimalNormalizedExponent = | 502 const uint64_t kMinimalNormalizedExponent = |
503 UINT64_2PART_C(0x00100000, 00000000); | 503 UINT64_2PART_C(0x00100000, 00000000); |
504 uint64_t significand = Double(v).Significand(); | 504 uint64_t significand = Double(v).Significand(); |
505 int exponent = Double(v).Exponent(); | 505 int exponent = Double(v).Exponent(); |
506 // Instead of multiplying the denominator with 10^estimated_power we | 506 // Instead of multiplying the denominator with 10^estimated_power we |
507 // multiply all values (numerator and deltas) by 10^-estimated_power. | 507 // multiply all values (numerator and deltas) by 10^-estimated_power. |
508 | 508 |
509 // Use numerator as temporary container for power_ten. | 509 // Use numerator as temporary container for power_ten. |
510 Bignum* power_ten = numerator; | 510 Bignum* power_ten = numerator; |
511 power_ten->AssignPowerUInt16(10, -estimated_power); | 511 power_ten->AssignPowerUInt16(10, -estimated_power); |
512 | 512 |
513 if (need_boundary_deltas) { | 513 if (need_boundary_deltas) { |
514 // Since power_ten == numerator we must make a copy of 10^estimated_
power | 514 // Since power_ten == numerator we must make a copy of 10^estimated_
power |
515 // before we complete the computation of the numerator. | 515 // before we complete the computation of the numerator. |
516 // delta_plus = delta_minus = 10^estimated_power | 516 // delta_plus = delta_minus = 10^estimated_power |
517 delta_plus->AssignBignum(*power_ten); | 517 delta_plus->AssignBignum(*power_ten); |
518 delta_minus->AssignBignum(*power_ten); | 518 delta_minus->AssignBignum(*power_ten); |
519 } | 519 } |
520 | 520 |
521 // numerator = significand * 2 * 10^-estimated_power | 521 // numerator = significand * 2 * 10^-estimated_power |
522 // since v = significand * 2^exponent this is equivalent to | 522 // since v = significand * 2^exponent this is equivalent to |
523 // numerator = v * 10^-estimated_power * 2 * 2^-exponent. | 523 // numerator = v * 10^-estimated_power * 2 * 2^-exponent. |
524 // Remember: numerator has been abused as power_ten. So no need to assig
n it | 524 // Remember: numerator has been abused as power_ten. So no need to assig
n it |
525 // to itself. | 525 // to itself. |
526 ASSERT(numerator == power_ten); | 526 ASSERT(numerator == power_ten); |
527 numerator->MultiplyByUInt64(significand); | 527 numerator->MultiplyByUInt64(significand); |
528 | 528 |
529 // denominator = 2 * 2^-exponent with exponent < 0. | 529 // denominator = 2 * 2^-exponent with exponent < 0. |
530 denominator->AssignUInt16(1); | 530 denominator->AssignUInt16(1); |
531 denominator->ShiftLeft(-exponent); | 531 denominator->ShiftLeft(-exponent); |
532 | 532 |
533 if (need_boundary_deltas) { | 533 if (need_boundary_deltas) { |
534 // Introduce a common denominator so that the deltas to the boundari
es are | 534 // Introduce a common denominator so that the deltas to the boundari
es are |
535 // integers. | 535 // integers. |
536 numerator->ShiftLeft(1); | 536 numerator->ShiftLeft(1); |
537 denominator->ShiftLeft(1); | 537 denominator->ShiftLeft(1); |
538 // With this shift the boundaries have their correct value, since | 538 // With this shift the boundaries have their correct value, since |
539 // delta_plus = 10^-estimated_power, and | 539 // delta_plus = 10^-estimated_power, and |
540 // delta_minus = 10^-estimated_power. | 540 // delta_minus = 10^-estimated_power. |
541 // These assignments have been done earlier. | 541 // These assignments have been done earlier. |
542 | 542 |
543 // The special case where the lower boundary is twice as close. | 543 // The special case where the lower boundary is twice as close. |
544 // This time we have to look out for the exception too. | 544 // This time we have to look out for the exception too. |
545 uint64_t v_bits = Double(v).AsUint64(); | 545 uint64_t v_bits = Double(v).AsUint64(); |
546 if ((v_bits & Double::kSignificandMask) == 0 && | 546 if ((v_bits & Double::kSignificandMask) == 0 && |
547 // The only exception where a significand == 0 has its boundarie
s at | 547 // The only exception where a significand == 0 has its boundarie
s at |
548 // "normal" distances: | 548 // "normal" distances: |
549 (v_bits & Double::kExponentMask) != kMinimalNormalizedExponent)
{ | 549 (v_bits & Double::kExponentMask) != kMinimalNormalizedExponent)
{ |
550 numerator->ShiftLeft(1); // *2 | 550 numerator->ShiftLeft(1); // *2 |
551 denominator->ShiftLeft(1); // *2 | 551 denominator->ShiftLeft(1); // *2 |
552 delta_plus->ShiftLeft(1); // *2 | 552 delta_plus->ShiftLeft(1); // *2 |
553 } | 553 } |
554 } | 554 } |
555 } | 555 } |
556 | 556 |
557 | 557 |
558 // Let v = significand * 2^exponent. | 558 // Let v = significand * 2^exponent. |
559 // Computes v / 10^estimated_power exactly, as a ratio of two bignums, numer
ator | 559 // Computes v / 10^estimated_power exactly, as a ratio of two bignums, numer
ator |
560 // and denominator. The functions GenerateShortestDigits and | 560 // and denominator. The functions GenerateShortestDigits and |
561 // GenerateCountedDigits will then convert this ratio to its decimal | 561 // GenerateCountedDigits will then convert this ratio to its decimal |
562 // representation d, with the required accuracy. | 562 // representation d, with the required accuracy. |
563 // Then d * 10^estimated_power is the representation of v. | 563 // Then d * 10^estimated_power is the representation of v. |
564 // (Note: the fraction and the estimated_power might get adjusted before | 564 // (Note: the fraction and the estimated_power might get adjusted before |
565 // generating the decimal representation.) | 565 // generating the decimal representation.) |
566 // | 566 // |
567 // The initial start values consist of: | 567 // The initial start values consist of: |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
605 } else if (estimated_power >= 0) { | 605 } else if (estimated_power >= 0) { |
606 InitialScaledStartValuesNegativeExponentPositivePower( | 606 InitialScaledStartValuesNegativeExponentPositivePower( |
607 v, estimated_p
ower, need_boundary_deltas, | 607 v, estimated_p
ower, need_boundary_deltas, |
608 numerator, den
ominator, delta_minus, delta_plus); | 608 numerator, den
ominator, delta_minus, delta_plus); |
609 } else { | 609 } else { |
610 InitialScaledStartValuesNegativeExponentNegativePower( | 610 InitialScaledStartValuesNegativeExponentNegativePower( |
611 v, estimated_p
ower, need_boundary_deltas, | 611 v, estimated_p
ower, need_boundary_deltas, |
612 numerator, den
ominator, delta_minus, delta_plus); | 612 numerator, den
ominator, delta_minus, delta_plus); |
613 } | 613 } |
614 } | 614 } |
615 | 615 |
616 | 616 |
617 // This routine multiplies numerator/denominator so that its values lies in
the | 617 // This routine multiplies numerator/denominator so that its values lies in
the |
618 // range 1-10. That is after a call to this function we have: | 618 // range 1-10. That is after a call to this function we have: |
619 // 1 <= (numerator + delta_plus) /denominator < 10. | 619 // 1 <= (numerator + delta_plus) /denominator < 10. |
620 // Let numerator the input before modification and numerator' the argument | 620 // Let numerator the input before modification and numerator' the argument |
621 // after modification, then the output-parameter decimal_point is such that | 621 // after modification, then the output-parameter decimal_point is such that |
622 // numerator / denominator * 10^estimated_power == | 622 // numerator / denominator * 10^estimated_power == |
623 // numerator' / denominator' * 10^(decimal_point - 1) | 623 // numerator' / denominator' * 10^(decimal_point - 1) |
624 // In some cases estimated_power was too low, and this is already the case.
We | 624 // In some cases estimated_power was too low, and this is already the case.
We |
625 // then simply adjust the power so that 10^(k-1) <= v < 10^k (with k == | 625 // then simply adjust the power so that 10^(k-1) <= v < 10^k (with k == |
626 // estimated_power) but do not touch the numerator or denominator. | 626 // estimated_power) but do not touch the numerator or denominator. |
(...skipping 19 matching lines...) Expand all Loading... |
646 numerator->Times10(); | 646 numerator->Times10(); |
647 if (Bignum::Equal(*delta_minus, *delta_plus)) { | 647 if (Bignum::Equal(*delta_minus, *delta_plus)) { |
648 delta_minus->Times10(); | 648 delta_minus->Times10(); |
649 delta_plus->AssignBignum(*delta_minus); | 649 delta_plus->AssignBignum(*delta_minus); |
650 } else { | 650 } else { |
651 delta_minus->Times10(); | 651 delta_minus->Times10(); |
652 delta_plus->Times10(); | 652 delta_plus->Times10(); |
653 } | 653 } |
654 } | 654 } |
655 } | 655 } |
656 | 656 |
657 } // namespace double_conversion | 657 } // namespace double_conversion |
658 | 658 |
659 } // namespace WTF | 659 } // namespace WTF |
OLD | NEW |