|
1 // Copyright 2010 the V8 project authors. All rights reserved. |
|
2 // Redistribution and use in source and binary forms, with or without |
|
3 // modification, are permitted provided that the following conditions are |
|
4 // met: |
|
5 // |
|
6 // * Redistributions of source code must retain the above copyright |
|
7 // notice, this list of conditions and the following disclaimer. |
|
8 // * Redistributions in binary form must reproduce the above |
|
9 // copyright notice, this list of conditions and the following |
|
10 // disclaimer in the documentation and/or other materials provided |
|
11 // with the distribution. |
|
12 // * Neither the name of Google Inc. nor the names of its |
|
13 // contributors may be used to endorse or promote products derived |
|
14 // from this software without specific prior written permission. |
|
15 // |
|
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
27 |
|
28 #include <math.h> |
|
29 |
|
30 #include "bignum-dtoa.h" |
|
31 |
|
32 #include "bignum.h" |
|
33 #include "ieee.h" |
|
34 |
|
35 namespace double_conversion { |
|
36 |
|
37 static int NormalizedExponent(uint64_t significand, int exponent) { |
|
38 ASSERT(significand != 0); |
|
39 while ((significand & Double::kHiddenBit) == 0) { |
|
40 significand = significand << 1; |
|
41 exponent = exponent - 1; |
|
42 } |
|
43 return exponent; |
|
44 } |
|
45 |
|
46 |
|
47 // Forward declarations: |
|
48 // Returns an estimation of k such that 10^(k-1) <= v < 10^k. |
|
49 static int EstimatePower(int exponent); |
|
50 // Computes v / 10^estimated_power exactly, as a ratio of two bignums, numerator |
|
51 // and denominator. |
|
52 static void InitialScaledStartValues(uint64_t significand, |
|
53 int exponent, |
|
54 bool lower_boundary_is_closer, |
|
55 int estimated_power, |
|
56 bool need_boundary_deltas, |
|
57 Bignum* numerator, |
|
58 Bignum* denominator, |
|
59 Bignum* delta_minus, |
|
60 Bignum* delta_plus); |
|
61 // Multiplies numerator/denominator so that its values lies in the range 1-10. |
|
62 // Returns decimal_point s.t. |
|
63 // v = numerator'/denominator' * 10^(decimal_point-1) |
|
64 // where numerator' and denominator' are the values of numerator and |
|
65 // denominator after the call to this function. |
|
66 static void FixupMultiply10(int estimated_power, bool is_even, |
|
67 int* decimal_point, |
|
68 Bignum* numerator, Bignum* denominator, |
|
69 Bignum* delta_minus, Bignum* delta_plus); |
|
70 // Generates digits from the left to the right and stops when the generated |
|
71 // digits yield the shortest decimal representation of v. |
|
72 static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator, |
|
73 Bignum* delta_minus, Bignum* delta_plus, |
|
74 bool is_even, |
|
75 Vector<char> buffer, int* length); |
|
76 // Generates 'requested_digits' after the decimal point. |
|
77 static void BignumToFixed(int requested_digits, int* decimal_point, |
|
78 Bignum* numerator, Bignum* denominator, |
|
79 Vector<char>(buffer), int* length); |
|
80 // Generates 'count' digits of numerator/denominator. |
|
81 // Once 'count' digits have been produced rounds the result depending on the |
|
82 // remainder (remainders of exactly .5 round upwards). Might update the |
|
83 // decimal_point when rounding up (for example for 0.9999). |
|
84 static void GenerateCountedDigits(int count, int* decimal_point, |
|
85 Bignum* numerator, Bignum* denominator, |
|
86 Vector<char>(buffer), int* length); |
|
87 |
|
88 |
|
89 void BignumDtoa(double v, BignumDtoaMode mode, int requested_digits, |
|
90 Vector<char> buffer, int* length, int* decimal_point) { |
|
91 ASSERT(v > 0); |
|
92 ASSERT(!Double(v).IsSpecial()); |
|
93 uint64_t significand; |
|
94 int exponent; |
|
95 bool lower_boundary_is_closer; |
|
96 if (mode == BIGNUM_DTOA_SHORTEST_SINGLE) { |
|
97 float f = static_cast<float>(v); |
|
98 ASSERT(f == v); |
|
99 significand = Single(f).Significand(); |
|
100 exponent = Single(f).Exponent(); |
|
101 lower_boundary_is_closer = Single(f).LowerBoundaryIsCloser(); |
|
102 } else { |
|
103 significand = Double(v).Significand(); |
|
104 exponent = Double(v).Exponent(); |
|
105 lower_boundary_is_closer = Double(v).LowerBoundaryIsCloser(); |
|
106 } |
|
107 bool need_boundary_deltas = |
|
108 (mode == BIGNUM_DTOA_SHORTEST || mode == BIGNUM_DTOA_SHORTEST_SINGLE); |
|
109 |
|
110 bool is_even = (significand & 1) == 0; |
|
111 int normalized_exponent = NormalizedExponent(significand, exponent); |
|
112 // estimated_power might be too low by 1. |
|
113 int estimated_power = EstimatePower(normalized_exponent); |
|
114 |
|
115 // Shortcut for Fixed. |
|
116 // The requested digits correspond to the digits after the point. If the |
|
117 // number is much too small, then there is no need in trying to get any |
|
118 // digits. |
|
119 if (mode == BIGNUM_DTOA_FIXED && -estimated_power - 1 > requested_digits) { |
|
120 buffer[0] = '\0'; |
|
121 *length = 0; |
|
122 // Set decimal-point to -requested_digits. This is what Gay does. |
|
123 // Note that it should not have any effect anyways since the string is |
|
124 // empty. |
|
125 *decimal_point = -requested_digits; |
|
126 return; |
|
127 } |
|
128 |
|
129 Bignum numerator; |
|
130 Bignum denominator; |
|
131 Bignum delta_minus; |
|
132 Bignum delta_plus; |
|
133 // Make sure the bignum can grow large enough. The smallest double equals |
|
134 // 4e-324. In this case the denominator needs fewer than 324*4 binary digits. |
|
135 // The maximum double is 1.7976931348623157e308 which needs fewer than |
|
136 // 308*4 binary digits. |
|
137 ASSERT(Bignum::kMaxSignificantBits >= 324*4); |
|
138 InitialScaledStartValues(significand, exponent, lower_boundary_is_closer, |
|
139 estimated_power, need_boundary_deltas, |
|
140 &numerator, &denominator, |
|
141 &delta_minus, &delta_plus); |
|
142 // We now have v = (numerator / denominator) * 10^estimated_power. |
|
143 FixupMultiply10(estimated_power, is_even, decimal_point, |
|
144 &numerator, &denominator, |
|
145 &delta_minus, &delta_plus); |
|
146 // We now have v = (numerator / denominator) * 10^(decimal_point-1), and |
|
147 // 1 <= (numerator + delta_plus) / denominator < 10 |
|
148 switch (mode) { |
|
149 case BIGNUM_DTOA_SHORTEST: |
|
150 case BIGNUM_DTOA_SHORTEST_SINGLE: |
|
151 GenerateShortestDigits(&numerator, &denominator, |
|
152 &delta_minus, &delta_plus, |
|
153 is_even, buffer, length); |
|
154 break; |
|
155 case BIGNUM_DTOA_FIXED: |
|
156 BignumToFixed(requested_digits, decimal_point, |
|
157 &numerator, &denominator, |
|
158 buffer, length); |
|
159 break; |
|
160 case BIGNUM_DTOA_PRECISION: |
|
161 GenerateCountedDigits(requested_digits, decimal_point, |
|
162 &numerator, &denominator, |
|
163 buffer, length); |
|
164 break; |
|
165 default: |
|
166 UNREACHABLE(); |
|
167 } |
|
168 buffer[*length] = '\0'; |
|
169 } |
|
170 |
|
171 |
|
172 // The procedure starts generating digits from the left to the right and stops |
|
173 // when the generated digits yield the shortest decimal representation of v. A |
|
174 // decimal representation of v is a number lying closer to v than to any other |
|
175 // double, so it converts to v when read. |
|
176 // |
|
177 // This is true if d, the decimal representation, is between m- and m+, the |
|
178 // upper and lower boundaries. d must be strictly between them if !is_even. |
|
179 // m- := (numerator - delta_minus) / denominator |
|
180 // m+ := (numerator + delta_plus) / denominator |
|
181 // |
|
182 // Precondition: 0 <= (numerator+delta_plus) / denominator < 10. |
|
183 // If 1 <= (numerator+delta_plus) / denominator < 10 then no leading 0 digit |
|
184 // will be produced. This should be the standard precondition. |
|
185 static void GenerateShortestDigits(Bignum* numerator, Bignum* denominator, |
|
186 Bignum* delta_minus, Bignum* delta_plus, |
|
187 bool is_even, |
|
188 Vector<char> buffer, int* length) { |
|
189 // Small optimization: if delta_minus and delta_plus are the same just reuse |
|
190 // one of the two bignums. |
|
191 if (Bignum::Equal(*delta_minus, *delta_plus)) { |
|
192 delta_plus = delta_minus; |
|
193 } |
|
194 *length = 0; |
|
195 while (true) { |
|
196 uint16_t digit; |
|
197 digit = numerator->DivideModuloIntBignum(*denominator); |
|
198 ASSERT(digit <= 9); // digit is a uint16_t and therefore always positive. |
|
199 // digit = numerator / denominator (integer division). |
|
200 // numerator = numerator % denominator. |
|
201 buffer[(*length)++] = digit + '0'; |
|
202 |
|
203 // Can we stop already? |
|
204 // If the remainder of the division is less than the distance to the lower |
|
205 // boundary we can stop. In this case we simply round down (discarding the |
|
206 // remainder). |
|
207 // Similarly we test if we can round up (using the upper boundary). |
|
208 bool in_delta_room_minus; |
|
209 bool in_delta_room_plus; |
|
210 if (is_even) { |
|
211 in_delta_room_minus = Bignum::LessEqual(*numerator, *delta_minus); |
|
212 } else { |
|
213 in_delta_room_minus = Bignum::Less(*numerator, *delta_minus); |
|
214 } |
|
215 if (is_even) { |
|
216 in_delta_room_plus = |
|
217 Bignum::PlusCompare(*numerator, *delta_plus, *denominator) >= 0; |
|
218 } else { |
|
219 in_delta_room_plus = |
|
220 Bignum::PlusCompare(*numerator, *delta_plus, *denominator) > 0; |
|
221 } |
|
222 if (!in_delta_room_minus && !in_delta_room_plus) { |
|
223 // Prepare for next iteration. |
|
224 numerator->Times10(); |
|
225 delta_minus->Times10(); |
|
226 // We optimized delta_plus to be equal to delta_minus (if they share the |
|
227 // same value). So don't multiply delta_plus if they point to the same |
|
228 // object. |
|
229 if (delta_minus != delta_plus) { |
|
230 delta_plus->Times10(); |
|
231 } |
|
232 } else if (in_delta_room_minus && in_delta_room_plus) { |
|
233 // Let's see if 2*numerator < denominator. |
|
234 // If yes, then the next digit would be < 5 and we can round down. |
|
235 int compare = Bignum::PlusCompare(*numerator, *numerator, *denominator); |
|
236 if (compare < 0) { |
|
237 // Remaining digits are less than .5. -> Round down (== do nothing). |
|
238 } else if (compare > 0) { |
|
239 // Remaining digits are more than .5 of denominator. -> Round up. |
|
240 // Note that the last digit could not be a '9' as otherwise the whole |
|
241 // loop would have stopped earlier. |
|
242 // We still have an assert here in case the preconditions were not |
|
243 // satisfied. |
|
244 ASSERT(buffer[(*length) - 1] != '9'); |
|
245 buffer[(*length) - 1]++; |
|
246 } else { |
|
247 // Halfway case. |
|
248 // TODO(floitsch): need a way to solve half-way cases. |
|
249 // For now let's round towards even (since this is what Gay seems to |
|
250 // do). |
|
251 |
|
252 if ((buffer[(*length) - 1] - '0') % 2 == 0) { |
|
253 // Round down => Do nothing. |
|
254 } else { |
|
255 ASSERT(buffer[(*length) - 1] != '9'); |
|
256 buffer[(*length) - 1]++; |
|
257 } |
|
258 } |
|
259 return; |
|
260 } else if (in_delta_room_minus) { |
|
261 // Round down (== do nothing). |
|
262 return; |
|
263 } else { // in_delta_room_plus |
|
264 // Round up. |
|
265 // Note again that the last digit could not be '9' since this would have |
|
266 // stopped the loop earlier. |
|
267 // We still have an ASSERT here, in case the preconditions were not |
|
268 // satisfied. |
|
269 ASSERT(buffer[(*length) -1] != '9'); |
|
270 buffer[(*length) - 1]++; |
|
271 return; |
|
272 } |
|
273 } |
|
274 } |
|
275 |
|
276 |
|
277 // Let v = numerator / denominator < 10. |
|
278 // Then we generate 'count' digits of d = x.xxxxx... (without the decimal point) |
|
279 // from left to right. Once 'count' digits have been produced we decide wether |
|
280 // to round up or down. Remainders of exactly .5 round upwards. Numbers such |
|
281 // as 9.999999 propagate a carry all the way, and change the |
|
282 // exponent (decimal_point), when rounding upwards. |
|
283 static void GenerateCountedDigits(int count, int* decimal_point, |
|
284 Bignum* numerator, Bignum* denominator, |
|
285 Vector<char>(buffer), int* length) { |
|
286 ASSERT(count >= 0); |
|
287 for (int i = 0; i < count - 1; ++i) { |
|
288 uint16_t digit; |
|
289 digit = numerator->DivideModuloIntBignum(*denominator); |
|
290 ASSERT(digit <= 9); // digit is a uint16_t and therefore always positive. |
|
291 // digit = numerator / denominator (integer division). |
|
292 // numerator = numerator % denominator. |
|
293 buffer[i] = digit + '0'; |
|
294 // Prepare for next iteration. |
|
295 numerator->Times10(); |
|
296 } |
|
297 // Generate the last digit. |
|
298 uint16_t digit; |
|
299 digit = numerator->DivideModuloIntBignum(*denominator); |
|
300 if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) { |
|
301 digit++; |
|
302 } |
|
303 buffer[count - 1] = digit + '0'; |
|
304 // Correct bad digits (in case we had a sequence of '9's). Propagate the |
|
305 // carry until we hat a non-'9' or til we reach the first digit. |
|
306 for (int i = count - 1; i > 0; --i) { |
|
307 if (buffer[i] != '0' + 10) break; |
|
308 buffer[i] = '0'; |
|
309 buffer[i - 1]++; |
|
310 } |
|
311 if (buffer[0] == '0' + 10) { |
|
312 // Propagate a carry past the top place. |
|
313 buffer[0] = '1'; |
|
314 (*decimal_point)++; |
|
315 } |
|
316 *length = count; |
|
317 } |
|
318 |
|
319 |
|
320 // Generates 'requested_digits' after the decimal point. It might omit |
|
321 // trailing '0's. If the input number is too small then no digits at all are |
|
322 // generated (ex.: 2 fixed digits for 0.00001). |
|
323 // |
|
324 // Input verifies: 1 <= (numerator + delta) / denominator < 10. |
|
325 static void BignumToFixed(int requested_digits, int* decimal_point, |
|
326 Bignum* numerator, Bignum* denominator, |
|
327 Vector<char>(buffer), int* length) { |
|
328 // Note that we have to look at more than just the requested_digits, since |
|
329 // a number could be rounded up. Example: v=0.5 with requested_digits=0. |
|
330 // Even though the power of v equals 0 we can't just stop here. |
|
331 if (-(*decimal_point) > requested_digits) { |
|
332 // The number is definitively too small. |
|
333 // Ex: 0.001 with requested_digits == 1. |
|
334 // Set decimal-point to -requested_digits. This is what Gay does. |
|
335 // Note that it should not have any effect anyways since the string is |
|
336 // empty. |
|
337 *decimal_point = -requested_digits; |
|
338 *length = 0; |
|
339 return; |
|
340 } else if (-(*decimal_point) == requested_digits) { |
|
341 // We only need to verify if the number rounds down or up. |
|
342 // Ex: 0.04 and 0.06 with requested_digits == 1. |
|
343 ASSERT(*decimal_point == -requested_digits); |
|
344 // Initially the fraction lies in range (1, 10]. Multiply the denominator |
|
345 // by 10 so that we can compare more easily. |
|
346 denominator->Times10(); |
|
347 if (Bignum::PlusCompare(*numerator, *numerator, *denominator) >= 0) { |
|
348 // If the fraction is >= 0.5 then we have to include the rounded |
|
349 // digit. |
|
350 buffer[0] = '1'; |
|
351 *length = 1; |
|
352 (*decimal_point)++; |
|
353 } else { |
|
354 // Note that we caught most of similar cases earlier. |
|
355 *length = 0; |
|
356 } |
|
357 return; |
|
358 } else { |
|
359 // The requested digits correspond to the digits after the point. |
|
360 // The variable 'needed_digits' includes the digits before the point. |
|
361 int needed_digits = (*decimal_point) + requested_digits; |
|
362 GenerateCountedDigits(needed_digits, decimal_point, |
|
363 numerator, denominator, |
|
364 buffer, length); |
|
365 } |
|
366 } |
|
367 |
|
368 |
|
369 // Returns an estimation of k such that 10^(k-1) <= v < 10^k where |
|
370 // v = f * 2^exponent and 2^52 <= f < 2^53. |
|
371 // v is hence a normalized double with the given exponent. The output is an |
|
372 // approximation for the exponent of the decimal approimation .digits * 10^k. |
|
373 // |
|
374 // The result might undershoot by 1 in which case 10^k <= v < 10^k+1. |
|
375 // Note: this property holds for v's upper boundary m+ too. |
|
376 // 10^k <= m+ < 10^k+1. |
|
377 // (see explanation below). |
|
378 // |
|
379 // Examples: |
|
380 // EstimatePower(0) => 16 |
|
381 // EstimatePower(-52) => 0 |
|
382 // |
|
383 // Note: e >= 0 => EstimatedPower(e) > 0. No similar claim can be made for e<0. |
|
384 static int EstimatePower(int exponent) { |
|
385 // This function estimates log10 of v where v = f*2^e (with e == exponent). |
|
386 // Note that 10^floor(log10(v)) <= v, but v <= 10^ceil(log10(v)). |
|
387 // Note that f is bounded by its container size. Let p = 53 (the double's |
|
388 // significand size). Then 2^(p-1) <= f < 2^p. |
|
389 // |
|
390 // Given that log10(v) == log2(v)/log2(10) and e+(len(f)-1) is quite close |
|
391 // to log2(v) the function is simplified to (e+(len(f)-1)/log2(10)). |
|
392 // The computed number undershoots by less than 0.631 (when we compute log3 |
|
393 // and not log10). |
|
394 // |
|
395 // Optimization: since we only need an approximated result this computation |
|
396 // can be performed on 64 bit integers. On x86/x64 architecture the speedup is |
|
397 // not really measurable, though. |
|
398 // |
|
399 // Since we want to avoid overshooting we decrement by 1e10 so that |
|
400 // floating-point imprecisions don't affect us. |
|
401 // |
|
402 // Explanation for v's boundary m+: the computation takes advantage of |
|
403 // the fact that 2^(p-1) <= f < 2^p. Boundaries still satisfy this requirement |
|
404 // (even for denormals where the delta can be much more important). |
|
405 |
|
406 const double k1Log10 = 0.30102999566398114; // 1/lg(10) |
|
407 |
|
408 // For doubles len(f) == 53 (don't forget the hidden bit). |
|
409 const int kSignificandSize = Double::kSignificandSize; |
|
410 double estimate = ceil((exponent + kSignificandSize - 1) * k1Log10 - 1e-10); |
|
411 return static_cast<int>(estimate); |
|
412 } |
|
413 |
|
414 |
|
415 // See comments for InitialScaledStartValues. |
|
416 static void InitialScaledStartValuesPositiveExponent( |
|
417 uint64_t significand, int exponent, |
|
418 int estimated_power, bool need_boundary_deltas, |
|
419 Bignum* numerator, Bignum* denominator, |
|
420 Bignum* delta_minus, Bignum* delta_plus) { |
|
421 // A positive exponent implies a positive power. |
|
422 ASSERT(estimated_power >= 0); |
|
423 // Since the estimated_power is positive we simply multiply the denominator |
|
424 // by 10^estimated_power. |
|
425 |
|
426 // numerator = v. |
|
427 numerator->AssignUInt64(significand); |
|
428 numerator->ShiftLeft(exponent); |
|
429 // denominator = 10^estimated_power. |
|
430 denominator->AssignPowerUInt16(10, estimated_power); |
|
431 |
|
432 if (need_boundary_deltas) { |
|
433 // Introduce a common denominator so that the deltas to the boundaries are |
|
434 // integers. |
|
435 denominator->ShiftLeft(1); |
|
436 numerator->ShiftLeft(1); |
|
437 // Let v = f * 2^e, then m+ - v = 1/2 * 2^e; With the common |
|
438 // denominator (of 2) delta_plus equals 2^e. |
|
439 delta_plus->AssignUInt16(1); |
|
440 delta_plus->ShiftLeft(exponent); |
|
441 // Same for delta_minus. The adjustments if f == 2^p-1 are done later. |
|
442 delta_minus->AssignUInt16(1); |
|
443 delta_minus->ShiftLeft(exponent); |
|
444 } |
|
445 } |
|
446 |
|
447 |
|
448 // See comments for InitialScaledStartValues |
|
449 static void InitialScaledStartValuesNegativeExponentPositivePower( |
|
450 uint64_t significand, int exponent, |
|
451 int estimated_power, bool need_boundary_deltas, |
|
452 Bignum* numerator, Bignum* denominator, |
|
453 Bignum* delta_minus, Bignum* delta_plus) { |
|
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 is |
|
456 // computed). |
|
457 |
|
458 // numerator = significand |
|
459 // since v = significand * 2^exponent this is equivalent to |
|
460 // numerator = v * / 2^-exponent |
|
461 numerator->AssignUInt64(significand); |
|
462 // denominator = 10^estimated_power * 2^-exponent (with exponent < 0) |
|
463 denominator->AssignPowerUInt16(10, estimated_power); |
|
464 denominator->ShiftLeft(-exponent); |
|
465 |
|
466 if (need_boundary_deltas) { |
|
467 // Introduce a common denominator so that the deltas to the boundaries are |
|
468 // integers. |
|
469 denominator->ShiftLeft(1); |
|
470 numerator->ShiftLeft(1); |
|
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. |
|
473 // Given that the denominator already includes v's exponent the distance |
|
474 // to the boundaries is simply 1. |
|
475 delta_plus->AssignUInt16(1); |
|
476 // Same for delta_minus. The adjustments if f == 2^p-1 are done later. |
|
477 delta_minus->AssignUInt16(1); |
|
478 } |
|
479 } |
|
480 |
|
481 |
|
482 // See comments for InitialScaledStartValues |
|
483 static void InitialScaledStartValuesNegativeExponentNegativePower( |
|
484 uint64_t significand, int exponent, |
|
485 int estimated_power, bool need_boundary_deltas, |
|
486 Bignum* numerator, Bignum* denominator, |
|
487 Bignum* delta_minus, Bignum* delta_plus) { |
|
488 // Instead of multiplying the denominator with 10^estimated_power we |
|
489 // multiply all values (numerator and deltas) by 10^-estimated_power. |
|
490 |
|
491 // Use numerator as temporary container for power_ten. |
|
492 Bignum* power_ten = numerator; |
|
493 power_ten->AssignPowerUInt16(10, -estimated_power); |
|
494 |
|
495 if (need_boundary_deltas) { |
|
496 // Since power_ten == numerator we must make a copy of 10^estimated_power |
|
497 // before we complete the computation of the numerator. |
|
498 // delta_plus = delta_minus = 10^estimated_power |
|
499 delta_plus->AssignBignum(*power_ten); |
|
500 delta_minus->AssignBignum(*power_ten); |
|
501 } |
|
502 |
|
503 // numerator = significand * 2 * 10^-estimated_power |
|
504 // since v = significand * 2^exponent this is equivalent to |
|
505 // numerator = v * 10^-estimated_power * 2 * 2^-exponent. |
|
506 // Remember: numerator has been abused as power_ten. So no need to assign it |
|
507 // to itself. |
|
508 ASSERT(numerator == power_ten); |
|
509 numerator->MultiplyByUInt64(significand); |
|
510 |
|
511 // denominator = 2 * 2^-exponent with exponent < 0. |
|
512 denominator->AssignUInt16(1); |
|
513 denominator->ShiftLeft(-exponent); |
|
514 |
|
515 if (need_boundary_deltas) { |
|
516 // Introduce a common denominator so that the deltas to the boundaries are |
|
517 // integers. |
|
518 numerator->ShiftLeft(1); |
|
519 denominator->ShiftLeft(1); |
|
520 // With this shift the boundaries have their correct value, since |
|
521 // delta_plus = 10^-estimated_power, and |
|
522 // delta_minus = 10^-estimated_power. |
|
523 // These assignments have been done earlier. |
|
524 // The adjustments if f == 2^p-1 (lower boundary is closer) are done later. |
|
525 } |
|
526 } |
|
527 |
|
528 |
|
529 // Let v = significand * 2^exponent. |
|
530 // Computes v / 10^estimated_power exactly, as a ratio of two bignums, numerator |
|
531 // and denominator. The functions GenerateShortestDigits and |
|
532 // GenerateCountedDigits will then convert this ratio to its decimal |
|
533 // representation d, with the required accuracy. |
|
534 // Then d * 10^estimated_power is the representation of v. |
|
535 // (Note: the fraction and the estimated_power might get adjusted before |
|
536 // generating the decimal representation.) |
|
537 // |
|
538 // The initial start values consist of: |
|
539 // - a scaled numerator: s.t. numerator/denominator == v / 10^estimated_power. |
|
540 // - a scaled (common) denominator. |
|
541 // optionally (used by GenerateShortestDigits to decide if it has the shortest |
|
542 // decimal converting back to v): |
|
543 // - v - m-: the distance to the lower boundary. |
|
544 // - m+ - v: the distance to the upper boundary. |
|
545 // |
|
546 // v, m+, m-, and therefore v - m- and m+ - v all share the same denominator. |
|
547 // |
|
548 // Let ep == estimated_power, then the returned values will satisfy: |
|
549 // v / 10^ep = numerator / denominator. |
|
550 // v's boundarys m- and m+: |
|
551 // m- / 10^ep == v / 10^ep - delta_minus / denominator |
|
552 // m+ / 10^ep == v / 10^ep + delta_plus / denominator |
|
553 // Or in other words: |
|
554 // m- == v - delta_minus * 10^ep / denominator; |
|
555 // m+ == v + delta_plus * 10^ep / denominator; |
|
556 // |
|
557 // Since 10^(k-1) <= v < 10^k (with k == estimated_power) |
|
558 // or 10^k <= v < 10^(k+1) |
|
559 // we then have 0.1 <= numerator/denominator < 1 |
|
560 // or 1 <= numerator/denominator < 10 |
|
561 // |
|
562 // It is then easy to kickstart the digit-generation routine. |
|
563 // |
|
564 // The boundary-deltas are only filled if the mode equals BIGNUM_DTOA_SHORTEST |
|
565 // or BIGNUM_DTOA_SHORTEST_SINGLE. |
|
566 |
|
567 static void InitialScaledStartValues(uint64_t significand, |
|
568 int exponent, |
|
569 bool lower_boundary_is_closer, |
|
570 int estimated_power, |
|
571 bool need_boundary_deltas, |
|
572 Bignum* numerator, |
|
573 Bignum* denominator, |
|
574 Bignum* delta_minus, |
|
575 Bignum* delta_plus) { |
|
576 if (exponent >= 0) { |
|
577 InitialScaledStartValuesPositiveExponent( |
|
578 significand, exponent, estimated_power, need_boundary_deltas, |
|
579 numerator, denominator, delta_minus, delta_plus); |
|
580 } else if (estimated_power >= 0) { |
|
581 InitialScaledStartValuesNegativeExponentPositivePower( |
|
582 significand, exponent, estimated_power, need_boundary_deltas, |
|
583 numerator, denominator, delta_minus, delta_plus); |
|
584 } else { |
|
585 InitialScaledStartValuesNegativeExponentNegativePower( |
|
586 significand, exponent, estimated_power, need_boundary_deltas, |
|
587 numerator, denominator, delta_minus, delta_plus); |
|
588 } |
|
589 |
|
590 if (need_boundary_deltas && lower_boundary_is_closer) { |
|
591 // The lower boundary is closer at half the distance of "normal" numbers. |
|
592 // Increase the common denominator and adapt all but the delta_minus. |
|
593 denominator->ShiftLeft(1); // *2 |
|
594 numerator->ShiftLeft(1); // *2 |
|
595 delta_plus->ShiftLeft(1); // *2 |
|
596 } |
|
597 } |
|
598 |
|
599 |
|
600 // This routine multiplies numerator/denominator so that its values lies in the |
|
601 // range 1-10. That is after a call to this function we have: |
|
602 // 1 <= (numerator + delta_plus) /denominator < 10. |
|
603 // Let numerator the input before modification and numerator' the argument |
|
604 // after modification, then the output-parameter decimal_point is such that |
|
605 // numerator / denominator * 10^estimated_power == |
|
606 // numerator' / denominator' * 10^(decimal_point - 1) |
|
607 // In some cases estimated_power was too low, and this is already the case. We |
|
608 // then simply adjust the power so that 10^(k-1) <= v < 10^k (with k == |
|
609 // estimated_power) but do not touch the numerator or denominator. |
|
610 // Otherwise the routine multiplies the numerator and the deltas by 10. |
|
611 static void FixupMultiply10(int estimated_power, bool is_even, |
|
612 int* decimal_point, |
|
613 Bignum* numerator, Bignum* denominator, |
|
614 Bignum* delta_minus, Bignum* delta_plus) { |
|
615 bool in_range; |
|
616 if (is_even) { |
|
617 // For IEEE doubles half-way cases (in decimal system numbers ending with 5) |
|
618 // are rounded to the closest floating-point number with even significand. |
|
619 in_range = Bignum::PlusCompare(*numerator, *delta_plus, *denominator) >= 0; |
|
620 } else { |
|
621 in_range = Bignum::PlusCompare(*numerator, *delta_plus, *denominator) > 0; |
|
622 } |
|
623 if (in_range) { |
|
624 // Since numerator + delta_plus >= denominator we already have |
|
625 // 1 <= numerator/denominator < 10. Simply update the estimated_power. |
|
626 *decimal_point = estimated_power + 1; |
|
627 } else { |
|
628 *decimal_point = estimated_power; |
|
629 numerator->Times10(); |
|
630 if (Bignum::Equal(*delta_minus, *delta_plus)) { |
|
631 delta_minus->Times10(); |
|
632 delta_plus->AssignBignum(*delta_minus); |
|
633 } else { |
|
634 delta_minus->Times10(); |
|
635 delta_plus->Times10(); |
|
636 } |
|
637 } |
|
638 } |
|
639 |
|
640 } // namespace double_conversion |