| //===--- SwiftDtoa.c ---------------------------------------------*- c -*-===// |
| // |
| // This source file is part of the Swift.org open source project |
| // |
| // Copyright (c) 2018 Apple Inc. and the Swift project authors |
| // Licensed under Apache License v2.0 with Runtime Library Exception |
| // |
| // See https://swift.org/LICENSE.txt for license information |
| // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors |
| // |
| //===---------------------------------------------------------------------===// |
| // |
| // Note: This is really a C file, but Swift's build system for Linux is |
| // partially allergic to C, so it's being compiled as ".cpp" for now. Please |
| // don't infect it with C++-isms. |
| // |
| /// |
| /// The core algorithm here (see `swift_decompose_double` below) is a |
| /// modified form of the Grisu2 algorithm from Florian Loitsch; |
| /// "Printing Floating-Point Numbers Quickly and Accurately with |
| /// Integers", 2010. https://dl.acm.org/citation.cfm?id=1806623 |
| /// |
| /// This includes some improvements suggested by the "Errol paper": |
| /// Marc Andrysco, Ranjit Jhala, Sorin Lerner; "Printing |
| /// Floating-Point Numbers: A Faster, Always Correct Method", 2016. |
| /// https://dl.acm.org/citation.cfm?id=2837654 |
| /// |
| /// The following summary assumes you're familiar with Grisu-style |
| /// algorithms in general: |
| /// |
| /// Loitsch' original Grisu2 implementation guarantees round-trip |
| /// accuracy but only generates the shortest decimal expansion about 99% |
| /// of the time. Grisu3 is similar, but fails rather than producing |
| /// a result that is not the shortest possible. |
| /// |
| /// The Errol paper provides a deeper analysis of the cases where |
| /// Grisu2 fails to find the shortest decimal expansion. There |
| /// are two root causes of such failures: |
| /// |
| /// * Insufficient precision leads to scattered failures across the |
| /// entire range. The enumeration technique described in the Errol |
| /// paper shows a way to construct a superset of the numbers subject |
| /// to such failures. With this list, we can simply test whether we |
| /// have sufficient precision. |
| /// |
| /// For Double, the Errol3 algorithm uses double-double arithmetic |
| /// with about 106 bits precision. This turns out to be not quite |
| /// sufficient, requiring Errol3 to pre-screen the input against a |
| /// list of exceptions culled from the larger list of possible |
| /// failures. Using high-precision integers, we've discovered that |
| /// 110 bit precision is sufficient to satisfy the Errol test cases |
| /// without requiring any pre-screening. |
| /// |
| /// For Float and Float80, the same approach shows that we need 53 |
| /// and 135 bits, respectively. It is an interesting coincidence |
| /// that for all three cases, an n-bit significand can be formatted |
| /// optimally with no more than 2n+7 bits of intermediate precision. |
| /// |
| /// * Sometimes, the shortest value might occur exactly at the |
| /// midpoint between two adjacent binary floating-point values. |
| /// When converted back to binary, this will round to the adjacent |
| /// even significand. We handle this by widening the interval |
| /// whenever the significand is even in order to allow these |
| /// exact midpoints to be considered. |
| /// |
| /// In addition to addressing the shortness failures characterized in the Errol |
| /// paper, the implementation here also incorporates final-digit corrections |
| /// that allow it to produce the optimal decimal decomposition in all cases. |
| /// |
| /// In summary, this implementation is: |
| /// |
| /// * Fast. It uses only fixed-width integer arithmetic and has |
| /// constant memory requirements. |
| /// |
| /// * Simple. It is only a little more complex than Loitsch' original |
| /// implementation of Grisu2. The full digit decomposition for double |
| /// is less than 300 lines of standard C, including routine arithmetic |
| /// helper functions. |
| /// |
| /// * Always Accurate. Converting the decimal form back to binary |
| /// will always yield exactly the same value. For the IEEE 754 |
| /// formats, the round-trip will produce exactly the same bit |
| /// pattern in memory. |
| /// |
| /// * Always Short. This always selects an accurate result with the |
| /// minimum number of decimal digits. |
| /// |
| /// * Always Close. Among all accurate, short results, this always |
| /// chooses the result that is closest to the exact floating-point |
| /// value. (In case of an exact tie, it rounds the last digit even.) |
| /// |
| /// For single-precision Float, we can simply test all 2^32 values. |
| /// This requires only a few minutes on a mid-range modern laptop. The |
| /// Double and Float80 formatters rely on results from the Errol paper |
| /// to ensure correctness. In addition, we have verified more than |
| /// 10^14 randomly-chosen Double values by comparing the results to the |
| /// output of Grisu3 (where Grisu3 fails, we've compared to Errol4). |
| /// |
| // ---------------------------------------------------------------------------- |
| |
| #include <float.h> |
| #include <inttypes.h> |
| #include <math.h> |
| #include <stdbool.h> |
| #include <stdint.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| |
| #include "swift/Runtime/SwiftDtoa.h" |
| |
| #if defined(__SIZEOF_INT128__) |
| // We get a significant speed boost if we can use the __uint128_t |
| // type that's present in GCC and Clang on 64-bit architectures. In |
| // particular, we can do 128-bit arithmetic directly and can |
| // represent 192-bit integers as a collection of 64-bit elements. |
| #define HAVE_UINT128_T 1 |
| #else |
| // On 32-bit, we have to use slower code that manipulates 128-bit |
| // and 192-bit integers as collections of 32-bit elements. |
| #define HAVE_UINT128_T 0 |
| #endif |
| |
| // Try to verify that the system floating-point types really are what we |
| // expect. Note that the code below is specific to these exact |
| // floating-point representations. |
| |
| #if (FLT_RADIX != 2) |
| // Either you're using hexadecimal float format on S390, or you have a |
| // really broken C environment. |
| #error "This platform claims to not use binary floating point." |
| #endif |
| |
| #if SWIFT_DTOA_FLOAT_SUPPORT |
| #if (FLT_MANT_DIG != 24) || (FLT_MIN_EXP != -125) || (FLT_MAX_EXP != 128) |
| #error "Are you certain `float` on this platform is really IEEE 754 single-precision binary32 format?" |
| #endif |
| #endif |
| |
| #if SWIFT_DTOA_DOUBLE_SUPPORT |
| #if (DBL_MANT_DIG != 53) || (DBL_MIN_EXP != -1021) || (DBL_MAX_EXP != 1024) |
| #error "Are you certain `double` on this platform is really IEEE 754 double-precision binary64 format?" |
| #endif |
| #endif |
| |
| #if SWIFT_DTOA_FLOAT80_SUPPORT |
| #if (LDBL_MANT_DIG != 64) || (LDBL_MIN_EXP != -16381) || (LDBL_MAX_EXP != 16384) |
| #error "Are you certain `long double` on this platform is really Intel 80-bit extended precision?" |
| #endif |
| #endif |
| |
| |
| // See the implementations at the bottom of this file for detailed explanations |
| // of the purpose of each function. |
| |
| // |
| // Helper functions used by float, double, and float80 machinery. |
| // |
| |
| #if SWIFT_DTOA_FLOAT_SUPPORT || SWIFT_DTOA_DOUBLE_SUPPORT || SWIFT_DTOA_FLOAT80_SUPPORT |
| static int binaryExponentFor10ToThe(int p); |
| static int decimalExponentFor2ToThe(int e); |
| #endif |
| |
| // |
| // Helper functions used only by the single-precision float formatter |
| // |
| |
| #if SWIFT_DTOA_FLOAT_SUPPORT |
| static uint64_t multiply64x32RoundingDown(uint64_t lhs, uint32_t rhs); |
| static uint64_t multiply64x32RoundingUp(uint64_t lhs, uint32_t rhs); |
| static uint64_t multiply64x64RoundingDown(uint64_t lhs, uint64_t rhs); |
| static uint64_t multiply64x64RoundingUp(uint64_t lhs, uint64_t rhs); |
| static void intervalContainingPowerOf10_Float(int p, uint64_t *lower, uint64_t *upper, int *exponent); |
| #endif |
| |
| // |
| // Helpers used by both the double-precision and float80 formatters |
| // |
| |
| #if SWIFT_DTOA_DOUBLE_SUPPORT || SWIFT_DTOA_FLOAT80_SUPPORT |
| #if HAVE_UINT128_T |
| typedef __uint128_t swift_uint128_t; |
| #define initialize128WithHighLow64(dest, high64, low64) ((dest) = ((__uint128_t)(high64) << 64) | (low64)) |
| #else |
| typedef struct { |
| uint32_t low, b, c, high; |
| } swift_uint128_t; |
| #define initialize128WithHighLow64(dest, high64, low64) \ |
| ((dest).low = (uint32_t)(low64), \ |
| (dest).b = (uint32_t)((low64) >> 32), \ |
| (dest).c = (uint32_t)(high64), \ |
| (dest).high = (uint32_t)((high64) >> 32)) |
| #endif |
| #endif |
| |
| |
| // |
| // Helper functions used only by the double-precision formatter |
| // |
| |
| #if SWIFT_DTOA_DOUBLE_SUPPORT |
| #if HAVE_UINT128_T |
| #define increment128(dest) ((dest) += 1) |
| #define isLessThan128x128(lhs, rhs) ((lhs) < (rhs)) |
| #define subtract128x128(lhs, rhs) (*(lhs) -= (rhs)) |
| #define multiply128xi32(lhs, rhs) (*(lhs) *= (rhs)) |
| #define initialize128WithHigh64(dest, value) ((dest) = (__uint128_t)(value) << 64) |
| #define extractHigh64From128(arg) ((uint64_t)((arg) >> 64)) |
| static int extractIntegerPart128(__uint128_t *fixed128, int fractionBits) { |
| return (int)(*fixed128 >> fractionBits); |
| } |
| static void clearIntegerPart128(__uint128_t *fixed128, int fractionBits) { |
| const swift_uint128_t fixedPointMask = (((__uint128_t)1 << fractionBits) - 1); |
| *fixed128 &= fixedPointMask; |
| } |
| #else |
| #define increment128(dest) \ |
| do { \ |
| uint64_t t = (dest).low + 1; \ |
| (dest).low = (uint32_t)t; \ |
| t >>= 32; \ |
| t += (dest).b; \ |
| (dest).b = (uint32_t)t; \ |
| t >>= 32; \ |
| t += (dest).c; \ |
| (dest).c = (uint32_t)t; \ |
| t >>= 32; \ |
| (dest).high += (uint32_t)t; \ |
| } while (0) |
| static int isLessThan128x128(swift_uint128_t lhs, swift_uint128_t rhs); |
| static void subtract128x128(swift_uint128_t *lhs, swift_uint128_t rhs); |
| static void multiply128xi32(swift_uint128_t *lhs, uint32_t rhs); |
| #define initialize128WithHigh64(dest, value) \ |
| ((dest).low = (dest).b = 0, \ |
| (dest).c = (uint32_t)(value), \ |
| (dest).high = (uint32_t)((value) >> 32)) |
| #define extractHigh64From128(arg) (((uint64_t)(arg).high << 32)|((arg).c)) |
| static int extractIntegerPart128(swift_uint128_t *fixed128, int fractionBits) { |
| const int highFractionBits = fractionBits % 32; |
| return (int)(fixed128->high >> highFractionBits); |
| } |
| static void clearIntegerPart128(swift_uint128_t *fixed128, int fractionBits) { |
| const int highFractionBits = fractionBits % 32; |
| fixed128->high &= ((uint32_t)1 << highFractionBits) - 1; |
| } |
| #endif |
| static swift_uint128_t multiply128x64RoundingDown(swift_uint128_t lhs, uint64_t rhs); |
| static swift_uint128_t multiply128x64RoundingUp(swift_uint128_t lhs, uint64_t rhs); |
| static swift_uint128_t shiftRightRoundingDown128(swift_uint128_t lhs, int shift); |
| static swift_uint128_t shiftRightRoundingUp128(swift_uint128_t lhs, int shift); |
| static void intervalContainingPowerOf10_Double(int p, swift_uint128_t *lower, swift_uint128_t *upper, int *exponent); |
| #endif |
| |
| // |
| // Helper functions used only by the extended-precision long double formatter |
| // |
| |
| #if SWIFT_DTOA_FLOAT80_SUPPORT |
| #if HAVE_UINT128_T |
| // A 192-bit unsigned integer type stored as 3 64-bit words |
| typedef struct {uint64_t low, mid, high;} swift_uint192_t; |
| #define initialize192WithHighMidLow64(dest, high64, mid64, low64) \ |
| ((dest).low = (low64), \ |
| (dest).mid = (mid64), \ |
| (dest).high = (high64)) |
| #else |
| // A 192-bit unsigned integer type stored as 6 32-bit words |
| typedef struct {uint32_t low, b, c, d, e, high;} swift_uint192_t; |
| #define initialize192WithHighMidLow64(dest, high64, mid64, low64) \ |
| ((dest).low = (uint64_t)(low64), \ |
| (dest).b = (uint64_t)(low64) >> 32, \ |
| (dest).c = (uint64_t)(mid64), \ |
| (dest).d = (uint64_t)(mid64) >> 32, \ |
| (dest).e = (uint64_t)(high64), \ |
| (dest).high = (uint64_t)(high64) >> 32) |
| #endif |
| static void multiply192x64RoundingDown(swift_uint192_t *lhs, uint64_t rhs); |
| static void multiply192x64RoundingUp(swift_uint192_t *lhs, uint64_t rhs); |
| static void multiply192xi32(swift_uint192_t *lhs, uint32_t rhs); |
| static void multiply192x128RoundingDown(swift_uint192_t *lhs, swift_uint128_t rhs); |
| static void multiply192x128RoundingUp(swift_uint192_t *lhs, swift_uint128_t rhs); |
| static void subtract192x192(swift_uint192_t *lhs, swift_uint192_t rhs); |
| static int isLessThan192x192(swift_uint192_t lhs, swift_uint192_t rhs); |
| static void shiftRightRoundingDown192(swift_uint192_t *lhs, int shift); |
| static void shiftRightRoundingUp192(swift_uint192_t *lhs, int shift); |
| static void intervalContainingPowerOf10_Float80(int p, swift_uint192_t *lower, swift_uint192_t *upper, int *exponent); |
| #endif |
| |
| // |
| // --------------- Digit generation --------------------- |
| // |
| |
| // This is the interesting part. |
| |
| // These routines take a floating-point value and efficiently compute |
| // everything necessary to write an optimal base-10 representation of |
| // that value. In particular, they compute the base-10 exponent and |
| // corresponding digits. |
| |
| // swift_decompose_double is thoroughly commented; swift_decompose_float |
| // and swift_decompose_float80 are fundamentally the same algorithm, but |
| // adjusted to perform optimally for those types. |
| |
| #if SWIFT_DTOA_DOUBLE_SUPPORT |
| // Return raw bits encoding the double |
| static uint64_t bitPatternForDouble(double d) { |
| union { double d; uint64_t u; } converter; |
| converter.d = d; |
| return converter.u; |
| } |
| |
| int swift_decompose_double(double d, |
| int8_t *digits, size_t digits_length, int *decimalExponent) |
| { |
| // Bits in raw significand (not including hidden bit, if present) |
| static const int significandBitCount = DBL_MANT_DIG - 1; |
| static const uint64_t significandMask |
| = ((uint64_t)1 << significandBitCount) - 1; |
| // Bits in raw exponent |
| static const int exponentBitCount = 11; |
| static const int exponentMask = (1 << exponentBitCount) - 1; |
| // Note: IEEE 754 conventionally uses 1023 as the exponent |
| // bias. That's because they treat the significand as a |
| // fixed-point number with one bit (the hidden bit) integer |
| // portion. The logic here reconstructs the significand as a |
| // pure fraction, so we need to accomodate that when |
| // reconstructing the binary exponent. |
| static const int64_t exponentBias = (1 << (exponentBitCount - 1)) - 2; // 1022 |
| |
| // Step 0: Deconstruct the target number |
| // Note: this strongly assumes IEEE 754 binary64 format |
| uint64_t raw = bitPatternForDouble(d); |
| int exponentBitPattern = (raw >> significandBitCount) & exponentMask; |
| uint64_t significandBitPattern = raw & significandMask; |
| |
| // Step 1: Handle the various input cases: |
| int binaryExponent; |
| uint64_t significand; |
| if (digits_length < 17) { |
| return 0; |
| } else if (exponentBitPattern == exponentMask) { // NaN or Infinity |
| // Return no digits |
| return 0; |
| } else if (exponentBitPattern == 0) { |
| if (significandBitPattern == 0) { // Zero |
| digits[0] = 0; |
| *decimalExponent = 0; |
| return 1; |
| } else { // subnormal |
| binaryExponent = 1 - exponentBias; |
| significand = significandBitPattern |
| << (64 - significandBitCount - 1); |
| } |
| } else { // normal |
| binaryExponent = exponentBitPattern - exponentBias; |
| uint64_t hiddenBit = (uint64_t)1 << significandBitCount; |
| uint64_t fullSignificand = significandBitPattern + hiddenBit; |
| significand = fullSignificand << (64 - significandBitCount - 1); |
| } |
| |
| // Step 2: Determine the exact unscaled target interval |
| |
| // Grisu-style algorithms construct the shortest decimal digit |
| // sequence within a specific interval. To build the appropriate |
| // interval, we start by computing the exact midpoints between |
| // this floating-point value and the adjacent ones. |
| |
| uint64_t halfUlp = (uint64_t)1 << (64 - significandBitCount - 2); |
| uint64_t quarterUlp = halfUlp >> 1; |
| uint64_t upperMidpointExact = significand + halfUlp; |
| |
| int isBoundary = significandBitPattern == 0; |
| uint64_t lowerMidpointExact |
| = significand - (isBoundary ? quarterUlp : halfUlp); |
| |
| // Step 3: Estimate the base 10 exponent |
| |
| // Grisu algorithms are based in part on a simple technique for |
| // generating a base-10 form for a binary floating-point number. |
| // Start with a binary floating-point number `f * 2^e` and then |
| // estimate the decimal exponent `p`. You can then rewrite your |
| // original number as: |
| // |
| // ``` |
| // f * 2^e * 10^-p * 10^p |
| // ``` |
| // |
| // The last term is part of our output, and a good estimate for |
| // `p` will ensure that `2^e * 10^-p` is going to be close to 1. |
| // So multiplying the first three terms yields a fraction suitable |
| // for producing the decimal digits. So we need to estimate `p`: |
| |
| int base10Exponent = decimalExponentFor2ToThe(binaryExponent); |
| |
| // Step 4: Compute a power-of-10 scale factor |
| // Compute `10^-p` to 128-bit precision. We generate |
| // both over- and under-estimates to ensure we can exactly |
| // bound the later use of these values. |
| swift_uint128_t powerOfTenRoundedDown; |
| swift_uint128_t powerOfTenRoundedUp; |
| int powerOfTenExponent = 0; |
| intervalContainingPowerOf10_Double(-base10Exponent, |
| &powerOfTenRoundedDown, |
| &powerOfTenRoundedUp, |
| &powerOfTenExponent); |
| const int extraBits = binaryExponent + powerOfTenExponent; |
| |
| // Step 5: Scale the interval (with rounding) |
| |
| // As mentioned above, the final digit generation works |
| // with an interval, so we actually apply the scaling |
| // to the upper and lower midpoint values separately. |
| |
| // As part of the scaling here, we'll switch from a pure |
| // fraction to a fixed-point form. Using 14 bit integer portion |
| // will allow us to compute four decimal digits at a time. |
| static const int integerBits = 14; |
| static const int fractionBits = 128 - integerBits; |
| |
| // We scale the interval in one of two different ways, |
| // depending on whether the significand is even or odd... |
| |
| swift_uint128_t u, l; |
| if (significandBitPattern & 1) { |
| // Case A: Narrow the interval (odd significand) |
| |
| // Loitsch' original Grisu2 always narrows the interval. |
| // Since our digit generation will select a value within |
| // the scaled interval, narrowing the interval guarantees |
| // that we will find a digit sequence that converts back |
| // to the original value. |
| |
| // This ensures accuracy but, as explained in Loitsch' paper, |
| // this carries a risk that there will be a shorter digit |
| // sequence outside of our narrowed interval that we will |
| // miss. This risk obviously gets lower with increased |
| // precision, but it wasn't until the Errol paper that anyone |
| // had a good way to test whether a particular implementation |
| // had sufficient precision. That paper shows a way to enumerate |
| // the worst-case numbers; those numbers that are extremely close |
| // to the mid-points between adjacent floating-point values. |
| // These are the values that might sit just outside of the |
| // narrowed interval. By testing these values, we can verify |
| // the correctness of our implementation. |
| |
| // Multiply out the upper midpoint, rounding down... |
| swift_uint128_t u1 = multiply128x64RoundingDown(powerOfTenRoundedDown, |
| upperMidpointExact); |
| // Account for residual binary exponent and adjust |
| // to the fixed-point format |
| u = shiftRightRoundingDown128(u1, integerBits - extraBits); |
| |
| // Conversely for the lower midpoint... |
| swift_uint128_t l1 = multiply128x64RoundingUp(powerOfTenRoundedUp, |
| lowerMidpointExact); |
| l = shiftRightRoundingUp128(l1, integerBits - extraBits); |
| |
| } else { |
| // Case B: Widen the interval (even significand) |
| |
| // As explained in Errol Theorem 6, in certain cases there is |
| // a short decimal representation at the exact boundary of the |
| // scaled interval. When such a number is converted back to |
| // binary, it will get rounded to the adjacent even |
| // significand. |
| |
| // So when the significand is even, we widen the interval in |
| // order to ensure that the exact midpoints are considered. |
| // Of couse, this ensures that we find a short result but |
| // carries a risk of selecting a result outside of the exact |
| // scaled interval (which would be inaccurate). |
| |
| // The same testing approach described above also applies |
| // to this case. |
| |
| swift_uint128_t u1 = multiply128x64RoundingUp(powerOfTenRoundedUp, |
| upperMidpointExact); |
| u = shiftRightRoundingUp128(u1, integerBits - extraBits); |
| |
| swift_uint128_t l1 = multiply128x64RoundingDown(powerOfTenRoundedDown, |
| lowerMidpointExact); |
| l = shiftRightRoundingDown128(l1, integerBits - extraBits); |
| } |
| |
| // Step 6: Align first digit, adjust exponent |
| |
| // This preps for digit generation. It just multiplies repeatedly |
| // by 10 until we have exactly one decimal digit in the integer |
| // part, adjusting the exponent as we go. |
| |
| // In particular, this prunes leading zeros from subnormals. |
| // Generate digits for `t` with interval width `delta` |
| swift_uint128_t t = u; |
| swift_uint128_t delta = u; |
| subtract128x128(&delta, l); // Explained below. |
| int exponent = base10Exponent + 1; |
| |
| // Except for subnormals, this loop should never run more than once. |
| #if HAVE_UINT128_T |
| static const swift_uint128_t fixedPointOne = (__uint128_t)1 << fractionBits; |
| while (t < fixedPointOne) |
| #else |
| // Because 1.0 in fixed point has a lot of zeros, it suffices |
| // to only compare the high-order word here. This is a minor |
| // performance win. |
| while (t.high < ((uint32_t)1 << (fractionBits % 32))) |
| #endif |
| { |
| exponent -= 1; |
| multiply128xi32(&delta, 10); |
| multiply128xi32(&t, 10); |
| } |
| |
| // Step 7: Generate digits |
| |
| // This is a common part of Grisu-style algorithms. The |
| // underlying idea is to generate digits for the scaled upper and |
| // lower boundaries, and stop when we hit the first different |
| // digit (at which point, the digit for the upper midpoint is the |
| // candidate final digit). To understand this, just note that |
| // 0.1234 is the shortest decimal between u = 0.123456 and l = |
| // 0.123345. |
| |
| // Grisu uses a slightly optimized technique: it generates digits |
| // for the upper bound (multiplying by 10 to isolate each digit) |
| // and multiplies the interval width `delta` at the same time. |
| // The `different digit` criteria above translates to a test for |
| // `delta` being larger than the remainder. |
| |
| int8_t *digit_p = digits; |
| |
| // Adjustment above already set up the first digit: |
| int nextDigit = extractIntegerPart128(&t, fractionBits); |
| clearIntegerPart128(&t, fractionBits); |
| |
| // Further optimization: Generating four digits at a time reduces |
| // the total arithmetic required per digit. Note: The following |
| // block can be entirely removed with no effect on the result. |
| // If you're trying to understand this algorithm, just skip this |
| // block on first reading. |
| swift_uint128_t d0 = delta; |
| multiply128xi32(&d0, 10000); |
| swift_uint128_t t0 = t; |
| multiply128xi32(&t0, 10000); |
| int fourDigits = extractIntegerPart128(&t0, fractionBits); // 4 digits |
| clearIntegerPart128(&t0, fractionBits); |
| while (isLessThan128x128(d0, t0)) { |
| *digit_p++ = nextDigit; |
| int d = fourDigits / 100; // top 2 digits |
| *digit_p++ = d / 10; |
| *digit_p++ = d % 10; |
| d = fourDigits % 100; // bottom 2 digits |
| *digit_p++ = d / 10; |
| nextDigit = d % 10; |
| t = t0; |
| delta = d0; |
| multiply128xi32(&d0, 10000); |
| multiply128xi32(&t0, 10000); |
| fourDigits = extractIntegerPart128(&t0, fractionBits); |
| clearIntegerPart128(&t0, fractionBits); |
| } |
| |
| // Finish by generating one digit at a time. |
| while (isLessThan128x128(delta, t)) { |
| *digit_p++ = nextDigit; |
| multiply128xi32(&delta, 10); |
| multiply128xi32(&t, 10); |
| nextDigit = extractIntegerPart128(&t, fractionBits); |
| clearIntegerPart128(&t, fractionBits); |
| } |
| |
| // Adjust the final digit to be closer to the original value. It accounts |
| // for the fact that sometimes there is more than one shortest digit |
| // sequence. |
| |
| // For example, consider how the above would work if you had the |
| // value 0.1234 and computed u = 0.1257, l = 0.1211. The above |
| // digit generation works with `u`, so produces 0.125. But the |
| // values 0.122, 0.123, and 0.124 are just as short and 0.123 is |
| // the best choice, since it's closest to the original value. |
| |
| // If `delta <= t + 1.0`, then the interval is narrower than |
| // one decimal digit, so there is no other option. |
| |
| // Note: We've already consumed most of our available precision, |
| // so it's okay to just work in 64 bits here... |
| uint64_t deltaHigh64 = extractHigh64From128(delta); |
| uint64_t tHigh64 = extractHigh64From128(t); |
| if (deltaHigh64 > tHigh64 + ((uint64_t)1 << (fractionBits % 64))) { |
| // Note: 64-bit arithmetic is okay here |
| uint64_t skew; |
| if (isBoundary) { |
| // If we're at the boundary where the exponent shifts, |
| // then the original value is 1/3 of the way from |
| // the bottom of the interval ... |
| skew = deltaHigh64 - deltaHigh64 / 3 - tHigh64; |
| } else { |
| // ... otherwise it's exactly in the middle. |
| skew = deltaHigh64 / 2 - tHigh64; |
| } |
| |
| // The `skew` above is the difference between our |
| // computed digits and the original exact value. |
| // Use that to offset the final digit: |
| uint64_t one = (uint64_t)(1) << (64 - integerBits); |
| uint64_t fractionMask = one - 1; |
| uint64_t oneHalf = one >> 1; |
| if ((skew & fractionMask) == oneHalf) { |
| int adjust = (int)(skew >> (64 - integerBits)); |
| // If the skew is exactly integer + 1/2, round the |
| // last digit even after adjustment |
| nextDigit = (nextDigit - adjust) & ~1; |
| } else { |
| // Else round to nearest... |
| int adjust = (int)((skew + oneHalf) >> (64 - integerBits)); |
| nextDigit = (nextDigit - adjust); |
| } |
| } |
| *digit_p++ = nextDigit; // Store the final digit. |
| |
| *decimalExponent = exponent; |
| return digit_p - digits; |
| } |
| #endif |
| |
| #if SWIFT_DTOA_FLOAT_SUPPORT |
| // Return raw bits encoding the float |
| static uint64_t bitPatternForFloat(float f) { |
| union { float f; uint32_t u; } converter; |
| converter.f = f; |
| return converter.u; |
| } |
| |
| // Decompose an IEEE 754 binary32 single-precision float |
| // into decimal digits and a corresponding decimal exponent. |
| |
| // See swift_decompose_double for detailed comments on the algorithm here |
| int swift_decompose_float(float f, |
| int8_t *digits, size_t digits_length, int *decimalExponent) |
| { |
| static const int significandBitCount = FLT_MANT_DIG - 1; |
| static const uint32_t significandMask |
| = ((uint32_t)1 << significandBitCount) - 1; |
| static const int exponentBitCount = 8; |
| static const int exponentMask = (1 << exponentBitCount) - 1; |
| // See comments in swift_decompose_double |
| static const int64_t exponentBias = (1 << (exponentBitCount - 1)) - 2; // 125 |
| |
| // Step 0: Deconstruct the target number |
| // Note: this strongly assumes IEEE 754 binary32 format |
| uint32_t raw = bitPatternForFloat(f); |
| int exponentBitPattern = (raw >> significandBitCount) & exponentMask; |
| uint32_t significandBitPattern = raw & significandMask; |
| |
| // Step 1: Handle the various input cases: |
| int binaryExponent; |
| uint32_t significand; |
| if (digits_length < 9) { |
| // Ensure we have space for 9 digits |
| return 0; |
| } else if (exponentBitPattern == exponentMask) { // NaN or Infinity |
| // Return no digits |
| return 0; |
| } else if (exponentBitPattern == 0) { |
| if (significandBitPattern == 0) { // Zero |
| // Return one zero digit and decimalExponent = 0. |
| digits[0] = 0; |
| *decimalExponent = 0; |
| return 1; |
| } else { // Subnormal |
| binaryExponent = 1 - exponentBias; |
| significand = significandBitPattern << (32 - significandBitCount - 1); |
| } |
| } else { // normal |
| binaryExponent = exponentBitPattern - exponentBias; |
| uint32_t hiddenBit = (uint32_t)1 << (uint32_t)significandBitCount; |
| uint32_t fullSignificand = significandBitPattern + hiddenBit; |
| significand = fullSignificand << (32 - significandBitCount - 1); |
| } |
| |
| // Step 2: Determine the exact unscaled target interval |
| static const uint32_t halfUlp = (uint32_t)1 << (32 - significandBitCount - 2); |
| uint32_t upperMidpointExact = significand + halfUlp; |
| |
| int isBoundary = significandBitPattern == 0; |
| static const uint32_t quarterUlp = halfUlp >> 1; |
| uint32_t lowerMidpointExact |
| = significand - (isBoundary ? quarterUlp : halfUlp); |
| |
| // Step 3: Estimate the base 10 exponent |
| int base10Exponent = decimalExponentFor2ToThe(binaryExponent); |
| |
| // Step 4: Compute a power-of-10 scale factor |
| uint64_t powerOfTenRoundedDown = 0; |
| uint64_t powerOfTenRoundedUp = 0; |
| int powerOfTenExponent = 0; |
| intervalContainingPowerOf10_Float(-base10Exponent, |
| &powerOfTenRoundedDown, |
| &powerOfTenRoundedUp, |
| &powerOfTenExponent); |
| const int extraBits = binaryExponent + powerOfTenExponent; |
| |
| // Step 5: Scale the interval (with rounding) |
| static const int integerBits = 5; |
| const int shift = integerBits - extraBits; |
| const int roundUpBias = (1 << shift) - 1; |
| static const int fractionBits = 64 - integerBits; |
| uint64_t u, l; |
| if (significandBitPattern & 1) { |
| // Narrow the interval (odd significand) |
| uint64_t u1 = multiply64x32RoundingDown(powerOfTenRoundedDown, |
| upperMidpointExact); |
| u = u1 >> shift; // Rounding down |
| |
| uint64_t l1 = multiply64x32RoundingUp(powerOfTenRoundedUp, |
| lowerMidpointExact); |
| l = (l1 + roundUpBias) >> shift; // Rounding Up |
| } else { |
| // Widen the interval (even significand) |
| uint64_t u1 = multiply64x32RoundingUp(powerOfTenRoundedUp, |
| upperMidpointExact); |
| u = (u1 + roundUpBias) >> shift; // Rounding Up |
| |
| uint64_t l1 = multiply64x32RoundingDown(powerOfTenRoundedDown, |
| lowerMidpointExact); |
| l = l1 >> shift; // Rounding down |
| } |
| |
| // Step 6: Align first digit, adjust exponent |
| // In particular, this prunes leading zeros from subnormals |
| static const uint64_t fixedPointOne = (uint64_t)1 << fractionBits; |
| static const uint64_t fixedPointMask = fixedPointOne - 1; |
| uint64_t t = u; |
| uint64_t delta = u - l; |
| int exponent = base10Exponent + 1; |
| |
| while (t < fixedPointOne) { |
| exponent -= 1; |
| delta *= 10; |
| t *= 10; |
| } |
| |
| // Step 7: Generate digits |
| int8_t *digit_p = digits; |
| int nextDigit = (int)(t >> fractionBits); |
| t &= fixedPointMask; |
| |
| // Generate one digit at a time... |
| while (t > delta) { |
| *digit_p++ = nextDigit; |
| delta *= 10; |
| t *= 10; |
| nextDigit = (int)(t >> fractionBits); |
| t &= fixedPointMask; |
| } |
| |
| // Adjust the final digit to be closer to the original value |
| if (delta > t + fixedPointOne) { |
| uint64_t skew; |
| if (isBoundary) { |
| skew = delta - delta / 3 - t; |
| } else { |
| skew = delta / 2 - t; |
| } |
| uint64_t one = (uint64_t)(1) << (64 - integerBits); |
| uint64_t lastAccurateBit = 1ULL << 24; |
| uint64_t fractionMask = (one - 1) & ~(lastAccurateBit - 1); |
| uint64_t oneHalf = one >> 1; |
| if (((skew + (lastAccurateBit >> 1)) & fractionMask) == oneHalf) { |
| // If the skew is exactly integer + 1/2, round the last |
| // digit even after adjustment |
| int adjust = (int)(skew >> (64 - integerBits)); |
| nextDigit = (nextDigit - adjust) & ~1; |
| } else { |
| // Else round to nearest... |
| int adjust = (int)((skew + oneHalf) >> (64 - integerBits)); |
| nextDigit = (nextDigit - adjust); |
| } |
| } |
| *digit_p++ = nextDigit; |
| |
| *decimalExponent = exponent; |
| return digit_p - digits; |
| } |
| #endif |
| |
| #if SWIFT_DTOA_FLOAT80_SUPPORT |
| // See `swift_decompose_double` for detailed comments on this implementatoin. |
| int swift_decompose_float80(long double d, |
| int8_t *digits, size_t digits_length, int *decimalExponent) |
| { |
| static const int exponentBitCount = 15; |
| static const int exponentMask = (1 << exponentBitCount) - 1; |
| // See comments in swift_decompose_double to understand |
| // why we use 16,382 instead of 16,383 here. |
| static const int64_t exponentBias = (1 << (exponentBitCount - 1)) - 2; // 16,382 |
| |
| // Step 0: Deconstruct the target number |
| // Note: this strongly assumes Intel 80-bit extended format in LSB |
| // byte order |
| const uint64_t *raw_p = (const uint64_t *)&d; |
| int exponentBitPattern = raw_p[1] & exponentMask; |
| uint64_t significandBitPattern = raw_p[0]; |
| |
| // Step 1: Handle the various input cases: |
| int64_t binaryExponent; |
| uint64_t significand; |
| if (digits_length < 21) { |
| return 0; |
| } else if (exponentBitPattern == exponentMask) { // NaN or Infinity |
| // Return no digits |
| return 0; |
| } else if (exponentBitPattern == 0) { |
| if (significandBitPattern == 0) { // Zero |
| digits[0] = 0; |
| *decimalExponent = 0; |
| return 1; |
| } else { // subnormal |
| binaryExponent = 1 - exponentBias; |
| significand = significandBitPattern; |
| } |
| } else if (significandBitPattern >> 63) { // Normal |
| binaryExponent = exponentBitPattern - exponentBias; |
| significand = significandBitPattern; |
| } else { |
| // "Unnormal" values are rejected as invalid by 80387 and later. |
| // Treat them the same as NaNs here. |
| return 0; |
| } |
| |
| // Step 2: Determine the exact unscaled target interval |
| uint64_t halfUlp = (uint64_t)1 << 63; |
| uint64_t quarterUlp = halfUlp >> 1; |
| uint64_t threeQuarterUlp = halfUlp + quarterUlp; |
| swift_uint128_t upperMidpointExact, lowerMidpointExact; |
| initialize128WithHighLow64(upperMidpointExact, significand, halfUlp); |
| int isBoundary = (significandBitPattern & 0x7fffffffffffffff) == 0; |
| // Subtract 1/4 or 1/2 ULP by first subtracting 1 full ULP, then adding some back |
| initialize128WithHighLow64(lowerMidpointExact, significand - 1, isBoundary ? threeQuarterUlp : halfUlp); |
| |
| // Step 3: Estimate the base 10 exponent |
| int base10Exponent = decimalExponentFor2ToThe(binaryExponent); |
| |
| // Step 4: Compute a power-of-10 scale factor |
| swift_uint192_t powerOfTenRoundedDown; |
| swift_uint192_t powerOfTenRoundedUp; |
| int powerOfTenExponent = 0; |
| intervalContainingPowerOf10_Float80(-base10Exponent, |
| &powerOfTenRoundedDown, |
| &powerOfTenRoundedUp, |
| &powerOfTenExponent); |
| const int extraBits = binaryExponent + powerOfTenExponent; |
| |
| // Step 5: Scale the interval (with rounding) |
| static const int integerBits = 14; |
| static const int fractionBits = 192 - integerBits; |
| #if HAVE_UINT128_T |
| static const int highFractionBits = fractionBits % 64; |
| #else |
| static const int highFractionBits = fractionBits % 32; |
| #endif |
| swift_uint192_t u, l; |
| if (significandBitPattern & 1) { |
| // Narrow the interval (odd significand) |
| u = powerOfTenRoundedDown; |
| multiply192x128RoundingDown(&u, upperMidpointExact); |
| shiftRightRoundingDown192(&u, integerBits - extraBits); |
| |
| l = powerOfTenRoundedUp; |
| multiply192x128RoundingUp(&l, lowerMidpointExact); |
| shiftRightRoundingUp192(&l, integerBits - extraBits); |
| } else { |
| // Widen the interval (even significand) |
| u = powerOfTenRoundedUp; |
| multiply192x128RoundingUp(&u, upperMidpointExact); |
| shiftRightRoundingUp192(&u, integerBits - extraBits); |
| |
| l = powerOfTenRoundedDown; |
| multiply192x128RoundingDown(&l, lowerMidpointExact); |
| shiftRightRoundingDown192(&l, integerBits - extraBits); |
| } |
| |
| // Step 6: Align first digit, adjust exponent |
| // In particular, this prunes leading zeros from subnormals |
| static const uint64_t fixedPointOneHigh = (uint64_t)1 << highFractionBits; |
| static const uint64_t fixedPointMaskHigh = fixedPointOneHigh - 1; |
| swift_uint192_t t = u; |
| swift_uint192_t delta = u; |
| subtract192x192(&delta, l); |
| int exponent = base10Exponent + 1; |
| |
| while (t.high < fixedPointOneHigh) { |
| exponent -= 1; |
| multiply192xi32(&delta, 10); |
| multiply192xi32(&t, 10); |
| } |
| |
| // Step 7: Generate digits |
| int8_t *digit_p = digits; |
| |
| // Adjustment above already set up the first digit: |
| int nextDigit = (int)(t.high >> highFractionBits); |
| t.high &= fixedPointMaskHigh; |
| |
| // Generate four digits at a time ... |
| swift_uint192_t d0 = delta; |
| swift_uint192_t t0 = t; |
| multiply192xi32(&d0, 10000); |
| multiply192xi32(&t0, 10000); |
| int fourDigits = (int)(t0.high >> highFractionBits); |
| t0.high &= fixedPointMaskHigh; |
| while (isLessThan192x192(d0, t0)) { |
| *digit_p++ = nextDigit; |
| int d = fourDigits / 100; |
| *digit_p++ = d / 10; |
| *digit_p++ = d % 10; |
| d = fourDigits % 100; |
| *digit_p++ = d / 10; |
| nextDigit = d % 10; |
| t = t0; |
| delta = d0; |
| multiply192xi32(&d0, 10000); |
| multiply192xi32(&t0, 10000); |
| fourDigits = (int)(t0.high >> highFractionBits); |
| t0.high &= fixedPointMaskHigh; |
| } |
| |
| // Generate one digit at a time... |
| while (isLessThan192x192(delta, t)) { |
| *digit_p++ = nextDigit; |
| multiply192xi32(&delta, 10); |
| multiply192xi32(&t, 10); |
| nextDigit = (int)(t.high >> highFractionBits); |
| t.high &= fixedPointMaskHigh; |
| } |
| |
| // Adjust the final digit to be closer to the original value |
| // We've already consumed most of our available precision, so it's |
| // okay to just work in 64 bits here... |
| #if HAVE_UINT128_T |
| uint64_t deltaHigh64 = delta.high; |
| uint64_t tHigh64 = t.high; |
| #else |
| uint64_t deltaHigh64 = ((uint64_t)delta.high << 32) + delta.e; |
| uint64_t tHigh64 = ((uint64_t)t.high << 32) + t.e; |
| #endif |
| if (deltaHigh64 > tHigh64 + ((uint64_t)1 << (fractionBits % 64))) { |
| uint64_t skew; |
| if (isBoundary) { |
| skew = deltaHigh64 - deltaHigh64 / 3 - tHigh64; |
| } else { |
| skew = deltaHigh64 / 2 - tHigh64; |
| } |
| uint64_t one = (uint64_t)(1) << (64 - integerBits); |
| uint64_t fractionMask = one - 1; |
| uint64_t oneHalf = one >> 1; |
| if ((skew & fractionMask) == oneHalf) { |
| int adjust = (int)(skew >> (64 - integerBits)); |
| // If the skew is integer + 1/2, round the last digit even |
| // after adjustment |
| nextDigit = (nextDigit - adjust) & ~1; |
| } else { |
| // Else round to nearest... |
| int adjust = (int)((skew + oneHalf) >> (64 - integerBits)); |
| nextDigit = (nextDigit - adjust); |
| } |
| } |
| *digit_p++ = nextDigit; |
| |
| *decimalExponent = exponent; |
| return digit_p - digits; |
| } |
| #endif |
| |
| // |
| // ---------------- High-level API ----------------- |
| // |
| // Functions that format a Float/Double/Float80 |
| // directly into a buffer. |
| // |
| // These handle various exception cases (infinity, Nan, zero) |
| // before invoking the general base-10 conversion. |
| |
| #if SWIFT_DTOA_FLOAT_SUPPORT || SWIFT_DTOA_DOUBLE_SUPPORT || SWIFT_DTOA_FLOAT80_SUPPORT |
| static size_t swift_format_constant(char *dest, size_t length, const char *s) { |
| const size_t l = strlen(s); |
| if (length <= l) { |
| return 0; |
| } |
| strcpy(dest, s); |
| return l; |
| } |
| #endif |
| |
| #if SWIFT_DTOA_FLOAT_SUPPORT |
| size_t swift_format_float(float d, char *dest, size_t length) |
| { |
| if (!isfinite(d)) { |
| if (isinf(d)) { |
| // Infinity |
| if (signbit(d)) { |
| return swift_format_constant(dest, length, "-inf"); |
| } else { |
| return swift_format_constant(dest, length, "inf"); |
| } |
| } else { |
| // NaN |
| static const int significandBitCount = 23; |
| uint32_t raw = bitPatternForFloat(d); |
| const char *sign = signbit(d) ? "-" : ""; |
| const char *signaling = ((raw >> (significandBitCount - 1)) & 1) ? "" : "s"; |
| uint32_t payload = raw & ((1L << (significandBitCount - 2)) - 1); |
| char buff[32]; |
| if (payload != 0) { |
| snprintf(buff, sizeof(buff), "%s%snan(0x%x)", |
| sign, signaling, payload); |
| } else { |
| snprintf(buff, sizeof(buff), "%s%snan", |
| sign, signaling); |
| } |
| return swift_format_constant(dest, length, buff); |
| } |
| } |
| |
| // zero |
| if (d == 0.0) { |
| if (signbit(d)) { |
| return swift_format_constant(dest, length, "-0.0"); |
| } else { |
| return swift_format_constant(dest, length, "0.0"); |
| } |
| } |
| |
| // Decimal numeric formatting |
| int decimalExponent; |
| int8_t digits[9]; |
| int digitCount = |
| swift_decompose_float(d, digits, sizeof(digits), &decimalExponent); |
| // People use float to model integers <= 2^24, so we use that |
| // as a cutoff for decimal vs. exponential format. |
| if (decimalExponent < -3 || fabsf(d) > 0x1.0p24F) { |
| return swift_format_exponential(dest, length, signbit(d), |
| digits, digitCount, decimalExponent); |
| } else { |
| return swift_format_decimal(dest, length, signbit(d), |
| digits, digitCount, decimalExponent); |
| } |
| } |
| #endif |
| |
| #if SWIFT_DTOA_DOUBLE_SUPPORT |
| size_t swift_format_double(double d, char *dest, size_t length) |
| { |
| if (!isfinite(d)) { |
| if (isinf(d)) { |
| // Infinity |
| if (signbit(d)) { |
| return swift_format_constant(dest, length, "-inf"); |
| } else { |
| return swift_format_constant(dest, length, "inf"); |
| } |
| } else { |
| // NaN |
| static const int significandBitCount = 52; |
| uint64_t raw = bitPatternForDouble(d); |
| const char *sign = signbit(d) ? "-" : ""; |
| const char *signaling = ((raw >> (significandBitCount - 1)) & 1) ? "" : "s"; |
| uint64_t payload = raw & ((1ull << (significandBitCount - 2)) - 1); |
| char buff[32]; |
| if (payload != 0) { |
| snprintf(buff, sizeof(buff), "%s%snan(0x%" PRIx64 ")", |
| sign, signaling, payload); |
| } else { |
| snprintf(buff, sizeof(buff), "%s%snan", |
| sign, signaling); |
| } |
| return swift_format_constant(dest, length, buff); |
| } |
| } |
| |
| // zero |
| if (d == 0.0) { |
| if (signbit(d)) { |
| return swift_format_constant(dest, length, "-0.0"); |
| } else { |
| return swift_format_constant(dest, length, "0.0"); |
| } |
| } |
| |
| // Decimal numeric formatting |
| int decimalExponent; |
| int8_t digits[17]; |
| int digitCount = |
| swift_decompose_double(d, digits, sizeof(digits), &decimalExponent); |
| // People use double to model integers <= 2^53, so we use that |
| // as a cutoff for decimal vs. exponential format. |
| if (decimalExponent < -3 || fabs(d) > 0x1.0p53) { |
| return swift_format_exponential(dest, length, signbit(d), |
| digits, digitCount, decimalExponent); |
| } else { |
| return swift_format_decimal(dest, length, signbit(d), |
| digits, digitCount, decimalExponent); |
| } |
| } |
| #endif |
| |
| #if SWIFT_DTOA_FLOAT80_SUPPORT |
| size_t swift_format_float80(long double d, char *dest, size_t length) |
| { |
| if (!isfinite(d)) { |
| if (isinf(d)) { |
| // Infinity |
| if (signbit(d)) { |
| return swift_format_constant(dest, length, "-inf"); |
| } else { |
| return swift_format_constant(dest, length, "inf"); |
| } |
| } else { |
| // NaN |
| // Assumes Intel 80-bit extended format in LSB byte order: |
| uint64_t significandBitPattern = *(const uint64_t *)&d; |
| const char *sign = signbit(d) ? "-" : ""; |
| const char *signaling = ((significandBitPattern >> 62) & 1) ? "" : "s"; |
| uint64_t payload = significandBitPattern & (((uint64_t)1 << 61) - 1); |
| char buff[32]; |
| if (payload != 0) { |
| snprintf(buff, sizeof(buff), "%s%snan(0x%" PRIx64 ")", |
| sign, signaling, payload); |
| } else { |
| snprintf(buff, sizeof(buff), "%s%snan", |
| sign, signaling); |
| } |
| return swift_format_constant(dest, length, buff); |
| } |
| } |
| |
| // zero |
| if (d == 0.0) { |
| if (signbit(d)) { |
| return swift_format_constant(dest, length, "-0.0"); |
| } else { |
| return swift_format_constant(dest, length, "0.0"); |
| } |
| } |
| |
| // Decimal numeric formatting |
| int decimalExponent; |
| int8_t digits[21]; |
| int digitCount = |
| swift_decompose_float80(d, digits, sizeof(digits), &decimalExponent); |
| // People use long double to model integers <= 2^64, so we use that |
| // as a cutoff for decimal vs. exponential format. |
| // The constant is written out as a float80 (aka "long double") literal |
| // here since it can't be expressed as a 64-bit integer. |
| if (decimalExponent < -3 || fabsl(d) > 0x1.0p64L) { |
| return swift_format_exponential(dest, length, signbit(d), |
| digits, digitCount, decimalExponent); |
| } else { |
| return swift_format_decimal(dest, length, signbit(d), |
| digits, digitCount, decimalExponent); |
| } |
| } |
| #endif |
| |
| /** |
| * Routines to format a decomposed value into a standard string form. |
| */ |
| |
| // Format into exponential format: "1.234e+56" |
| // Returns number of characters actually written to `dest`. |
| // Returns zero if buffer is too small. |
| size_t swift_format_exponential(char *dest, size_t length, |
| bool negative, const int8_t *digits, int digit_count, int exponent) |
| { |
| // Largest buffer we could possibly need: |
| size_t maximum_size = digit_count + 9; |
| if (length < maximum_size) { |
| // We only do the detailed check if the size is borderline. |
| size_t actual_size = |
| + (negative ? 1 : 0) // Leading minus |
| + digit_count // digits |
| + (digit_count > 1 ? 1 : 0) // decimal |
| + 1 // 'e' |
| + 1 // sign |
| + (exponent > 99 ? (exponent > 999 ? 4 : 3) : 2) // exponent |
| + 1; // trailing zero byte |
| if (length < actual_size) { |
| if (length > 0) { |
| dest[0] = 0; |
| } |
| return 0; |
| } |
| } |
| char *p = dest; |
| if (negative) { |
| *p++ = '-'; |
| } |
| |
| *p++ = digits[0] + '0'; |
| exponent -= 1; |
| if (digit_count > 1) { |
| *p++ = '.'; |
| for (int i = 1; i < digit_count; i++) { |
| *p++ = digits[i] + '0'; |
| } |
| } |
| *p++ = 'e'; |
| if (exponent < 0) { |
| *p++ = '-'; |
| exponent = -exponent; |
| } else { |
| *p++ = '+'; |
| } |
| if (exponent > 99) { |
| if (exponent > 999) { |
| *p++ = (exponent / 1000 % 10) + '0'; |
| } |
| *p++ = (exponent / 100 % 10) + '0'; |
| exponent %= 100; |
| } |
| *p++ = (exponent / 10) + '0'; |
| *p++ = (exponent % 10) + '0'; |
| *p = '\0'; |
| return p - dest; |
| } |
| |
| // Format into decimal form: "123456789000.0", "1234.5678", "0.0000001234" |
| // Returns number of bytes of `dest` actually used, or zero if |
| // provided buffer is too small. |
| size_t swift_format_decimal(char *dest, size_t length, |
| bool negative, const int8_t *digits, int digit_count, int exponent) |
| { |
| // Largest buffer we could possibly need: |
| size_t maximum_size = |
| digit_count // All the digits |
| + (exponent > 0 ? exponent : -exponent) // Max # of extra zeros |
| + 4; // Max # of other items |
| if (length < maximum_size) { |
| // We only do the detailed check if the size is borderline. |
| if (exponent <= 0) { // "0.0000001234" |
| size_t actual_size = |
| (negative ? 1 : 0) // Leading minus |
| + 2 // Leading "0." |
| + (-exponent) // Leading zeros after decimal point |
| + digit_count |
| + 1; // Trailing zero byte |
| if (length < actual_size) { |
| if (length > 0) { |
| dest[0] = 0; |
| } |
| return 0; |
| } |
| } else if (exponent < digit_count) { // "123.45" |
| size_t actual_size = |
| (negative ? 1 : 0) // Leading minus |
| + digit_count |
| + 1 // embedded decimal point |
| + 1; // Trailing zero byte |
| if (length < actual_size) { |
| if (length > 0) { |
| dest[0] = 0; |
| } |
| return 0; |
| } |
| } else { // "12345000.0" |
| size_t actual_size = |
| (negative ? 1 : 0) // Leading minus |
| + digit_count |
| + (exponent - digit_count) // trailing zeros |
| + 2 // ".0" to mark this as floating point |
| + 1; // Trailing zero byte |
| if (length < actual_size) { |
| if (length > 0) { |
| dest[0] = 0; |
| } |
| return 0; |
| } |
| } |
| } |
| |
| char *p = dest; |
| if (negative) { |
| *p++ = '-'; |
| } |
| |
| if (exponent <= 0) { |
| *p++ = '0'; |
| *p++ = '.'; |
| while (exponent < 0) { |
| *p++ = '0'; |
| exponent += 1; |
| } |
| for (int i = 0; i < digit_count; ++i) { |
| *p++ = digits[i] + '0'; |
| } |
| } else if (exponent < digit_count) { |
| for (int i = 0; i < digit_count; i++) { |
| if (exponent == 0) { |
| *p++ = '.'; |
| } |
| *p++ = digits[i] + '0'; |
| exponent -= 1; |
| } |
| } else { |
| for (int i = 0; i < digit_count; i++) { |
| *p++ = digits[i] + '0'; |
| exponent -= 1; |
| } |
| while (exponent > 0) { |
| *p++ = '0'; |
| exponent -= 1; |
| } |
| *p++ = '.'; |
| *p++ = '0'; |
| } |
| *p = '\0'; |
| return p - dest; |
| } |
| |
| // |
| // ------------ Arithmetic helpers ---------------- |
| // |
| |
| // The core algorithm relies heavily on fraction and fixed-point |
| // arithmetic with 64-bit, 128-bit, and 192-bit integer values. (For |
| // float, double, and float80, respectively.) They also need precise |
| // control over all rounding. |
| // |
| // Note that most arithmetic operations are the same for integers and |
| // fractions, so we can just use the normal integer operations in most |
| // places. Multiplication however, is different for fixed-size |
| // fractions. Integer multiplication preserves the low-order part and |
| // discards the high-order part (ignoring overflow). Fraction |
| // multiplication preserves the high-order part and discards the |
| // low-order part (rounding). So most of the arithmetic helpers here |
| // are for multiplication. |
| |
| // Note: With 64-bit GCC and Clang, we get a noticable performance |
| // gain by using `__uint128_t`. Otherwise, we have to break things |
| // down into 32-bit chunks so we don't overflow 64-bit temporaries. |
| |
| #if SWIFT_DTOA_FLOAT_SUPPORT |
| // Multiply a 64-bit fraction by a 32-bit fraction, rounding down. |
| static uint64_t multiply64x32RoundingDown(uint64_t lhs, uint32_t rhs) { |
| static const uint64_t mask32 = UINT32_MAX; |
| uint64_t t = ((lhs & mask32) * rhs) >> 32; |
| return t + (lhs >> 32) * rhs; |
| } |
| |
| // Multiply a 64-bit fraction by a 32-bit fraction, rounding up. |
| static uint64_t multiply64x32RoundingUp(uint64_t lhs, uint32_t rhs) { |
| static const uint64_t mask32 = UINT32_MAX; |
| uint64_t t = (((lhs & mask32) * rhs) + mask32) >> 32; |
| return t + (lhs >> 32) * rhs; |
| } |
| |
| // Multiply a 64-bit fraction by a 64-bit fraction, rounding down. |
| static uint64_t multiply64x64RoundingDown(uint64_t lhs, uint64_t rhs) { |
| #if HAVE_UINT128_T |
| __uint128_t full = (__uint128_t)lhs * rhs; |
| return (uint64_t)(full >> 64); |
| #else |
| static const uint64_t mask32 = UINT32_MAX; |
| uint64_t t = (lhs & mask32) * (rhs & mask32); |
| t >>= 32; |
| uint64_t a = (lhs >> 32) * (rhs & mask32); |
| uint64_t b = (lhs & mask32) * (rhs >> 32); |
| // Useful: If w,x,y,z are all 32-bit values, then: |
| // w * x + y + z |
| // <= (2^64 - 2^33 + 1) + (2^32 - 1) + (2^32 - 1) |
| // <= 2^64 - 1 |
| // |
| // That is, a product of two 32-bit values plus two more 32-bit |
| // values can't overflow 64 bits. (But "three more" can, so be |
| // careful!) |
| // |
| // Here: t + a + (b & mask32) <= 2^64 - 1 |
| t += a + (b & mask32); |
| t >>= 32; |
| t += (b >> 32); |
| return t + (lhs >> 32) * (rhs >> 32); |
| #endif |
| } |
| |
| // Multiply a 64-bit fraction by a 64-bit fraction, rounding up. |
| static uint64_t multiply64x64RoundingUp(uint64_t lhs, uint64_t rhs) { |
| #if HAVE_UINT128_T |
| static const __uint128_t roundingUpBias = ((__uint128_t)1 << 64) - 1; |
| __uint128_t full = (__uint128_t)lhs * rhs; |
| return (uint64_t)((full + roundingUpBias) >> 64); |
| #else |
| static const uint64_t mask32 = UINT32_MAX; |
| uint64_t t = (lhs & mask32) * (rhs & mask32); |
| t = (t + mask32) >> 32; |
| uint64_t a = (lhs >> 32) * (rhs & mask32); |
| uint64_t b = (lhs & mask32) * (rhs >> 32); |
| t += (a & mask32) + (b & mask32) + mask32; |
| t >>= 32; |
| t += (a >> 32) + (b >> 32); |
| return t + (lhs >> 32) * (rhs >> 32); |
| #endif |
| } |
| |
| #endif |
| |
| #if SWIFT_DTOA_DOUBLE_SUPPORT |
| // Multiply a 128-bit fraction by a 64-bit fraction, rounding down. |
| static swift_uint128_t multiply128x64RoundingDown(swift_uint128_t lhs, uint64_t rhs) { |
| #if HAVE_UINT128_T |
| uint64_t lhsl = (uint64_t)lhs; |
| uint64_t lhsh = (uint64_t)(lhs >> 64); |
| swift_uint128_t h = (swift_uint128_t)lhsh * rhs; |
| swift_uint128_t l = (swift_uint128_t)lhsl * rhs; |
| return h + (l >> 64); |
| #else |
| swift_uint128_t result; |
| static const uint64_t mask32 = UINT32_MAX; |
| uint64_t rhs0 = rhs & mask32; |
| uint64_t rhs1 = rhs >> 32; |
| uint64_t t = (lhs.low) * rhs0; |
| t >>= 32; |
| uint64_t a = (lhs.b) * rhs0; |
| uint64_t b = (lhs.low) * rhs1; |
| t += a + (b & mask32); |
| t >>= 32; |
| t += (b >> 32); |
| a = lhs.c * rhs0; |
| b = lhs.b * rhs1; |
| t += (a & mask32) + (b & mask32); |
| result.low = t; |
| t >>= 32; |
| t += (a >> 32) + (b >> 32); |
| a = lhs.high * rhs0; |
| b = lhs.c * rhs1; |
| t += (a & mask32) + (b & mask32); |
| result.b = t; |
| t >>= 32; |
| t += (a >> 32) + (b >> 32); |
| t += lhs.high * rhs1; |
| result.c = t; |
| result.high = t >> 32; |
| return result; |
| #endif |
| } |
| |
| // Multiply a 128-bit fraction by a 64-bit fraction, rounding up. |
| static swift_uint128_t multiply128x64RoundingUp(swift_uint128_t lhs, uint64_t rhs) { |
| #if HAVE_UINT128_T |
| uint64_t lhsl = (uint64_t)lhs; |
| uint64_t lhsh = (uint64_t)(lhs >> 64); |
| swift_uint128_t h = (swift_uint128_t)lhsh * rhs; |
| swift_uint128_t l = (swift_uint128_t)lhsl * rhs; |
| const static __uint128_t bias = ((__uint128_t)1 << 64) - 1; |
| return h + ((l + bias) >> 64); |
| #else |
| swift_uint128_t result; |
| static const uint64_t mask32 = UINT32_MAX; |
| uint64_t rhs0 = rhs & mask32; |
| uint64_t rhs1 = rhs >> 32; |
| uint64_t t = (lhs.low) * rhs0 + mask32; |
| t >>= 32; |
| uint64_t a = (lhs.b) * rhs0; |
| uint64_t b = (lhs.low) * rhs1; |
| t += (a & mask32) + (b & mask32) + mask32; |
| t >>= 32; |
| t += (a >> 32) + (b >> 32); |
| a = lhs.c * rhs0; |
| b = lhs.b * rhs1; |
| t += (a & mask32) + (b & mask32); |
| result.low = t; |
| t >>= 32; |
| t += (a >> 32) + (b >> 32); |
| a = lhs.high * rhs0; |
| b = lhs.c * rhs1; |
| t += (a & mask32) + (b & mask32); |
| result.b = t; |
| t >>= 32; |
| t += (a >> 32) + (b >> 32); |
| t += lhs.high * rhs1; |
| result.c = t; |
| result.high = t >> 32; |
| return result; |
| #endif |
| } |
| |
| #if !HAVE_UINT128_T |
| // Multiply a 128-bit fraction by a 32-bit integer in a 32-bit environment. |
| // (On 64-bit, we use a fast inline macro.) |
| static void multiply128xi32(swift_uint128_t *lhs, uint32_t rhs) { |
| uint64_t t = (uint64_t)(lhs->low) * rhs; |
| lhs->low = (uint32_t)t; |
| t = (t >> 32) + (uint64_t)(lhs->b) * rhs; |
| lhs->b = (uint32_t)t; |
| t = (t >> 32) + (uint64_t)(lhs->c) * rhs; |
| lhs->c = (uint32_t)t; |
| t = (t >> 32) + (uint64_t)(lhs->high) * rhs; |
| lhs->high = (uint32_t)t; |
| } |
| |
| // Compare two 128-bit integers in a 32-bit environment |
| // (On 64-bit, we use a fast inline macro.) |
| static int isLessThan128x128(swift_uint128_t lhs, swift_uint128_t rhs) { |
| return ((lhs.high < rhs.high) |
| || ((lhs.high == rhs.high) |
| && ((lhs.c < rhs.c) |
| || ((lhs.c == rhs.c) |
| && ((lhs.b < rhs.b) |
| || ((lhs.b == rhs.b) |
| && (lhs.low < rhs.low))))))); |
| } |
| |
| // Subtract 128-bit values in a 32-bit environment |
| static void subtract128x128(swift_uint128_t *lhs, swift_uint128_t rhs) { |
| uint64_t t = (uint64_t)lhs->low + (~rhs.low) + 1; |
| lhs->low = (uint32_t)t; |
| t = (t >> 32) + lhs->b + (~rhs.b); |
| lhs->b = (uint32_t)t; |
| t = (t >> 32) + lhs->c + (~rhs.c); |
| lhs->c = (uint32_t)t; |
| t = (t >> 32) + lhs->high + (~rhs.high); |
| lhs->high = (uint32_t)t; |
| } |
| #endif |
| |
| // Shift a 128-bit integer right, rounding down. |
| static swift_uint128_t shiftRightRoundingDown128(swift_uint128_t lhs, int shift) { |
| #if HAVE_UINT128_T |
| return lhs >> shift; |
| #else |
| // Note: Shift is always less than 32 |
| swift_uint128_t result; |
| uint64_t t = (uint64_t)lhs.low >> shift; |
| t += ((uint64_t)lhs.b << (32 - shift)); |
| result.low = t; |
| t >>= 32; |
| t += ((uint64_t)lhs.c << (32 - shift)); |
| result.b = t; |
| t >>= 32; |
| t += ((uint64_t)lhs.high << (32 - shift)); |
| result.c = t; |
| t >>= 32; |
| result.high = t; |
| return result; |
| #endif |
| } |
| |
| // Shift a 128-bit integer right, rounding up. |
| static swift_uint128_t shiftRightRoundingUp128(swift_uint128_t lhs, int shift) { |
| #if HAVE_UINT128_T |
| uint64_t bias = ((uint64_t)1 << shift) - 1; |
| return ((lhs + bias) >> shift); |
| #else |
| swift_uint128_t result; |
| const uint64_t bias = (1 << shift) - 1; |
| uint64_t t = ((uint64_t)lhs.low + bias) >> shift; |
| t += ((uint64_t)lhs.b << (32 - shift)); |
| result.low = t; |
| t >>= 32; |
| t += ((uint64_t)lhs.c << (32 - shift)); |
| result.b = t; |
| t >>= 32; |
| t += ((uint64_t)lhs.high << (32 - shift)); |
| result.c = t; |
| t >>= 32; |
| result.high = t; |
| return result; |
| #endif |
| } |
| #endif |
| |
| #if SWIFT_DTOA_FLOAT80_SUPPORT |
| // Multiply a 192-bit fraction by a 64-bit fraction, rounding down. |
| static void multiply192x64RoundingDown(swift_uint192_t *lhs, uint64_t rhs) { |
| #if HAVE_UINT128_T |
| // Compute the three 128-bit cross-products |
| __uint128_t cd = (__uint128_t)lhs->low * rhs; |
| __uint128_t bc = (__uint128_t)lhs->mid * rhs; |
| __uint128_t ab = (__uint128_t)lhs->high * rhs; |
| // Add up the three 64-bit outputs (including carries) |
| __uint128_t c = (cd >> 64) + (uint64_t)bc; |
| __uint128_t b = (bc >> 64) + (uint64_t)ab + (c >> 64); |
| __uint128_t a = (ab >> 64) + (b >> 64); |
| lhs->high = a; |
| lhs->mid = b; |
| lhs->low = c; |
| #else |
| static const uint64_t mask32 = UINT32_MAX; |
| uint64_t rhs0 = rhs & mask32; |
| uint64_t rhs1 = rhs >> 32; |
| uint64_t t = lhs->low * rhs0; |
| t >>= 32; |
| uint64_t a = lhs->low * rhs1; |
| uint64_t b = lhs->b * rhs0; |
| t += a + (b & mask32); |
| t >>= 32; |
| t += (b >> 32); |
| a = lhs->b * rhs1; |
| b = lhs->c * rhs0; |
| t += (a & mask32) + (b & mask32); |
| lhs->low = t; |
| t >>= 32; |
| t += (a >> 32) + (b >> 32); |
| a = lhs->c * rhs1; |
| b = lhs->d * rhs0; |
| t += (a & mask32) + (b & mask32); |
| lhs->b = t; |
| t >>= 32; |
| t += (a >> 32) + (b >> 32); |
| a = lhs->d * rhs1; |
| b = lhs->e * rhs0; |
| t += (a & mask32) + (b & mask32); |
| lhs->c = t; |
| t >>= 32; |
| t += (a >> 32) + (b >> 32); |
| a = lhs->e * rhs1; |
| b = lhs->high * rhs0; |
| t += (a & mask32) + (b & mask32); |
| lhs->d = t; |
| t >>= 32; |
| t += (a >> 32) + (b >> 32); |
| t += lhs->high * rhs1; |
| lhs->e = t; |
| lhs->high = t >> 32; |
| #endif |
| } |
| |
| // Multiply a 192-bit fraction by a 64-bit fraction, rounding up. |
| static void multiply192x64RoundingUp(swift_uint192_t *lhs, uint64_t rhs) { |
| #if HAVE_UINT128_T |
| // Compute the three 128-bit cross-products |
| __uint128_t cd = (__uint128_t)lhs->low * rhs + UINT64_MAX; |
| __uint128_t bc = (__uint128_t)lhs->mid * rhs; |
| __uint128_t ab = (__uint128_t)lhs->high * rhs; |
| // Add up the three 64-bit outputs (including carries) |
| __uint128_t c = (cd >> 64) + (uint64_t)bc; |
| __uint128_t b = (bc >> 64) + (uint64_t)ab + (c >> 64); |
| __uint128_t a = (ab >> 64) + (b >> 64); |
| lhs->high = a; |
| lhs->mid = b; |
| lhs->low = c; |
| #else |
| static const uint64_t mask32 = UINT32_MAX; |
| static const uint64_t bias = mask32; |
| uint64_t rhs0 = rhs & mask32; |
| uint64_t rhs1 = rhs >> 32; |
| uint64_t t = lhs->low * rhs0 + bias; |
| t >>= 32; |
| uint64_t a = lhs->low * rhs1; |
| uint64_t b = lhs->b * rhs0; |
| t += (a & mask32) + (b & mask32) + bias; |
| t >>= 32; |
| t += (a >> 32) + (b >> 32); |
| a = lhs->b * rhs1; |
| b = lhs->c * rhs0; |
| t += (a & mask32) + (b & mask32); |
| lhs->low = t; |
| t >>= 32; |
| t += (a >> 32) + (b >> 32); |
| a = lhs->c * rhs1; |
| b = lhs->d * rhs0; |
| t += (a & mask32) + (b & mask32); |
| lhs->b = t; |
| t >>= 32; |
| t += (a >> 32) + (b >> 32); |
| a = lhs->d * rhs1; |
| b = lhs->e * rhs0; |
| t += (a & mask32) + (b & mask32); |
| lhs->c = t; |
| t >>= 32; |
| t += (a >> 32) + (b >> 32); |
| a = lhs->e * rhs1; |
| b = lhs->high * rhs0; |
| t += (a & mask32) + (b & mask32); |
| lhs->d = t; |
| t >>= 32; |
| t += (a >> 32) + (b >> 32); |
| t += lhs->high * rhs1; |
| lhs->e = t; |
| lhs->high = t >> 32; |
| #endif |
| } |
| |
| // Multiply a 192-bit fraction by a 64-bit integer. |
| // This is used in the digit generation to multiply by ten or |
| // 10,000. Note that rounding never appliles here. |
| // As used below, this will never overflow. |
| static void multiply192xi32(swift_uint192_t *lhs, uint32_t rhs) { |
| #if HAVE_UINT128_T |
| __uint128_t t = (__uint128_t)lhs->low * rhs; |
| lhs->low = (uint64_t)t; |
| t = (t >> 64) + (__uint128_t)lhs->mid * rhs; |
| lhs->mid = (uint64_t)t; |
| t = (t >> 64) + (__uint128_t)lhs->high * rhs; |
| lhs->high = (uint64_t)t; |
| #else |
| uint64_t t = (uint64_t)lhs->low * rhs; |
| lhs->low = t; |
| t = (t >> 32) + (uint64_t)lhs->b * rhs; |
| lhs->b = t; |
| t = (t >> 32) + (uint64_t)lhs->c * rhs; |
| lhs->c = t; |
| t = (t >> 32) + (uint64_t)lhs->d * rhs; |
| lhs->d = t; |
| t = (t >> 32) + (uint64_t)lhs->e * rhs; |
| lhs->e = t; |
| t = (t >> 32) + (uint64_t)lhs->high * rhs; |
| lhs->high = t; |
| #endif |
| } |
| |
| // Multiply a 192-bit fraction by a 128-bit fraction, rounding down. |
| static void multiply192x128RoundingDown(swift_uint192_t *lhs, swift_uint128_t rhs) { |
| #if HAVE_UINT128_T |
| // A full multiply of three 64-bit values by two 64-bit values |
| // yields five such components. We discard the bottom two (except |
| // for carries) to get a rounded-down three-element result. |
| __uint128_t current = (__uint128_t)lhs->low * (uint64_t)rhs; |
| |
| current = (current >> 64); |
| __uint128_t t = (__uint128_t)lhs->low * (rhs >> 64); |
| current += (uint64_t)t; |
| __uint128_t next = t >> 64; |
| t = (__uint128_t)lhs->mid * (uint64_t)rhs; |
| current += (uint64_t)t; |
| next += t >> 64; |
| |
| current = next + (current >> 64); |
| t = (__uint128_t)lhs->mid * (rhs >> 64); |
| current += (uint64_t)t; |
| next = t >> 64; |
| t = (__uint128_t)lhs->high * (uint64_t)rhs; |
| current += (uint64_t)t; |
| next += t >> 64; |
| lhs->low = (uint64_t)current; |
| |
| current = next + (current >> 64); |
| t = (__uint128_t)lhs->high * (rhs >> 64); |
| current += t; |
| lhs->mid = (uint64_t)current; |
| lhs->high = (uint64_t)(current >> 64); |
| #else |
| uint64_t a, b, c, d; // temporaries |
| // Six 32-bit values multiplied by 4 32-bit values. Oh my. |
| static const uint64_t mask32 = UINT32_MAX; |
| uint64_t t = lhs->low * rhs.low; |
| t >>= 32; |
| a = (uint64_t)lhs->low * rhs.b; |
| b = (uint64_t)lhs->b * rhs.low; |
| t += a + (b & mask32); |
| t >>= 32; |
| t += (b >> 32); |
| a = (uint64_t)lhs->low * rhs.c; |
| b = (uint64_t)lhs->b * rhs.b; |
| c = (uint64_t)lhs->c * rhs.low; |
| t += (a & mask32) + (b & mask32) + (c & mask32); |
| t >>= 32; |
| t += (a >> 32) + (b >> 32) + (c >> 32); |
| a = (uint64_t)lhs->low * rhs.high; |
| b = (uint64_t)lhs->b * rhs.c; |
| c = (uint64_t)lhs->c * rhs.b; |
| d = (uint64_t)lhs->d * rhs.low; |
| t += (a & mask32) + (b & mask32) + (c & mask32) + (d & mask32); |
| t >>= 32; |
| t += (a >> 32) + (b >> 32) + (c >> 32) + (d >> 32); |
| a = (uint64_t)lhs->b * rhs.high; |
| b = (uint64_t)lhs->c * rhs.c; |
| c = (uint64_t)lhs->d * rhs.b; |
| d = (uint64_t)lhs->e * rhs.low; |
| t += (a & mask32) + (b & mask32) + (c & mask32) + (d & mask32); |
| lhs->low = t; |
| t >>= 32; |
| t += (a >> 32) + (b >> 32) + (c >> 32) + (d >> 32); |
| a = (uint64_t)lhs->c * rhs.high; |
| b = (uint64_t)lhs->d * rhs.c; |
| c = (uint64_t)lhs->e * rhs.b; |
| d = (uint64_t)lhs->high * rhs.low; |
| t += (a & mask32) + (b & mask32) + (c & mask32) + (d & mask32); |
| lhs->b = t; |
| t >>= 32; |
| t += (a >> 32) + (b >> 32) + (c >> 32) + (d >> 32); |
| a = (uint64_t)lhs->d * rhs.high; |
| b = (uint64_t)lhs->e * rhs.c; |
| c = (uint64_t)lhs->high * rhs.b; |
| t += (a & mask32) + (b & mask32) + (c & mask32); |
| lhs->c = t; |
| t >>= 32; |
| t += (a >> 32) + (b >> 32) + (c >> 32); |
| a = (uint64_t)lhs->e * rhs.high; |
| b = (uint64_t)lhs->high * rhs.c; |
| t += (a & mask32) + (b & mask32); |
| lhs->d = t; |
| t >>= 32; |
| t += (a >> 32) + (b >> 32); |
| t += (uint64_t)lhs->high * rhs.high; |
| lhs->e = t; |
| lhs->high = t >> 32; |
| #endif |
| } |
| |
| // Multiply a 192-bit fraction by a 128-bit fraction, rounding up. |
| static void multiply192x128RoundingUp(swift_uint192_t *lhs, swift_uint128_t rhs) { |
| #if HAVE_UINT128_T |
| // Same as the rounding-down version, but we add |
| // UINT128_MAX to the bottom two to force an extra |
| // carry if they are non-zero. |
| swift_uint128_t current = (swift_uint128_t)lhs->low * (uint64_t)rhs; |
| current += UINT64_MAX; |
| |
| current = (current >> 64); |
| swift_uint128_t t = (swift_uint128_t)lhs->low * (rhs >> 64); |
| current += (uint64_t)t; |
| swift_uint128_t next = t >> 64; |
| t = (swift_uint128_t)lhs->mid * (uint64_t)rhs; |
| current += (uint64_t)t; |
| next += t >> 64; |
| // Round up by adding UINT128_MAX (upper half) |
| current += UINT64_MAX; |
| |
| current = next + (current >> 64); |
| t = (swift_uint128_t)lhs->mid * (rhs >> 64); |
| current += (uint64_t)t; |
| next = t >> 64; |
| t = (swift_uint128_t)lhs->high * (uint64_t)rhs; |
| current += (uint64_t)t; |
| next += t >> 64; |
| lhs->low = (uint64_t)current; |
| |
| current = next + (current >> 64); |
| t = (swift_uint128_t)lhs->high * (rhs >> 64); |
| current += t; |
| lhs->mid = (uint64_t)current; |
| lhs->high = (uint64_t)(current >> 64); |
| #else |
| uint64_t a, b, c, d; // temporaries |
| // Six 32-bit values multiplied by 4 32-bit values. Oh my. |
| static const uint64_t mask32 = UINT32_MAX; |
| uint64_t t = (uint64_t)lhs->low * rhs.low + mask32; |
| t >>= 32; |
| a = (uint64_t)lhs->low * rhs.b; |
| b = (uint64_t)lhs->b * rhs.low; |
| t += (a & mask32) + (b & mask32) + mask32; |
| t >>= 32; |
| t += (a >> 32) + (b >> 32); |
| a = (uint64_t)lhs->low * rhs.c; |
| b = (uint64_t)lhs->b * rhs.b; |
| c = (uint64_t)lhs->c * rhs.low; |
| t += (a & mask32) + (b & mask32) + (c & mask32) + mask32; |
| t >>= 32; |
| t += (a >> 32) + (b >> 32) + (c >> 32); |
| a = (uint64_t)lhs->low * rhs.high; |
| b = (uint64_t)lhs->b * rhs.c; |
| c = (uint64_t)lhs->c * rhs.b; |
| d = (uint64_t)lhs->d * rhs.low; |
| t += (a & mask32) + (b & mask32) + (c & mask32) + (d & mask32) + mask32; |
| t >>= 32; |
| t += (a >> 32) + (b >> 32) + (c >> 32) + (d >> 32); |
| a = (uint64_t)lhs->b * rhs.high; |
| b = (uint64_t)lhs->c * rhs.c; |
| c = (uint64_t)lhs->d * rhs.b; |
| d = (uint64_t)lhs->e * rhs.low; |
| t += (a & mask32) + (b & mask32) + (c & mask32) + (d & mask32); |
| lhs->low = t; |
| t >>= 32; |
| t += (a >> 32) + (b >> 32) + (c >> 32) + (d >> 32); |
| a = (uint64_t)lhs->c * rhs.high; |
| b = (uint64_t)lhs->d * rhs.c; |
| c = (uint64_t)lhs->e * rhs.b; |
| d = (uint64_t)lhs->high * rhs.low; |
| t += (a & mask32) + (b & mask32) + (c & mask32) + (d & mask32); |
| lhs->b = t; |
| t >>= 32; |
| t += (a >> 32) + (b >> 32) + (c >> 32) + (d >> 32); |
| a = (uint64_t)lhs->d * rhs.high; |
| b = (uint64_t)lhs->e * rhs.c; |
| c = (uint64_t)lhs->high * rhs.b; |
| t += (a & mask32) + (b & mask32) + (c & mask32); |
| lhs->c = t; |
| t >>= 32; |
| t += (a >> 32) + (b >> 32) + (c >> 32); |
| a = (uint64_t)lhs->e * rhs.high; |
| b = (uint64_t)lhs->high * rhs.c; |
| t += (a & mask32) + (b & mask32); |
| lhs->d = t; |
| t >>= 32; |
| t += (a >> 32) + (b >> 32); |
| t += (uint64_t)lhs->high * rhs.high; |
| lhs->e = t; |
| lhs->high = t >> 32; |
| #endif |
| } |
| |
| // Subtract two 192-bit integers or fractions. |
| static void subtract192x192(swift_uint192_t *lhs, swift_uint192_t rhs) { |
| #if HAVE_UINT128_T |
| swift_uint128_t t = (swift_uint128_t)lhs->low + (~rhs.low) + 1; |
| lhs->low = t; |
| t = (t >> 64) + lhs->mid + (~rhs.mid); |
| lhs->mid = t; |
| lhs->high += (t >> 64) + (~rhs.high); |
| #else |
| uint64_t t = (uint64_t)lhs->low + (~rhs.low) + 1; |
| lhs->low = t; |
| t = (t >> 32) + lhs->b + (~rhs.b); |
| lhs->b = t; |
| t = (t >> 32) + lhs->c + (~rhs.c); |
| lhs->c = t; |
| t = (t >> 32) + lhs->d + (~rhs.d); |
| lhs->d = t; |
| t = (t >> 32) + lhs->e + (~rhs.e); |
| lhs->e = t; |
| lhs->high += (t >> 32) + (~rhs.high); |
| #endif |
| } |
| |
| // Compare two 192-bit integers or fractions. |
| static int isLessThan192x192(swift_uint192_t lhs, swift_uint192_t rhs) { |
| #if HAVE_UINT128_T |
| return (lhs.high < rhs.high) |
| || (lhs.high == rhs.high |
| && (lhs.mid < rhs.mid |
| || (lhs.mid == rhs.mid |
| && lhs.low < rhs.low))); |
| #else |
| return (lhs.high < rhs.high |
| || (lhs.high == rhs.high |
| && (lhs.e < rhs.e |
| || (lhs.e == rhs.e |
| && (lhs.d < rhs.d |
| || (lhs.d == rhs.d |
| && (lhs.c < rhs.c |
| || (lhs.c == rhs.c |
| && (lhs.b < rhs.b |
| || (lhs.b == rhs.b |
| && (lhs.low < rhs.low))))))))))); |
| #endif |
| } |
| |
| // Shift a 192-bit integer right, rounding down. |
| static void shiftRightRoundingDown192(swift_uint192_t *lhs, int shift) { |
| #if HAVE_UINT128_T |
| __uint128_t t = (__uint128_t)lhs->low >> shift; |
| t += ((__uint128_t)lhs->mid << (64 - shift)); |
| lhs->low = t; |
| t >>= 64; |
| t += ((__uint128_t)lhs->high << (64 - shift)); |
| lhs->mid = t; |
| t >>= 64; |
| lhs->high = t; |
| #else |
| uint64_t t = (uint64_t)lhs->low >> shift; |
| t += ((uint64_t)lhs->b << (32 - shift)); |
| lhs->low = t; |
| t >>= 32; |
| t += ((uint64_t)lhs->c << (32 - shift)); |
| lhs->b = t; |
| t >>= 32; |
| t += ((uint64_t)lhs->d << (32 - shift)); |
| lhs->c = t; |
| t >>= 32; |
| t += ((uint64_t)lhs->e << (32 - shift)); |
| lhs->d = t; |
| t >>= 32; |
| t += ((uint64_t)lhs->high << (32 - shift)); |
| lhs->e = t; |
| t >>= 32; |
| lhs->high = t; |
| #endif |
| } |
| |
| // Shift a 192-bit integer right, rounding up. |
| // Note: The shift will always be less than 20. Someday, that |
| // might suggest a way to further optimize this. |
| static void shiftRightRoundingUp192(swift_uint192_t *lhs, int shift) { |
| #if HAVE_UINT128_T |
| const uint64_t bias = (1 << shift) - 1; |
| __uint128_t t = ((__uint128_t)lhs->low + bias) >> shift; |
| t += ((__uint128_t)lhs->mid << (64 - shift)); |
| lhs->low = t; |
| t >>= 64; |
| t += ((__uint128_t)lhs->high << (64 - shift)); |
| lhs->mid = t; |
| t >>= 64; |
| lhs->high = t; |
| #else |
| const uint64_t bias = (1 << shift) - 1; |
| uint64_t t = ((uint64_t)lhs->low + bias) >> shift; |
| t += ((uint64_t)lhs->b << (32 - shift)); |
| lhs->low = t; |
| t >>= 32; |
| t += ((uint64_t)lhs->c << (32 - shift)); |
| lhs->b = t; |
| t >>= 32; |
| t += ((uint64_t)lhs->d << (32 - shift)); |
| lhs->c = t; |
| t >>= 32; |
| t += ((uint64_t)lhs->e << (32 - shift)); |
| lhs->d = t; |
| t >>= 32; |
| t += ((uint64_t)lhs->high << (32 - shift)); |
| lhs->e = t; |
| t >>= 32; |
| lhs->high = t; |
| #endif |
| } |
| #endif |
| |
| // |
| // ------------ Power of 10 calculation ---------------- |
| // |
| |
| // |
| // ------------ Power-of-10 tables. -------------------------- |
| // |
| // Grisu-style algorithms rely on being able to rapidly |
| // find a high-precision approximation of any power of 10. |
| // These values were computed by a simple script that |
| // relied on Python's excellent variable-length |
| // integer support. |
| |
| #if SWIFT_DTOA_FLOAT_SUPPORT || SWIFT_DTOA_DOUBLE_SUPPORT || SWIFT_DTOA_FLOAT80_SUPPORT |
| // Float table |
| // |
| // The constant powers of 10 here represent pure fractions |
| // with a binary point at the far left. (Each number in |
| // this first table is implicitly divided by 2^64.) |
| // |
| // Table size: 320 bytes |
| // |
| // A 64-bit significand allows us to exactly represent |
| // powers of 10 up to 10^27. For larger powers, the |
| // value here is rounded DOWN from the exact value. |
| // For those powers, the value here is less than the |
| // exact power of 10; adding one gives a value greater |
| // than the exact power of 10. |
| // |
| // For single-precision Float, we use these directly |
| // for positive powers of 10. For negative powers of |
| // ten, we multiply a value here by 10^-40. |
| // |
| // For Double and Float80, we use the 28 exact values |
| // here to help reduce the size of those tables. |
| static const uint64_t powersOf10_Float[40] = { |
| 0x8000000000000000, // x 2^1 == 10^0 exactly |
| 0xa000000000000000, // x 2^4 == 10^1 exactly |
| 0xc800000000000000, // x 2^7 == 10^2 exactly |
| 0xfa00000000000000, // x 2^10 == 10^3 exactly |
| 0x9c40000000000000, // x 2^14 == 10^4 exactly |
| 0xc350000000000000, // x 2^17 == 10^5 exactly |
| 0xf424000000000000, // x 2^20 == 10^6 exactly |
| 0x9896800000000000, // x 2^24 == 10^7 exactly |
| 0xbebc200000000000, // x 2^27 == 10^8 exactly |
| 0xee6b280000000000, // x 2^30 == 10^9 exactly |
| 0x9502f90000000000, // x 2^34 == 10^10 exactly |
| 0xba43b74000000000, // x 2^37 == 10^11 exactly |
| 0xe8d4a51000000000, // x 2^40 == 10^12 exactly |
| 0x9184e72a00000000, // x 2^44 == 10^13 exactly |
| 0xb5e620f480000000, // x 2^47 == 10^14 exactly |
| 0xe35fa931a0000000, // x 2^50 == 10^15 exactly |
| 0x8e1bc9bf04000000, // x 2^54 == 10^16 exactly |
| 0xb1a2bc2ec5000000, // x 2^57 == 10^17 exactly |
| 0xde0b6b3a76400000, // x 2^60 == 10^18 exactly |
| 0x8ac7230489e80000, // x 2^64 == 10^19 exactly |
| 0xad78ebc5ac620000, // x 2^67 == 10^20 exactly |
| 0xd8d726b7177a8000, // x 2^70 == 10^21 exactly |
| 0x878678326eac9000, // x 2^74 == 10^22 exactly |
| 0xa968163f0a57b400, // x 2^77 == 10^23 exactly |
| 0xd3c21bcecceda100, // x 2^80 == 10^24 exactly |
| 0x84595161401484a0, // x 2^84 == 10^25 exactly |
| 0xa56fa5b99019a5c8, // x 2^87 == 10^26 exactly |
| 0xcecb8f27f4200f3a, // x 2^90 == 10^27 exactly |
| 0x813f3978f8940984, // x 2^94 ~= 10^28 |
| 0xa18f07d736b90be5, // x 2^97 ~= 10^29 |
| 0xc9f2c9cd04674ede, // x 2^100 ~= 10^30 |
| 0xfc6f7c4045812296, // x 2^103 ~= 10^31 |
| 0x9dc5ada82b70b59d, // x 2^107 ~= 10^32 |
| 0xc5371912364ce305, // x 2^110 ~= 10^33 |
| 0xf684df56c3e01bc6, // x 2^113 ~= 10^34 |
| 0x9a130b963a6c115c, // x 2^117 ~= 10^35 |
| 0xc097ce7bc90715b3, // x 2^120 ~= 10^36 |
| 0xf0bdc21abb48db20, // x 2^123 ~= 10^37 |
| 0x96769950b50d88f4, // x 2^127 ~= 10^38 |
| 0xbc143fa4e250eb31, // x 2^130 ~= 10^39 |
| }; |
| #endif |
| |
| #if SWIFT_DTOA_DOUBLE_SUPPORT |
| // As above, but with 128-bit fractions. |
| // |
| // Table size: 464 bytes |
| // |
| // We only store every 28th power of ten here. |
| // We can multiply by an exact 64-bit power of |
| // ten from the table above to reconstruct the |
| // significand for any power of 10. |
| static const uint64_t powersOf10_Double[] = { |
| // low-order half, high-order half |
| 0x3931b850df08e738, 0x95fe7e07c91efafa, // x 2^-1328 ~= 10^-400 |
| 0xba954f8e758fecb3, 0x9774919ef68662a3, // x 2^-1235 ~= 10^-372 |
| 0x9028bed2939a635c, 0x98ee4a22ecf3188b, // x 2^-1142 ~= 10^-344 |
| 0x47b233c92125366e, 0x9a6bb0aa55653b2d, // x 2^-1049 ~= 10^-316 |
| 0x4ee367f9430aec32, 0x9becce62836ac577, // x 2^-956 ~= 10^-288 |
| 0x6f773fc3603db4a9, 0x9d71ac8fada6c9b5, // x 2^-863 ~= 10^-260 |
| 0xc47bc5014a1a6daf, 0x9efa548d26e5a6e1, // x 2^-770 ~= 10^-232 |
| 0x80e8a40eccd228a4, 0xa086cfcd97bf97f3, // x 2^-677 ~= 10^-204 |
| 0xb8ada00e5a506a7c, 0xa21727db38cb002f, // x 2^-584 ~= 10^-176 |
| 0xc13e60d0d2e0ebba, 0xa3ab66580d5fdaf5, // x 2^-491 ~= 10^-148 |
| 0xc2974eb4ee658828, 0xa54394fe1eedb8fe, // x 2^-398 ~= 10^-120 |
| 0xcb4ccd500f6bb952, 0xa6dfbd9fb8e5b88e, // x 2^-305 ~= 10^-92 |
| 0x3f2398d747b36224, 0xa87fea27a539e9a5, // x 2^-212 ~= 10^-64 |
| 0xdde50bd1d5d0b9e9, 0xaa242499697392d2, // x 2^-119 ~= 10^-36 |
| 0xfdc20d2b36ba7c3d, 0xabcc77118461cefc, // x 2^-26 ~= 10^-8 |
| 0x0000000000000000, 0xad78ebc5ac620000, // x 2^67 == 10^20 exactly |
| 0x9670b12b7f410000, 0xaf298d050e4395d6, // x 2^160 == 10^48 exactly |
| 0x3b25a55f43294bcb, 0xb0de65388cc8ada8, // x 2^253 ~= 10^76 |
| 0x58edec91ec2cb657, 0xb2977ee300c50fe7, // x 2^346 ~= 10^104 |
| 0x29babe4598c311fb, 0xb454e4a179dd1877, // x 2^439 ~= 10^132 |
| 0x577b986b314d6009, 0xb616a12b7fe617aa, // x 2^532 ~= 10^160 |
| 0x0c11ed6d538aeb2f, 0xb7dcbf5354e9bece, // x 2^625 ~= 10^188 |
| 0x6d953e2bd7173692, 0xb9a74a0637ce2ee1, // x 2^718 ~= 10^216 |
| 0x9d6d1ad41abe37f1, 0xbb764c4ca7a4440f, // x 2^811 ~= 10^244 |
| 0x4b2d8644d8a74e18, 0xbd49d14aa79dbc82, // x 2^904 ~= 10^272 |
| 0xe0470a63e6bd56c3, 0xbf21e44003acdd2c, // x 2^997 ~= 10^300 |
| 0x505f522e53053ff2, 0xc0fe908895cf3b44, // x 2^1090 ~= 10^328 |
| 0xcca845ab2beafa9a, 0xc2dfe19c8c055535, // x 2^1183 ~= 10^356 |
| 0x1027fff56784f444, 0xc4c5e310aef8aa17, // x 2^1276 ~= 10^384 |
| }; |
| #endif |
| |
| #if SWIFT_DTOA_FLOAT80_SUPPORT |
| // Every 83rd power of 10 across the range of Float80 |
| // |
| // Table size: 2,928 bytes |
| // |
| // Note: We could cut this in half at the cost of one additional |
| // 192-bit multiply by only storing the positive values and |
| // multiplying by 10^-5063 to obtain the negative ones, similar |
| // to how we handle Float above. |
| static const uint64_t powersOf10_Float80[] = { |
| // low 64 bits, middle 64 bits, high 64 bits |
| 0x56825ada98468526, 0x0abc23fcfda07e29, 0x871db786569ca2dd, // x 2^-16818 ~= 10^-5063 |
| 0xe3885beff5ee930d, 0xd1e638f68c97f0e5, 0xde90d1b113564507, // x 2^-16543 ~= 10^-4980 |
| 0x5a7d22b5236bcad4, 0xbab3a28a6f0a489c, 0xb74ea21ab2946479, // x 2^-16267 ~= 10^-4897 |
| 0x7d1f78bf0f4e2878, 0xcf4aea39615ffe6e, 0x96f9351fcfdd2686, // x 2^-15991 ~= 10^-4814 |
| 0xad725c0d6c214314, 0x5bd5c19f18bd2857, 0xf8afafd6ef185238, // x 2^-15716 ~= 10^-4731 |
| 0xe418e9217ce83755, 0x801e38463183fc88, 0xccd1ffc6bba63e21, // x 2^-15440 ~= 10^-4648 |
| 0x4dcd52747e029d0c, 0x867b3096b1619df8, 0xa8b11ff4721d92fb, // x 2^-15164 ~= 10^-4565 |
| 0xed2903f7e1df2b78, 0xc846664fe1364ee8, 0x8aefaaae9060380f, // x 2^-14888 ~= 10^-4482 |
| 0xed7a7f4e1e171498, 0x7da1a627b88527f1, 0xe4dbb751faa311b0, // x 2^-14613 ~= 10^-4399 |
| 0x320796dc9b1a158c, 0x2a11a871597b8012, 0xbc7d620092481a7e, // x 2^-14337 ~= 10^-4316 |
| 0x796014ec6f4c0dcb, 0xcfa99f62903708d7, 0x9b3dee433c1311e9, // x 2^-14061 ~= 10^-4233 |
| 0x08920ae76bdb8282, 0x952b06c385a08ff6, 0xffb7a402531fd4c9, // x 2^-13786 ~= 10^-4150 |
| 0x18faa162f2c4d6b9, 0x050be8c5d21c6db6, 0xd29c7528965ae5bd, // x 2^-13510 ~= 10^-4067 |
| 0x576a6c1abab7f7e7, 0xc05fb0b5c550f28d, 0xad7617610634129e, // x 2^-13234 ~= 10^-3984 |
| 0x6cc3b2fb9cae4875, 0xe1bd5b09b7202157, 0x8edd4417ae3dc210, // x 2^-12958 ~= 10^-3901 |
| 0xfafc1dc8fd12a6f8, 0xc3f29d230036529b, 0xeb542860da9bc7d8, // x 2^-12683 ~= 10^-3818 |
| 0x9d198c56bc799f35, 0x42960adf9591f02a, 0xc1d1a4b6bc2eafc8, // x 2^-12407 ~= 10^-3735 |
| 0x1803d096e43ff4bc, 0xdef9759d6432dab7, 0x9fa18c5de65a16fb, // x 2^-12131 ~= 10^-3652 |
| 0x74872779576a577c, 0x9150140eb5101a96, 0x83793dfc83fd2f9b, // x 2^-11855 ~= 10^-3569 |
| 0x415d0667f0f88262, 0x4898d98d1314d99f, 0xd890d45a257f4644, // x 2^-11580 ~= 10^-3486 |
| 0x30a5256a610c1c72, 0x6ebca4d0365d504d, 0xb25d93f98145bdab, // x 2^-11304 ~= 10^-3403 |
| 0xfb149b1f86a46376, 0xb5143323a7f8e16c, 0x92e74be10524c389, // x 2^-11028 ~= 10^-3320 |
| 0x7b7532e25fead4c8, 0x0df6ab8ac6a0ec2f, 0xf1fb6e82e4df4a77, // x 2^-10753 ~= 10^-3237 |
| 0x3b738d6a3caae67a, 0x346b2dd31826cfed, 0xc74c79bce7fe949f, // x 2^-10477 ~= 10^-3154 |
| 0x22d3a12777cee527, 0xe185ac46f6ef1993, 0xa424ef0bb5ad3129, // x 2^-10201 ~= 10^-3071 |
| 0xb7b6bccb9f60adec, 0x30ad7df78fe30cc8, 0x8730d40821cd89f3, // x 2^-9925 ~= 10^-2988 |
| 0x21049149d72d44d5, 0x1e86debc54dd290d, 0xdeb04cb82aec22cb, // x 2^-9650 ~= 10^-2905 |
| 0xeb69d287f5e7f920, 0x8d7e84a13801d034, 0xb7688f9800d26b3a, // x 2^-9374 ~= 10^-2822 |
| 0x47b3da9aeff7df71, 0x82678774d6c0ac59, 0x970e8fd25ead01e3, // x 2^-9098 ~= 10^-2739 |
| 0x50d3e92e2e4f8210, 0x9492db3d978aaca8, 0xf8d2dcaf37504b51, // x 2^-8823 ~= 10^-2656 |
| 0xf4ce72058f777a4c, 0xb9eb2c585e924efe, 0xcceef83fdedcc506, // x 2^-8547 ~= 10^-2573 |
| 0xb0e624a35b791884, 0x7104a98dbbb38b94, 0xa8c8fc3b03c3d1ed, // x 2^-8271 ~= 10^-2490 |
| 0x6c94ecd8291e2ac9, 0x978b03821014b68c, 0x8b03518396007c08, // x 2^-7995 ~= 10^-2407 |
| 0x96475208daa03ee3, 0x10eaa1481b149e5a, 0xe4fc163319551441, // x 2^-7720 ~= 10^-2324 |
| 0xd709a820ff4ac847, 0x75aab7cb5cb15414, 0xbc980b270680156a, // x 2^-7444 ~= 10^-2241 |
| 0xf273bca6b4de9e24, 0xb5025d88d4b252e1, 0x9b53e384eccabcf7, // x 2^-7168 ~= 10^-2158 |
| 0x6c55a0603a928f40, 0x9e20db16dfb6b461, 0xffdbcf7251089796, // x 2^-6893 ~= 10^-2075 |
| 0x9006db4d43cffe42, 0x9b4bca4cd6cec2db, 0xd2ba3f510a3aa638, // x 2^-6617 ~= 10^-1992 |
| 0xa6b3c457fd0cd4d6, 0x28a4de91ba868fbf, 0xad8ea05a5f27642a, // x 2^-6341 ~= 10^-1909 |
| 0xe7b14ed140f8d98e, 0x7b2f7d61ce5d426c, 0x8ef179291b6f5424, // x 2^-6065 ~= 10^-1826 |
| 0x4a964d052fd03e10, 0x06897060bf491e6e, 0xeb75718d285cd8bf, // x 2^-5790 ~= 10^-1743 |
| 0x22b2270f0e8dd87c, 0xa8510fa2f5a9e4de, 0xc1ed0ed498f7c54c, // x 2^-5514 ~= 10^-1660 |
| 0x09102915726a9905, 0x5a0eb896edc89b54, 0x9fb8208d65ea5eda, // x 2^-5238 ~= 10^-1577 |
| 0xb80d5f481d01deb9, 0x673f2aa50486f5ba, 0x838bd699b7c539e6, // x 2^-4962 ~= 10^-1494 |
| 0x668b62b20ec2633b, 0x8682604c7123f859, 0xd8af761f94d2db2c, // x 2^-4687 ~= 10^-1411 |
| 0xb2adaed8559cc199, 0x712339ba54f12372, 0xb276ce87987995d5, // x 2^-4411 ~= 10^-1328 |
| 0x6beb873308685711, 0xac1ce34246ed56ad, 0x92fc133455668c02, // x 2^-4135 ~= 10^-1245 |
| 0x593293d68a2261bc, 0x3c368f9497ca075d, 0xf21da89a29fa1c61, // x 2^-3860 ~= 10^-1162 |
| 0x854051f9f0e4ca66, 0x8c5d5a234eda57f7, 0xc768aa46d6d1b675, // x 2^-3584 ~= 10^-1079 |
| 0x333d09b2299c5e6b, 0xcf1f49c33399c5ac, 0xa43c26a751d4f7e7, // x 2^-3308 ~= 10^-996 |
| 0x25a440d8b1620532, 0x274ebc67c3e21943, 0x8743f33df0feed29, // x 2^-3032 ~= 10^-913 |
| 0x3ca95e3deb5be648, 0x52d18ccca1c558c2, 0xdecfcc3329238dd8, // x 2^-2757 ~= 10^-830 |
| 0x59d1a7704af3acd7, 0xfae7722c6af19467, 0xb78280c024488353, // x 2^-2481 ~= 10^-747 |
| 0x78813f3e80148049, 0x73b2baf13aa1c233, 0x9723ed8a28baf5ac, // x 2^-2205 ~= 10^-664 |
| 0xf296a8198aa40fb8, 0x235532b08487fe6a, 0xf8f60e812de0cd7d, // x 2^-1930 ~= 10^-581 |
| 0xa7fbdcb40b4f648f, 0x4f20ba9a64a7f6e7, 0xcd0bf4d206072167, // x 2^-1654 ~= 10^-498 |
| 0x8dbf63ea468c724f, 0xa0e25c08b5c189d6, 0xa8e0dbe18ffb82cf, // x 2^-1378 ~= 10^-415 |
| 0x765995c6cfd406ce, 0x4c3bcb5021afcc31, 0x8b16fb203055ac76, // x 2^-1102 ~= 10^-332 |
| 0xe1d09ab6fb409872, 0x82b7e12780e7401a, 0xe51c79a85916f484, // x 2^-827 ~= 10^-249 |
| 0x89cbe2422f9e1df9, 0x7415d448f6b6f0e7, 0xbcb2b812db11a5de, // x 2^-551 ~= 10^-166 |
| 0x605fe83842e4d290, 0xc986afbe3ee11aba, 0x9b69dbe1b548ce7c, // x 2^-275 ~= 10^-83 |
| 0x0000000000000000, 0x0000000000000000, 0x8000000000000000, // x 2^1 == 10^0 exactly |
| 0x0d6953169e1c7a1e, 0xf50a3fa490c30190, 0xd2d80db02aabd62b, // x 2^276 ~= 10^83 |
| 0x3720b80c7d8ee39d, 0xaf561aa79a10ae6a, 0xada72ccc20054ae9, // x 2^552 ~= 10^166 |
| 0x7cb3f026a212df74, 0x29cb4d87f2a7400e, 0x8f05b1163ba6832d, // x 2^828 ~= 10^249 |
| 0x7dda22f9451d28a4, 0xe41c5bd18c57e88f, 0xeb96bf6ebadf77d8, // x 2^1103 ~= 10^332 |
| 0xd5da00e6e2d05e5d, 0x5e510c5a752f0f8e, 0xc2087cd3215a16ad, // x 2^1379 ~= 10^415 |
| 0x5603ba353e0b2fac, 0x48bbddc4d7359e49, 0x9fceb7ee780436f0, // x 2^1655 ~= 10^498 |
| 0x15ceea8df15e47c7, 0x6a83c85cf158c652, 0x839e71d847c1779e, // x 2^1931 ~= 10^581 |
| 0x514478d1fcd48eea, 0x3a4181cdda0d6e24, 0xd8ce1c3a2fffaea7, // x 2^2206 ~= 10^664 |
| 0xe8b634620f1062be, 0x7304c7fb8a2f8a8a, 0xb2900ca735bdf121, // x 2^2482 ~= 10^747 |
| 0xc3ec2fd9302c9bda, 0x729a6a7e830e1cf2, 0x9310dd78089bd66f, // x 2^2758 ~= 10^830 |
| 0x1750ef5f751be079, 0x52ccabc96fc88a23, 0xf23fe788c763dffa, // x 2^3033 ~= 10^913 |
| 0xaa80925ec1c80b65, 0x97681c548ff6c12f, 0xc784decd820a6180, // x 2^3309 ~= 10^996 |
| 0xb4212d4b435a2317, 0x8df0a55abbb2c99a, 0xa453618b9dfd92db, // x 2^3585 ~= 10^1079 |
| 0x939c2fedd434642a, 0x7d7de34bf5aa96b4, 0x875715282612729b, // x 2^3861 ~= 10^1162 |
| 0xb7d9a0e46bbebb36, 0x3b2057dea52d686b, 0xdeef5022af37f1f6, // x 2^4136 ~= 10^1245 |
| 0x931a74148ea64e59, 0xfe7fe67bd1074d0c, 0xb79c7593a1c17df0, // x 2^4412 ~= 10^1328 |
| 0xabd20df0f1f1ad54, 0x0fff83cc7fa6b77b, 0x97394e479b6573b1, // x 2^4688 ~= 10^1411 |
| 0x25f2467421674b7a, 0x828ff55a248bc026, 0xf919454d86f16685, // x 2^4963 ~= 10^1494 |
| 0xe32dbd7131e6ab7d, 0xf674dd4821982084, 0xcd28f57dc585d094, // x 2^5239 ~= 10^1577 |
| 0x866ab816a532b07d, 0xdc567471f9639b4e, 0xa8f8bee890f905c7, // x 2^5515 ~= 10^1660 |
| 0xaca3a975993a2626, 0xc41cf207a71d87e4, 0x8b2aa784c405e2f1, // x 2^5791 ~= 10^1743 |
| 0x731f0b7d820918bd, 0x355fde18e8448607, 0xe53ce1b25fb31788, // x 2^6066 ~= 10^1826 |
| 0x0be7c29568db3f20, 0xc1328a3f1bf4d2b8, 0xbccd68c49888be61, // x 2^6342 ~= 10^1909 |
| 0x9c6e0b1b927b7d3f, 0xffc9b96619da642a, 0x9b7fd75a060350cd, // x 2^6618 ~= 10^1992 |
| 0x2a84c8fb4bd2edc9, 0xa679df45d339389b, 0x80121ad60ca2c518, // x 2^6894 ~= 10^2075 |
| 0x0d4648d0876cf1c3, 0x48c67661c087fb5a, 0xd2f5e0469040e0eb, // x 2^7169 ~= 10^2158 |
| 0xfe2d99a281a011ac, 0x65c13361e6b2c078, 0xadbfbcb6c676a69b, // x 2^7445 ~= 10^2241 |
| 0xf4ec157aa4147562, 0xac89bfa5e79484a6, 0x8f19ebdf7661e3e9, // x 2^7721 ~= 10^2324 |
| 0xe945f8c80090be1f, 0x9b8672e64aadbed2, 0xebb812063c9e01db, // x 2^7996 ~= 10^2407 |
| 0xca12d8ad3b36d2e4, 0xd252322ea50ad274, 0xc223eeb2e1bde452, // x 2^8272 ~= 10^2490 |
| 0xf554fb41e5b3e384, 0x977acb4d4af624fc, 0x9fe55281904ba38b, // x 2^8548 ~= 10^2573 |
| 0xf3f69093398e2573, 0x111ae5735ec0e878, 0x83b10fb893300cde, // x 2^8824 ~= 10^2656 |
| 0x30f65a8da0d10429, 0x1eecf4cf8a0b25f5, 0xd8ecc6aa93e876fc, // x 2^9099 ~= 10^2739 |
| 0xa577f5f0c9f1e5a7, 0x91a5430ed623abf0, 0xb2a94e58da4930c3, // x 2^9375 ~= 10^2822 |
| 0x202d2f87585ec0d7, 0x7a63589863efd480, 0x9325aaac89304b57, // x 2^9651 ~= 10^2905 |
| 0x049544fbba3c01a1, 0x53accb0f60ac6095, 0xf2622b4f6c68d6ce, // x 2^9926 ~= 10^2988 |
| 0x268a0d5f9d5ce861, 0xfe40703e1a91de57, 0xc7a117517a09153b, // x 2^10202 ~= 10^3071 |
| 0xb6cd470a2a3b1d63, 0x5f963916b20ea587, 0xa46a9fb9111003bc, // x 2^10478 ~= 10^3154 |
| 0xa3101c09fd8e6e96, 0xa2c6328011db5211, 0x876a39c722f798a7, // x 2^10754 ~= 10^3237 |
| 0x8507e5fdb0ec5d83, 0x7ce93cc7f8feeed4, 0xdf0ed8875e7b8914, // x 2^11029 ~= 10^3320 |
| 0xe19b7ebe4c7bfbca, 0x40930d1129943838, 0xb7b66e12fe1af499, // x 2^11305 ~= 10^3403 |
| 0xc90c4ec15c21a357, 0xd91c86512d147305, 0x974eb20b241a65f6, // x 2^11581 ~= 10^3486 |
| 0xb90341199c02a4eb, 0x69e684f53db6e8ce, 0xf93c8114f6c31f8a, // x 2^11856 ~= 10^3569 |
| 0xa873f1318cef91cb, 0xbf8718466b31a7ca, 0xcd45fa43b1ce4c8e, // x 2^12132 ~= 10^3652 |
| 0xacfe0dcc5262e273, 0x6e1bbb68662fd27a, 0xa910a550810203f8, // x 2^12408 ~= 10^3735 |
| 0x59e7c8921bbe3758, 0x834743c5eab7dcea, 0x8b3e56b1b5c57589, // x 2^12684 ~= 10^3818 |
| 0x145eed64fda2e6af, 0x1c605bdcc764238f, 0xe55d4e51d30b5592, // x 2^12959 ~= 10^3901 |
| 0xb747164b17268ea2, 0xd8aa19f1d85da07d, 0xbce81d3cc784a1ca, // x 2^13235 ~= 10^3984 |
| 0x3666af1cb2f0356b, 0xc8dd55687a68bb70, 0x9b95d5ee4f80366d, // x 2^13511 ~= 10^4067 |
| 0x70d67261b5bde1e9, 0x1d76f2d15166ec20, 0x8024383bab19730d, // x 2^13787 ~= 10^4150 |
| 0x084a3ba0b748546a, 0xc67f9026f83dca47, 0xd313b714d3a1c65e, // x 2^14062 ~= 10^4233 |
| 0x4411a8127eea085e, 0x441eb397ffcdab0d, 0xadd8501ad0361d15, // x 2^14338 ~= 10^4316 |
| 0x7b62a54ed6233032, 0x75458a1c8300e014, 0x8f2e2985332eae98, // x 2^14614 ~= 10^4399 |
| 0x162d5b51a1dd9594, 0x655bb1b7aa4e8196, 0xebd96954582af06f, // x 2^14889 ~= 10^4482 |
| 0x55e6c62f920d3682, 0x79fd57cf7c37941c, 0xc23f6474669f4abe, // x 2^15165 ~= 10^4565 |
| 0x19482fa0ac45669c, 0x803c1cd864033781, 0x9ffbf04722750449, // x 2^15441 ~= 10^4648 |
| 0xa412d1f95f4624cd, 0xc95abe9ce589e048, 0x83c3b03af95c9674, // x 2^15717 ~= 10^4731 |
| 0xc1207e487c57b4e1, 0xf93dd2c7669a8ed1, 0xd90b75715d861b38, // x 2^15992 ~= 10^4814 |
| 0xeb20d9a25e0372bd, 0xb5073df6adc221b4, 0xb2c2939d0763fcac, // x 2^16268 ~= 10^4897 |
| 0x1a648c339e28cc45, 0xbd14f0fa3e24b6ae, 0x933a7ad2419ea0b5, // x 2^16544 ~= 10^4980 |
| }; |
| #endif |
| |
| #if SWIFT_DTOA_FLOAT_SUPPORT || SWIFT_DTOA_DOUBLE_SUPPORT || SWIFT_DTOA_FLOAT80_SUPPORT |
| // The power-of-10 tables do not directly store the associated binary |
| // exponent. That's because the binary exponent is a simple linear |
| // function of the decimal power (and vice versa), so it's just as |
| // fast (and uses much less memory) to compute it: |
| |
| // The binary exponent corresponding to a particular power of 10. |
| // This matches the power-of-10 tables across the full range of Float80. |
| static int binaryExponentFor10ToThe(int p) { |
| return (int)(((((int64_t)p) * 55732705) >> 24) + 1); |
| } |
| |
| // A decimal exponent that approximates a particular binary power. |
| static int decimalExponentFor2ToThe(int e) { |
| return (int)(((int64_t)e * 20201781) >> 26); |
| } |
| #endif |
| |
| #if SWIFT_DTOA_FLOAT_SUPPORT |
| // Given a power `p`, this returns three values: |
| // * 64-bit fractions `lower` and `upper` |
| // * integer `exponent` |
| // |
| // The returned values satisty the following: |
| // ``` |
| // lower * 2^exponent <= 10^p <= upper * 2^exponent |
| // ``` |
| // |
| // Note: Max(*upper - *lower) = 3 |
| static void intervalContainingPowerOf10_Float(int p, uint64_t *lower, uint64_t *upper, int *exponent) { |
| if (p < 0) { |
| uint64_t base = powersOf10_Float[p + 40]; |
| int baseExponent = binaryExponentFor10ToThe(p + 40); |
| uint64_t tenToTheMinus40 = 0x8b61313bbabce2c6; // x 2^-132 ~= 10^-40 |
| *upper = multiply64x64RoundingUp(base + 1, tenToTheMinus40 + 1); |
| *lower = multiply64x64RoundingDown(base, tenToTheMinus40); |
| *exponent = baseExponent - 132; |
| } else { |
| uint64_t base = powersOf10_Float[p]; |
| *upper = base + 1; |
| *lower = base; |
| *exponent = binaryExponentFor10ToThe(p); |
| } |
| } |
| #endif |
| |
| #if SWIFT_DTOA_DOUBLE_SUPPORT |
| // As above, but returning 128-bit fractions suitable for |
| // converting doubles. |
| static void intervalContainingPowerOf10_Double(int p, swift_uint128_t *lower, swift_uint128_t *upper, int *exponent) { |
| if (p >= 0 && p <= 54) { |
| if (p <= 27) { |
| // Use one 64-bit exact value |
| swift_uint128_t exact; |
| initialize128WithHigh64(exact, powersOf10_Float[p]); |
| *upper = exact; |
| *lower = exact; |
| *exponent = binaryExponentFor10ToThe(p); |
| return; |
| } else { |
| // Multiply two 64-bit exact values to get a 128-bit exact value |
| swift_uint128_t base; |
| initialize128WithHigh64(base, powersOf10_Float[p - 27]); |
| int baseExponent = binaryExponentFor10ToThe(p - 27); |
| uint64_t extra = powersOf10_Float[27]; |
| int extraExponent = binaryExponentFor10ToThe(27); |
| swift_uint128_t exact = multiply128x64RoundingDown(base, extra); |
| *upper = exact; |
| *lower = exact; |
| *exponent = baseExponent + extraExponent; |
| return; |
| } |
| } |
| |
| // Multiply a 128-bit approximate value with a 64-bit exact value |
| int index = p + 400; |
| // Copy a pair of uint64_t into a swift_uint128_t |
| const uint64_t *base_p = powersOf10_Double + (index / 28) * 2; |
| swift_uint128_t base; |
| initialize128WithHighLow64(base, base_p[1], base_p[0]); |
| int extraPower = index % 28; |
| int baseExponent = binaryExponentFor10ToThe(p - extraPower); |
| |
| int e = baseExponent; |
| if (extraPower > 0) { |
| int64_t extra = powersOf10_Float[extraPower]; |
| e += binaryExponentFor10ToThe(extraPower); |
| *lower = multiply128x64RoundingDown(base, extra); |
| increment128(base); |
| *upper = multiply128x64RoundingUp(base, extra); |
| } else { |
| *lower = base; |
| increment128(base); |
| *upper = base; |
| } |
| *exponent = e; |
| } |
| #endif |
| |
| #if SWIFT_DTOA_FLOAT80_SUPPORT |
| // As above, but returning 192-bit fractions suitable for |
| // converting float80. |
| static void intervalContainingPowerOf10_Float80(int p, swift_uint192_t *lower, swift_uint192_t *upper, int *exponent) { |
| if (p >= 0 && p <= 27) { |
| // We have an exact form, return a zero-width interval. |
| uint64_t exact = powersOf10_Float[p]; |
| initialize192WithHighMidLow64(*upper, exact, 0, 0); |
| initialize192WithHighMidLow64(*lower, exact, 0, 0); |
| *exponent = binaryExponentFor10ToThe(p); |
| return; |
| } |
| |
| int index = p + 5063; |
| const uint64_t *base_p = powersOf10_Float80 + (index / 83) * 3; |
| // Note: The low-order value in the Float80 table above |
| // is never UINT64_MAX, so there's never a carry from |
| // the increment here. |
| initialize192WithHighMidLow64(*upper, base_p[2], base_p[1], base_p[0] + 1); |
| initialize192WithHighMidLow64(*lower, base_p[2], base_p[1], base_p[0]); |
| int extraPower = index % 83; |
| int e = binaryExponentFor10ToThe(p - extraPower); |
| |
| while (extraPower > 27) { |
| uint64_t power27 = powersOf10_Float[27]; |
| multiply192x64RoundingDown(lower, power27); |
| multiply192x64RoundingUp(upper, power27); |
| e += binaryExponentFor10ToThe(27); |
| extraPower -= 27; |
| } |
| if (extraPower > 0) { |
| uint64_t extra = powersOf10_Float[extraPower]; |
| multiply192x64RoundingDown(lower, extra); |
| multiply192x64RoundingUp(upper, extra); |
| e += binaryExponentFor10ToThe(extraPower); |
| } |
| *exponent = e; |
| } |
| #endif |
| |