diff --git a/src/float/fast_float/bigint.cr b/src/float/fast_float/bigint.cr index 14b0bb2d0549..466057848a50 100644 --- a/src/float/fast_float/bigint.cr +++ b/src/float/fast_float/bigint.cr @@ -339,47 +339,92 @@ module Float::FastFloat module Pow5Tables LARGE_STEP = 135_u32 - SMALL_POWER_OF_5 = [ - 1_u64, - 5_u64, - 25_u64, - 125_u64, - 625_u64, - 3125_u64, - 15625_u64, - 78125_u64, - 390625_u64, - 1953125_u64, - 9765625_u64, - 48828125_u64, - 244140625_u64, - 1220703125_u64, - 6103515625_u64, - 30517578125_u64, - 152587890625_u64, - 762939453125_u64, - 3814697265625_u64, - 19073486328125_u64, - 95367431640625_u64, - 476837158203125_u64, - 2384185791015625_u64, - 11920928955078125_u64, - 59604644775390625_u64, - 298023223876953125_u64, - 1490116119384765625_u64, - 7450580596923828125_u64, - ] - - {% if Limb == UInt64 %} - LARGE_POWER_OF_5 = Slice[ - 1414648277510068013_u64, 9180637584431281687_u64, 4539964771860779200_u64, - 10482974169319127550_u64, 198276706040285095_u64, + {% if compare_versions(Crystal::VERSION, "1.16.0") < 0 %} + SMALL_POWER_OF_5 = [ + 1_u64, + 5_u64, + 25_u64, + 125_u64, + 625_u64, + 3125_u64, + 15625_u64, + 78125_u64, + 390625_u64, + 1953125_u64, + 9765625_u64, + 48828125_u64, + 244140625_u64, + 1220703125_u64, + 6103515625_u64, + 30517578125_u64, + 152587890625_u64, + 762939453125_u64, + 3814697265625_u64, + 19073486328125_u64, + 95367431640625_u64, + 476837158203125_u64, + 2384185791015625_u64, + 11920928955078125_u64, + 59604644775390625_u64, + 298023223876953125_u64, + 1490116119384765625_u64, + 7450580596923828125_u64, ] + + {% if Limb == UInt64 %} + LARGE_POWER_OF_5 = Slice[ + 1414648277510068013_u64, 9180637584431281687_u64, 4539964771860779200_u64, + 10482974169319127550_u64, 198276706040285095_u64, + ] + {% else %} + LARGE_POWER_OF_5 = Slice[ + 4279965485_u32, 329373468_u32, 4020270615_u32, 2137533757_u32, 4287402176_u32, + 1057042919_u32, 1071430142_u32, 2440757623_u32, 381945767_u32, 46164893_u32, + ] + {% end %} {% else %} - LARGE_POWER_OF_5 = Slice[ - 4279965485_u32, 329373468_u32, 4020270615_u32, 2137533757_u32, 4287402176_u32, - 1057042919_u32, 1071430142_u32, 2440757623_u32, 381945767_u32, 46164893_u32, - ] + SMALL_POWER_OF_5 = Slice(UInt64).literal( + 1_u64, + 5_u64, + 25_u64, + 125_u64, + 625_u64, + 3125_u64, + 15625_u64, + 78125_u64, + 390625_u64, + 1953125_u64, + 9765625_u64, + 48828125_u64, + 244140625_u64, + 1220703125_u64, + 6103515625_u64, + 30517578125_u64, + 152587890625_u64, + 762939453125_u64, + 3814697265625_u64, + 19073486328125_u64, + 95367431640625_u64, + 476837158203125_u64, + 2384185791015625_u64, + 11920928955078125_u64, + 59604644775390625_u64, + 298023223876953125_u64, + 1490116119384765625_u64, + 7450580596923828125_u64, + ) + + {% if Limb == UInt64 %} + LARGE_POWER_OF_5 = Slice(UInt64).literal( + 1414648277510068013_u64, 9180637584431281687_u64, 4539964771860779200_u64, + 10482974169319127550_u64, 198276706040285095_u64, + ) + {% else %} + LARGE_POWER_OF_5 = Slice(UInt32).literal( + 4279965485_u32, 329373468_u32, 4020270615_u32, 2137533757_u32, 4287402176_u32, + 1057042919_u32, 1071430142_u32, 2440757623_u32, 381945767_u32, 46164893_u32, + ) + {% end %} {% end %} end diff --git a/src/float/fast_float/digit_comparison.cr b/src/float/fast_float/digit_comparison.cr index 2da4c455bac4..c7483d4407d9 100644 --- a/src/float/fast_float/digit_comparison.cr +++ b/src/float/fast_float/digit_comparison.cr @@ -4,28 +4,53 @@ require "./ascii_number" module Float::FastFloat # 1e0 to 1e19 - POWERS_OF_TEN_UINT64 = [ - 1_u64, - 10_u64, - 100_u64, - 1000_u64, - 10000_u64, - 100000_u64, - 1000000_u64, - 10000000_u64, - 100000000_u64, - 1000000000_u64, - 10000000000_u64, - 100000000000_u64, - 1000000000000_u64, - 10000000000000_u64, - 100000000000000_u64, - 1000000000000000_u64, - 10000000000000000_u64, - 100000000000000000_u64, - 1000000000000000000_u64, - 10000000000000000000_u64, - ] + {% if compare_versions(Crystal::VERSION, "1.16.0") < 0 %} + POWERS_OF_TEN_UINT64 = [ + 1_u64, + 10_u64, + 100_u64, + 1000_u64, + 10000_u64, + 100000_u64, + 1000000_u64, + 10000000_u64, + 100000000_u64, + 1000000000_u64, + 10000000000_u64, + 100000000000_u64, + 1000000000000_u64, + 10000000000000_u64, + 100000000000000_u64, + 1000000000000000_u64, + 10000000000000000_u64, + 100000000000000000_u64, + 1000000000000000000_u64, + 10000000000000000000_u64, + ] + {% else %} + POWERS_OF_TEN_UINT64 = Slice(UInt64).literal( + 1_u64, + 10_u64, + 100_u64, + 1000_u64, + 10000_u64, + 100000_u64, + 1000000_u64, + 10000000_u64, + 100000000_u64, + 1000000000_u64, + 10000000000_u64, + 100000000000_u64, + 1000000000000_u64, + 10000000000000_u64, + 100000000000000_u64, + 1000000000000000_u64, + 10000000000000000_u64, + 100000000000000000_u64, + 1000000000000000000_u64, + 10000000000000000000_u64, + ) + {% end %} # calculate the exponent, in scientific notation, of the number. # this algorithm is not even close to optimized, but it has no practical diff --git a/src/float/fast_float/float_common.cr b/src/float/fast_float/float_common.cr index a66dc99f82f7..228b8970ee19 100644 --- a/src/float/fast_float/float_common.cr +++ b/src/float/fast_float/float_common.cr @@ -67,39 +67,75 @@ module Float::FastFloat struct BinaryFormat_Float64 include BinaryFormat(Float64, UInt64) - POWERS_OF_TEN = [ - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, - 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22, - ] - - # Largest integer value v so that (5**index * v) <= 1<<53. - # 0x20000000000000 == 1 << 53 - MAX_MANTISSA = [ - 0x20000000000000_u64, - 0x20000000000000_u64.unsafe_div(5), - 0x20000000000000_u64.unsafe_div(5 * 5), - 0x20000000000000_u64.unsafe_div(5 * 5 * 5), - 0x20000000000000_u64.unsafe_div(5 * 5 * 5 * 5), - 0x20000000000000_u64.unsafe_div(CONSTANT_55555), - 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * 5), - 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * 5 * 5), - 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * 5 * 5 * 5), - 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * 5 * 5 * 5 * 5), - 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555), - 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555 * 5), - 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555 * 5 * 5), - 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555 * 5 * 5 * 5), - 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555), - 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * 5), - 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * 5 * 5), - 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * 5 * 5 * 5), - 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * 5 * 5 * 5 * 5), - 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555), - 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * 5), - 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * 5 * 5), - 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * 5 * 5 * 5), - 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * 5 * 5 * 5 * 5), - ] + {% if compare_versions(Crystal::VERSION, "1.16.0") < 0 %} + POWERS_OF_TEN = [ + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, + 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22, + ] + + # Largest integer value v so that (5**index * v) <= 1<<53. + # 0x20000000000000 == 1 << 53 + MAX_MANTISSA = [ + 0x20000000000000_u64, + 0x20000000000000_u64.unsafe_div(5), + 0x20000000000000_u64.unsafe_div(5 * 5), + 0x20000000000000_u64.unsafe_div(5 * 5 * 5), + 0x20000000000000_u64.unsafe_div(5 * 5 * 5 * 5), + 0x20000000000000_u64.unsafe_div(CONSTANT_55555), + 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * 5), + 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * 5 * 5), + 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * 5 * 5 * 5), + 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * 5 * 5 * 5 * 5), + 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555), + 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555 * 5), + 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555 * 5 * 5), + 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555 * 5 * 5 * 5), + 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555), + 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * 5), + 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * 5 * 5), + 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * 5 * 5 * 5), + 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * 5 * 5 * 5 * 5), + 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555), + 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * 5), + 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * 5 * 5), + 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * 5 * 5 * 5), + 0x20000000000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * 5 * 5 * 5 * 5), + ] + {% else %} + POWERS_OF_TEN = Slice(Float64).literal( + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, + 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22, + ) + + # Largest integer value v so that (5**index * v) <= 1<<53. + # 0x20000000000000 == 1 << 53 + MAX_MANTISSA = Slice(UInt64).literal( + {{ 0x20000000000000_u64 }}, + {{ 0x20000000000000_u64 // (5) }}, + {{ 0x20000000000000_u64 // (5 * 5) }}, + {{ 0x20000000000000_u64 // (5 * 5 * 5) }}, + {{ 0x20000000000000_u64 // (5 * 5 * 5 * 5) }}, + {{ 0x20000000000000_u64 // (CONSTANT_55555) }}, + {{ 0x20000000000000_u64 // (CONSTANT_55555 * 5) }}, + {{ 0x20000000000000_u64 // (CONSTANT_55555 * 5 * 5) }}, + {{ 0x20000000000000_u64 // (CONSTANT_55555 * 5 * 5 * 5) }}, + {{ 0x20000000000000_u64 // (CONSTANT_55555 * 5 * 5 * 5 * 5) }}, + {{ 0x20000000000000_u64 // (CONSTANT_55555 * CONSTANT_55555) }}, + {{ 0x20000000000000_u64 // (CONSTANT_55555 * CONSTANT_55555 * 5) }}, + {{ 0x20000000000000_u64 // (CONSTANT_55555 * CONSTANT_55555 * 5 * 5) }}, + {{ 0x20000000000000_u64 // (CONSTANT_55555 * CONSTANT_55555 * 5 * 5 * 5) }}, + {{ 0x20000000000000_u64 // (CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555) }}, + {{ 0x20000000000000_u64 // (CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * 5) }}, + {{ 0x20000000000000_u64 // (CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * 5 * 5) }}, + {{ 0x20000000000000_u64 // (CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * 5 * 5 * 5) }}, + {{ 0x20000000000000_u64 // (CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * 5 * 5 * 5 * 5) }}, + {{ 0x20000000000000_u64 // (CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555) }}, + {{ 0x20000000000000_u64 // (CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * 5) }}, + {{ 0x20000000000000_u64 // (CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * 5 * 5) }}, + {{ 0x20000000000000_u64 // (CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * 5 * 5 * 5) }}, + {{ 0x20000000000000_u64 // (CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * CONSTANT_55555 * 5 * 5 * 5 * 5) }}, + ) + {% end %} def min_exponent_fast_path : Int32 -22 @@ -175,26 +211,49 @@ module Float::FastFloat struct BinaryFormat_Float32 include BinaryFormat(Float32, UInt32) - POWERS_OF_TEN = [ - 1e0f32, 1e1f32, 1e2f32, 1e3f32, 1e4f32, 1e5f32, 1e6f32, 1e7f32, 1e8f32, 1e9f32, 1e10f32, - ] - - # Largest integer value v so that (5**index * v) <= 1<<24. - # 0x1000000 == 1<<24 - MAX_MANTISSA = [ - 0x1000000_u64, - 0x1000000_u64.unsafe_div(5), - 0x1000000_u64.unsafe_div(5 * 5), - 0x1000000_u64.unsafe_div(5 * 5 * 5), - 0x1000000_u64.unsafe_div(5 * 5 * 5 * 5), - 0x1000000_u64.unsafe_div(CONSTANT_55555), - 0x1000000_u64.unsafe_div(CONSTANT_55555 * 5), - 0x1000000_u64.unsafe_div(CONSTANT_55555 * 5 * 5), - 0x1000000_u64.unsafe_div(CONSTANT_55555 * 5 * 5 * 5), - 0x1000000_u64.unsafe_div(CONSTANT_55555 * 5 * 5 * 5 * 5), - 0x1000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555), - 0x1000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555 * 5), - ] + {% if compare_versions(Crystal::VERSION, "1.16.0") < 0 %} + POWERS_OF_TEN = [ + 1e0f32, 1e1f32, 1e2f32, 1e3f32, 1e4f32, 1e5f32, 1e6f32, 1e7f32, 1e8f32, 1e9f32, 1e10f32, + ] + + # Largest integer value v so that (5**index * v) <= 1<<24. + # 0x1000000 == 1<<24 + MAX_MANTISSA = [ + 0x1000000_u64, + 0x1000000_u64.unsafe_div(5), + 0x1000000_u64.unsafe_div(5 * 5), + 0x1000000_u64.unsafe_div(5 * 5 * 5), + 0x1000000_u64.unsafe_div(5 * 5 * 5 * 5), + 0x1000000_u64.unsafe_div(CONSTANT_55555), + 0x1000000_u64.unsafe_div(CONSTANT_55555 * 5), + 0x1000000_u64.unsafe_div(CONSTANT_55555 * 5 * 5), + 0x1000000_u64.unsafe_div(CONSTANT_55555 * 5 * 5 * 5), + 0x1000000_u64.unsafe_div(CONSTANT_55555 * 5 * 5 * 5 * 5), + 0x1000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555), + 0x1000000_u64.unsafe_div(CONSTANT_55555 * CONSTANT_55555 * 5), + ] + {% else %} + POWERS_OF_TEN = Slice(Float32).literal( + 1e0f32, 1e1f32, 1e2f32, 1e3f32, 1e4f32, 1e5f32, 1e6f32, 1e7f32, 1e8f32, 1e9f32, 1e10f32, + ) + + # Largest integer value v so that (5**index * v) <= 1<<24. + # 0x1000000 == 1<<24 + MAX_MANTISSA = Slice(UInt64).literal( + {{ 0x1000000_u64 }}, + {{ 0x1000000_u64 // (5) }}, + {{ 0x1000000_u64 // (5 * 5) }}, + {{ 0x1000000_u64 // (5 * 5 * 5) }}, + {{ 0x1000000_u64 // (5 * 5 * 5 * 5) }}, + {{ 0x1000000_u64 // (CONSTANT_55555) }}, + {{ 0x1000000_u64 // (CONSTANT_55555 * 5) }}, + {{ 0x1000000_u64 // (CONSTANT_55555 * 5 * 5) }}, + {{ 0x1000000_u64 // (CONSTANT_55555 * 5 * 5 * 5) }}, + {{ 0x1000000_u64 // (CONSTANT_55555 * 5 * 5 * 5 * 5) }}, + {{ 0x1000000_u64 // (CONSTANT_55555 * CONSTANT_55555) }}, + {{ 0x1000000_u64 // (CONSTANT_55555 * CONSTANT_55555 * 5) }}, + ) + {% end %} def min_exponent_fast_path : Int32 -10