runtime/float-conversion.cpp (2,189 lines of code) (raw):

// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) #include "float-conversion.h" #include <cerrno> #include <cfloat> #include <climits> #include <cmath> #include <cstdint> #include <cstdio> #include <cstdlib> #include <cstring> #include <limits> #include "globals.h" #include "utils.h" // The following code is a copy of `pystrtod.c` and `dtoa.c` from cpython. // The public interface has been slightly changes and the code was heavily // modified to conform to our style guides. It also doesn't contain code for // non-ieee754 architectures any longer. // However there were no changes to the algorithm and there are no plans to // do so at the moment! namespace py { static char* dtoa(double dd, int mode, int ndigits, int* decpt, int* sign, char** rve); static double strtod(const char* s00, char** se); static void freedtoa(char* s); // Case-insensitive string match used for nan and inf detection; t should be // lower-case. Returns 1 for a successful match, 0 otherwise. static bool caseInsensitiveMatch(const char* s, const char* t) { for (; *t != '\0'; s++, t++) { DCHECK('a' <= *t && *t <= 'z', "t must be lowercase letters"); if (*t != *s && *t != (*s - 'A' + 'a')) { return false; } } return true; } // parseInfOrNan: Attempt to parse a string of the form "nan", "inf" or // "infinity", with an optional leading sign of "+" or "-". On success, // return the NaN or Infinity as a double and set *endptr to point just beyond // the successfully parsed portion of the string. On failure, return -1.0 and // set *endptr to point to the start of the string. double parseInfOrNan(const char* p, char** endptr) { const char* s = p; bool negate = false; if (*s == '-') { negate = true; s++; } else if (*s == '+') { s++; } double retval; if (caseInsensitiveMatch(s, "inf")) { s += 3; if (caseInsensitiveMatch(s, "inity")) { s += 5; } retval = negate ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity(); } else if (caseInsensitiveMatch(s, "nan")) { s += 3; retval = negate ? -kDoubleNaN : kDoubleNaN; } else { s = p; retval = -1.0; } *endptr = const_cast<char*>(s); return retval; } // asciiStrtod: // @nptr: the string to convert to a numeric value. // @endptr: if non-%nullptr, it returns the character after // the last character used in the conversion. // // Converts a string to a #gdouble value. // This function behaves like the standard strtod() function // does in the C locale. It does this without actually // changing the current locale, since that would not be // thread-safe. // // This function is typically used when reading configuration // files or other non-user input that should be locale independent. // To handle input from the user you should normally use the // locale-sensitive system strtod() function. // // If the correct value would cause overflow, plus or minus %HUGE_VAL // is returned (according to the sign of the value), and %ERANGE is // stored in %errno. If the correct value would cause underflow, // zero is returned and %ERANGE is stored in %errno. // If memory allocation fails, %ENOMEM is stored in %errno. // // This function resets %errno before calling strtod() so that // you can reliably detect overflow and underflow. // // Return value: the #gdouble value. static double asciiStrtod(const char* nptr, char** endptr) { double result = strtod(nptr, endptr); if (*endptr == nptr) { // string might represent an inf or nan result = parseInfOrNan(nptr, endptr); } return result; } // parseFloat converts a null-terminated byte string s (interpreted // as a string of ASCII characters) to a float. The string should not have // leading or trailing whitespace. The conversion is independent of the // current locale. // // If endptr is nullptr, try to convert the whole string. Raise ValueError and // return -1.0 if the string is not a valid representation of a floating-point // number. // // If endptr is non-nullptr, try to convert as much of the string as possible. // If no initial segment of the string is the valid representation of a // floating-point number then *endptr is set to point to the beginning of the // string, -1.0 is returned and again ValueError is raised. // // On overflow (e.g., when trying to convert '1e500' on an IEEE 754 machine), // if overflow_exception is nullptr then +-HUGE_VAL is returned, and no // Python exception is raised. Otherwise, overflow_exception should point to a // Python exception, this exception will be raised, -1.0 will be returned, and // *endptr will point just past the end of the converted value. // // If any other failure occurs (for example lack of memory), -1.0 is returned // and the appropriate Python exception will have been set. double parseFloat(const char* s, char** endptr, ConversionResult* conversion_result) { errno = 0; char* fail_pos; double x = asciiStrtod(s, &fail_pos); double result = -1.0; if (errno == ENOMEM) { *conversion_result = ConversionResult::kOutOfMemory; fail_pos = const_cast<char*>(s); } else if (!endptr && (fail_pos == s || *fail_pos != '\0')) { *conversion_result = ConversionResult::kInvalid; } else if (fail_pos == s) { *conversion_result = ConversionResult::kInvalid; } else if (errno == ERANGE && std::fabs(x) >= 1.0) { *conversion_result = ConversionResult::kOverflow; } else { *conversion_result = ConversionResult::kSuccess; result = x; } if (endptr != nullptr) { *endptr = fail_pos; } return result; } // I'm using a lookup table here so that I don't have to invent a non-locale // specific way to convert to uppercase. static const int kOfsInf = 0; static const int kOfsNan = 1; static const int kOfsE = 2; // The lengths of these are known to the code below, so don't change them. static const char* const kLcFloatStrings[] = { "inf", "nan", "e", }; static const char* const kUcFloatStrings[] = { "INF", "NAN", "E", }; // Convert a double d to a string, and return a PyMem_Malloc'd block of // memory contain the resulting string. // // Arguments: // d is the double to be converted // format_code is one of 'e', 'f', 'g', 'r'. 'e', 'f' and 'g' // correspond to '%e', '%f' and '%g'; 'r' corresponds to repr. // mode is one of '0', '2' or '3', and is completely determined by // format_code: 'e' and 'g' use mode 2; 'f' mode 3, 'r' mode 0. // precision is the desired precision // skip_sign do not prepend any sign even for negative numbers. // add_dot_0_if_integer is nonzero if integers in non-exponential form // should have ".0" added. Only applies to format codes 'r' and 'g'. // use_alt_formatting is nonzero if alternative formatting should be // used. Only applies to format codes 'e', 'f' and 'g'. For code 'g', // at most one of use_alt_formatting and add_dot_0_if_integer should // be nonzero. // type, if non-nullptr, will be set to one of these constants to identify // the type of the 'd' argument: // FormatResultKind::kFinite // FormatResultKind::kInfinite // FormatResultKind::kNan // // Returns a PyMem_Malloc'd block of memory containing the resulting string, // or nullptr on error. If nullptr is returned, the Python error has been set. static char* formatFloatShort(double d, char format_code, int mode, int precision, bool skip_sign, bool always_add_sign, bool add_dot_0_if_integer, bool use_alt_formatting, const char* const* float_strings, FormatResultKind* type) { // py::dtoa returns a digit string (no decimal point or exponent). // Must be matched by a call to py::freedtoa. char* digits_end; int decpt_as_int; int sign; char* digits = dtoa(d, mode, precision, &decpt_as_int, &sign, &digits_end); word decpt = decpt_as_int; if (digits == nullptr) { // The only failure mode is no memory. return nullptr; } DCHECK(digits_end != nullptr && digits_end >= digits, "unexpected result"); word digits_len = digits_end - digits; word vdigits_end = digits_len; bool use_exp = false; word bufsize = 0; char* p = nullptr; char* buf = nullptr; if (digits_len && !('0' <= digits[0] && digits[0] <= '9')) { // Infinities and nans here; adapt Gay's output, // so convert Infinity to inf and NaN to nan, and // ignore sign of nan. Then return. // ignore the actual sign of a nan. if (digits[0] == 'n' || digits[0] == 'N') { sign = 0; } // We only need 5 bytes to hold the result "+inf\0". bufsize = 5; // Used later in an assert. buf = static_cast<char*>(std::malloc(bufsize)); if (buf == nullptr) { goto exit; } p = buf; if (!skip_sign) { if (sign == 1) { *p++ = '-'; } else if (always_add_sign) { *p++ = '+'; } } if (digits[0] == 'i' || digits[0] == 'I') { std::strncpy(p, float_strings[kOfsInf], 3); p += 3; if (type) { *type = FormatResultKind::kInfinite; } } else if (digits[0] == 'n' || digits[0] == 'N') { std::strncpy(p, float_strings[kOfsNan], 3); p += 3; if (type) { *type = FormatResultKind::kNan; } } else { // shouldn't get here: Gay's code should always return // something starting with a digit, an 'I', or 'N'. UNIMPLEMENTED("should always return digit, I or N"); } goto exit; } // The result must be finite (not inf or nan). if (type) { *type = FormatResultKind::kFinite; } // We got digits back, format them. We may need to pad 'digits' // either on the left or right (or both) with extra zeros, so in // general the resulting string has the form // [<sign>]<zeros><digits><zeros>[<exponent>] // where either of the <zeros> pieces could be empty, and there's a // decimal point that could appear either in <digits> or in the // leading or trailing <zeros>. // Imagine an infinite 'virtual' string vdigits, consisting of the // string 'digits' (starting at index 0) padded on both the left and // right with infinite strings of zeros. We want to output a slice // vdigits[vdigits_start : vdigits_end] // of this virtual string. Thus if vdigits_start < 0 then we'll end // up producing some leading zeros; if vdigits_end > digits_len there // will be trailing zeros in the output. The next section of code // determines whether to use an exponent or not, figures out the // position 'decpt' of the decimal point, and computes 'vdigits_start' // and 'vdigits_end'. switch (format_code) { case 'e': use_exp = true; vdigits_end = precision; break; case 'f': vdigits_end = decpt + precision; break; case 'g': if (decpt <= -4 || decpt > (add_dot_0_if_integer ? precision - 1 : precision)) { use_exp = true; } if (use_alt_formatting) { vdigits_end = precision; } break; case 'r': // convert to exponential format at 1e16. We used to convert // at 1e17, but that gives odd-looking results for some values // when a 16-digit 'shortest' repr is padded with bogus zeros. // For example, repr(2e16+8) would give 20000000000000010.0; // the true value is 20000000000000008.0. if (decpt <= -4 || decpt > 16) { use_exp = true; } break; default: goto exit; } // if using an exponent, reset decimal point position to 1 and adjust // exponent accordingly. { int exp = 0; if (use_exp) { exp = static_cast<int>(decpt) - 1; decpt = 1; } // ensure vdigits_start < decpt <= vdigits_end, or vdigits_start < // decpt < vdigits_end if add_dot_0_if_integer and no exponent. word vdigits_start = decpt <= 0 ? decpt - 1 : 0; if (!use_exp && add_dot_0_if_integer) { vdigits_end = vdigits_end > decpt ? vdigits_end : decpt + 1; } else { vdigits_end = vdigits_end > decpt ? vdigits_end : decpt; } // double check inequalities. DCHECK(vdigits_start <= 0 && 0 <= digits_len && digits_len <= vdigits_end, "failed consistency check"); // decimal point should be in (vdigits_start, vdigits_end] DCHECK(vdigits_start < decpt && decpt <= vdigits_end, "failed decimal point check"); // Compute an upper bound how much memory we need. This might be a few // chars too long, but no big deal. bufsize = // sign, decimal point and trailing 0 byte 3 - skip_sign + // total digit count (including zero padding on both sides) (vdigits_end - vdigits_start) + // exponent "e+100", max 3 numerical digits (use_exp ? 5 : 0); // Now allocate the memory and initialize p to point to the start of it. buf = static_cast<char*>(std::malloc(bufsize)); if (buf == nullptr) { goto exit; } p = buf; // Add a negative sign if negative, and a plus sign if non-negative // and always_add_sign is true. if (!skip_sign) { if (sign == 1) { *p++ = '-'; } else if (always_add_sign) { *p++ = '+'; } } // note that exactly one of the three 'if' conditions is true, // so we include exactly one decimal point. // Zero padding on left of digit string if (decpt <= 0) { std::memset(p, '0', decpt - vdigits_start); p += decpt - vdigits_start; *p++ = '.'; std::memset(p, '0', 0 - decpt); p += 0 - decpt; } else { std::memset(p, '0', 0 - vdigits_start); p += 0 - vdigits_start; } // Digits, with included decimal point if (0 < decpt && decpt <= digits_len) { std::strncpy(p, digits, decpt - 0); p += decpt - 0; *p++ = '.'; std::strncpy(p, digits + decpt, digits_len - decpt); p += digits_len - decpt; } else { std::strncpy(p, digits, digits_len); p += digits_len; } // And zeros on the right if (digits_len < decpt) { std::memset(p, '0', decpt - digits_len); p += decpt - digits_len; *p++ = '.'; std::memset(p, '0', vdigits_end - decpt); p += vdigits_end - decpt; } else { std::memset(p, '0', vdigits_end - digits_len); p += vdigits_end - digits_len; } // Delete a trailing decimal pt unless using alternative formatting. if (p[-1] == '.' && !use_alt_formatting) { p--; } // Now that we've done zero padding, add an exponent if needed. if (use_exp) { *p++ = float_strings[kOfsE][0]; int exp_len = std::sprintf(p, "%+.02d", exp); p += exp_len; } } exit: if (buf) { *p = '\0'; // It's too late if this fails, as we've already stepped on // memory that isn't ours. But it's an okay debugging test. DCHECK(p - buf < bufsize, "buffer overflow"); } if (digits) { freedtoa(digits); } return buf; } char* doubleToString(double value, char format_code, int precision, bool skip_sign, bool add_dot_0, bool use_alt_formatting, FormatResultKind* type) { const char* const* float_strings = kLcFloatStrings; // Validate format_code, and map upper and lower case. Compute the // mode and make any adjustments as needed. int mode; switch (format_code) { // exponent case 'E': float_strings = kUcFloatStrings; format_code = 'e'; FALLTHROUGH; case 'e': mode = 2; precision++; break; // fixed case 'F': float_strings = kUcFloatStrings; format_code = 'f'; FALLTHROUGH; case 'f': mode = 3; break; // general case 'G': float_strings = kUcFloatStrings; format_code = 'g'; FALLTHROUGH; case 'g': mode = 2; // precision 0 makes no sense for 'g' format; interpret as 1 if (precision == 0) { precision = 1; } break; // repr format case 'r': mode = 0; // Supplied precision is unused, must be 0. if (precision != 0) { return nullptr; } break; default: return nullptr; } return formatFloatShort(value, format_code, mode, precision, skip_sign, /*always_add_sign=*/false, add_dot_0, use_alt_formatting, float_strings, type); } double doubleRoundDecimals(double value, int ndigits) { // Print value to a string with `ndigits` decimal digits. char* buf_end; int decpt; int sign; char* buf = dtoa(value, 3, ndigits, &decpt, &sign, &buf_end); CHECK(buf != nullptr, "out of memory"); char shortbuf[100]; unique_c_ptr<char> longbuf; size_t buflen = buf_end - buf; char* number_buf; size_t number_buf_len = buflen + 8; if (number_buf_len <= sizeof(shortbuf)) { number_buf = shortbuf; } else { longbuf.reset(static_cast<char*>(std::malloc(number_buf_len))); number_buf = longbuf.get(); } std::snprintf(number_buf, number_buf_len, "%c0%se%d", (sign ? '-' : '+'), buf, decpt - static_cast<int>(buflen)); freedtoa(buf); // Convert resulting string back to a double. return strtod(number_buf, nullptr); } /**************************************************************** * * The author of this software is David M. Gay. * * Copyright (c) 1991, 2000, 2001 by Lucent Technologies. * * Permission to use, copy, modify, and distribute this software for any * purpose without fee is hereby granted, provided that this entire notice * is included in all copies of any software which is or includes a copy * or modification of this software and in all copies of the supporting * documentation for such software. * * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. * ***************************************************************/ // This is dtoa.c by David M. Gay, downloaded from // http://www.netlib.org/fp/dtoa.c on April 15, 2009 and modified for // inclusion into the Python core by Mark E. T. Dickinson and Eric V. Smith. // // Please remember to check http://www.netlib.org/fp regularly (and especially // before any Python release) for bugfixes and updates. // // The major modifications from Gay's original code are as follows: // // 0. The original code has been specialized to Python's needs by removing // many of the #ifdef'd sections. In particular, code to support VAX and // IBM floating-point formats, hex NaNs, hex floats, locale-aware // treatment of the decimal point, and setting of the inexact flag have // been removed. // // 1. We use PyMem_Malloc and PyMem_Free in place of malloc and free. // // 2. The public functions strtod, dtoa and freedtoa all now have // a _Py_dg_ prefix. // // 3. Instead of assuming that PyMem_Malloc always succeeds, we thread // PyMem_Malloc failures through the code. The functions // // Balloc, multadd, s2b, i2b, mult, pow5mult, lshift, diff, d2b // // of return type *Bigint all return nullptr to indicate a malloc failure. // Similarly, rv_alloc and nrv_alloc (return type char *) return nullptr on // failure. bigcomp now has return type int (it used to be void) and // returns -1 on failure and 0 otherwise. dtoa returns nullptr // on failure. strtod indicates failure due to malloc failure // by returning -1.0, setting errno=ENOMEM and *se to s00. // // 4. The static variable dtoa_result has been removed. Callers of // dtoa are expected to call freedtoa to free // the memory allocated by dtoa. // // 5. The code has been reformatted to better fit with Python's // C style guide (PEP 7). // // 6. A bug in the memory allocation has been fixed: to avoid FREEing memory // that hasn't been std::malloc'ed, private_mem should only be used when // k <= kKmax. // // 7. strtod has been modified so that it doesn't accept strings with // leading whitespace. // // Please send bug reports for the original dtoa.c code to David M. Gay (dmg // at acm dot org, with " at " changed at "@" and " dot " changed to "."). // Please report bugs for this modified version using the Python issue tracker // (http://bugs.python.org). // On a machine with IEEE extended-precision registers, it is // necessary to specify double-precision (53-bit) rounding precision // before invoking strtod or dtoa. If the machine uses (the equivalent // of) Intel 80x87 arithmetic, the call // _control87(PC_53, MCW_PC); // does this with many compilers. Whether this or another call is // appropriate depends on the compiler; for this to work, it may be // necessary to #include "float.h" or another system-dependent header // file. // strtod for IEEE-, VAX-, and IBM-arithmetic machines. // // This strtod returns a nearest machine number to the input decimal // string (or sets errno to ERANGE). With IEEE arithmetic, ties are // broken by the IEEE round-even rule. Otherwise ties are broken by // biased rounding (add half and chop). // // Inspired loosely by William D. Clinger's paper "How to Read Floating // Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101]. // // Modifications: // // 1. We only require IEEE, IBM, or VAX double-precision // arithmetic (not IEEE double-extended). // 2. We get by with floating-point arithmetic in a case that // Clinger missed -- when we're computing d * 10^n // for a small integer d and the integer n is not too // much larger than 22 (the maximum integer k for which // we can represent 10^k exactly), we may be able to // compute (d*10^k) * 10^(e-k) with just one roundoff. // 3. Rather than a bit-at-a-time adjustment of the binary // result in the hard case, we use floating-point // arithmetic to determine the adjustment to within // one bit; only in really hard cases do we need to // compute a second residual. // 4. Because of 3., we don't need a large table of powers of 10 // for ten-to-e (just some small tables, e.g. of 10^k // for 0 <= k <= 22). static const int kPrivateMemBytes = 2304; static const int kPrivateMemArraySize = ((kPrivateMemBytes + sizeof(double) - 1) / sizeof(double)); static double private_mem[kPrivateMemArraySize]; static double* pmem_next = private_mem; typedef union { double d; uint32_t L[2]; } U; #define word0(x) (x)->L[1] #define word1(x) (x)->L[0] #define dval(x) (x)->d static const int kStrtodDiglim = 40; // maximum permitted exponent value for strtod; exponents larger than // kMaxAbsExp in absolute value get truncated to +-kMaxAbsExp. kMaxAbsExp // should fit into an int. static const int kMaxAbsExp = 1100000000; // Bound on length of pieces of input strings in strtod; specifically, // this is used to bound the total number of digits ignoring leading zeros and // the number of digits that follow the decimal point. Ideally, kMaxDigits // should satisfy kMaxDigits + 400 < kMaxAbsExp; that ensures that the // exponent clipping in strtod can't affect the value of the output. static const unsigned kMaxDigits = 1000000000U; // kTenPmax = floor(P*log(2)/log(5)) // kBletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 // kQuickMax = floor((P-1)*log(FLT_RADIX)/log(10) - 1) // kIntMax = floor(P*log(FLT_RADIX)/log(10) - 1) static_assert(sizeof(double) == 8, "Expected IEEE 754 binary64"); static_assert(DBL_MANT_DIG == 53, "Expected IEEE 754 binary64"); static const int kExpShift = 20; static const int kExpShift1 = 20; static const int kExpMsk1 = 0x100000; static const uint32_t kExpMask = 0x7ff00000; static const int kP = 53; static const int kBias = 1023; static const int kEtiny = -1074; // smallest denormal is 2**kEtiny static const uint32_t kExp1 = 0x3ff00000; static const uint32_t kExp11 = 0x3ff00000; static const int kEbits = 11; static const uint32_t kFracMask = 0xfffff; static const uint32_t kFracMask1 = 0xfffff; static const int kTenPmax = 22; static const int kBletch = 0x10; static const uint32_t kBndryMask = 0xfffff; static const uint32_t kBndryMask1 = 0xfffff; static const uint32_t kSignBit = 0x80000000; static const int kLog2P = 1; static const int kTiny1 = 1; static const int kQuickMax = 14; static const int kIntMax = 14; static const uint32_t kBig0 = (kFracMask1 | kExpMsk1 * (DBL_MAX_EXP + kBias - 1)); static const uint32_t kBig1 = 0xffffffff; // struct BCinfo is used to pass information from strtod to bigcomp struct BCinfo { int e0, nd, nd0, scale; }; static const uint32_t kFfffffff = 0xffffffffU; static const int kKmax = 7; // struct Bigint is used to represent arbitrary-precision integers. These // integers are stored in sign-magnitude format, with the magnitude stored as // an array of base 2**32 digits. Bigints are always normalized: if x is a // Bigint then x->wds >= 1, and either x->wds == 1 or x[wds-1] is nonzero. // // The Bigint fields are as follows: // // - next is a header used by Balloc and Bfree to keep track of lists // of freed Bigints; it's also used for the linked list of // powers of 5 of the form 5**2**i used by pow5mult. // - k indicates which pool this Bigint was allocated from // - maxwds is the maximum number of words space was allocated for // (usually maxwds == 2**k) // - sign is 1 for negative Bigints, 0 for positive. The sign is unused // (ignored on inputs, set to 0 on outputs) in almost all operations // involving Bigints: a notable exception is the diff function, which // ignores signs on inputs but sets the sign of the output correctly. // - wds is the actual number of significant words // - x contains the vector of words (digits) for this Bigint, from least // significant (x[0]) to most significant (x[wds-1]). struct Bigint { struct Bigint* next; int k, maxwds, sign, wds; uint32_t x[1]; }; // Memory management: memory is allocated from, and returned to, kKmax+1 pools // of memory, where pool k (0 <= k <= kKmax) is for Bigints b with b->maxwds == // 1 << k. These pools are maintained as linked lists, with freelist[k] // pointing to the head of the list for pool k. // // On allocation, if there's no free slot in the appropriate pool, std::malloc // is called to get more memory. This memory is not returned to the system // until Python quits. There's also a private memory pool that's allocated from // in preference to using std::malloc. // // For Bigints with more than (1 << kKmax) digits (which implies at least 1233 // decimal digits), memory is directly allocated using std::malloc, and freed // using std::free. // // XXX: it would be easy to bypass this memory-management system and // translate each call to Balloc into a call to PyMem_Malloc, and each // Bfree to PyMem_Free. Investigate whether this has any significant // performance on impact. static Bigint* freelist[kKmax + 1]; // Allocate space for a Bigint with up to 1<<k digits. static Bigint* Balloc(int k) { Bigint* rv; if (k <= kKmax && (rv = freelist[k])) { freelist[k] = rv->next; } else { int x = 1 << k; unsigned len = (sizeof(Bigint) + (x - 1) * sizeof(uint32_t) + sizeof(double) - 1) / sizeof(double); if (k <= kKmax && pmem_next - private_mem + len <= static_cast<long>(kPrivateMemArraySize)) { rv = reinterpret_cast<Bigint*>(pmem_next); pmem_next += len; } else { rv = static_cast<Bigint*>(std::malloc(len * sizeof(double))); if (rv == nullptr) { return nullptr; } } rv->k = k; rv->maxwds = x; } rv->sign = rv->wds = 0; return rv; } // Free a Bigint allocated with Balloc. static void Bfree(Bigint* v) { if (v == nullptr) { return; } if (v->k > kKmax) { std::free(v); } else { v->next = freelist[v->k]; freelist[v->k] = v; } } static inline void Bcopy(Bigint* dest, const Bigint* src) { std::memcpy(&dest->sign, &src->sign, src->wds * sizeof(int32_t) + 2 * sizeof(int)); } // Multiply a Bigint b by m and add a. Either modifies b in place and returns // a pointer to the modified b, or Bfrees b and returns a pointer to a copy. // On failure, return nullptr. In this case, b will have been already freed. static Bigint* multadd(Bigint* b, int m, int a) // multiply by m and add a { int wds = b->wds; uint32_t* x = b->x; int i = 0; uint64_t carry = a; do { uint64_t y = *x * static_cast<uint64_t>(m) + carry; carry = y >> 32; *x++ = static_cast<uint32_t>(y & kFfffffff); } while (++i < wds); if (carry) { if (wds >= b->maxwds) { Bigint* b1 = Balloc(b->k + 1); if (b1 == nullptr) { Bfree(b); return nullptr; } Bcopy(b1, b); Bfree(b); b = b1; } b->x[wds++] = static_cast<uint32_t>(carry); b->wds = wds; } return b; } // convert a string s containing nd decimal digits (possibly containing a // decimal separator at position nd0, which is ignored) to a Bigint. This // function carries on where the parsing code in strtod leaves off: on // entry, y9 contains the result of converting the first 9 digits. Returns // nullptr on failure. static Bigint* s2b(const char* s, int nd0, int nd, uint32_t y9) { int32_t x = (nd + 8) / 9; int k = 0; for (int32_t y = 1; x > y; y <<= 1, k++) { } Bigint* b = Balloc(k); if (b == nullptr) { return nullptr; } b->x[0] = y9; b->wds = 1; if (nd <= 9) { return b; } s += 9; int i; for (i = 9; i < nd0; i++) { b = multadd(b, 10, *s++ - '0'); if (b == nullptr) { return nullptr; } } s++; for (; i < nd; i++) { b = multadd(b, 10, *s++ - '0'); if (b == nullptr) { return nullptr; } } return b; } // count leading 0 bits in the 32-bit integer x. static int hi0bits(uint32_t x) { int k = 0; if (!(x & 0xffff0000)) { k = 16; x <<= 16; } if (!(x & 0xff000000)) { k += 8; x <<= 8; } if (!(x & 0xf0000000)) { k += 4; x <<= 4; } if (!(x & 0xc0000000)) { k += 2; x <<= 2; } if (!(x & 0x80000000)) { k++; if (!(x & 0x40000000)) { return 32; } } return k; } // count trailing 0 bits in the 32-bit integer y, and shift y right by that // number of bits. static int lo0bits(uint32_t* y) { uint32_t x = *y; if (x & 7) { if (x & 1) { return 0; } if (x & 2) { *y = x >> 1; return 1; } *y = x >> 2; return 2; } int k = 0; if (!(x & 0xffff)) { k = 16; x >>= 16; } if (!(x & 0xff)) { k += 8; x >>= 8; } if (!(x & 0xf)) { k += 4; x >>= 4; } if (!(x & 0x3)) { k += 2; x >>= 2; } if (!(x & 1)) { k++; x >>= 1; if (!x) { return 32; } } *y = x; return k; } // convert a small nonnegative integer to a Bigint static Bigint* i2b(int i) { Bigint* b = Balloc(1); if (b == nullptr) { return nullptr; } b->x[0] = i; b->wds = 1; return b; } // multiply two Bigints. Returns a new Bigint, or nullptr on failure. Ignores // the signs of a and b. static Bigint* mult(Bigint* a, Bigint* b) { Bigint* c; if ((!a->x[0] && a->wds == 1) || (!b->x[0] && b->wds == 1)) { c = Balloc(0); if (c == nullptr) { return nullptr; } c->wds = 1; c->x[0] = 0; return c; } if (a->wds < b->wds) { c = a; a = b; b = c; } int k = a->k; int wa = a->wds; int wb = b->wds; int wc = wa + wb; if (wc > a->maxwds) { k++; } c = Balloc(k); if (c == nullptr) { return nullptr; } uint32_t* x; uint32_t* xa; for (x = c->x, xa = x + wc; x < xa; x++) { *x = 0; } xa = a->x; uint32_t* xae = xa + wa; uint32_t* xb = b->x; uint32_t* xbe = xb + wb; uint32_t* xc0 = c->x; uint32_t* xc; for (; xb < xbe; xc0++) { uint32_t y = *xb++; if (y) { x = xa; xc = xc0; uint64_t carry = 0; do { uint64_t z = *x++ * static_cast<uint64_t>(y) + *xc + carry; carry = z >> 32; *xc++ = static_cast<uint32_t>(z & kFfffffff); } while (x < xae); *xc = static_cast<uint32_t>(carry); } } for (xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) { } c->wds = wc; return c; } // p5s is a linked list of powers of 5 of the form 5**(2**i), i >= 2 static Bigint* p5s; // multiply the Bigint b by 5**k. Returns a pointer to the result, or nullptr // on failure; if the returned pointer is distinct from b then the original // Bigint b will have been Bfree'd. Ignores the sign of b. static Bigint* pow5mult(Bigint* b, int k) { static const int p05[3] = {5, 25, 125}; int i = k & 3; if (i) { b = multadd(b, p05[i - 1], 0); if (b == nullptr) { return nullptr; } } if (!(k >>= 2)) { return b; } Bigint* p5 = p5s; if (!p5) { // first time p5 = i2b(625); if (p5 == nullptr) { Bfree(b); return nullptr; } p5s = p5; p5->next = nullptr; } for (;;) { if (k & 1) { Bigint* b1 = mult(b, p5); Bfree(b); b = b1; if (b == nullptr) { return nullptr; } } if (!(k >>= 1)) { break; } Bigint* p51 = p5->next; if (!p51) { p51 = mult(p5, p5); if (p51 == nullptr) { Bfree(b); return nullptr; } p51->next = nullptr; p5->next = p51; } p5 = p51; } return b; } // shift a Bigint b left by k bits. Return a pointer to the shifted result, // or nullptr on failure. If the returned pointer is distinct from b then the // original b will have been Bfree'd. Ignores the sign of b. static Bigint* lshift(Bigint* b, int k) { if (!k || (!b->x[0] && b->wds == 1)) { return b; } int n = k >> 5; int k1 = b->k; int n1 = n + b->wds + 1; for (int i = b->maxwds; n1 > i; i <<= 1) { k1++; } Bigint* b1 = Balloc(k1); if (b1 == nullptr) { Bfree(b); return nullptr; } uint32_t* x1 = b1->x; for (int i = 0; i < n; i++) { *x1++ = 0; } uint32_t* x = b->x; uint32_t* xe = x + b->wds; if (k &= 0x1f) { k1 = 32 - k; uint32_t z = 0; do { *x1++ = *x << k | z; z = *x++ >> k1; } while (x < xe); if ((*x1 = z)) { ++n1; } } else { do { *x1++ = *x++; } while (x < xe); } b1->wds = n1 - 1; Bfree(b); return b1; } // Do a three-way compare of a and b, returning -1 if a < b, 0 if a == b and // 1 if a > b. Ignores signs of a and b. static int cmp(Bigint* a, Bigint* b) { uint32_t *xa, *xa0, *xb, *xb0; int i, j; i = a->wds; j = b->wds; DCHECK(i <= 1 || a->x[i - 1], "cmp called with a->x[a->wds-1] == 0"); DCHECK(j <= 1 || b->x[j - 1], "cmp called with b->x[b->wds-1] == 0"); if (i -= j) { return i; } xa0 = a->x; xa = xa0 + j; xb0 = b->x; xb = xb0 + j; for (;;) { if (*--xa != *--xb) { return *xa < *xb ? -1 : 1; } if (xa <= xa0) { break; } } return 0; } // Take the difference of Bigints a and b, returning a new Bigint. Returns // nullptr on failure. The signs of a and b are ignored, but the sign of the // result is set appropriately. static Bigint* diff(Bigint* a, Bigint* b) { Bigint* c; int i, wa, wb; uint32_t *xa, *xae, *xb, *xbe, *xc; uint64_t borrow, y; i = cmp(a, b); if (!i) { c = Balloc(0); if (c == nullptr) { return nullptr; } c->wds = 1; c->x[0] = 0; return c; } if (i < 0) { c = a; a = b; b = c; i = 1; } else { i = 0; } c = Balloc(a->k); if (c == nullptr) { return nullptr; } c->sign = i; wa = a->wds; xa = a->x; xae = xa + wa; wb = b->wds; xb = b->x; xbe = xb + wb; xc = c->x; borrow = 0; do { y = static_cast<uint64_t>(*xa++) - *xb++ - borrow; borrow = y >> 32 & uint32_t{1}; *xc++ = static_cast<uint32_t>(y & kFfffffff); } while (xb < xbe); while (xa < xae) { y = *xa++ - borrow; borrow = y >> 32 & uint32_t{1}; *xc++ = static_cast<uint32_t>(y & kFfffffff); } while (!*--xc) { wa--; } c->wds = wa; return c; } // Given a positive normal double x, return the difference between x and the // next double up. Doesn't give correct results for subnormals. static double ulp(U* x) { int32_t big_l = (word0(x) & kExpMask) - (kP - 1) * kExpMsk1; U u; word0(&u) = big_l; word1(&u) = 0; return dval(&u); } // Convert a Bigint to a double plus an exponent static double b2d(Bigint* a, int* e) { uint32_t* xa0 = a->x; uint32_t* xa = xa0 + a->wds; uint32_t y = *--xa; DCHECK(y != 0, "zero y in b2d"); int k = hi0bits(y); *e = 32 - k; U d; if (k < kEbits) { word0(&d) = kExp1 | y >> (kEbits - k); uint32_t w = xa > xa0 ? *--xa : 0; word1(&d) = y << ((32 - kEbits) + k) | w >> (kEbits - k); return dval(&d); } uint32_t z = xa > xa0 ? *--xa : 0; if (k -= kEbits) { word0(&d) = kExp1 | y << k | z >> (32 - k); y = xa > xa0 ? *--xa : 0; word1(&d) = z << k | y >> (32 - k); } else { word0(&d) = kExp1 | y; word1(&d) = z; } return dval(&d); } // Convert a scaled double to a Bigint plus an exponent. Similar to d2b, // except that it accepts the scale parameter used in strtod (which // should be either 0 or 2*kP), and the normalization for the return value is // different (see below). On input, d should be finite and nonnegative, and d // / 2**scale should be exactly representable as an IEEE 754 double. // // Returns a Bigint b and an integer e such that // // dval(d) / 2**scale = b * 2**e. // // Unlike d2b, b is not necessarily odd: b and e are normalized so // that either 2**(kP-1) <= b < 2**kP and e >= kEtiny, or b < 2**kP // and e == kEtiny. This applies equally to an input of 0.0: in that // case the return values are b = 0 and e = kEtiny. // // The above normalization ensures that for all possible inputs d, // 2**e gives ulp(d/2**scale). // // Returns nullptr on failure. static Bigint* sd2b(U* d, int scale, int* e) { Bigint* b = Balloc(1); if (b == nullptr) { return nullptr; } // First construct b and e assuming that scale == 0. b->wds = 2; b->x[0] = word1(d); b->x[1] = word0(d) & kFracMask; *e = kEtiny - 1 + static_cast<int>((word0(d) & kExpMask) >> kExpShift); if (*e < kEtiny) { *e = kEtiny; } else { b->x[1] |= kExpMsk1; } // Now adjust for scale, provided that b != 0. if (scale && (b->x[0] || b->x[1])) { *e -= scale; if (*e < kEtiny) { scale = kEtiny - *e; *e = kEtiny; // We can't shift more than kP-1 bits without shifting out a 1. DCHECK(0 < scale && scale <= kP - 1, "unexpected scale"); if (scale >= 32) { // The bits shifted out should all be zero. DCHECK(b->x[0] == 0, "unexpected bits"); b->x[0] = b->x[1]; b->x[1] = 0; scale -= 32; } if (scale) { // The bits shifted out should all be zero. DCHECK(b->x[0] << (32 - scale) == 0, "unexpected bits"); b->x[0] = (b->x[0] >> scale) | (b->x[1] << (32 - scale)); b->x[1] >>= scale; } } } // Ensure b is normalized. if (!b->x[1]) { b->wds = 1; } return b; } // Convert a double to a Bigint plus an exponent. Return nullptr on failure. // // Given a finite nonzero double d, return an odd Bigint b and exponent *e // such that fabs(d) = b * 2**e. On return, *bbits gives the number of // significant bits of b; that is, 2**(*bbits-1) <= b < 2**(*bbits). // // If d is zero, then b == 0, *e == -1010, *bbits = 0. static Bigint* d2b(U* d, int* e, int* bits) { Bigint* b = Balloc(1); if (b == nullptr) { return nullptr; } uint32_t* x = b->x; uint32_t z = word0(d) & kFracMask; word0(d) &= 0x7fffffff; // clear sign bit, which we ignore int de = static_cast<int>(word0(d) >> kExpShift); if (de) { z |= kExpMsk1; } uint32_t y = word1(d); int i; int k; if (y) { if ((k = lo0bits(&y))) { x[0] = y | z << (32 - k); z >>= k; } else { x[0] = y; } i = b->wds = (x[1] = z) ? 2 : 1; } else { k = lo0bits(&z); x[0] = z; i = b->wds = 1; k += 32; } if (de) { *e = de - kBias - (kP - 1) + k; *bits = kP - k; } else { *e = de - kBias - (kP - 1) + 1 + k; *bits = 32 * i - hi0bits(x[i - 1]); } return b; } // Compute the ratio of two Bigints, as a double. The result may have an // error of up to 2.5 ulps. static double ratio(Bigint* a, Bigint* b) { U da; int ka; dval(&da) = b2d(a, &ka); U db; int kb; dval(&db) = b2d(b, &kb); int k = ka - kb + 32 * (a->wds - b->wds); if (k > 0) { word0(&da) += k * kExpMsk1; } else { k = -k; word0(&db) += k * kExpMsk1; } return dval(&da) / dval(&db); } static const double kTens[] = {1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22}; static const double kBigTens[] = {1e16, 1e32, 1e64, 1e128, 1e256}; static const double kTinyTens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 9007199254740992. * 9007199254740992.e-256 // = 2^106 * 1e-256 }; // The factor of 2^53 in kTinyTens[4] helps us avoid setting the underflow // flag unnecessarily. It leads to a song and dance at the end of strtod. static const int kScaleBit = 0x10; static const int kKmask = 31; static int dshift(Bigint* b, int p2) { int rv = hi0bits(b->x[b->wds - 1]) - 4; if (p2 > 0) { rv -= p2; } return rv & kKmask; } // special case of Bigint division. The quotient is always in the range 0 <= // quotient < 10, and on entry the divisor big_s is normalized so that its top 4 // bits (28--31) are zero and bit 27 is set. static int quorem(Bigint* b, Bigint* big_s) { int n = big_s->wds; DCHECK(b->wds <= n, "oversize b in quorem"); if (b->wds < n) { return 0; } uint32_t* sx = big_s->x; uint32_t* sxe = sx + --n; uint32_t* bx = b->x; uint32_t* bxe = bx + n; uint32_t q = *bxe / (*sxe + 1); // ensure q <= true quotient. DCHECK(q <= 9, "oversized quotient in quorem"); if (q) { uint64_t borrow = 0; uint64_t carry = 0; do { uint64_t ys = *sx++ * static_cast<uint64_t>(q) + carry; carry = ys >> 32; uint64_t y = *bx - (ys & kFfffffff) - borrow; borrow = y >> 32 & uint32_t{1}; *bx++ = static_cast<uint32_t>(y & kFfffffff); } while (sx <= sxe); if (!*bxe) { bx = b->x; while (--bxe > bx && !*bxe) { --n; } b->wds = n; } } if (cmp(b, big_s) >= 0) { q++; uint64_t borrow = 0; uint64_t carry = 0; bx = b->x; sx = big_s->x; do { uint64_t ys = *sx++ + carry; carry = ys >> 32; uint64_t y = *bx - (ys & kFfffffff) - borrow; borrow = y >> 32 & uint32_t{1}; *bx++ = static_cast<uint32_t>(y & kFfffffff); } while (sx <= sxe); bx = b->x; bxe = bx + n; if (!*bxe) { while (--bxe > bx && !*bxe) { --n; } b->wds = n; } } return q; } // sulp(x) is a version of ulp(x) that takes bc.scale into account. // // Assuming that x is finite and nonnegative (positive zero is fine // here) and x / 2^bc.scale is exactly representable as a double, // sulp(x) is equivalent to 2^bc.scale * ulp(x / 2^bc.scale). static double sulp(U* x, BCinfo* bc) { if (bc->scale && 2 * kP + 1 > static_cast<int>((word0(x) & kExpMask) >> kExpShift)) { // rv/2^bc->scale is subnormal U u; word0(&u) = (kP + 2) * kExpMsk1; word1(&u) = 0; return u.d; } DCHECK(word0(x) || word1(x), "should not be zero"); // x != 0.0 return ulp(x); } // The bigcomp function handles some hard cases for strtod, for inputs // with more than kStrtodDiglim digits. It's called once an initial // estimate for the double corresponding to the input string has // already been obtained by the code in strtod. // // The bigcomp function is only called after strtod has found a // double value rv such that either rv or rv + 1ulp represents the // correctly rounded value corresponding to the original string. It // determines which of these two values is the correct one by // computing the decimal digits of rv + 0.5ulp and comparing them with // the corresponding digits of s0. // // In the following, write dv for the absolute value of the number represented // by the input string. // // Inputs: // // s0 points to the first significant digit of the input string. // // rv is a (possibly scaled) estimate for the closest double value to the // value represented by the original input to strtod. If // bc->scale is nonzero, then rv/2^(bc->scale) is the approximation to // the input value. // // bc is a struct containing information gathered during the parsing and // estimation steps of strtod. Description of fields follows: // // bc->e0 gives the exponent of the input value, such that dv = (integer // given by the bd->nd digits of s0) * 10**e0 // // bc->nd gives the total number of significant digits of s0. It will // be at least 1. // // bc->nd0 gives the number of significant digits of s0 before the // decimal separator. If there's no decimal separator, bc->nd0 == // bc->nd. // // bc->scale is the value used to scale rv to avoid doing arithmetic with // subnormal values. It's either 0 or 2*kP (=106). // // Outputs: // // On successful exit, rv/2^(bc->scale) is the closest double to dv. // // Returns 0 on success, -1 on failure (e.g., due to a failed malloc call). static int bigcomp(U* rv, const char* s0, BCinfo* bc) { int nd = bc->nd; int nd0 = bc->nd0; int p5 = nd + bc->e0; int p2; Bigint* b = sd2b(rv, bc->scale, &p2); if (b == nullptr) { return -1; } // record whether the lsb of rv/2^(bc->scale) is odd: in the exact halfway // case, this is used for round to even. int odd = b->x[0] & 1; // left shift b by 1 bit and or a 1 into the least significant bit; // this gives us b * 2**p2 = rv/2^(bc->scale) + 0.5 ulp. b = lshift(b, 1); if (b == nullptr) { return -1; } b->x[0] |= 1; p2--; p2 -= p5; Bigint* d = i2b(1); if (d == nullptr) { Bfree(b); return -1; } // Arrange for convenient computation of quotients: // shift left if necessary so divisor has 4 leading 0 bits. if (p5 > 0) { d = pow5mult(d, p5); if (d == nullptr) { Bfree(b); return -1; } } else if (p5 < 0) { b = pow5mult(b, -p5); if (b == nullptr) { Bfree(d); return -1; } } int b2; int d2; if (p2 > 0) { b2 = p2; d2 = 0; } else { b2 = 0; d2 = -p2; } int i = dshift(d, d2); if ((b2 += i) > 0) { b = lshift(b, b2); if (b == nullptr) { Bfree(d); return -1; } } if ((d2 += i) > 0) { d = lshift(d, d2); if (d == nullptr) { Bfree(b); return -1; } } // Compare s0 with b/d: set dd to -1, 0, or 1 according as s0 < b/d, s0 == // b/d, or s0 > b/d. Here the digits of s0 are thought of as representing // a number in the range [0.1, 1). int dd; if (cmp(b, d) >= 0) { // b/d >= 1 dd = -1; } else { i = 0; for (;;) { b = multadd(b, 10, 0); if (b == nullptr) { Bfree(d); return -1; } dd = s0[i < nd0 ? i : i + 1] - '0' - quorem(b, d); i++; if (dd) { break; } if (!b->x[0] && b->wds == 1) { // b/d == 0 dd = i < nd; break; } if (!(i < nd)) { // b/d != 0, but digits of s0 exhausted dd = -1; break; } } } Bfree(b); Bfree(d); if (dd > 0 || (dd == 0 && odd)) { dval(rv) += sulp(rv, bc); } return 0; } static double strtod(const char* s00, char** se) { int bb2, bb5, bbe, bd2, bd5, bs2, dsign, e1, error; int i, j, k, nd, nd0, odd; double aadj, aadj1; U aadj2, adj, rv0; uint32_t y, z; BCinfo bc; Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; U rv; dval(&rv) = 0.; // Start parsing. const char* s = s00; int c = *s; // Parse optional sign, if present. bool sign = false; switch (c) { case '-': sign = true; FALLTHROUGH; case '+': c = *++s; } // Skip leading zeros: lz is true iff there were leading zeros. const char* s1 = s; while (c == '0') { c = *++s; } bool lz = s != s1; // Point s0 at the first nonzero digit (if any). fraclen will be the // number of digits between the decimal point and the end of the // digit string. ndigits will be the total number of digits ignoring // leading zeros. const char* s0 = s1 = s; while ('0' <= c && c <= '9') { c = *++s; } size_t ndigits = s - s1; size_t fraclen = 0; // Parse decimal point and following digits. if (c == '.') { c = *++s; if (!ndigits) { s1 = s; while (c == '0') { c = *++s; } lz = lz || s != s1; fraclen += (s - s1); s0 = s; } s1 = s; while ('0' <= c && c <= '9') { c = *++s; } ndigits += s - s1; fraclen += s - s1; } // Now lz is true if and only if there were leading zero digits, and // ndigits gives the total number of digits ignoring leading zeros. A // valid input must have at least one digit. if (!ndigits && !lz) { if (se) { *se = const_cast<char*>(s00); } return 0.0; } // Range check ndigits and fraclen to make sure that they, and values // computed with them, can safely fit in an int. if (ndigits > kMaxDigits || fraclen > kMaxDigits) { if (se) { *se = const_cast<char*>(s00); } return 0.0; } nd = static_cast<int>(ndigits); nd0 = nd - static_cast<int>(fraclen); // Parse exponent. int e = 0; if (c == 'e' || c == 'E') { s00 = s; c = *++s; // Exponent sign. bool esign = false; switch (c) { case '-': esign = true; // fall through case '+': c = *++s; } // Skip zeros. lz is true iff there are leading zeros. s1 = s; while (c == '0') { c = *++s; } lz = s != s1; // Get absolute value of the exponent. s1 = s; uint32_t abs_exp = 0; while ('0' <= c && c <= '9') { abs_exp = 10 * abs_exp + (c - '0'); c = *++s; } // abs_exp will be correct modulo 2**32. But 10**9 < 2**32, so if // there are at most 9 significant exponent digits then overflow is // impossible. if (s - s1 > 9 || abs_exp > kMaxAbsExp) { e = kMaxAbsExp; } else { e = static_cast<int>(abs_exp); } if (esign) { e = -e; } // A valid exponent must have at least one digit. if (s == s1 && !lz) { s = s00; } } // Adjust exponent to take into account position of the point. e -= nd - nd0; if (nd0 <= 0) { nd0 = nd; } // Finished parsing. Set se to indicate how far we parsed if (se) { *se = const_cast<char*>(s); } // If all digits were zero, exit with return value +-0.0. Otherwise, // strip trailing zeros: scan back until we hit a nonzero digit. if (!nd) { goto ret; } for (i = nd; i > 0;) { --i; if (s0[i < nd0 ? i : i + 1] != '0') { ++i; break; } } e += nd - i; nd = i; if (nd0 > nd) { nd0 = nd; } // Summary of parsing results. After parsing, and dealing with zero // inputs, we have values s0, nd0, nd, e, sign, where: // // - s0 points to the first significant digit of the input string // // - nd is the total number of significant digits (here, and // below, 'significant digits' means the set of digits of the // significand of the input that remain after ignoring leading // and trailing zeros). // // - nd0 indicates the position of the decimal point, if present; it // satisfies 1 <= nd0 <= nd. The nd significant digits are in // s0[0:nd0] and s0[nd0+1:nd+1] using the usual Python half-open slice // notation. (If nd0 < nd, then s0[nd0] contains a '.' character; if // nd0 == nd, then s0[nd0] could be any non-digit character.) // // - e is the adjusted exponent: the absolute value of the number // represented by the original input string is n * 10**e, where // n is the integer represented by the concatenation of // s0[0:nd0] and s0[nd0+1:nd+1] // // - sign gives the sign of the input: 1 for negative, 0 for positive // // - the first and last significant digits are nonzero // put first DBL_DIG+1 digits into integer y and z. // // - y contains the value represented by the first min(9, nd) // significant digits // // - if nd > 9, z contains the value represented by significant digits // with indices in [9, min(16, nd)). So y * 10**(min(16, nd) - 9) + z // gives the value represented by the first min(16, nd) sig. digits. bc.e0 = e1 = e; y = z = 0; for (i = 0; i < nd; i++) { if (i < 9) { y = 10 * y + s0[i < nd0 ? i : i + 1] - '0'; } else if (i < DBL_DIG + 1) { z = 10 * z + s0[i < nd0 ? i : i + 1] - '0'; } else { break; } } k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; dval(&rv) = y; if (k > 9) { dval(&rv) = kTens[k - 9] * dval(&rv) + z; } bd0 = nullptr; if (nd <= DBL_DIG && FLT_ROUNDS == 1) { if (!e) { goto ret; } if (e > 0) { if (e <= kTenPmax) { dval(&rv) *= kTens[e]; goto ret; } i = DBL_DIG - nd; if (e <= kTenPmax + i) { // A fancier test would sometimes let us do // this for larger i values. e -= i; dval(&rv) *= kTens[i]; dval(&rv) *= kTens[e]; goto ret; } } else if (e >= -kTenPmax) { dval(&rv) /= kTens[-e]; goto ret; } } e1 += nd - k; bc.scale = 0; // Get starting approximation = rv * 10**e1 if (e1 > 0) { if ((i = e1 & 15)) { dval(&rv) *= kTens[i]; } if (e1 &= ~15) { if (e1 > DBL_MAX_10_EXP) { goto ovfl; } e1 >>= 4; for (j = 0; e1 > 1; j++, e1 >>= 1) { if (e1 & 1) { dval(&rv) *= kBigTens[j]; } } // The last multiplication could overflow. word0(&rv) -= kP * kExpMsk1; dval(&rv) *= kBigTens[j]; if ((z = word0(&rv) & kExpMask) > kExpMsk1 * (DBL_MAX_EXP + kBias - kP)) { goto ovfl; } if (z > kExpMsk1 * (DBL_MAX_EXP + kBias - 1 - kP)) { // set to largest number (Can't trust DBL_MAX) word0(&rv) = kBig0; word1(&rv) = kBig1; } else { word0(&rv) += kP * kExpMsk1; } } } else if (e1 < 0) { // The input decimal value lies in [10**e1, 10**(e1+16)). // If e1 <= -512, underflow immediately. // If e1 <= -256, set bc.scale to 2*kP. // So for input value < 1e-256, bc.scale is always set; // for input value >= 1e-240, bc.scale is never set. // For input values in [1e-256, 1e-240), bc.scale may or may // not be set. e1 = -e1; if ((i = e1 & 15)) { dval(&rv) /= kTens[i]; } if (e1 >>= 4) { if (e1 >= 1 << ARRAYSIZE(kBigTens)) { goto undfl; } if (e1 & kScaleBit) { bc.scale = 2 * kP; } for (j = 0; e1 > 0; j++, e1 >>= 1) { if (e1 & 1) { dval(&rv) *= kTinyTens[j]; } } if (bc.scale && (j = 2 * kP + 1 - ((word0(&rv) & kExpMask) >> kExpShift)) > 0) { // scaled rv is denormal; clear j low bits if (j >= 32) { word1(&rv) = 0; if (j >= 53) { word0(&rv) = (kP + 2) * kExpMsk1; } else { word0(&rv) &= 0xffffffff << (j - 32); } } else { word1(&rv) &= 0xffffffff << j; } } if (!dval(&rv)) { goto undfl; } } } // Now the hard part -- adjusting rv to the correct value. // Put digits into bd: true value = bd * 10^e bc.nd = nd; bc.nd0 = nd0; // Only needed if nd > kStrtodDiglim, but done here // to silence an erroneous warning about bc.nd0 // possibly not being initialized. if (nd > kStrtodDiglim) { // ASSERT(kStrtodDiglim >= 18); 18 == one more than the // minimum number of decimal digits to distinguish double values // in IEEE arithmetic. // Truncate input to 18 significant digits, then discard any trailing // zeros on the result by updating nd, nd0, e and y suitably. (There's // no need to update z; it's not reused beyond this point.) for (i = 18; i > 0;) { // scan back until we hit a nonzero digit. significant digit 'i' // is s0[i] if i < nd0, s0[i+1] if i >= nd0. --i; if (s0[i < nd0 ? i : i + 1] != '0') { ++i; break; } } e += nd - i; nd = i; if (nd0 > nd) { nd0 = nd; } if (nd < 9) { // must recompute y y = 0; for (i = 0; i < nd0; ++i) { y = 10 * y + s0[i] - '0'; } for (; i < nd; ++i) { y = 10 * y + s0[i + 1] - '0'; } } } bd0 = s2b(s0, nd0, nd, y); if (bd0 == nullptr) { goto failed_malloc; } // Notation for the comments below. Write: // // - dv for the absolute value of the number represented by the original // decimal input string. // // - if we've truncated dv, write tdv for the truncated value. // Otherwise, set tdv == dv. // // - srv for the quantity rv/2^bc.scale; so srv is the current binary // approximation to tdv (and dv). It should be exactly representable // in an IEEE 754 double. for (;;) { // This is the main correction loop for strtod. // // We've got a decimal value tdv, and a floating-point approximation // srv=rv/2^bc.scale to tdv. The aim is to determine whether srv is // close enough (i.e., within 0.5 ulps) to tdv, and to compute a new // approximation if not. // // To determine whether srv is close enough to tdv, compute integers // bd, bb and bs proportional to tdv, srv and 0.5 ulp(srv) // respectively, and then use integer arithmetic to determine whether // |tdv - srv| is less than, equal to, or greater than 0.5 ulp(srv). bd = Balloc(bd0->k); if (bd == nullptr) { Bfree(bd0); goto failed_malloc; } Bcopy(bd, bd0); bb = sd2b(&rv, bc.scale, &bbe); // srv = bb * 2^bbe if (bb == nullptr) { Bfree(bd); Bfree(bd0); goto failed_malloc; } // Record whether lsb of bb is odd, in case we need this // for the round-to-even step later. odd = bb->x[0] & 1; // tdv = bd * 10**e; srv = bb * 2**bbe bs = i2b(1); if (bs == nullptr) { Bfree(bb); Bfree(bd); Bfree(bd0); goto failed_malloc; } if (e >= 0) { bb2 = bb5 = 0; bd2 = bd5 = e; } else { bb2 = bb5 = -e; bd2 = bd5 = 0; } if (bbe >= 0) { bb2 += bbe; } else { bd2 -= bbe; } bs2 = bb2; bb2++; bd2++; // At this stage bd5 - bb5 == e == bd2 - bb2 + bbe, bb2 - bs2 == 1, // and bs == 1, so: // // tdv == bd * 10**e = bd * 2**(bbe - bb2 + bd2) * 5**(bd5 - bb5) // srv == bb * 2**bbe = bb * 2**(bbe - bb2 + bb2) // 0.5 ulp(srv) == 2**(bbe-1) = bs * 2**(bbe - bb2 + bs2) // // It follows that: // // M * tdv = bd * 2**bd2 * 5**bd5 // M * srv = bb * 2**bb2 * 5**bb5 // M * 0.5 ulp(srv) = bs * 2**bs2 * 5**bb5 // // for some constant M. (Actually, M == 2**(bb2 - bbe) * 5**bb5, but // this fact is not needed below.) // Remove factor of 2**i, where i = min(bb2, bd2, bs2). i = bb2 < bd2 ? bb2 : bd2; if (i > bs2) { i = bs2; } if (i > 0) { bb2 -= i; bd2 -= i; bs2 -= i; } // Scale bb, bd, bs by the appropriate powers of 2 and 5. if (bb5 > 0) { bs = pow5mult(bs, bb5); if (bs == nullptr) { Bfree(bb); Bfree(bd); Bfree(bd0); goto failed_malloc; } bb1 = mult(bs, bb); Bfree(bb); bb = bb1; if (bb == nullptr) { Bfree(bs); Bfree(bd); Bfree(bd0); goto failed_malloc; } } if (bb2 > 0) { bb = lshift(bb, bb2); if (bb == nullptr) { Bfree(bs); Bfree(bd); Bfree(bd0); goto failed_malloc; } } if (bd5 > 0) { bd = pow5mult(bd, bd5); if (bd == nullptr) { Bfree(bb); Bfree(bs); Bfree(bd0); goto failed_malloc; } } if (bd2 > 0) { bd = lshift(bd, bd2); if (bd == nullptr) { Bfree(bb); Bfree(bs); Bfree(bd0); goto failed_malloc; } } if (bs2 > 0) { bs = lshift(bs, bs2); if (bs == nullptr) { Bfree(bb); Bfree(bd); Bfree(bd0); goto failed_malloc; } } // Now bd, bb and bs are scaled versions of tdv, srv and 0.5 ulp(srv), // respectively. Compute the difference |tdv - srv|, and compare // with 0.5 ulp(srv). delta = diff(bb, bd); if (delta == nullptr) { Bfree(bb); Bfree(bs); Bfree(bd); Bfree(bd0); goto failed_malloc; } dsign = delta->sign; delta->sign = 0; i = cmp(delta, bs); if (bc.nd > nd && i <= 0) { if (dsign) { break; // Must use bigcomp(). } // Here rv overestimates the truncated decimal value by at most // 0.5 ulp(rv). Hence rv either overestimates the true decimal // value by <= 0.5 ulp(rv), or underestimates it by some small // amount (< 0.1 ulp(rv)); either way, rv is within 0.5 ulps of // the true decimal value, so it's possible to exit. // // Exception: if scaled rv is a normal exact power of 2, but not // DBL_MIN, then rv - 0.5 ulp(rv) takes us all the way down to the // next double, so the correctly rounded result is either rv - 0.5 // ulp(rv) or rv; in this case, use bigcomp to distinguish. if (!word1(&rv) && !(word0(&rv) & kBndryMask)) { // rv can't be 0, since it's an overestimate for some // nonzero value. So rv is a normal power of 2. j = static_cast<int>((word0(&rv) & kExpMask) >> kExpShift); // rv / 2^bc.scale = 2^(j - 1023 - bc.scale); use bigcomp if // rv / 2^bc.scale >= 2^-1021. if (j - bc.scale >= 2) { dval(&rv) -= 0.5 * sulp(&rv, &bc); break; // Use bigcomp. } } { bc.nd = nd; i = -1; // Discarded digits make delta smaller. } } if (i < 0) { // Error is less than half an ulp -- check for // special case of mantissa a power of two. if (dsign || word1(&rv) || word0(&rv) & kBndryMask || (word0(&rv) & kExpMask) <= (2 * kP + 1) * kExpMsk1) { break; } if (!delta->x[0] && delta->wds <= 1) { // exact result break; } delta = lshift(delta, kLog2P); if (delta == nullptr) { Bfree(bb); Bfree(bs); Bfree(bd); Bfree(bd0); goto failed_malloc; } if (cmp(delta, bs) > 0) { goto drop_down; } break; } if (i == 0) { // exactly half-way between if (dsign) { if ((word0(&rv) & kBndryMask1) == kBndryMask1 && word1(&rv) == ((bc.scale && (y = word0(&rv) & kExpMask) <= 2 * kP * kExpMsk1) ? (0xffffffff & (0xffffffff << (2 * kP + 1 - (y >> kExpShift)))) : 0xffffffff)) { // boundary case -- increment exponent word0(&rv) = (word0(&rv) & kExpMask) + kExpMsk1; word1(&rv) = 0; // dsign = 0; break; } } else if (!(word0(&rv) & kBndryMask) && !word1(&rv)) { drop_down: // boundary case -- decrement exponent if (bc.scale) { int32_t big_l = word0(&rv) & kExpMask; if (big_l <= (2 * kP + 1) * kExpMsk1) { if (big_l > (kP + 2) * kExpMsk1) { // round even ==> // accept rv break; } // rv = smallest denormal if (bc.nd > nd) { break; } goto undfl; } } int32_t big_l = (word0(&rv) & kExpMask) - kExpMsk1; word0(&rv) = big_l | kBndryMask1; word1(&rv) = 0xffffffff; break; } if (!odd) { break; } if (dsign) { dval(&rv) += sulp(&rv, &bc); } else { dval(&rv) -= sulp(&rv, &bc); if (!dval(&rv)) { if (bc.nd > nd) { break; } goto undfl; } } // dsign = 1 - dsign; break; } if ((aadj = ratio(delta, bs)) <= 2.) { if (dsign) { aadj = aadj1 = 1.; } else if (word1(&rv) || word0(&rv) & kBndryMask) { if (word1(&rv) == kTiny1 && !word0(&rv)) { if (bc.nd > nd) { break; } goto undfl; } aadj = 1.; aadj1 = -1.; } else { // special case -- power of FLT_RADIX to be // rounded down... if (aadj < 2. / FLT_RADIX) { aadj = 1. / FLT_RADIX; } else { aadj *= 0.5; } aadj1 = -aadj; } } else { aadj *= 0.5; aadj1 = dsign ? aadj : -aadj; if (FLT_ROUNDS == 0) { aadj1 += 0.5; } } y = word0(&rv) & kExpMask; // Check for overflow if (y == kExpMsk1 * (DBL_MAX_EXP + kBias - 1)) { dval(&rv0) = dval(&rv); word0(&rv) -= kP * kExpMsk1; adj.d = aadj1 * ulp(&rv); dval(&rv) += adj.d; if ((word0(&rv) & kExpMask) >= kExpMsk1 * (DBL_MAX_EXP + kBias - kP)) { if (word0(&rv0) == kBig0 && word1(&rv0) == kBig1) { Bfree(bb); Bfree(bd); Bfree(bs); Bfree(bd0); Bfree(delta); goto ovfl; } word0(&rv) = kBig0; word1(&rv) = kBig1; goto cont; } else { word0(&rv) += kP * kExpMsk1; } } else { if (bc.scale && y <= 2 * kP * kExpMsk1) { if (aadj <= 0x7fffffff) { if ((z = static_cast<uint32_t>(aadj)) <= 0) { z = 1; } aadj = z; aadj1 = dsign ? aadj : -aadj; } dval(&aadj2) = aadj1; word0(&aadj2) += (2 * kP + 1) * kExpMsk1 - y; aadj1 = dval(&aadj2); } adj.d = aadj1 * ulp(&rv); dval(&rv) += adj.d; } z = word0(&rv) & kExpMask; if (bc.nd == nd) { if (!bc.scale) { if (y == z) { // Can we stop now? int32_t big_l = static_cast<int32_t>(aadj); aadj -= big_l; // The tolerances below are conservative. if (dsign || word1(&rv) || word0(&rv) & kBndryMask) { if (aadj < .4999999 || aadj > .5000001) { break; } } else if (aadj < .4999999 / FLT_RADIX) { break; } } } } cont: Bfree(bb); Bfree(bd); Bfree(bs); Bfree(delta); } Bfree(bb); Bfree(bd); Bfree(bs); Bfree(bd0); Bfree(delta); if (bc.nd > nd) { error = bigcomp(&rv, s0, &bc); if (error) { goto failed_malloc; } } if (bc.scale) { word0(&rv0) = kExp1 - 2 * kP * kExpMsk1; word1(&rv0) = 0; dval(&rv) *= dval(&rv0); } ret: return sign ? -dval(&rv) : dval(&rv); failed_malloc: errno = ENOMEM; return -1.0; undfl: return sign ? -0.0 : 0.0; ovfl: errno = ERANGE; return sign ? -HUGE_VAL : HUGE_VAL; } static char* rv_alloc(int i) { int j = sizeof(uint32_t); int k; for (k = 0; sizeof(Bigint) - sizeof(uint32_t) - sizeof(int) + j <= static_cast<unsigned>(i); j <<= 1) { k++; } int* r = reinterpret_cast<int*>(Balloc(k)); if (r == nullptr) { return nullptr; } *r = k; return reinterpret_cast<char*>(r + 1); } static char* nrv_alloc(const char* s, char** rve, int n) { char* rv = rv_alloc(n); if (rv == nullptr) { return nullptr; } char* t = rv; while ((*t = *s++)) { t++; } if (rve) { *rve = t; } return rv; } // freedtoa(s) must be used to free values s returned by dtoa // when MULTIPLE_THREADS is #defined. It should be used in all cases, // but for consistency with earlier versions of dtoa, it is optional // when MULTIPLE_THREADS is not defined. void freedtoa(char* s) { Bigint* b = reinterpret_cast<Bigint*>(reinterpret_cast<int*>(s) - 1); b->maxwds = 1 << (b->k = *reinterpret_cast<int*>(b)); Bfree(b); } // dtoa for IEEE arithmetic (dmg): convert double to ASCII string. // // Inspired by "How to Print Floating-Point Numbers Accurately" by // Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126]. // // Modifications: // 1. Rather than iterating, we use a simple numeric overestimate // to determine k = floor(log10(d)). We scale relevant // quantities using O(log2(k)) rather than O(k) multiplications. // 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't // try to generate digits strictly left to right. Instead, we // compute with fewer bits and propagate the carry if necessary // when rounding the final digit up. This is often faster. // 3. Under the assumption that input will be rounded nearest, // mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. // That is, we allow equality in stopping tests when the // round-nearest rule will give the same floating-point value // as would satisfaction of the stopping test with strict // inequality. // 4. We remove common factors of powers of 2 from relevant // quantities. // 5. When converting floating-point integers less than 1e16, // we use floating-point arithmetic rather than resorting // to multiple-precision integers. // 6. When asked to produce fewer than 15 digits, we first try // to get by with floating-point arithmetic; we resort to // multiple-precision integer arithmetic only if we cannot // guarantee that the floating-point calculation has given // the correctly rounded result. For k requested digits and // "uniformly" distributed input, the probability is // something like 10^(k-15) that we must resort to the int32_t // calculation. // // Additional notes (METD): (1) returns nullptr on failure. (2) to avoid // memory leakage, a successful call to dtoa should always be matched // by a call to freedtoa. static char* dtoa(double dd, int mode, int ndigits, int* decpt, int* sign, char** rve) { // Arguments ndigits, decpt, sign are similar to those // of ecvt and fcvt; trailing zeros are suppressed from // the returned string. If not null, *rve is set to point // to the end of the return value. If d is +-Infinity or NaN, // then *decpt is set to 9999. // // mode: // 0 ==> shortest string that yields d when read in // and rounded to nearest. // 1 ==> like 0, but with Steele & White stopping rule; // e.g. with IEEE P754 arithmetic , mode 0 gives // 1e23 whereas mode 1 gives 9.999999999999999e22. // 2 ==> max(1,ndigits) significant digits. This gives a // return value similar to that of ecvt, except // that trailing zeros are suppressed. // 3 ==> through ndigits past the decimal point. This // gives a return value similar to that from fcvt, // except that trailing zeros are suppressed, and // ndigits can be negative. // 4,5 ==> similar to 2 and 3, respectively, but (in // round-nearest mode) with the tests of mode 0 to // possibly return a shorter string that rounds to d. // With IEEE arithmetic and compilation with // -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same // as modes 2 and 3 when FLT_ROUNDS != 1. // 6-9 ==> Debugging modes similar to mode - 4: don't try // fast floating-point estimate (if applicable). // // Values of mode other than 0-9 are treated as mode 0. // // Sufficient space is allocated to the return value // to hold the suppressed trailing zeros. int b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, spec_case, try_quick; U d2, eps; char* s; double ds; // set pointers to nullptr, to silence gcc compiler warnings and make // cleanup easier on error Bigint* mlo = nullptr; Bigint* mhi = nullptr; Bigint* big_s = nullptr; char* s0 = nullptr; U u; u.d = dd; if (word0(&u) & kSignBit) { // set sign for everything, including 0's and NaNs *sign = 1; word0(&u) &= ~kSignBit; // clear sign bit } else { *sign = 0; } // quick return for Infinities, NaNs and zeros if ((word0(&u) & kExpMask) == kExpMask) { // Infinity or NaN *decpt = 9999; if (!word1(&u) && !(word0(&u) & 0xfffff)) { return nrv_alloc("Infinity", rve, 8); } return nrv_alloc("NaN", rve, 3); } if (!dval(&u)) { *decpt = 1; return nrv_alloc("0", rve, 1); } // compute k = floor(log10(d)). The computation may leave k // one too large, but should never leave k too small. int bbits; Bigint* b = d2b(&u, &be, &bbits); if (b == nullptr) { goto failed_malloc; } bool denorm; i = static_cast<int>(word0(&u) >> kExpShift1 & (kExpMask >> kExpShift1)); if (i) { dval(&d2) = dval(&u); word0(&d2) &= kFracMask1; word0(&d2) |= kExp11; // log(x) ~=~ log(1.5) + (x-1.5)/1.5 // log10(x) = log(x) / log(10) // ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) // log10(d) = (i-kBias)*log(2)/log(10) + log10(d2) // // This suggests computing an approximation k to log10(d) by // // k = (i - kBias)*0.301029995663981 // + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); // // We want k to be too large rather than too small. // The error in the first-order Taylor series approximation // is in our favor, so we just round up the constant enough // to compensate for any error in the multiplication of // (i - kBias) by 0.301029995663981; since |i - kBias| <= 1077, // and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, // adding 1e-13 to the constant term more than suffices. // Hence we adjust the constant term to 0.1760912590558. // (We could get a more accurate k by invoking log10, // but this is probably not worthwhile.) i -= kBias; denorm = false; } else { // d is denormalized i = bbits + be + (kBias + (kP - 1) - 1); uint32_t x = i > 32 ? word0(&u) << (64 - i) | word1(&u) >> (i - 32) : word1(&u) << (32 - i); dval(&d2) = x; word0(&d2) -= 31 * kExpMsk1; // adjust exponent i -= (kBias + (kP - 1) - 1) + 1; denorm = true; } ds = (dval(&d2) - 1.5) * 0.289529654602168 + 0.1760912590558 + i * 0.301029995663981; k = static_cast<int>(ds); if (ds < 0. && ds != k) k--; // want k = floor(ds) k_check = 1; if (k >= 0 && k <= kTenPmax) { if (dval(&u) < kTens[k]) { k--; } k_check = 0; } j = bbits - i - 1; if (j >= 0) { b2 = 0; s2 = j; } else { b2 = -j; s2 = 0; } if (k >= 0) { b5 = 0; s5 = k; s2 += k; } else { b2 -= k; b5 = -k; s5 = 0; } if (mode < 0 || mode > 9) { mode = 0; } try_quick = 1; if (mode > 5) { mode -= 4; try_quick = 0; } leftright = 1; ilim = ilim1 = -1; // Values for cases 0 and 1; done here to // silence erroneous "gcc -Wall" warning. switch (mode) { case 0: case 1: i = 18; ndigits = 0; break; case 2: leftright = 0; FALLTHROUGH; case 4: if (ndigits <= 0) { ndigits = 1; } ilim = ilim1 = i = ndigits; break; case 3: leftright = 0; FALLTHROUGH; case 5: i = ndigits + k + 1; ilim = i; ilim1 = i - 1; if (i <= 0) { i = 1; } } s0 = rv_alloc(i); if (s0 == nullptr) { goto failed_malloc; } s = s0; int32_t big_l; if (ilim >= 0 && ilim <= kQuickMax && try_quick) { // Try to get by with floating-point arithmetic. i = 0; dval(&d2) = dval(&u); k0 = k; ilim0 = ilim; ieps = 2; // conservative if (k > 0) { ds = kTens[k & 0xf]; j = k >> 4; if (j & kBletch) { // prevent overflows j &= kBletch - 1; dval(&u) /= kBigTens[ARRAYSIZE(kBigTens) - 1]; ieps++; } for (; j; j >>= 1, i++) { if (j & 1) { ieps++; ds *= kBigTens[i]; } } dval(&u) /= ds; } else if ((j1 = -k)) { dval(&u) *= kTens[j1 & 0xf]; for (j = j1 >> 4; j; j >>= 1, i++) { if (j & 1) { ieps++; dval(&u) *= kBigTens[i]; } } } if (k_check && dval(&u) < 1. && ilim > 0) { if (ilim1 <= 0) { goto fast_failed; } ilim = ilim1; k--; dval(&u) *= 10.; ieps++; } dval(&eps) = ieps * dval(&u) + 7.; word0(&eps) -= (kP - 1) * kExpMsk1; if (ilim == 0) { big_s = nullptr; mhi = nullptr; dval(&u) -= 5.; if (dval(&u) > dval(&eps)) { goto one_digit; } if (dval(&u) < -dval(&eps)) { goto no_digits; } goto fast_failed; } if (leftright) { // Use Steele & White method of only // generating digits needed. dval(&eps) = 0.5 / kTens[ilim - 1] - dval(&eps); for (i = 0;;) { big_l = static_cast<int32_t>(dval(&u)); dval(&u) -= big_l; *s++ = '0' + big_l; if (dval(&u) < dval(&eps)) { goto ret1; } if (1. - dval(&u) < dval(&eps)) { goto bump_up; } if (++i >= ilim) { break; } dval(&eps) *= 10.; dval(&u) *= 10.; } } else { // Generate ilim digits, then fix them up. dval(&eps) *= kTens[ilim - 1]; for (i = 1;; i++, dval(&u) *= 10.) { big_l = static_cast<int32_t>(dval(&u)); if (!(dval(&u) -= big_l)) { ilim = i; } *s++ = '0' + big_l; if (i == ilim) { if (dval(&u) > 0.5 + dval(&eps)) { goto bump_up; } else if (dval(&u) < 0.5 - dval(&eps)) { while (*--s == '0') { } s++; goto ret1; } break; } } } fast_failed: s = s0; dval(&u) = dval(&d2); k = k0; ilim = ilim0; } // Do we have a "small" integer? if (be >= 0 && k <= kIntMax) { // Yes. ds = kTens[k]; if (ndigits < 0 && ilim <= 0) { big_s = nullptr; mhi = nullptr; if (ilim < 0 || dval(&u) <= 5 * ds) { goto no_digits; } goto one_digit; } for (i = 1;; i++, dval(&u) *= 10.) { big_l = static_cast<int32_t>(dval(&u) / ds); dval(&u) -= big_l * ds; *s++ = '0' + big_l; if (!dval(&u)) { break; } if (i == ilim) { dval(&u) += dval(&u); if (dval(&u) > ds || (dval(&u) == ds && big_l & 1)) { bump_up: while (*--s == '9') { if (s == s0) { k++; *s = '0'; break; } } ++*s++; } break; } } goto ret1; } m2 = b2; m5 = b5; if (leftright) { i = denorm ? be + (kBias + (kP - 1) - 1 + 1) : 1 + kP - bbits; b2 += i; s2 += i; mhi = i2b(1); if (mhi == nullptr) { goto failed_malloc; } } if (m2 > 0 && s2 > 0) { i = m2 < s2 ? m2 : s2; b2 -= i; m2 -= i; s2 -= i; } if (b5 > 0) { if (leftright) { if (m5 > 0) { mhi = pow5mult(mhi, m5); if (mhi == nullptr) { goto failed_malloc; } Bigint* b1 = mult(mhi, b); Bfree(b); b = b1; if (b == nullptr) { goto failed_malloc; } } if ((j = b5 - m5)) { b = pow5mult(b, j); if (b == nullptr) { goto failed_malloc; } } } else { b = pow5mult(b, b5); if (b == nullptr) { goto failed_malloc; } } } big_s = i2b(1); if (big_s == nullptr) { goto failed_malloc; } if (s5 > 0) { big_s = pow5mult(big_s, s5); if (big_s == nullptr) { goto failed_malloc; } } // Check for special case that d is a normalized power of 2. spec_case = 0; if (mode < 2 || leftright) { if (!word1(&u) && !(word0(&u) & kBndryMask) && word0(&u) & (kExpMask & ~kExpMsk1)) { // The special case b2 += kLog2P; s2 += kLog2P; spec_case = 1; } } // Arrange for convenient computation of quotients: // shift left if necessary so divisor has 4 leading 0 bits. // // Perhaps we should just compute leading 28 bits of big_s once // and for all and pass them and a shift to quorem, so it // can do shifts and ors to compute the numerator for q. i = dshift(big_s, s2); b2 += i; m2 += i; s2 += i; if (b2 > 0) { b = lshift(b, b2); if (b == nullptr) { goto failed_malloc; } } if (s2 > 0) { big_s = lshift(big_s, s2); if (big_s == nullptr) { goto failed_malloc; } } if (k_check) { if (cmp(b, big_s) < 0) { k--; b = multadd(b, 10, 0); // we botched the k estimate if (b == nullptr) { goto failed_malloc; } if (leftright) { mhi = multadd(mhi, 10, 0); if (mhi == nullptr) { goto failed_malloc; } } ilim = ilim1; } } if (ilim <= 0 && (mode == 3 || mode == 5)) { if (ilim < 0) { // no digits, fcvt style no_digits: k = -1 - ndigits; goto ret; } else { big_s = multadd(big_s, 5, 0); if (big_s == nullptr) { goto failed_malloc; } if (cmp(b, big_s) <= 0) { goto no_digits; } } one_digit: *s++ = '1'; k++; goto ret; } if (leftright) { if (m2 > 0) { mhi = lshift(mhi, m2); if (mhi == nullptr) { goto failed_malloc; } } // Compute mlo -- check for special case // that d is a normalized power of 2. mlo = mhi; if (spec_case) { mhi = Balloc(mhi->k); if (mhi == nullptr) { goto failed_malloc; } Bcopy(mhi, mlo); mhi = lshift(mhi, kLog2P); if (mhi == nullptr) { goto failed_malloc; } } for (i = 1;; i++) { dig = quorem(b, big_s) + '0'; // Do we yet have the shortest decimal string // that will round to d? j = cmp(b, mlo); Bigint* delta = diff(big_s, mhi); if (delta == nullptr) { goto failed_malloc; } j1 = delta->sign ? 1 : cmp(b, delta); Bfree(delta); if (j1 == 0 && mode != 1 && !(word1(&u) & 1)) { if (dig == '9') { goto round_9_up; } if (j > 0) { dig++; } *s++ = dig; goto ret; } if (j < 0 || (j == 0 && mode != 1 && !(word1(&u) & 1))) { if (!b->x[0] && b->wds <= 1) { goto accept_dig; } if (j1 > 0) { b = lshift(b, 1); if (b == nullptr) { goto failed_malloc; } j1 = cmp(b, big_s); if ((j1 > 0 || (j1 == 0 && dig & 1)) && dig++ == '9') { goto round_9_up; } } accept_dig: *s++ = dig; goto ret; } if (j1 > 0) { if (dig == '9') { // possible if i == 1 round_9_up: *s++ = '9'; goto roundoff; } *s++ = dig + 1; goto ret; } *s++ = dig; if (i == ilim) { break; } b = multadd(b, 10, 0); if (b == nullptr) { goto failed_malloc; } if (mlo == mhi) { mlo = mhi = multadd(mhi, 10, 0); if (mlo == nullptr) { goto failed_malloc; } } else { mlo = multadd(mlo, 10, 0); if (mlo == nullptr) { goto failed_malloc; } mhi = multadd(mhi, 10, 0); if (mhi == nullptr) { goto failed_malloc; } } } } else { for (i = 1;; i++) { *s++ = dig = quorem(b, big_s) + '0'; if (!b->x[0] && b->wds <= 1) { goto ret; } if (i >= ilim) { break; } b = multadd(b, 10, 0); if (b == nullptr) { goto failed_malloc; } } } // Round off last digit b = lshift(b, 1); if (b == nullptr) { goto failed_malloc; } j = cmp(b, big_s); if (j > 0 || (j == 0 && dig & 1)) { roundoff: while (*--s == '9') { if (s == s0) { k++; *s++ = '1'; goto ret; } } ++*s++; } else { while (*--s == '0') { } s++; } ret: Bfree(big_s); if (mhi) { if (mlo && mlo != mhi) { Bfree(mlo); } Bfree(mhi); } ret1: Bfree(b); *s = 0; *decpt = k + 1; if (rve) { *rve = s; } return s0; failed_malloc: if (big_s) { Bfree(big_s); } if (mlo && mlo != mhi) { Bfree(mlo); } if (mhi) { Bfree(mhi); } if (b) { Bfree(b); } if (s0) { freedtoa(s0); } return nullptr; } } // namespace py