MCPcopy Create free account
hub / github.com/questdb/questdb / d2d

Method d2d

core/src/main/java/io/questdb/std/RyuDouble.java:424–609  ·  view source on GitHub ↗

Converts a decoded IEEE 754 double to its shortest decimal representation. @param ieeeMantissa the 52-bit mantissa (without implicit leading 1) @param ieeeExponent the biased 11-bit exponent (0-2046; 0 means subnormal) @param e10Out single-element array; receives the decimal exponent e10

(long ieeeMantissa, int ieeeExponent, int[] e10Out)

Source from the content-addressed store, hash-verified

422 * @return the decimal significand as a positive long (1-17 digits)
423 */
424 static long d2d(long ieeeMantissa, int ieeeExponent, int[] e10Out) {
425 int e2;
426 long m2;
427 if (ieeeExponent == 0) {
428 // Subnormal: no implicit leading 1, exponent is 1 (not 0)
429 e2 = 1 - 1023 - 52;
430 m2 = ieeeMantissa;
431 } else {
432 e2 = ieeeExponent - 1023 - 52;
433 m2 = ieeeMantissa | (1L << 52);
434 }
435
436 // Fast path for small integers: if the value is an exact integer in [1, 2^53),
437 // return it directly. This avoids the 4x-scaling issue in the main Ryu path.
438 if (e2 >= -52 && e2 <= 0) {
439 long mask = (1L << -e2) - 1;
440 if ((m2 & mask) == 0) {
441 long mantissa = m2 >>> -e2;
442 int exp = 0;
443 // Strip trailing decimal zeros
444 while (mantissa > 0) {
445 long q = mantissa / 10;
446 long r = mantissa - 10 * q;
447 if (r != 0) {
448 break;
449 }
450 mantissa = q;
451 exp++;
452 }
453 e10Out[0] = exp;
454 return mantissa;
455 }
456 }
457
458 // Subtract 2 from e2 to account for the 4x scaling (mv = 4*m2 below).
459 // This ensures mv * 2^e2 == m2 * 2^(e2_original), so the decimal
460 // conversion produces the correct (non-4x) significand.
461 e2 -= 2;
462
463 boolean acceptBounds = (m2 & 1) == 0;
464
465 // Step 2: Determine the interval of valid decimal representations.
466 long mv = 4 * m2;
467 long mp = 4 * m2 + 2;
468 int mmShift = (ieeeMantissa != 0 || ieeeExponent <= 1) ? 1 : 0;
469 long mm = 4 * m2 - 1 - mmShift;
470
471 // Step 3: Convert to a decimal power base using 128-bit arithmetic.
472 long vr, vp, vm;
473 int e10;
474 boolean vmIsTrailingZeros = false;
475 boolean vrIsTrailingZeros = false;
476
477 if (e2 >= 0) {
478 int q = Math.max(0, ((e2 * 78913) >>> 18) - 1);
479 e10 = q;
480 int k = DOUBLE_POW5_INV_BITCOUNT + pow5bits(q) - 1;
481 int i = -e2 + q + k;

Callers 2

appendMethod · 0.95
doubleToDecimalMethod · 0.95

Calls 4

pow5bitsMethod · 0.95
mulShift64Method · 0.95
multipleOfPowerOf5Method · 0.95
multipleOfPowerOf2Method · 0.95

Tested by

no test coverage detected