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