From 952fbbce28f4de0a125c0fcf62d70e57b6f087fb Mon Sep 17 00:00:00 2001 From: Carlo Piovesan Date: Fri, 21 Jun 2024 15:16:32 +0200 Subject: [PATCH] Optimize fast path where ints are represented exactly --- src/common/operator/cast_operators.cpp | 51 ++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/common/operator/cast_operators.cpp b/src/common/operator/cast_operators.cpp index f6b33eff7156..e9f1be4fa5df 100644 --- a/src/common/operator/cast_operators.cpp +++ b/src/common/operator/cast_operators.cpp @@ -2631,6 +2631,52 @@ bool TryCastFromDecimal::Operation(hugeint_t input, uhugeint_t &result, CastPara //===--------------------------------------------------------------------===// // Decimal -> Float/Double Cast //===--------------------------------------------------------------------===// +template +static bool IsRepresentableExactly(SRC input, DST); + +template <> +bool IsRepresentableExactly(int16_t input, float dst) { + return true; +} + +const int64_t MAX_INT_REPRESENTABLE_IN_FLOAT = 0x001000000LL; +const int64_t MAX_INT_REPRESENTABLE_IN_DOUBLE = 0x0020000000000000LL; + +template <> +bool IsRepresentableExactly(int32_t input, float dst) { + return (input <= MAX_INT_REPRESENTABLE_IN_FLOAT && input >= -MAX_INT_REPRESENTABLE_IN_FLOAT); +} + +template <> +bool IsRepresentableExactly(int64_t input, float dst) { + return (input <= MAX_INT_REPRESENTABLE_IN_FLOAT && input >= -MAX_INT_REPRESENTABLE_IN_FLOAT); +} + +template <> +bool IsRepresentableExactly(hugeint_t input, float dst) { + return (input <= MAX_INT_REPRESENTABLE_IN_FLOAT && input >= -MAX_INT_REPRESENTABLE_IN_FLOAT); +} + +template <> +bool IsRepresentableExactly(int16_t input, double dst) { + return true; +} + +template <> +bool IsRepresentableExactly(int32_t input, double dst) { + return true; +} + +template <> +bool IsRepresentableExactly(int64_t input, double dst) { + return (input <= MAX_INT_REPRESENTABLE_IN_DOUBLE && input >= -MAX_INT_REPRESENTABLE_IN_DOUBLE); +} + +template <> +bool IsRepresentableExactly(hugeint_t input, double dst) { + return (input <= MAX_INT_REPRESENTABLE_IN_DOUBLE && input >= -MAX_INT_REPRESENTABLE_IN_DOUBLE); +} + template static SRC GetPowerOfTen(SRC input, uint8_t scale) { return static_cast(NumericHelper::POWERS_OF_TEN[scale]); @@ -2643,6 +2689,11 @@ hugeint_t GetPowerOfTen(hugeint_t input, uint8_t scale) { template bool TryCastDecimalToFloatingPoint(SRC input, DST &result, uint8_t scale) { + if (IsRepresentableExactly(input,DST(0.0))) { + // Fast path, integer is representable exaclty as a float/double + result = Cast::Operation(input) / DST(NumericHelper::DOUBLE_POWERS_OF_TEN[scale]); + return true; + } auto power_of_ten = GetPowerOfTen(input, scale); result = Cast::Operation(input / power_of_ten) + Cast::Operation(input % power_of_ten) / DST(NumericHelper::DOUBLE_POWERS_OF_TEN[scale]);