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

Method doubleToDecimal

core/src/main/java/io/questdb/std/Numbers.java:676–722  ·  view source on GitHub ↗

Converts a double to the smallest DECIMAL type that represents it losslessly. Populates exactly one of the three sinks. Returns the full column type int (ColumnType#getDecimalType(int, int)) on success, or 0 for NaN / Infinity / value doesn't fit in any DECIMAL type. @param value the doub

(
            double value,
            Decimal64 sink64,
            Decimal128 sink128,
            Decimal256 sink256
    )

Source from the content-addressed store, hash-verified

674 * @return the column type int, or 0 on failure
675 */
676 public static int doubleToDecimal(
677 double value,
678 Decimal64 sink64,
679 Decimal128 sink128,
680 Decimal256 sink256
681 ) {
682 final long doubleBits = Double.doubleToRawLongBits(value);
683 boolean negative = (doubleBits & SIGN_BIT_MASK) != 0L;
684 long ieeeMantissa = doubleBits & SIGNIF_BIT_MASK;
685 int ieeeExponent = (int) ((doubleBits & EXP_BIT_MASK) >> EXP_SHIFT);
686
687 if (ieeeExponent == 2047) {
688 return 0; // NaN or Infinity
689 }
690
691 if (ieeeExponent == 0 && ieeeMantissa == 0L) {
692 sink64.ofZero();
693 return ColumnType.getDecimalType(1, 0);
694 }
695
696 int[] e10 = tlE10.get();
697 long output = RyuDouble.d2d(ieeeMantissa, ieeeExponent, e10);
698 int olength = RyuDouble.decimalLength17(output);
699 int decExp = e10[0] + olength;
700
701 int naturalScale = Math.max(0, -e10[0]);
702 int integerDigits = Math.max(0, decExp);
703 int precision = Math.max(1, integerDigits + naturalScale);
704
705 Decimal target;
706 if (precision <= Decimal64.MAX_PRECISION && naturalScale <= Decimal64.MAX_SCALE) {
707 target = sink64;
708 } else if (precision <= Decimal128.MAX_PRECISION && naturalScale <= Decimal128.MAX_SCALE) {
709 target = sink128;
710 } else if (precision <= Decimals.MAX_PRECISION && naturalScale <= Decimal256.MAX_SCALE) {
711 target = sink256;
712 } else {
713 return 0;
714 }
715
716 target.ofDigitsAndPower(output, e10[0]);
717 if (negative) {
718 target.negate();
719 }
720
721 return ColumnType.getDecimalType(precision, naturalScale);
722 }
723
724 /**
725 * Converts a double directly to a Decimal with the specified target precision and scale,

Calls 10

getDecimalTypeMethod · 0.95
d2dMethod · 0.95
decimalLength17Method · 0.95
ofDigitsAndPowerMethod · 0.95
negateMethod · 0.95
instanceMethod · 0.95
ofZeroMethod · 0.65
getMethod · 0.65
putMethod · 0.65
setScaleMethod · 0.65