Use 10^52, as that makes more sense.

This commit is contained in:
K. Lange 2024-02-28 07:16:18 +09:00
parent 27b2d584ab
commit 4a2e736594

View File

@ -2414,14 +2414,14 @@ KrkValue krk_double_to_string(double a, int exact, unsigned int digits, char for
} }
if (e == -1023 && m == 0) return OBJECT_VAL(S("0.0")); if (e == -1023 && m == 0) return OBJECT_VAL(S("0.0"));
/* We need to cache the decimal versions of each necessary division of 10⁵, if we've not seen them before. */ /* We need to cache the decimal versions of each necessary division of 10⁵², if we've not seen them before. */
KrkValue float_decimal_parts = NONE_VAL(); KrkValue float_decimal_parts = NONE_VAL();
if (!krk_tableGet_fast(&vm.baseClasses->floatClass->methods, S("__decimals__"), &float_decimal_parts)) { if (!krk_tableGet_fast(&vm.baseClasses->floatClass->methods, S("__decimals__"), &float_decimal_parts)) {
krk_push(OBJECT_VAL(krk_newTuple(54))); krk_push(OBJECT_VAL(krk_newTuple(54)));
float_decimal_parts = krk_peek(0); float_decimal_parts = krk_peek(0);
KrkLong d; KrkLong d;
krk_long_parse_string("10000000000000000000000000000000000000000000000000000000", &d, 10, 56); krk_long_parse_string("10000000000000000000000000000000000000000000000000000", &d, 10, 53);
for (int i = 0; i < 53; ++i) { for (int i = 0; i < 53; ++i) {
AS_TUPLE(float_decimal_parts)->values.values[AS_TUPLE(float_decimal_parts)->values.count++] = make_long_obj(&d); AS_TUPLE(float_decimal_parts)->values.values[AS_TUPLE(float_decimal_parts)->values.count++] = make_long_obj(&d);
@ -2433,6 +2433,8 @@ KrkValue krk_double_to_string(double a, int exact, unsigned int digits, char for
} }
} }
/* We use 10^31 to add additional digits to ensure right shifting does not result
* in dropped bits when converting the base-2 exponent to base-10. */
KrkLong f; KrkLong f;
krk_long_parse_string("10000000000000000000000000000000", &f, 10, 32); krk_long_parse_string("10000000000000000000000000000000", &f, 10, 32);
AS_TUPLE(float_decimal_parts)->values.values[AS_TUPLE(float_decimal_parts)->values.count++] = make_long_obj(&f); AS_TUPLE(float_decimal_parts)->values.values[AS_TUPLE(float_decimal_parts)->values.count++] = make_long_obj(&f);
@ -2444,7 +2446,7 @@ KrkValue krk_double_to_string(double a, int exact, unsigned int digits, char for
/* Given that a double takes the form 2ⁿ × m, where either 1.0 ≤ m < 2.0 or /* Given that a double takes the form 2ⁿ × m, where either 1.0 ≤ m < 2.0 or
* (for subnormals) 0 < m < 1.0, generate a decimal representation of m as the * (for subnormals) 0 < m < 1.0, generate a decimal representation of m as the
* numerator in a fraction with 10 as the denominator. For example, the * numerator in a fraction with 10² as the denominator. For example, the
* value 123.456 is represented as: * value 123.456 is represented as:
* 2 × 1.9290000000000000479616346638067625463008880615234375 * 2 × 1.9290000000000000479616346638067625463008880615234375
* So we want to have the value: * So we want to have the value:
@ -2461,7 +2463,7 @@ KrkValue krk_double_to_string(double a, int exact, unsigned int digits, char for
e = -1022; e = -1022;
} else { } else {
/* Otherwise, our decimal representation of the multiplier will start with a 1, so /* Otherwise, our decimal representation of the multiplier will start with a 1, so
* start us off with 10 from above. */ * start us off with 10² from above. */
krk_long_init_copy(&c, AS_long(AS_TUPLE(float_decimal_parts)->values.values[0])->value); krk_long_init_copy(&c, AS_long(AS_TUPLE(float_decimal_parts)->values.values[0])->value);
} }
@ -2472,12 +2474,12 @@ KrkValue krk_double_to_string(double a, int exact, unsigned int digits, char for
} }
} }
/* At this point, we know that we have 55 decimal digits to the right of the radix point; /* At this point, we know that we have 52 decimal digits to the right of the radix point;
* this represents the base-10 exponent of our denominator. We want to maintain an exact * this represents the base-10 exponent of our denominator. We want to maintain an exact
* value for m after turning the base-2 exponent into a base-10 exponent, so if our * value for m after turning the base-2 exponent into a base-10 exponent, so if our
* original base-2 exponent is negative, we might need to add more 0s to the end of * original base-2 exponent is negative, we might need to add more 0s to the end of
* both the top and bottom of the fraction - we'll add to b to account for that. */ * both the top and bottom of the fraction - we'll add to b to account for that. */
int b = 55; int b = 52;
if (e < 0) { if (e < 0) {
/* Repeatedly multiply to increase number of decimal digits by 31, until the resulting /* Repeatedly multiply to increase number of decimal digits by 31, until the resulting