Merge pull request #320 from dcurrie/double-roundtrip

Double roundtrip
This commit is contained in:
Yuichi Nishiwaki 2016-01-09 23:27:10 +09:00
commit 9beff702c0
12 changed files with 2553 additions and 520 deletions

1
.gitignore vendored
View File

@ -11,3 +11,4 @@ GTAGS
_build
_static
_template
.DS_Store

View File

@ -11,6 +11,7 @@ PICRIN_OBJS = \
CONTRIB_SRCS =
CONTRIB_OBJS = $(CONTRIB_SRCS:.c=.o)
CONTRIB_LIBS =
CONTRIB_DEFS =
CONTRIB_INITS =
CONTRIB_TESTS =
CONTRIB_DOCS = $(wildcard contrib/*/docs/*.rst)
@ -19,7 +20,7 @@ REPL_ISSUE_TESTS = $(wildcard t/issue/*.sh)
TEST_RUNNER = bin/picrin
CFLAGS += -I./extlib/benz/include -Wall -Wextra
CFLAGS += -I./extlib/benz/include -Wall -Wextra $(CONTRIB_DEFS)
LDFLAGS += -lm
prefix ?= /usr/local

View File

@ -0,0 +1,766 @@
/* emyg_atod.c
**
** Copyright (C) 2015 Doug Currie, Londonderry, NH, USA
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and associated documentation files (the "Software"), to deal
** in the Software without restriction, including without limitation the rights
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
** copies of the Software, and to permit persons to whom the Software is
** furnished to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in
** all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
** THE SOFTWARE.
*/
/* This code is an implementation of strtod() to accompany emyg_dtoa.c
** It is based on an algorithm described by Aubrey Jaffer, January 2015,
** "Easy Accurate Reading and Writing of Floating-Point Numbers"
** arXiv:1310.8121v6 -- http://arxiv.org/abs/1310.8121v6
*/
/* This implementation, besides the obvious translation from Java to C, has
** some differences/improvements:
** 1. All memory allocations are on the stack, no heap allocations
** 2. We don't shift numerator right for the case: negative dpoint, positive bex
** This can happen for an input like -139745422447689500.0 that has...
** mant: 1397454224476895000 dp: -1 bex: 5. Shifting the mantissa right would
** lose information; instead we shift the scale factor left.
** 3. We use a roundQuotient function (quornd) optimized for atod; it adjusts
** the result to be 53 bits if it is 54 before rounding by appropriate use
** of the quotient LSB and remainder; this avoids doing the divide twice.
*/
#include <stdlib.h>
#include <limits.h>
#include <stdint.h>
#include <ctype.h> // used by emyg_strtod
#include <math.h> // scalb()
#include "emyg_pow5.h" // in separate file to support alternate implementations, and it's big
#ifdef TESTING_QUOREM
#include <stdio.h>
#include <string.h>
#define QUODBG(x) x
#else
#define QUODBG(x)
#endif
#define OPTIMIZE_FOR_ATOD
#define BIGNUM_JUMBO_SIZE_UINT32 (30) /* 960 bits > (64 + 54 + (log (expt 5 345) 2) = 919) */
#define BIGNUM_NORMAL_SIZE_UINT32 (28) /* when we don't need the extra space for multiply */
#define BIGNUM_QUOTIENT_SIZE_UINT32 (4) /* difference twixt dividend - divisor; see m - n + 1 */
static const int doubleMantissaBits = 53;
static inline int nlz32 (uint32_t x)
{
#if defined(_MSC_VER) && defined(_M_AMD64)
unsigned long bitno;
uint8_t s = _BitScanReverse(&bitno, (unsigned long )x);
return s ? (31 - (int )bitno) : 32;
#elif defined(__GNUC__) && (UINT_MAX == 0xFFFFFFFFUL)
return (x == 0u) ? 32 : __builtin_clz((unsigned int )x);
#elif defined(__GNUC__) && (ULONG_MAX == 0xFFFFFFFFUL)
return (x == 0u) ? 32 : __builtin_clzl((unsigned long )x);
#else
int n;
if (x == 0) return(32);
n = 0;
if (x <= 0x0000FFFF) { n = n +16; x = x <<16; }
if (x <= 0x00FFFFFF) { n = n + 8; x = x << 8; }
if (x <= 0x0FFFFFFF) { n = n + 4; x = x << 4; }
if (x <= 0x3FFFFFFF) { n = n + 2; x = x << 2; }
if (x <= 0x7FFFFFFF) { n = n + 1; }
return n;
#endif
}
static inline int nlz64 (uint64_t x)
{
#if defined(_MSC_VER) && defined(_M_AMD64)
unsigned long bitno;
uint8_t s = _BitScanReverse64(&bitno, x);
return s ? (63 - (int )bitno) : 64;
#elif defined(__GNUC__) && (ULONG_MAX > 0xFFFFFFFFFFFFFFF5ULL)
return (x == 0u) ? 64 : __builtin_clzl((unsigned long )x);
#elif defined(__GNUC__) && (ULONGLONG_MAX > 0xFFFFFFFFFFFFFFF5ULL)
return (x == 0u) ? 64 : __builtin_clzll((unsigned long long )x);
#else
int s = nlz32(x >> 32);
return (s == 32) ? (32 + nlz32(x & UINT32_MAX)) : s;
#endif
}
/* Divide code divmnu.c adapted from Hacker's Delight; here are the changes:
** 1. Eliminated signed arithmetic (shift left and conversions) since
** these are undefined behavior for C; adapted similar solution from
** David Ireland's BigDigits library.
** 2. Removed the option to return the remainder, and added the rounding
** feature needed for IEEE conversion.
** 3. Eliminated the alloca() calls; we know that for IEEE doubles none
** of our bignums will be larger than 112 bits.
** 4. Added code specific to emyg_atod() to force result size to 53 bits
** and returning a -1 to indicate the scaling by /2
** Hacker's Delight web site has a permission statement, incuding: you are
** free to use, copy, and distribute any of the code on this web site,
** whether modified by you or not. You need not give attribution.
*/
/* This divides an n-word dividend by an m-word divisor, giving an
** n-m+1-word quotient and m-word remainder. The bignums are in arrays of
** words. Here a "word" is 32 bits. This routine is designed for a 64-bit
** machine which has a 64/64 division instruction. */
/* q[0], u[0], and v[0] contain the LEAST significant words.
** (The sequence is in little-endian order).
**
** This is a fairly precise implementation of Knuth's Algorithm D, for a
** binary computer with base b = 2**32. The caller supplies:
** 1. Space q for the quotient, m - n + 1 words (at least one).
** 2. The dividend u, m words, m >= 1.
** 3. The divisor v, n words, n >= 1.
** The most significant digit of the divisor, v[n-1], must be nonzero. The
** dividend u may have leading zeros; this just makes the algorithm take
** longer and makes the quotient contain more leading zeros.
** The program does not alter the input parameters u and v.
** The quotient returned may have leading zeros. The
** function itself returns a value of 0 for success and 1 for invalid
** parameters (e.g., division by 0).
** For now, we must have m >= n. Knuth's Algorithm D also requires
** that the dividend be at least as long as the divisor. (In his terms,
** m >= 0 (unstated). Therefore m+n >= n.)
*/
int quornd (uint32_t q[], const uint32_t u[], const uint32_t v[], int m, int n)
{
const uint64_t b = 4294967296ULL; // Number base (2**32).
uint32_t un[BIGNUM_JUMBO_SIZE_UINT32]; // Normalized form of u, v.
uint32_t vn[BIGNUM_JUMBO_SIZE_UINT32];
uint64_t qhat; // Estimated quotient digit.
uint64_t rhat; // A remainder.
uint64_t p; // Product of two digits.
uint64_t t, k;
int s, i, j;
int res = 0;
if (m < n || n <= 0 || v[n-1] == 0)
return 1; // Return if invalid param.
if (n == 1)
{
k = 0; // Take care of the case of a
for (j = m - 1; j >= 0; j--) // single-digit divisor here.
{
q[j] = (k*b + u[j]) / v[0];
k = (k*b + u[j]) - (q[j] * v[0]);
}
#ifdef OPTIMIZE_FOR_ATOD
if ((64 - nlz32(q[1])) > doubleMantissaBits)
{
// we need to divide quotient by 2 to make it fit
res = -1; // let caller know we made this adjustment
uint32_t saved_q0 = q[0];
q[0] = (q[0] >> 1) | (q[1] << 31);
q[1] = q[1] >> 1;
if (0 == (saved_q0 & 1))
return res; // no need to round
// now the remainder is >= 0.5
// if un is 0, then the remainder is 0.5
// otherwise it is > 0.5
if ((k & UINT32_MAX) != 0)
goto round_up; // (2 * remainder) > divisor, round
// continue with check for round_even
if ((q[0] & 1) == 1)
goto round_up; // round to even
return res;
}
#endif
// rounding
k = (k & UINT32_MAX) * 2; // k is now 2 * remainder
if ((k > v[0]) || ((k == v[0]) && ((q[0] & 1) == 1)))
{
round_up:
i = 0;
do
{
t = (uint64_t)q[i] + 1;
q[i++] = t;
} while ((t > UINT32_MAX) && (i < (m - n + 1)));
}
return res;
}
/* Normalize by shifting v left just enough so that its high-order
bit is on, and shift u left the same amount. We may have to append a
high-order digit on the dividend; we do that unconditionally. */
s = nlz32(v[n-1]); // 0 <= s <= 31.
if (n > BIGNUM_JUMBO_SIZE_UINT32) return 1;
for (i = n - 1; i > 0; i--)
vn[i] = (v[i] << s) | ((uint64_t)v[i-1] >> (32-s));
vn[0] = v[0] << s;
if ((m + 1) > BIGNUM_JUMBO_SIZE_UINT32) return 1;
un[m] = (uint64_t)u[m-1] >> (32-s);
for (i = m - 1; i > 0; i--)
un[i] = (u[i] << s) | ((uint64_t)u[i-1] >> (32-s));
un[0] = u[0] << s;
for (j = m - n; j >= 0; j--) // Main loop.
{
// Compute estimate qhat of q[j].
qhat = (un[j+n]*b + un[j+n-1]) / vn[n-1];
rhat = (un[j+n]*b + un[j+n-1]) - qhat*vn[n-1];
again:
if (qhat >= b || qhat*vn[n-2] > b*rhat + un[j+n-2])
{
qhat = qhat - 1;
rhat = rhat + vn[n-1];
if (rhat < b) goto again;
}
// Multiply and subtract.
k = 0;
for (i = 0; i < n; i++)
{
p = qhat * vn[i];
un[i+j] -= k;
k = (un[i+j] > (UINT32_MAX - k)) ? 1 : 0;
un[i+j] -= (p & UINT32_MAX);
if (un[i+j] > (UINT32_MAX - (p & UINT32_MAX))) k++;
k += (p >> 32);
}
un[j+n] -= k;
q[j] = qhat; // Store quotient digit.
if (un[j+n]) // If we subtracted too
{
q[j] = q[j] - 1; // much, add back.
k = 0;
for (i = 0; i < n; i++)
{
t = (uint64_t)un[i+j] + vn[i] + k;
un[i+j] = t;
k = t >> 32;
}
un[j+n] = un[j+n] + k;
}
} // End j.
#ifdef OPTIMIZE_FOR_ATOD
if ((64 - nlz32(q[1])) > doubleMantissaBits)
{
// we need to divide quotient by 2 to make it fit
res = -1; // let caller know we made this adjustment
uint32_t saved_q0 = q[0];
q[0] = (q[0] >> 1) | (q[1] << 31);
q[1] = q[1] >> 1;
if (0 == (saved_q0 & 1))
return -1; // no need to round
// now the remainder is >= 0.5
// if un is 0, then the remainder is 0.5
// otherwise it is > 0.5
for (i = n-1; i >= 0; i--)
{
if (un[i] != 0)
goto round_up; // (2 * remainder) > divisor, round
}
// continue with check for round_even
}
else
#endif
{
// Rounding: multiply the remainder by 2 and compare with the divisor
//
if (un[n-1] > (UINT32_MAX / 2u))
goto round_up;
for (i = n-1; i > 0; i--)
{
uint32_t ud = (un[i] << 1) | (un[i-1] >> 31);
if (ud > vn[i])
goto round_up; // (2 * remainder) > divisor, round
if (ud < vn[i])
return 0; // (2 * remainder) < divisor, done
}
if ((un[0] << 1) > vn[0])
goto round_up; // (2 * remainder) > divisor, round
if ((un[0] << 1) < vn[0])
return 0; // (2 * remainder) < divisor, done
}
// Check for round to even
// (2 * remainder) == divisor
if ((q[0] & 1) == 1) goto round_up; // round to even
return res;
}
#if TESTING_QUOREM
void print_bigint (const char *nm, const uint32_t num[], const int n)
{
int i;
printf("%s: ", nm);
for (i = 0; i < n; i++)
printf("%u ", num[i]);
printf("\n");
}
#endif
static inline void one_shiftLeft (uint32_t v[], int s)
{
int x = 0;
while (s >= 32) { v[x++] = 0; s -= 32; }
v[x] = 1u << s;
}
static inline void scl_shift_left_by (uint32_t v[], const uint32_t x[], int sz, int s)
{
// v and x may be identical
int w = s / 32; // words to shift
int b = s % 32; // bits to shift
int i;
QUODBG(printf("scl_shift_left_by sz %d shift %d (%d %d)\n", sz, s, w, b));
// sz is the size of the result, v
// x is guaranteed to be appropriately sized to provide enough data
// this is a dumb api but works for now
// first copy words
v[sz - 1] = 0u;
for (i = sz - 2; i >= 0; i--)
{
v[i] = ((i - w) >= 0) ? x[i - w] : 0u;
}
// then shift bits
for (i = sz - 1; i > 0; i--)
{
v[i] = (v[i] << b) | (v[i - 1] >> (32 - b));
}
v[0] = (v[0] << b);
}
static inline void u64_shiftLeft (uint32_t v[], uint64_t n, int sz, int s)
{
uint64_t ns;
int x = 0;
if (s >= 0)
{
while (s >= 32) { v[x++] = 0; s -= 32; }
ns = n << s;
v[x++] = (ns & UINT32_MAX);
if (x < sz) // -- don't write past end of v[], caller determined size needed
{
v[x++] = (ns >> 32);
if (x < sz && s != 0) // no more data if s == 0
v[x] = n >> (64 - s);
}
}
}
static inline double doubleValue (uint32_t v[])
{
// only the fist 64-bits of v[] are used; caller has determined that's all that's needed
return (double )((uint64_t )v[0] + ((uint64_t )v[1] << 32));
}
static inline int bitLength (const uint32_t v[], int sz_in_32bit_words)
{
int x = sz_in_32bit_words - 1;
while ((v[x] == 0) && (x > 0)) x = x - 1;
return (x * 32) + (32 - nlz32(v[x]));
}
static inline void mulbyu64 (uint32_t p[], const uint64_t u64mant, const uint32_t m[], int z)
{
// p is z+2 32-bit words
// m is z 32-bit words
// TODO: could this be optimized to use 128 bit math on platforms that support it?
uint64_t lo = u64mant & UINT32_MAX;
uint64_t hi = u64mant >> 32;
uint64_t a = 0;
int i;
for (i = 0; i < z; i++)
{
a += lo * m[i];
p[i] = a & UINT32_MAX;
a = a >> 32;
}
p[z] = a;
//p[z+1] = 0;
a = 0;
if (hi > 0) for (i = 0; i < z; i++)
{
a += (hi * m[i]) + p[i+1]; // this always (just) fits in 64 bits
p[i+1] = (a & UINT32_MAX);
a = a >> 32;
}
p[z+1] = a;
}
/* atod_guts
** input: u64mant dpoint
** result: u64mant * 10**dpoint
**
** case dpoint >= 0:
** reframe as: u64mant * 5**dpoint * 2**dpoint
** if (u64mant * 5**dpoint) is less than 53 bits
** then the answer is just scalb(u64mant * 5**dpoint, dpoint)
** else
** calculate bex = the bit length of (u64mant * 5**dpoint)
** divide and round: (u64mant * 5**dpoint) / 2**bex
** the answer is scalb(u64mant * 5**dpoint, bex + dpoint)
** case dpoint < 0
** reframe as: (u64mant / (5**(-dpoint)) / 2**(-dpoint)
*/
double atod_guts (uint64_t u64mant, int dpoint)
{
const uint32_t *pow5p;
uint32_t num[BIGNUM_JUMBO_SIZE_UINT32]; // up to (log (expt 5 325) 2) = 755 bits => ~104 bytes
uint32_t scl[BIGNUM_NORMAL_SIZE_UINT32];
uint32_t quo[BIGNUM_QUOTIENT_SIZE_UINT32];
int n, m; // as per quornd: n is size of divisor, m is size of dividend in 32-bit words
int z; // z is size of pow5p in 32-bit words
int bex; // binary exponentish
QUODBG(fprintf(stderr, "mant: %llu dp: %d\n", u64mant, dpoint));
if (dpoint >= 0)
{
int r = get_pow5(dpoint, &pow5p, &z);
if (r) return 0.0/0.0; // NaN for bad input -- TODO: use inf for excessive +exponents?
m = z + 2; // size is sum of lengths of multiplicands
if (m > BIGNUM_JUMBO_SIZE_UINT32) { n = 0; goto atod_fail; }
mulbyu64(num, u64mant, pow5p, z); // num = pow5 * u64mant
bex = bitLength(num, m) - doubleMantissaBits;
if (bex <= 0) return scalb(doubleValue(num), dpoint);
QUODBG(fprintf(stderr, "+ bex: %d z: %d m: %d\n", bex, z, m));
n = (bex / 32) + 1; // 32-bit words needed to hold 1 << bex
m = (bex + doubleMantissaBits + 31) / 32; // we may be able to shrink by a word
if (n > BIGNUM_NORMAL_SIZE_UINT32) goto atod_fail;
one_shiftLeft(scl, bex);
if ((m - n + 1) > BIGNUM_QUOTIENT_SIZE_UINT32) goto atod_fail;
QUODBG(fprintf(stderr, "+ n: %d m: %d q: %d\n", n, m, m - n + 1));
if (quornd(quo, num, scl, m, n))
{
QUODBG(fprintf(stderr, "+ quornd returned error\n"));
return 0.0/0.0; // NaN for bad input or software error
}
QUODBG(print_bigint("num", num, m));
QUODBG(print_bigint("scl", scl, n));
QUODBG(print_bigint("quo", quo, m - n + 1));
return scalb(doubleValue(quo), bex + dpoint);
}
else
{
int bma = 64 - nlz64(u64mant); // bits in mantissa
int r = get_pow5(-dpoint, &pow5p, &z);
if (r) return 0.0/0.0; // NaN for bad input -- TODO: use 0.0 for excessive -exponents?
bex = bma - bitLength(pow5p, z) - doubleMantissaBits;
if (bex > 0)
{
// to avoid losing significant bits, which could occur in the u64_shiftLeft below
// instead of shifting num right, let's shift pow5 left
// DANGER Will Robinson! We are aliasing pow5p and scl -- this is OK since
// the only place below they are both used in the same statement or call is
// scl_shift_left_by(), which is designed to handle aliased pointers
// and which doesn't happen at all if OPTIMIZE_FOR_ATOD is defined
//
m = 2;
if (m > BIGNUM_JUMBO_SIZE_UINT32) { n = 0; goto atod_fail; }
num[0] = u64mant & UINT32_MAX;
num[1] = u64mant >> 32;
// use z+1 because scl_shift_left_by my shift by as many as 10 bits (64 - 1 - 53)
if ((z + 1) > BIGNUM_NORMAL_SIZE_UINT32) { n = 0; goto atod_fail; }
scl_shift_left_by(scl, pow5p, z + 1, bex);
QUODBG(print_bigint("scl", scl, z + 1));
n = (bitLength(scl, z + 1) + 31) / 32;
pow5p = scl; // DANGER Will Robinson! -- see above
QUODBG(fprintf(stderr, "- bma %d bex: %d z: %d m: %d n: %d\n", bma, bex, z, m, n));
}
else
{
m = (((bma - bex) + 31) / 32); // u64mant << -bex
if (m > BIGNUM_JUMBO_SIZE_UINT32) { n = 0; goto atod_fail; }
QUODBG(fprintf(stderr, "- bma %d bex: %d z: %d m: %d\n", bma, bex, z, m));
u64_shiftLeft(num, u64mant, m, -bex);
n = z;
}
if ((m - n + 1) > BIGNUM_QUOTIENT_SIZE_UINT32) goto atod_fail;
QUODBG(fprintf(stderr, "- n: %d m: %d q: %d\n", n, m, m - n + 1));
r = quornd(quo, num, pow5p, m, n);
if (r > 0)
{
QUODBG(fprintf(stderr, "- quornd returned error\n"));
return 0.0/0.0; // NaN for bad input
}
QUODBG(print_bigint("num", num, m));
QUODBG(print_bigint("pow5p", pow5p, n));
QUODBG(print_bigint("quo", quo, m - n + 1));
#ifdef OPTIMIZE_FOR_ATOD
QUODBG(fprintf(stderr, "- r: %d\n", r));
if (r < 0)
{
bex++;
}
#else
bma = 64 - nlz64(doubleValue(quo));
if (bma > doubleMantissaBits)
{
bex++;
n = (pow5p[z-1] > (UINT32_MAX / 2u)) ? z + 1 : z;
// use z+2 because mulbyu64 will set those words even though they may be zero
if ((z + 2) > BIGNUM_NORMAL_SIZE_UINT32) goto atod_fail;
QUODBG(fprintf(stderr, "- n: %d m: %d q: %d bma: %d\n", n, m, m - n + 1, bma));
scl_shift_left_by(scl, pow5p, z + 1, 1);
if (quornd(quo, num, scl, m, n))
{
QUODBG(fprintf(stderr, "- quornd returned error; v[n-1]: %u\n", scl[n-1]));
return 0.0/0.0; // NaN for bad input
}
QUODBG(print_bigint("num", num, m));
QUODBG(print_bigint("scl", scl, n));
QUODBG(print_bigint("quo", quo, m - n + 1));
}
#endif
return scalb(doubleValue(quo), bex + dpoint);
}
atod_fail:
QUODBG(fprintf(stderr, "atod_guts undersized bignum n: %d m: %d\n", n, m));
return 0.0/0.0; // NaN for bad input
}
/*
double strtod(const char *nptr, char **endptr);
The expected form of the (initial portion of the) string is optional
leading white space as recognized by isspace(3), an optional plus
('+') or minus sign ('-') and then either (i) a decimal number, or
(ii) a hexadecimal number, or (iii) an infinity, or (iv) a NAN (not-
a-number).
A decimal number consists of a nonempty sequence of decimal digits
possibly containing a radix character (decimal point, locale-
dependent, usually '.'), optionally followed by a decimal exponent.
A decimal exponent consists of an 'E' or 'e', followed by an optional
plus or minus sign, followed by a nonempty sequence of decimal
digits, and indicates multiplication by a power of 10.
A hexadecimal number consists of a "0x" or "0X" followed by a
nonempty sequence of hexadecimal digits possibly containing a radix
character, optionally followed by a binary exponent. A binary
exponent consists of a 'P' or 'p', followed by an optional plus or
minus sign, followed by a nonempty sequence of decimal digits, and
indicates multiplication by a power of 2. At least one of radix
character and binary exponent must be present.
An infinity is either "INF" or "INFINITY", disregarding case.
A NAN is "NAN" (disregarding case) optionally followed by a string,
(n-char-sequence), where n-char-sequence specifies in an
implementation-dependent way the type of NAN (see NOTES).
These functions return the converted value, if any.
If endptr is not NULL, a pointer to the character after the last
character used in the conversion is stored in the location referenced
by endptr.
If no conversion is performed, zero is returned and the value of nptr
is stored in the location referenced by endptr.
If the correct value would cause overflow, plus or minus HUGE_VAL
(HUGE_VALF, HUGE_VALL) 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.
*/
double emyg_strtod(const char *nptr, char **endptr)
{
const char *cp = nptr;
double res;
uint64_t mant; // mantissa
int minus = 0; // mantissa minus
int dadp = 0; // digits after decimal point
int expt = 0; // explicit exponent
int expm = 0; // exponent minus
char c;
while (isspace(c = *cp++)) /*skip*/;
if ('-' == c) { minus = 1; c = *cp++; }
else if ('+' == c) { c = *cp++; }
else {}
if (('n' == c || 'N' == c)
&& ('a' == cp[0] || 'A' == cp[0])
&& ('n' == cp[1] || 'N' == cp[1]))
{
// for Scheme allow (require?) ".0"
if ('.' == cp[2] && '0' == cp[3]) cp = &cp[4];
else cp = &cp[2];
res = 0.0/0.0;
}
else
if (('i' == c || 'I' == c)
&& ('n' == cp[0] || 'N' == cp[0])
&& ('f' == cp[1] || 'F' == cp[1]))
{
// for Scheme allow (require?) ".0"
if ('.' == cp[2] && '0' == cp[3]) cp = &cp[4];
else cp = &cp[2];
res = 1.0/0.0;
// TODO: allow "INITY"
}
else if ('.' == c)
{
mant = 0;
goto after_dp;
}
else if (isdigit(c))
{
mant = c - '0'; // mantissa
while (isdigit(c = *cp++))
{
uint8_t d = c - '0';
if (mant <= (UINT64_MAX / 10)) mant *= 10;
else
{
if (0 == d) expt += 1;
else
{
QUODBG(fprintf(stderr, "- overlow in emyg_strtod 1\n"));
goto no_conv;
}
}
if (mant <= (UINT64_MAX - d)) mant += d;
else
{
QUODBG(fprintf(stderr, "- overlow in emyg_strtod 2\n"));
goto no_conv;
}
}
if ('.' == c)
{
after_dp:
while (isdigit(c = *cp++))
{
uint8_t d = c - '0';
if (mant <= (UINT64_MAX / 10)) mant *= 10;
else
{
if (0 == d)
{
/* ignore trailing zeroes by not scaling nor bumping dadp */
continue;
}
else
{
QUODBG(fprintf(stderr, "- overlow in emyg_strtod 3\n"));
//goto no_conv;
continue; // ignore extra digits
}
}
if (mant <= (UINT64_MAX - d)) mant += d;
else
{
QUODBG(fprintf(stderr, "- overlow in emyg_strtod 4\n"));
//goto no_conv;
continue; // ignore extra digits
}
dadp++;
}
}
if ('e' == c || 'E' == c)
{
c = *cp++;
if ('-' == c) { expm = 1; c = *cp++; }
else if ('+' == c) { c = *cp++; }
else {}
if (isdigit(c))
{
expt += c - '0';
while (isdigit(c = *cp++))
{
uint8_t d = c - '0';
if (expt <= (INT_MAX / 10)) expt *= 10;
else
{
QUODBG(fprintf(stderr, "- overlow in emyg_strtod\n"));
goto no_conv;
}
if (expt <= (INT_MAX - d)) expt += d;
else
{
QUODBG(fprintf(stderr, "- overlow in emyg_strtod\n"));
goto no_conv;
}
}
}
else
{
// oops, not an exp at all
c = *--cp;
if (('-' == c) || ('+' == c)) --cp;
res = 0.0;
}
}
if (expm) expt = -expt;
res = atod_guts(mant, expt - dadp);
}
else // no conversion
{
no_conv:
cp = nptr + 1;
res = 0.0;
}
if (NULL != endptr) *endptr = (char *)--cp;
return minus ? -res : res;
}
double emyg_atod (const char *nptr)
{
return emyg_strtod(nptr, NULL);
}
#ifdef TESTING_QUOREM
int main (int argc, char **argv)
{
if ((argc == 4) && (0 == strcmp(argv[1], "-p")))
{
char *p;
double d = atod_guts(strtoull(argv[2], &p, 10), strtol(argv[3], &p, 10));
printf("%.17g %a\n", d, d);
return 0;
}
if ((argc == 3) && (0 == strcmp(argv[1], "-s")))
{
char *p;
double d = emyg_strtod(argv[2], &p);
printf("%.17g %a\n", d, d);
return 0;
}
return 0;
}
#endif

View File

@ -0,0 +1,14 @@
/* emyg_atod.h */
#ifdef __cplusplus
extern "C" {
#endif
double emyg_strtod (const char *nptr, char **endptr);
double emyg_atod (const char *nptr);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,443 @@
/* emyg_dtoa.c
** Copyright (C) 2015 Doug Currie
** based on dtoa_milo.h
** Copyright (C) 2014 Milo Yip
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and associated documentation files (the "Software"), to deal
** in the Software without restriction, including without limitation the rights
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
** copies of the Software, and to permit persons to whom the Software is
** furnished to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in
** all copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
** THE SOFTWARE.
*/
/* This code is a mostly mechanical translation of Milo Yip's C++ version of
** Grisu2 to C. For algorithm information, see Loitsch, Florian. "Printing
** floating-point numbers quickly and accurately with integers." ACM Sigplan
** Notices 45.6 (2010): 233-243.
*/
#include <assert.h>
#include <math.h>
#if defined(_MSC_VER)
#include "msinttypes/stdint.h"
#include <intrin.h>
#else
#include <stdint.h>
#endif
#include <string.h>
#include "emyg_dtoa.h"
#define UINT64_C2(h, l) (((uint64_t )(h) << 32) | (uint64_t )(l))
typedef struct DiyFp_s {
uint64_t f;
int e;
} DiyFp;
static const int kDiySignificandSize = 64;
static const int kDpSignificandSize = 52;
static const int kDpExponentBias = 0x3FF + 52 /* 0x3FF + kDpSignificandSize */;
static const int kDpMinExponent = -(0x3FF + 52) /* -kDpExponentBias */;
static const uint64_t kDpExponentMask = UINT64_C2(0x7FF00000, 0x00000000);
static const uint64_t kDpSignificandMask = UINT64_C2(0x000FFFFF, 0xFFFFFFFF);
static const uint64_t kDpHiddenBit = UINT64_C2(0x00100000, 0x00000000);
static inline DiyFp DiyFp_from_parts (uint64_t f, int e) {
DiyFp fp;
fp.f = f;
fp.e = e;
return fp;
}
DiyFp DiyFp_from_double (double d) {
union {
double d;
uint64_t u64;
} u = { d };
DiyFp res;
int biased_e = (u.u64 & kDpExponentMask) >> kDpSignificandSize;
uint64_t significand = (u.u64 & kDpSignificandMask);
if (biased_e != 0) {
res.f = significand + kDpHiddenBit;
res.e = biased_e - kDpExponentBias;
}
else {
res.f = significand;
res.e = kDpMinExponent + 1;
}
return res;
}
static inline DiyFp DiyFp_subtract (const DiyFp lhs, const DiyFp rhs) {
assert(lhs.e == rhs.e);
assert(lhs.f >= rhs.f);
return DiyFp_from_parts(lhs.f - rhs.f, lhs.e);
}
static inline DiyFp DiyFp_multiply (const DiyFp lhs, const DiyFp rhs) {
#if defined(_MSC_VER) && defined(_M_AMD64)
uint64_t h;
uint64_t l = _umul128(lhs.f, rhs.f, &h);
if (l & (uint64_t(1) << 63)) // rounding
h++;
return DiyFp_fro_parts(h, lhs.e + rhs.e + 64);
#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
unsigned __int128 p = (unsigned __int128 )(lhs.f) * (unsigned __int128 )(rhs.f);
uint64_t h = p >> 64;
uint64_t l = (uint64_t )(p);
if (l & (((uint64_t )1) << 63)) // rounding
h++;
return DiyFp_from_parts(h, lhs.e + rhs.e + 64);
#else
const uint64_t M32 = 0xFFFFFFFF;
const uint64_t a = lhs.f >> 32;
const uint64_t b = lhs.f & M32;
const uint64_t c = rhs.f >> 32;
const uint64_t d = rhs.f & M32;
const uint64_t ac = a * c;
const uint64_t bc = b * c;
const uint64_t ad = a * d;
const uint64_t bd = b * d;
uint64_t tmp = (bd >> 32) + (ad & M32) + (bc & M32);
tmp += 1U << 31; /// mult_round
return DiyFp_from_parts(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32), lhs.e + rhs.e + 64);
#endif
}
static inline DiyFp Normalize (const DiyFp lhs) {
#if defined(_MSC_VER) && defined(_M_AMD64)
unsigned long index;
_BitScanReverse64(&index, lhs.f);
return DiyFp_from_parts(lhs.f << (63 - index), lhs.e - (63 - index));
#elif defined(__GNUC__)
int s = __builtin_clzll(lhs.f);
return DiyFp_from_parts(lhs.f << s, lhs.e - s);
#else
DiyFp res = lhs;
while (!(res.f & kDpHiddenBit)) {
res.f <<= 1;
res.e--;
}
res.f <<= (kDiySignificandSize - kDpSignificandSize - 1);
res.e = res.e - (kDiySignificandSize - kDpSignificandSize - 1);
return res;
#endif
}
static inline DiyFp NormalizeBoundary (const DiyFp lhs) {
#if defined(_MSC_VER) && defined(_M_AMD64)
unsigned long index;
_BitScanReverse64(&index, lhs.f);
return DiyFp_from_parts(lhs.f << (63 - index), lhs.e - (63 - index));
#else
DiyFp res = lhs;
while (!(res.f & (kDpHiddenBit << 1))) {
res.f <<= 1;
res.e--;
}
res.f <<= (kDiySignificandSize - kDpSignificandSize - 2);
res.e = res.e - (kDiySignificandSize - kDpSignificandSize - 2);
return res;
#endif
}
static inline void NormalizedBoundaries (DiyFp lhs, DiyFp* minus, DiyFp* plus) {
DiyFp pl = NormalizeBoundary(DiyFp_from_parts((lhs.f << 1) + 1, lhs.e - 1));
DiyFp mi = (lhs.f == kDpHiddenBit)
? DiyFp_from_parts((lhs.f << 2) - 1, lhs.e - 2)
: DiyFp_from_parts((lhs.f << 1) - 1, lhs.e - 1);
mi.f <<= mi.e - pl.e;
mi.e = pl.e;
*plus = pl;
*minus = mi;
}
static inline DiyFp GetCachedPower (int e, int* K) {
// 10^-348, 10^-340, ..., 10^340
static const uint64_t kCachedPowers_F[] = {
UINT64_C2(0xfa8fd5a0, 0x081c0288), UINT64_C2(0xbaaee17f, 0xa23ebf76),
UINT64_C2(0x8b16fb20, 0x3055ac76), UINT64_C2(0xcf42894a, 0x5dce35ea),
UINT64_C2(0x9a6bb0aa, 0x55653b2d), UINT64_C2(0xe61acf03, 0x3d1a45df),
UINT64_C2(0xab70fe17, 0xc79ac6ca), UINT64_C2(0xff77b1fc, 0xbebcdc4f),
UINT64_C2(0xbe5691ef, 0x416bd60c), UINT64_C2(0x8dd01fad, 0x907ffc3c),
UINT64_C2(0xd3515c28, 0x31559a83), UINT64_C2(0x9d71ac8f, 0xada6c9b5),
UINT64_C2(0xea9c2277, 0x23ee8bcb), UINT64_C2(0xaecc4991, 0x4078536d),
UINT64_C2(0x823c1279, 0x5db6ce57), UINT64_C2(0xc2109436, 0x4dfb5637),
UINT64_C2(0x9096ea6f, 0x3848984f), UINT64_C2(0xd77485cb, 0x25823ac7),
UINT64_C2(0xa086cfcd, 0x97bf97f4), UINT64_C2(0xef340a98, 0x172aace5),
UINT64_C2(0xb23867fb, 0x2a35b28e), UINT64_C2(0x84c8d4df, 0xd2c63f3b),
UINT64_C2(0xc5dd4427, 0x1ad3cdba), UINT64_C2(0x936b9fce, 0xbb25c996),
UINT64_C2(0xdbac6c24, 0x7d62a584), UINT64_C2(0xa3ab6658, 0x0d5fdaf6),
UINT64_C2(0xf3e2f893, 0xdec3f126), UINT64_C2(0xb5b5ada8, 0xaaff80b8),
UINT64_C2(0x87625f05, 0x6c7c4a8b), UINT64_C2(0xc9bcff60, 0x34c13053),
UINT64_C2(0x964e858c, 0x91ba2655), UINT64_C2(0xdff97724, 0x70297ebd),
UINT64_C2(0xa6dfbd9f, 0xb8e5b88f), UINT64_C2(0xf8a95fcf, 0x88747d94),
UINT64_C2(0xb9447093, 0x8fa89bcf), UINT64_C2(0x8a08f0f8, 0xbf0f156b),
UINT64_C2(0xcdb02555, 0x653131b6), UINT64_C2(0x993fe2c6, 0xd07b7fac),
UINT64_C2(0xe45c10c4, 0x2a2b3b06), UINT64_C2(0xaa242499, 0x697392d3),
UINT64_C2(0xfd87b5f2, 0x8300ca0e), UINT64_C2(0xbce50864, 0x92111aeb),
UINT64_C2(0x8cbccc09, 0x6f5088cc), UINT64_C2(0xd1b71758, 0xe219652c),
UINT64_C2(0x9c400000, 0x00000000), UINT64_C2(0xe8d4a510, 0x00000000),
UINT64_C2(0xad78ebc5, 0xac620000), UINT64_C2(0x813f3978, 0xf8940984),
UINT64_C2(0xc097ce7b, 0xc90715b3), UINT64_C2(0x8f7e32ce, 0x7bea5c70),
UINT64_C2(0xd5d238a4, 0xabe98068), UINT64_C2(0x9f4f2726, 0x179a2245),
UINT64_C2(0xed63a231, 0xd4c4fb27), UINT64_C2(0xb0de6538, 0x8cc8ada8),
UINT64_C2(0x83c7088e, 0x1aab65db), UINT64_C2(0xc45d1df9, 0x42711d9a),
UINT64_C2(0x924d692c, 0xa61be758), UINT64_C2(0xda01ee64, 0x1a708dea),
UINT64_C2(0xa26da399, 0x9aef774a), UINT64_C2(0xf209787b, 0xb47d6b85),
UINT64_C2(0xb454e4a1, 0x79dd1877), UINT64_C2(0x865b8692, 0x5b9bc5c2),
UINT64_C2(0xc83553c5, 0xc8965d3d), UINT64_C2(0x952ab45c, 0xfa97a0b3),
UINT64_C2(0xde469fbd, 0x99a05fe3), UINT64_C2(0xa59bc234, 0xdb398c25),
UINT64_C2(0xf6c69a72, 0xa3989f5c), UINT64_C2(0xb7dcbf53, 0x54e9bece),
UINT64_C2(0x88fcf317, 0xf22241e2), UINT64_C2(0xcc20ce9b, 0xd35c78a5),
UINT64_C2(0x98165af3, 0x7b2153df), UINT64_C2(0xe2a0b5dc, 0x971f303a),
UINT64_C2(0xa8d9d153, 0x5ce3b396), UINT64_C2(0xfb9b7cd9, 0xa4a7443c),
UINT64_C2(0xbb764c4c, 0xa7a44410), UINT64_C2(0x8bab8eef, 0xb6409c1a),
UINT64_C2(0xd01fef10, 0xa657842c), UINT64_C2(0x9b10a4e5, 0xe9913129),
UINT64_C2(0xe7109bfb, 0xa19c0c9d), UINT64_C2(0xac2820d9, 0x623bf429),
UINT64_C2(0x80444b5e, 0x7aa7cf85), UINT64_C2(0xbf21e440, 0x03acdd2d),
UINT64_C2(0x8e679c2f, 0x5e44ff8f), UINT64_C2(0xd433179d, 0x9c8cb841),
UINT64_C2(0x9e19db92, 0xb4e31ba9), UINT64_C2(0xeb96bf6e, 0xbadf77d9),
UINT64_C2(0xaf87023b, 0x9bf0ee6b)
};
static const int16_t kCachedPowers_E[] = {
-1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980,
-954, -927, -901, -874, -847, -821, -794, -768, -741, -715,
-688, -661, -635, -608, -582, -555, -529, -502, -475, -449,
-422, -396, -369, -343, -316, -289, -263, -236, -210, -183,
-157, -130, -103, -77, -50, -24, 3, 30, 56, 83,
109, 136, 162, 189, 216, 242, 269, 295, 322, 348,
375, 402, 428, 455, 481, 508, 534, 561, 588, 614,
641, 667, 694, 720, 747, 774, 800, 827, 853, 880,
907, 933, 960, 986, 1013, 1039, 1066
};
//int k = (int )(ceil((-61 - e) * 0.30102999566398114)) + 374;
double dk = (-61 - e) * 0.30102999566398114 + 347; // dk must be positive, so can do ceiling in positive
int k = (int )(dk);
if (k != dk)
k++;
unsigned index = (unsigned )((k >> 3) + 1);
*K = -(-348 + (int )(index << 3)); // decimal exponent no need lookup table
assert(index < sizeof(kCachedPowers_F) / sizeof(kCachedPowers_F[0]));
return DiyFp_from_parts(kCachedPowers_F[index], kCachedPowers_E[index]);
}
static inline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w) {
while (rest < wp_w && delta - rest >= ten_kappa &&
(rest + ten_kappa < wp_w || /// closer
wp_w - rest > rest + ten_kappa - wp_w)) {
buffer[len - 1]--;
rest += ten_kappa;
}
}
static inline unsigned CountDecimalDigit32(uint32_t n) {
// Simple pure C++ implementation was faster than __builtin_clz version in this situation.
if (n < 10) return 1;
if (n < 100) return 2;
if (n < 1000) return 3;
if (n < 10000) return 4;
if (n < 100000) return 5;
if (n < 1000000) return 6;
if (n < 10000000) return 7;
if (n < 100000000) return 8;
if (n < 1000000000) return 9;
return 10;
}
static inline void DigitGen(const DiyFp W, const DiyFp Mp, uint64_t delta, char* buffer, int* len, int* K) {
static const uint32_t kPow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
const DiyFp one = DiyFp_from_parts((uint64_t )(1) << -Mp.e, Mp.e);
const DiyFp wp_w = DiyFp_subtract(Mp, W);
uint32_t p1 = (uint32_t )(Mp.f >> -one.e);
uint64_t p2 = Mp.f & (one.f - 1);
int kappa = (int )(CountDecimalDigit32(p1));
*len = 0;
while (kappa > 0) {
uint32_t d;
switch (kappa) {
case 10: d = p1 / 1000000000; p1 %= 1000000000; break;
case 9: d = p1 / 100000000; p1 %= 100000000; break;
case 8: d = p1 / 10000000; p1 %= 10000000; break;
case 7: d = p1 / 1000000; p1 %= 1000000; break;
case 6: d = p1 / 100000; p1 %= 100000; break;
case 5: d = p1 / 10000; p1 %= 10000; break;
case 4: d = p1 / 1000; p1 %= 1000; break;
case 3: d = p1 / 100; p1 %= 100; break;
case 2: d = p1 / 10; p1 %= 10; break;
case 1: d = p1; p1 = 0; break;
default:
#if defined(_MSC_VER)
__assume(0);
#elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
__builtin_unreachable();
#else
d = 0;
#endif
}
if (d || *len)
buffer[(*len)++] = '0' + (char )(d);
kappa--;
uint64_t tmp = ((uint64_t )(p1) << -one.e) + p2;
if (tmp <= delta) {
*K += kappa;
GrisuRound(buffer, *len, delta, tmp, (uint64_t )(kPow10[kappa]) << -one.e, wp_w.f);
return;
}
}
// kappa = 0
for (;;) {
p2 *= 10;
delta *= 10;
char d = (char )(p2 >> -one.e);
if (d || *len)
buffer[(*len)++] = '0' + d;
p2 &= one.f - 1;
kappa--;
if (p2 < delta) {
*K += kappa;
GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * kPow10[-kappa]);
return;
}
}
}
static inline void Grisu2(double value, char* buffer, int* length, int* K) {
const DiyFp v = DiyFp_from_double(value);
DiyFp w_m, w_p;
NormalizedBoundaries(v, &w_m, &w_p);
const DiyFp c_mk = GetCachedPower(w_p.e, K);
const DiyFp W = DiyFp_multiply(Normalize(v), c_mk);
DiyFp Wp = DiyFp_multiply(w_p, c_mk);
DiyFp Wm = DiyFp_multiply(w_m, c_mk);
Wm.f++;
Wp.f--;
DigitGen(W, Wp, Wp.f - Wm.f, buffer, length, K);
}
static inline const char* GetDigitsLut() {
static const char cDigitsLut[200] = {
'0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7', '0', '8', '0', '9',
'1', '0', '1', '1', '1', '2', '1', '3', '1', '4', '1', '5', '1', '6', '1', '7', '1', '8', '1', '9',
'2', '0', '2', '1', '2', '2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7', '2', '8', '2', '9',
'3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3', '7', '3', '8', '3', '9',
'4', '0', '4', '1', '4', '2', '4', '3', '4', '4', '4', '5', '4', '6', '4', '7', '4', '8', '4', '9',
'5', '0', '5', '1', '5', '2', '5', '3', '5', '4', '5', '5', '5', '6', '5', '7', '5', '8', '5', '9',
'6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6', '7', '6', '8', '6', '9',
'7', '0', '7', '1', '7', '2', '7', '3', '7', '4', '7', '5', '7', '6', '7', '7', '7', '8', '7', '9',
'8', '0', '8', '1', '8', '2', '8', '3', '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9',
'9', '0', '9', '1', '9', '2', '9', '3', '9', '4', '9', '5', '9', '6', '9', '7', '9', '8', '9', '9'
};
return cDigitsLut;
}
static inline void WriteExponent(int K, char* buffer) {
if (K < 0) {
*buffer++ = '-';
K = -K;
}
if (K >= 100) {
*buffer++ = '0' + (char )(K / 100);
K %= 100;
const char* d = GetDigitsLut() + K * 2;
*buffer++ = d[0];
*buffer++ = d[1];
}
else if (K >= 10) {
const char* d = GetDigitsLut() + K * 2;
*buffer++ = d[0];
*buffer++ = d[1];
}
else
*buffer++ = '0' + (char )(K);
*buffer = '\0';
}
static inline void Prettify(char* buffer, int length, int k) {
const int kk = length + k; // 10^(kk-1) <= v < 10^kk
if (length <= kk && kk <= 21) {
// 1234e7 -> 12340000000
int i;
for (i = length; i < kk; i++)
buffer[i] = '0';
buffer[kk] = '.';
buffer[kk + 1] = '0';
buffer[kk + 2] = '\0';
}
else if (0 < kk && kk <= 21) {
// 1234e-2 -> 12.34
memmove(&buffer[kk + 1], &buffer[kk], length - kk);
buffer[kk] = '.';
buffer[length + 1] = '\0';
}
else if (-6 < kk && kk <= 0) {
// 1234e-6 -> 0.001234
int i;
const int offset = 2 - kk;
memmove(&buffer[offset], &buffer[0], length);
buffer[0] = '0';
buffer[1] = '.';
for (i = 2; i < offset; i++)
buffer[i] = '0';
buffer[length + offset] = '\0';
}
else if (length == 1) {
// 1e30
buffer[1] = 'e';
WriteExponent(kk - 1, &buffer[2]);
}
else {
// 1234e30 -> 1.234e33
memmove(&buffer[2], &buffer[1], length - 1);
buffer[1] = '.';
buffer[length + 1] = 'e';
WriteExponent(kk - 1, &buffer[0 + length + 2]);
}
}
void emyg_dtoa (double value, char* buffer) {
// Not handling NaN and inf
assert(!isnan(value));
assert(!isinf(value));
if (value == 0) {
buffer[0] = '0';
buffer[1] = '.';
buffer[2] = '0';
buffer[3] = '\0';
}
else {
if (value < 0) {
*buffer++ = '-';
value = -value;
}
int length, K;
Grisu2(value, buffer, &length, &K);
Prettify(buffer, length, K);
}
}

View File

@ -0,0 +1,12 @@
/* emyg_dtoa.h */
#ifdef __cplusplus
extern "C" {
#endif
void emyg_dtoa (double value, char *buffer);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,735 @@
/* emyg_pow5.h */
/* This isn't really a header file, but we keep it in a separate file
** to support alternate implementations, and because it's big.
** It has be a .h (rather than a .c) file to avoid fooling premake4
** into building into the image twice.
*/
#ifndef MAX_POW5_IN_TABLE
#define MAX_POW5_IN_TABLE 345u
/* These are powers of 5 with 32-bit digits in little endian format */
/* generated using (pow5c 345) from testgen.scm */
static const uint32_t pow5[] = {
1u,
5u,
25u,
125u,
625u,
3125u,
15625u,
78125u,
390625u,
1953125u,
9765625u,
48828125u,
244140625u,
1220703125u,
1808548329u, 1u,
452807053u, 7u,
2264035265u, 35u,
2730241733u, 177u,
766306777u, 888u,
3831533885u, 4440u,
1977800241u, 22204u,
1299066613u, 111022u,
2200365769u, 555111u,
2411894253u, 2775557u,
3469536673u, 13877787u,
167814181u, 69388939u,
839070905u, 346944695u,
4195354525u, 1734723475u,
3796903441u, 83682787u, 2u,
1804648021u, 418413939u, 10u,
433305513u, 2092069697u, 50u,
2166527565u, 1870413893u, 252u,
2242703233u, 762134875u, 1262u,
2623581573u, 3810674377u, 6310u,
233005977u, 1873502704u, 31554u,
1165029885u, 777578928u, 157772u,
1530182129u, 3887894641u, 788860u,
3355943349u, 2259604022u, 3944304u,
3894814857u, 2708085521u, 19721522u,
2294205101u, 655525721u, 98607613u,
2881090913u, 3277628607u, 493038065u,
1520552677u, 3503241150u, 2465190328u,
3307796089u, 336336567u, 3736017052u, 2u,
3654078557u, 1681682838u, 1500216076u, 14u,
1090523601u, 4113446898u, 3206113085u, 71u,
1157650709u, 3387365307u, 3145663541u, 358u,
1493286249u, 4051924648u, 2843415820u, 1793u,
3171463949u, 3079754057u, 1332177216u, 8968u,
2972417857u, 2513868400u, 2365918787u, 44841u,
1977187397u, 3979407411u, 3239659345u, 224207u,
1296002393u, 2717167873u, 3313394841u, 1121038u,
2185044669u, 700937478u, 3682072320u, 5605193u,
2335288753u, 3504687392u, 1230492416u, 28025969u,
3086509173u, 343567778u, 1857494788u, 140129846u,
2547643977u, 1717838893u, 697539348u, 700649232u,
4148285293u, 4294227171u, 3487696741u, 3503246160u,
3561557281u, 4291266675u, 258614525u, 336361620u, 4u,
627917221u, 4276464195u, 1293072629u, 1681808100u, 20u,
3139586105u, 4202451791u, 2170395853u, 4114073205u, 101u,
2813028637u, 3832389774u, 2262044677u, 3390496843u, 509u,
1180241297u, 1982079689u, 2720288797u, 4067582329u, 2548u,
1606239189u, 1320463854u, 716542099u, 3158042464u, 12744u,
3736228649u, 2307351975u, 3582710496u, 2905310432u, 63723u,
1501274061u, 2946825287u, 733683298u, 1641650276u, 318618u,
3211403009u, 1849224548u, 3668416493u, 3913284084u, 1593091u,
3172113157u, 656188151u, 1162213283u, 2386551240u, 7965459u,
2975663897u, 3280940758u, 1516099119u, 3342821609u, 39827297u,
1993417597u, 3519801905u, 3285528302u, 3829206158u, 199136488u,
1377153393u, 419140343u, 3542739626u, 1966161609u, 995682444u,
2590799669u, 2095701716u, 533828946u, 1240873457u, 683444926u, 1u,
69096457u, 1888573991u, 2669144732u, 1909399989u, 3417224631u, 5u,
345482285u, 852935363u, 460821774u, 957065356u, 4201221269u, 28u,
1727411425u, 4264676815u, 2304108870u, 490359484u, 3826237162u, 144u,
47122533u, 4143514893u, 2930609762u, 2451797422u, 1951316626u, 724u,
235612665u, 3537705281u, 1768146926u, 3669052521u, 1166648540u, 3622u,
1178063325u, 508657221u, 250800042u, 1165393423u, 1538275408u, 18111u,
1595349329u, 2543286106u, 1254000210u, 1531999819u, 3396409745u, 90556u,
3681779349u, 4126495939u, 1975033756u, 3365031800u, 4097146838u, 452783u,
1229027561u, 3452610515u, 1285234192u, 3940257114u, 3305865009u, 2263919u,
1850170509u, 83183392u, 2131203668u, 2521416387u, 3644423161u, 11319598u,
660917953u, 415916962u, 2066083748u, 4017147345u, 1042246623u, 56597994u,
3304589765u, 2079584810u, 1740484148u, 2905867543u, 916265823u, 282989971u,
3638046937u, 1807989461u, 112486150u, 1644435829u, 286361822u, 1414949856u,
1010365501u, 450012717u, 562430752u, 3927211849u, 1431809111u, 2779781984u, 1u,
756860209u, 2250063586u, 2812153760u, 2456190061u, 2864078263u, 1014008033u, 8u,
3784301045u, 2660383338u, 1175866914u, 3691015716u, 1435489429u, 775072872u, 41u,
1741636041u, 417014806u, 1584367277u, 1275209397u, 2882479853u, 3875364361u, 205u,
118245613u, 2085074032u, 3626869089u, 2081079690u, 1527497378u, 2196952624u, 1029u,
591228065u, 1835435568u, 954476263u, 1815463862u, 3342519596u, 2394828529u, 5147u,
2956140325u, 587243248u, 477414021u, 487384719u, 3827696094u, 3384208056u, 25737u,
1895799737u, 2936216243u, 2387070105u, 2436923595u, 1958611286u, 4036138396u, 128688u,
889064093u, 1796179329u, 3345415936u, 3594683385u, 1203121840u, 3000822798u, 643444u,
150353169u, 390962054u, 3842177794u, 793547744u, 1720641908u, 2119212103u, 3217223u,
751765845u, 1954810270u, 2031019786u, 3967738724u, 13274948u, 2006125925u, 16086117u,
3758829225u, 1184116758u, 1565164340u, 2658824438u, 66374744u, 1440695033u, 80430587u,
1614276941u, 1625616498u, 3530854405u, 409220303u, 331873723u, 2908507869u, 402152936u,
3776417409u, 3833115195u, 474402842u, 2046101519u, 1659368615u, 1657637457u, 2010764683u,
1702217861u, 1985706795u, 2372014214u, 1640573003u, 4001875781u, 3993219990u, 1463888824u, 2u,
4216122009u, 1338599384u, 3270136480u, 3907897721u, 2829509722u, 2786230770u, 3024476828u, 11u,
3900740861u, 2398029628u, 3465780513u, 2359619424u, 1262646726u, 1046251965u, 2237482255u, 58u,
2323835121u, 3400213552u, 149033383u, 3208162532u, 2018266336u, 936292530u, 2597476684u, 292u,
3029241013u, 4116165874u, 745166918u, 3155910772u, 1501397091u, 386495356u, 102481533u, 1463u,
2261303177u, 3400960189u, 3725834594u, 2894651972u, 3212018162u, 1932476781u, 512407665u, 7315u,
2716581293u, 4119899059u, 1449303789u, 1588357976u, 3175188925u, 1072449316u, 2562038327u, 36575u,
698004577u, 3419626114u, 2951551653u, 3646822585u, 2991042738u, 1067279287u, 4220257044u, 182877u,
3490022885u, 4213228682u, 1872856380u, 1054243744u, 2070311806u, 1041429142u, 3921416037u, 914389u,
270245241u, 3886274230u, 774347312u, 976251426u, 1761624439u, 912178416u, 2427211002u, 4571949u,
1351226205u, 2251501966u, 3871736564u, 586289834u, 218187604u, 265924786u, 3546120419u, 22859747u,
2461163729u, 2667575239u, 2178813638u, 2931449174u, 1090938020u, 1329623930u, 550732911u, 114298739u,
3715884053u, 452974309u, 2304133601u, 1772343984u, 1159722807u, 2353152355u, 2753664556u, 571493695u,
1399551081u, 2264871549u, 2930733413u, 271785330u, 1503646741u, 3175827184u, 883420894u, 2857468478u,
2702788109u, 2734423154u, 1768765179u, 1358926653u, 3223266409u, 2994234033u, 122137177u, 1402440503u, 3u,
629038657u, 787213885u, 253891306u, 2499665971u, 3231430158u, 2086268280u, 610685888u, 2717235219u, 16u,
3145193285u, 3936069425u, 1269456530u, 3908395263u, 3272248904u, 1841406811u, 3053429442u, 701274207u, 83u,
2841064537u, 2500477944u, 2052315358u, 2362107132u, 3476342636u, 617099466u, 2382245324u, 3506371038u, 415u,
1320420797u, 3912455131u, 1671642200u, 3220601070u, 201843998u, 3085497334u, 3321292028u, 351986008u, 2079u,
2307136689u, 2382406472u, 4063243708u, 3218103463u, 1009219993u, 2542584782u, 3721558255u, 1759930043u, 10395u,
2945748853u, 3322097770u, 3136349358u, 3205615431u, 751132672u, 4122989319u, 1427922093u, 209715627u, 51977u,
1843842377u, 3725586965u, 2796844905u, 3143175270u, 3755663363u, 3435077411u, 2844643173u, 1048578136u, 259885u,
629277293u, 1448065643u, 1099322641u, 2830974465u, 1598447634u, 4290485171u, 1338313980u, 947923387u, 1299426u,
3146386465u, 2945360919u, 1201645910u, 1269970438u, 3697270877u, 4272556672u, 2396602608u, 444649640u, 6497131u,
2847030437u, 1841902710u, 1713262257u, 2054884895u, 1306485202u, 4182914180u, 3393078452u, 2223248202u, 32485655u,
1350250297u, 619578961u, 4271343991u, 1684489884u, 2237458716u, 3734701717u, 4080490376u, 2526306421u, 162428277u,
2456284189u, 3097894806u, 4176850771u, 4127482128u, 2597358989u, 1493639403u, 3222582700u, 4041597517u, 812141387u,
3691486353u, 2604572144u, 3704384674u, 3457541460u, 101893061u, 3173229722u, 3228011613u, 3028118404u, 4060706939u,
1277562581u, 137958836u, 1342054189u, 107838120u, 509465309u, 2981246722u, 3255156180u, 2255690135u, 3123665514u, 4u,
2092845609u, 689794181u, 2415303649u, 539190601u, 2547326545u, 2021331722u, 3390879015u, 2688516086u, 2733425684u, 23u,
1874293453u, 3448970907u, 3486583653u, 2695953007u, 4146698133u, 1516724020u, 4069493189u, 557678545u, 782226535u, 118u,
781532673u, 64985353u, 253049085u, 594863151u, 3553621484u, 3288652808u, 3167596762u, 2788392729u, 3911132675u, 590u,
3907663365u, 324926765u, 1265245425u, 2974315755u, 588238236u, 3558362156u, 2953081925u, 1057061760u, 2375794194u, 2954u,
2358447641u, 1624633829u, 2031259829u, 1986676888u, 2941191183u, 611941596u, 1880507741u, 990341507u, 3289036379u, 14772u,
3202303613u, 3828201851u, 1566364554u, 1343449850u, 1821054029u, 3059707983u, 812604113u, 656740241u, 3560280008u, 73863u,
3126616177u, 1961140074u, 3536855478u, 2422281955u, 515335554u, 2413638029u, 4063020568u, 3283701205u, 621530856u, 369319u,
2748178997u, 1215765781u, 504408208u, 3521475187u, 2576677772u, 3478255553u, 3135233658u, 3533604141u, 3107654283u, 1846595u,
855993097u, 1783861612u, 2522041041u, 427506751u, 4293454272u, 211408583u, 2791266406u, 488151524u, 2653369531u, 9232978u,
4279965485u, 329373468u, 4020270615u, 2137533757u, 4287402176u, 1057042919u, 1071430142u, 2440757623u, 381945767u, 46164893u,
4219958241u, 1646867344u, 2921483891u, 2097734197u, 4257141698u, 990247303u, 1062183415u, 3613853524u, 1909728837u, 230824465u,
3919922021u, 3939369428u, 1722517568u, 1898736396u, 4105839308u, 656269223u, 1015949780u, 889398437u, 958709597u, 1154122327u,
2419740921u, 2516977960u, 22653252u, 903747390u, 3349327358u, 3281346119u, 784781604u, 152024890u, 498580690u, 1475644340u, 1u,
3508770013u, 3994955210u, 113266262u, 223769654u, 3861734903u, 3521828710u, 3923908023u, 760124450u, 2492903450u, 3083254404u, 6u,
363980881u, 2794906870u, 566331314u, 1118848270u, 2128805331u, 429274370u, 2439670935u, 3800622254u, 3874582658u, 2531370134u, 33u,
1819904405u, 1089632462u, 2831656573u, 1299274054u, 2054092064u, 2146371852u, 3608420083u, 1823242088u, 2193044110u, 4066916082u, 167u,
509587433u, 1153195016u, 1273380978u, 2201402977u, 1680525729u, 2141924670u, 862231233u, 526275852u, 2375285960u, 3154711228u, 839u,
2547937165u, 1471007784u, 2071937595u, 2417080294u, 4107661351u, 2119688759u, 16188871u, 2631379261u, 3286495208u, 2888654254u, 4198u,
4149751233u, 3060071626u, 1769753384u, 3495466880u, 3358437573u, 2008509207u, 80944357u, 271994417u, 3547574155u, 1558369385u, 20993u,
3568886981u, 2415456246u, 258832331u, 297465218u, 3907285981u, 1452611446u, 404721787u, 1359972085u, 558001591u, 3496879633u, 104966u,
664565721u, 3487346642u, 1294161657u, 1487326090u, 2356560721u, 2968089938u, 2023608936u, 2504893129u, 2790007956u, 304528981u, 524834u,
3322828605u, 256864026u, 2175840993u, 3141663155u, 3192869014u, 1955547804u, 1528110091u, 3934531055u, 1065137894u, 1522644908u, 2624170u,
3729241137u, 1284320133u, 2289270373u, 2823413889u, 3079443185u, 1187804431u, 3345583161u, 2492786092u, 1030722178u, 3318257245u, 13120851u,
1466336501u, 2126633373u, 2856417274u, 1232167559u, 2512314040u, 1644054862u, 3843013918u, 3873995871u, 858643596u, 3706384338u, 65604258u,
3036715209u, 2043232274u, 1397184484u, 1865870502u, 3971635609u, 3925307016u, 2035200407u, 2190110175u, 4293217984u, 1352052506u, 328021294u,
2298674157u, 1626226781u, 2690955126u, 739417919u, 2678308863u, 2446665900u, 1586067447u, 2360616285u, 4286220738u, 2465295238u, 1640106471u,
2903436193u, 3836166611u, 569873743u, 3697089598u, 506642427u, 3643394911u, 3635369941u, 3213146834u, 4251234508u, 3736541602u, 3905565061u, 1u,
1632279077u, 2000963874u, 2849368719u, 1305578806u, 2533212139u, 1037105371u, 996980525u, 3180832286u, 4076303359u, 1502838830u, 2347956125u, 9u,
3866428089u, 1414884779u, 1361941709u, 2232926737u, 4076126104u, 890559561u, 689935330u, 3019259543u, 3201647614u, 3219226858u, 3149846034u, 47u,
2152271261u, 2779456603u, 2514741250u, 2574699094u, 3200761338u, 157830513u, 3449676651u, 2211395827u, 3123336185u, 3211232405u, 2864328285u, 238u,
2171421713u, 1012381129u, 3983771661u, 4283560880u, 3118904804u, 789152568u, 68514071u, 2467044547u, 2731779039u, 3171260140u, 1436739540u, 1193u,
2267173973u, 766938351u, 2738989122u, 4237935220u, 2709622136u, 3945762843u, 342570355u, 3745288143u, 773993309u, 2971398815u, 2888730407u, 5966u,
2745935273u, 3834691757u, 810043722u, 4009806919u, 663208796u, 2548945034u, 1712851779u, 1546571531u, 3869966549u, 1972092187u, 1558750150u, 29833u,
844774477u, 1993589604u, 4050218614u, 2869165411u, 3316043984u, 4154790578u, 4269291601u, 3437890360u, 2169963562u, 1270526347u, 3498783456u, 149166u,
4223872385u, 1378013428u, 3071223888u, 1460925171u, 3695318035u, 3594083709u, 4166588825u, 9582620u, 2259883222u, 2057664441u, 314048097u, 745834u,
3939492741u, 2595099848u, 2471217553u, 3009658562u, 1296720992u, 790549365u, 3653074945u, 47913104u, 2709481518u, 1698387615u, 1570240487u, 3729170u,
2517594521u, 90597356u, 3766153176u, 2163390924u, 2188637667u, 3952746826u, 1085505541u, 239565524u, 662505702u, 4196970782u, 3556235140u, 18645851u,
3998038013u, 452986782u, 1650896696u, 2227020032u, 2353253745u, 2583864948u, 1132560413u, 1197827621u, 3312528510u, 3804984726u, 601306520u, 93229259u,
2810320881u, 2264933914u, 3959516184u, 2545165569u, 3176334135u, 34422854u, 1367834772u, 1694170810u, 3677740663u, 1845054449u, 3006532604u, 466146295u,
1166702517u, 2734734981u, 2617711738u, 4135893257u, 2996768789u, 172114273u, 2544206564u, 4175886755u, 1208834132u, 635337657u, 2147761134u, 2330731478u,
1538545289u, 788773018u, 203656805u, 3499597104u, 2098942061u, 860571368u, 4131098228u, 3699564593u, 1749203368u, 3176688286u, 2148871078u, 3063722800u, 2u,
3397759149u, 3943865091u, 1018284025u, 318116336u, 1904775717u, 7889546u, 3475621957u, 1317953785u, 156082252u, 2998539544u, 2154420801u, 2433712114u, 13u,
4103893857u, 2539456274u, 796452833u, 1590581681u, 933943993u, 39447732u, 198240601u, 2294801633u, 780411261u, 2107795832u, 2182169416u, 3578625980u, 67u,
3339600101u, 4107346782u, 3982264167u, 3657941109u, 374752670u, 197238661u, 991203005u, 2884073573u, 3902056307u, 1949044568u, 2320912490u, 713260718u, 339u,
3813098617u, 3356864729u, 2731451655u, 1109836365u, 1873763354u, 986193305u, 661047729u, 1535465978u, 2330412354u, 1155288252u, 3014627860u, 3566303592u, 1695u,
1885623901u, 3899421761u, 772356390u, 1254214532u, 778882179u, 635999231u, 3305238646u, 3382362594u, 3062127179u, 1481473966u, 2188237413u, 651648779u, 8479u,
838184913u, 2317239623u, 3861781954u, 1976105364u, 3894410896u, 3179996155u, 3641291342u, 4026911085u, 2425734010u, 3112402537u, 2351252474u, 3258243897u, 42395u,
4190924565u, 2996263523u, 2129040588u, 1290592232u, 2292185298u, 3015078891u, 1026587529u, 2954686245u, 3538735462u, 2677110799u, 3166327781u, 3406317599u, 211978u,
3774753641u, 2096415731u, 2055268351u, 2157993866u, 2870991899u, 2190492569u, 837970352u, 1888529338u, 513808129u, 500652111u, 2946737020u, 4146686110u, 1059893u,
1693899021u, 1892144067u, 1686407165u, 2200034740u, 1470057609u, 2362528256u, 4189851762u, 852712098u, 2569040647u, 2503260555u, 1848783212u, 3553561369u, 5299469u,
4174527809u, 870785744u, 4137068531u, 2410239109u, 3055320751u, 3222706689u, 3769389628u, 4263560494u, 4255268643u, 3926368185u, 653981470u, 587937663u, 26497349u,
3692769861u, 58961428u, 3505473472u, 3461260957u, 2391701869u, 3228631560u, 1667078959u, 4137933290u, 4096474035u, 2451971745u, 3269907354u, 2939688315u, 132486745u,
1283980121u, 294807144u, 347498176u, 126435605u, 3368574757u, 3258255914u, 4040427502u, 3509797267u, 3302500995u, 3669924137u, 3464634884u, 1813539690u, 662433728u,
2124933309u, 1474035721u, 1737490880u, 632178025u, 3957971897u, 3406377685u, 3022268329u, 369117155u, 3627603091u, 1169751504u, 143305240u, 477763862u, 3312168642u,
2034731953u, 3075211311u, 97519809u, 3160890127u, 2609990301u, 4146986541u, 2226439760u, 1845585778u, 958146271u, 1553790228u, 716526201u, 2388819310u, 3675941322u, 3u,
1583725173u, 2491154669u, 487599048u, 2919548747u, 165049620u, 3555063524u, 2542264212u, 637994300u, 495764061u, 3473983845u, 3582631006u, 3354161958u, 1199837428u, 19u,
3623658569u, 3865838754u, 2437995242u, 1712841847u, 825248103u, 595448436u, 4121386472u, 3189971502u, 2478820305u, 190050041u, 733285850u, 3885907906u, 1704219847u, 96u,
938423661u, 2149324590u, 3600041622u, 4269241941u, 4126240516u, 2977242180u, 3427063176u, 3064955626u, 3804166936u, 950250207u, 3666429250u, 2249670346u, 4226131943u, 481u,
397151009u, 2156688359u, 820338928u, 4166340525u, 3451333400u, 2001309016u, 4250413995u, 2439876245u, 1840965499u, 456283743u, 1152277067u, 2658417142u, 3950790533u, 2409u,
1985755045u, 2193507203u, 4101694642u, 3651833441u, 76797820u, 1416610492u, 4072200793u, 3609446637u, 614892905u, 2281418717u, 1466418039u, 407183823u, 2574083484u, 12049u,
1338840633u, 2377601425u, 3328604028u, 1079298025u, 383989104u, 2788085164u, 3181134782u, 867364005u, 3074464529u, 2817158993u, 3037122901u, 2035919116u, 4280482828u, 60247u,
2399235869u, 3298072534u, 3758118254u, 1101522832u, 1919945521u, 1055523932u, 3020772025u, 41852732u, 2487420758u, 1200893080u, 2300712620u, 1589660991u, 4222544958u, 301239u,
3406244753u, 3605460784u, 1610722089u, 1212646868u, 1009793014u, 982652366u, 2218958238u, 209263663u, 3847169198u, 1709498106u, 2913628509u, 3653337661u, 3932855607u, 1506199u,
4146321877u, 847434739u, 3758643153u, 1768267045u, 753997775u, 618294535u, 2504856599u, 1046318317u, 2055976806u, 4252523238u, 1683240658u, 1086819124u, 2484408855u, 7530999u,
3551740201u, 4237173699u, 1613346581u, 251400637u, 3769988877u, 3091472675u, 3934348403u, 936624291u, 1689949439u, 4082747008u, 4121235998u, 1139128325u, 3832109684u, 37654997u,
578831821u, 4005999315u, 3771765613u, 1257003186u, 1670075201u, 2572461491u, 2491872834u, 388154163u, 4154779900u, 3233865857u, 3426310810u, 1400674333u, 1980679237u, 188274989u,
2894159105u, 2850127391u, 1678958885u, 1990048638u, 4055408710u, 4272372864u, 3869429580u, 1940770817u, 3594030316u, 3284427401u, 4246652165u, 2708404372u, 1313461594u, 941374947u,
1585893637u, 1365735070u, 4099827132u, 1360308599u, 3097174368u, 4181995140u, 2167278720u, 1113919497u, 790282398u, 3537235121u, 4053391644u, 657119976u, 2272340677u, 411907440u, 1u,
3634500889u, 2533708055u, 3319266477u, 2506575703u, 2600969953u, 3730106519u, 2246459012u, 1274630191u, 3951411991u, 506306421u, 3087089040u, 3285599884u, 2771768793u, 2059537202u, 5u,
992635261u, 4078605687u, 3711430499u, 3942943926u, 119947879u, 1470663414u, 2642360472u, 2078183661u, 2577190772u, 2531532109u, 2550543312u, 3543097535u, 973942080u, 1707751421u, 27u,
668209009u, 3213159252u, 1377283315u, 2534850450u, 599739399u, 3058349774u, 326900473u, 1800983716u, 1051974u, 4067725956u, 4162781970u, 535618493u, 574743108u, 4243789810u, 136u,
3341045045u, 3180894372u, 2591449282u, 4084317659u, 2998696997u, 2406846982u, 1634502368u, 414983988u, 5259872u, 3158760596u, 3634040670u, 2678092469u, 2873715540u, 4039079866u, 684u,
3820323337u, 3019569975u, 72344525u, 3241719114u, 2108583101u, 3444300321u, 3877544546u, 2074919941u, 26299360u, 2908901092u, 990334169u, 505560461u, 1483675815u, 3015530149u, 3424u,
1921747501u, 2212947991u, 361722628u, 3323693682u, 1952980916u, 41632423u, 2207853550u, 1784665117u, 131496802u, 1659603572u, 656703552u, 2527802306u, 3123411779u, 2192748858u, 17123u,
1018802913u, 2474805365u, 1808613142u, 3733566522u, 1174969991u, 208162117u, 2449333158u, 333390995u, 657484012u, 4003050564u, 3283517761u, 4049076938u, 2732157009u, 2373809701u, 85617u,
799047269u, 3784092234u, 453131120u, 1487963428u, 1579882663u, 1040810586u, 3656731198u, 1666954977u, 3287420060u, 2835383636u, 3532686921u, 3065515509u, 775883161u, 3279113916u, 428087u,
3995236345u, 1740591986u, 2265655604u, 3144849844u, 3604446020u, 909085635u, 1103786807u, 4039807593u, 3552198413u, 1292016295u, 483565424u, 2442675661u, 3879415808u, 3510667692u, 2140438u,
2796312541u, 113025342u, 2738343430u, 2839347334u, 842360919u, 250460883u, 1223966740u, 3019168782u, 581122885u, 2165114183u, 2417827121u, 3623443713u, 2217209858u, 373469280u, 10702194u,
1096660817u, 565126713u, 806815262u, 1311834785u, 4211804598u, 1252304415u, 1824866404u, 2210942023u, 2905614428u, 2235636323u, 3499201015u, 937349383u, 2496114702u, 1867346402u, 53510970u,
1188336789u, 2825633566u, 4034076310u, 2264206629u, 3879153807u, 1966554783u, 534397429u, 2464775525u, 1643170254u, 2588247026u, 316135893u, 391779623u, 3890638919u, 746797420u, 267554852u,
1646716649u, 1243265943u, 2990512369u, 2731098557u, 2215899853u, 1242839327u, 2671987147u, 3733943033u, 3920883976u, 56333243u, 1580679468u, 1958898115u, 2273325411u, 3733987104u, 1337774260u,
3938615949u, 1921362420u, 2067659958u, 770590900u, 2489564676u, 1919229341u, 475033848u, 1489845984u, 2424550700u, 281666219u, 3608430044u, 1204555984u, 2776692465u, 1490066338u, 2393904008u, 1u,
2513210561u, 1016877512u, 1748365200u, 3852954502u, 3857888788u, 1006212115u, 2375169242u, 3154262624u, 3532818909u, 1408331097u, 862281036u, 1727812628u, 998560438u, 3155364397u, 3379585449u, 7u,
3976118213u, 789420266u, 151891409u, 2084903328u, 2109574760u, 736093283u, 3285911619u, 2886411234u, 484225364u, 2746688193u, 16437885u, 49128549u, 697834896u, 2891920098u, 4013025360u, 38u,
2700721881u, 3947101334u, 759457045u, 1834582048u, 1957939210u, 3680466417u, 3544656207u, 1547154285u, 2421126823u, 848539077u, 82189428u, 245642745u, 3489174480u, 1574698602u, 2885257619u, 194u,
618707517u, 2555637489u, 3797285229u, 582975648u, 1199761460u, 1222462903u, 543411855u, 3440804133u, 3515699524u, 4242695387u, 410947140u, 1228213725u, 266003216u, 3578525718u, 1541386208u, 973u,
3093537585u, 4188252853u, 1806556963u, 2914878244u, 1703840004u, 1817347220u, 2717059276u, 24151481u, 398628440u, 4033607755u, 2054735704u, 1846101329u, 1330016081u, 712759406u, 3411963748u, 4866u,
2582786037u, 3761395084u, 442850227u, 1689489334u, 4224232727u, 496801509u, 700394494u, 120757408u, 1993142200u, 2988169591u, 1683743932u, 640572055u, 2355113111u, 3563797031u, 4174916852u, 24333u,
29028297u, 1627106239u, 2214251139u, 4152479374u, 3941294452u, 2484007549u, 3501972470u, 603787040u, 1375776408u, 2055946069u, 4123752367u, 3202860276u, 3185630963u, 639115973u, 3694715080u, 121669u,
145141485u, 3840563899u, 2481321104u, 3582527688u, 2526603080u, 3830103157u, 329993168u, 3018935204u, 2583914744u, 1689795754u, 3438892653u, 3129399496u, 3043252930u, 3195579868u, 1293706216u, 608349u,
725707425u, 2022950311u, 3816670932u, 732769258u, 4043080812u, 1970646603u, 1649965844u, 2209774132u, 34671835u, 4154011477u, 14594082u, 2762095596u, 2331362765u, 3092997455u, 2173563787u, 3041746u,
3628537125u, 1524816963u, 1903485478u, 3663846294u, 3035534876u, 1263298427u, 3954861926u, 2458936069u, 173359177u, 3590188201u, 72970414u, 925576092u, 3066879236u, 2580085389u, 2277884346u, 15208732u,
962816441u, 3329117523u, 927492799u, 1139362288u, 2292772496u, 2021524842u, 2594440447u, 3704745757u, 866795887u, 771071821u, 364852074u, 332913164u, 2449494293u, 15525060u, 2799487141u, 76043662u,
519114909u, 3760685728u, 342496702u, 1401844145u, 2873927889u, 1517689620u, 87300349u, 1343859604u, 39012143u, 3855359106u, 1824260370u, 1664565820u, 3657536873u, 77625302u, 1112533817u, 380218313u,
2595574545u, 1623559456u, 1712483514u, 2714253429u, 1484737558u, 3293480807u, 436501746u, 2424330724u, 195060716u, 2096926346u, 531367262u, 4027861806u, 1107815182u, 388126514u, 1267701789u, 1901091566u,
92970837u, 3822829987u, 4267450275u, 686365258u, 3128720497u, 3582502148u, 2182508733u, 3531719028u, 975303582u, 1894697138u, 2656836312u, 2959439846u, 1244108618u, 1940632571u, 2043541649u, 915523239u, 2u,
464854185u, 1934280751u, 4157382195u, 3431826294u, 2758700597u, 732641559u, 2322609077u, 478725958u, 581550618u, 883551099u, 399279674u, 1912297345u, 1925575797u, 1113228264u, 1627773655u, 282648901u, 11u,
2324270925u, 1081469163u, 3607041793u, 4274229586u, 908601100u, 3663207798u, 3023110793u, 2393629792u, 2907753090u, 122788199u, 1996398371u, 971552133u, 1037944395u, 1271174026u, 3843900980u, 1413244506u, 55u,
3031420033u, 1112378521u, 855339782u, 4191278750u, 248038208u, 1136169807u, 2230652081u, 3378214371u, 1653863564u, 613940998u, 1392057263u, 562793371u, 894754680u, 2060902835u, 2039635717u, 2771255238u, 276u,
2272198277u, 1266925312u, 4276698911u, 3776524566u, 1240191044u, 1385881739u, 2563325814u, 4006169969u, 3974350527u, 3069704991u, 2665319019u, 2813966856u, 178806104u, 1714579584u, 1608243995u, 971374304u, 1383u,
2771056793u, 2039659266u, 4203625372u, 1702753650u, 1905987928u, 2634441400u, 4226694479u, 2850980663u, 2691883455u, 2463623071u, 441693210u, 1184932395u, 894030523u, 4277930624u, 3746252680u, 561904225u, 6916u,
970382077u, 1608361741u, 3838257678u, 4218800958u, 940005049u, 287305114u, 3953603214u, 1370001431u, 574515390u, 3728180766u, 2208466052u, 1629694679u, 175185320u, 4209783937u, 1551394220u, 2809521129u, 34580u,
556943089u, 3746841410u, 2011419207u, 3914135610u, 405057953u, 1436525571u, 2588146886u, 2555039863u, 2872576951u, 1461034646u, 2452395672u, 3853506101u, 875926601u, 3869050501u, 3462003808u, 1162703758u, 172903u,
2784715445u, 1554337866u, 1467161447u, 2390808868u, 2025289769u, 2887660559u, 55832543u, 4185264726u, 1477982869u, 3010205937u, 3672043769u, 2087661323u, 84665713u, 2165383322u, 130149860u, 1518551498u, 864516u,
1038675337u, 3476722037u, 3040839940u, 3364109749u, 1536514255u, 1553400909u, 279162718u, 3746454446u, 3094947053u, 2166127798u, 1180349664u, 1848372027u, 423328567u, 2236982018u, 650749302u, 3297790194u, 4322581u,
898409389u, 203741002u, 2319297816u, 3935646860u, 3387603982u, 3472037250u, 1395813591u, 1552403046u, 2589833381u, 2240704401u, 1606781026u, 651925544u, 2116642837u, 2594975498u, 3253746512u, 3604049082u, 21612908u,
197079649u, 1018705011u, 3006554488u, 2498365118u, 4053118026u, 180317069u, 2684100663u, 3467047935u, 64265018u, 2613587416u, 3738937836u, 3259627721u, 1993279593u, 89975604u, 3383830675u, 840376229u, 108064544u,
985398245u, 798557759u, 2147870553u, 3901891001u, 3085720948u, 901585349u, 535601427u, 155370494u, 321325094u, 183035192u, 1514819999u, 3413236721u, 1376463376u, 449878022u, 4034251487u, 4201881148u, 540322720u,
632023929u, 3992788796u, 2149418173u, 2329585823u, 2543702856u, 212959452u, 2678007136u, 776852470u, 1606625470u, 915175960u, 3279132699u, 4181281718u, 2587349587u, 2249390111u, 2991388251u, 3829536560u, 2701613604u,
3160119645u, 2784074796u, 2157156277u, 3057994525u, 4128579690u, 1064797262u, 505133792u, 3884262353u, 3738160054u, 280912505u, 3510761608u, 3726539409u, 51846051u, 2657015966u, 2072039369u, 1967813619u, 623166136u, 3u,
2915696337u, 1035472095u, 2195846796u, 2405070739u, 3463029269u, 1029019018u, 2525668961u, 2241442581u, 1510931090u, 1404562529u, 373938856u, 1452827865u, 259230259u, 400177942u, 1770262256u, 1249133505u, 3115830682u, 15u,
1693579797u, 882393182u, 2389299389u, 3435419105u, 135277163u, 850127798u, 4038410214u, 2617278315u, 3259688156u, 2727845350u, 1869694281u, 2969172029u, 1296151296u, 2000889710u, 261376688u, 1950700231u, 2694251523u, 78u,
4172931689u, 116998615u, 3356562354u, 4292193639u, 676385818u, 4250638990u, 3012181886u, 201489691u, 3413538895u, 754324865u, 758536816u, 1960958259u, 2185789187u, 1414513959u, 1306883442u, 1163566563u, 586355729u, 393u,
3684789261u, 584993079u, 3897909882u, 4281099014u, 3381929094u, 4073325766u, 2176007546u, 1007448458u, 4182792587u, 3771624328u, 3792684080u, 1214856703u, 2339011345u, 2777602501u, 2239449915u, 1522865520u, 2931778646u, 1965u,
1244077121u, 2924965399u, 2309680226u, 4225625890u, 4024743586u, 3186759649u, 2290103142u, 742274996u, 3734093752u, 1678252460u, 1783551220u, 1779316223u, 3105122134u, 1003110619u, 2607314986u, 3319360306u, 1773991343u, 9828u,
1925418309u, 1739925108u, 2958466541u, 3948260268u, 2943848750u, 3048896361u, 2860581121u, 3711374982u, 1490599576u, 4096295008u, 327821509u, 306646525u, 2640708784u, 720585802u, 151673043u, 3711899645u, 280022126u, 49142u,
1037156953u, 109690950u, 1907430819u, 2561432159u, 1834341866u, 2359579920u, 1418003720u, 1377005729u, 3158030588u, 3301605857u, 1639107549u, 1533232625u, 318642032u, 3602929013u, 758365215u, 1379629041u, 1400110634u, 245710u,
890817469u, 548454751u, 947219503u, 4217226205u, 581774740u, 3207965010u, 2795051306u, 2590061350u, 2905251053u, 3623127400u, 3900570452u, 3371195830u, 1593210161u, 834775881u, 3791826079u, 2603177909u, 2705585875u, 1228551u,
159120049u, 2742273756u, 441130219u, 3906261842u, 2908873704u, 3154923162u, 1090354645u, 65404865u, 1641353380u, 935767819u, 2322983080u, 3971077266u, 3671083512u, 4173879406u, 1779261211u, 130987661u, 643027490u, 6142758u,
795600245u, 826466892u, 2205651098u, 2351440026u, 1659466636u, 2889713925u, 1156805932u, 327024326u, 3911799604u, 383871800u, 3024980809u, 2675517148u, 1175548380u, 3689527850u, 306371467u, 654938307u, 3215137450u, 30713790u,
3978001225u, 4132334460u, 2438320898u, 3167265540u, 4002365886u, 1563667738u, 1489062367u, 1635121631u, 2379128836u, 1919359004u, 2240002157u, 492683855u, 1582774607u, 1267770067u, 1531857339u, 3274691535u, 3190785362u, 153568953u,
2710136941u, 3481803120u, 3601669902u, 2951425814u, 2831960249u, 3523371398u, 3150344540u, 3880640860u, 3305709589u, 1006860430u, 2610076195u, 2463419277u, 3618905739u, 2043883040u, 3364319400u, 3488555788u, 3069024925u, 767844768u,
665782817u, 229146419u, 828480330u, 1872227186u, 1274899360u, 436987809u, 2866820816u, 2223335119u, 3643646061u, 739334857u, 165479088u, 3727161796u, 914659513u, 1629480612u, 3936695114u, 262909759u, 2460222741u, 3839223843u,
3328914085u, 1145732095u, 4142401650u, 771201338u, 2079529506u, 2184939046u, 1449202192u, 2526741006u, 1038361123u, 3696674289u, 827395440u, 1455939796u, 278330273u, 3852435765u, 2503606387u, 1314548799u, 3711179113u, 2016250033u, 4u,
3759668537u, 1433693182u, 3532139067u, 3856006694u, 1807712938u, 2334760640u, 2951043666u, 4043770439u, 896838321u, 1303502262u, 4136977204u, 2984731684u, 1391651366u, 2082309641u, 3928097347u, 2277776701u, 1376026382u, 1491315577u, 22u,
1618473501u, 2873498618u, 480826152u, 2100164290u, 448630102u, 3083868610u, 1870316444u, 3038983014u, 189224313u, 2222544015u, 3505016837u, 2038756536u, 2663289537u, 1821613614u, 2460617553u, 2798948917u, 2585164616u, 3161610590u, 111u,
3797400209u, 1482591203u, 2404130763u, 1910886858u, 2243150512u, 2534441162u, 761647631u, 2310013184u, 946121568u, 2522785483u, 345215003u, 1603848092u, 431545799u, 518133481u, 3713153175u, 1109842699u, 40921195u, 2923151065u, 558u,
1807131861u, 3117988723u, 3430719224u, 964499700u, 2625817970u, 4082271220u, 3808238157u, 2960131328u, 435640546u, 4023992824u, 1726075017u, 3724273164u, 2157728996u, 2590667405u, 1385896691u, 1254246203u, 204605976u, 1730853437u, 2793u,
445724713u, 2705041729u, 4268694235u, 527531207u, 244187963u, 3231486919u, 1861321605u, 1915754756u, 2178202733u, 2940094936u, 40440497u, 1441496638u, 2198710392u, 68435139u, 2634516162u, 1976263720u, 1023029881u, 64332593u, 13967u,
2228623565u, 640306757u, 4163601994u, 2637656039u, 1220939815u, 3272532707u, 716673436u, 988839190u, 2301079075u, 1815572794u, 202202488u, 2912515894u, 2403617369u, 342175697u, 287678922u, 1291384011u, 820182111u, 321662966u, 69835u,
2553183233u, 3201533787u, 3638140786u, 303378311u, 1809731782u, 3477761648u, 3583367183u, 649228654u, 2915460784u, 487929380u, 1011012442u, 1677677582u, 3428152256u, 1710878487u, 1438394610u, 2161952759u, 4100910556u, 1608314830u, 349175u,
4175981573u, 3122767049u, 1010834749u, 1516891559u, 458724318u, 208939058u, 736966735u, 3246143274u, 1692402032u, 2439646903u, 760094914u, 4093420615u, 4255859393u, 4259425142u, 2897005755u, 2219829204u, 3324683598u, 3746606858u, 1745876u,
3700038681u, 2728933361u, 759206452u, 3289490500u, 2293621591u, 1044695290u, 3684833675u, 3345814482u, 4167042867u, 3608299924u, 3800474572u, 3287233891u, 4099427785u, 4117256530u, 1600126891u, 2509211431u, 3738516104u, 1553165109u, 8729384u,
1320324221u, 759764921u, 3796032263u, 3562550612u, 2878173366u, 928509156u, 1244299192u, 3844170526u, 3655345154u, 861630440u, 1822503680u, 3551267571u, 3317269744u, 3406413470u, 3705667163u, 3956122564u, 1512711338u, 3470858253u, 43646921u,
2306653809u, 3798824606u, 1800292131u, 632883880u, 1505964946u, 347578487u, 1926528665u, 2040983447u, 1096856590u, 13184908u, 522583809u, 576468673u, 3701446836u, 4147165465u, 1348466634u, 2600743640u, 3268589398u, 174422082u, 218234609u,
2943334453u, 1814253848u, 411526067u, 3164419402u, 3234857434u, 1737892436u, 1042708733u, 1614982645u, 1189315656u, 65924541u, 2612919045u, 2882343365u, 1327364996u, 3555958145u, 2447365878u, 118816313u, 3458045105u, 872110413u, 1091173045u,
1831770377u, 481334651u, 2057630337u, 2937195122u, 3289385285u, 99527591u, 918576371u, 3779945930u, 1651610985u, 329622706u, 179693337u, 1526814940u, 2341857687u, 599921542u, 3646894802u, 594081567u, 110356341u, 65584773u, 1160897930u, 1u,
568917293u, 2406673257u, 1698217093u, 1801073724u, 3562024540u, 497637958u, 297914559u, 1719860467u, 3963087633u, 1648113531u, 898466685u, 3339107404u, 3119353844u, 2999607712u, 1054604826u, 2970407839u, 551781705u, 327923865u, 1509522354u, 6u,
2844586465u, 3443431693u, 4196118171u, 415434029u, 630253518u, 2488189794u, 1489572795u, 9367743u, 2635568983u, 3945600363u, 197366130u, 3810635133u, 2711867335u, 2113136675u, 978056837u, 1967137308u, 2758908528u, 1639619325u, 3252644474u, 31u,
1338030437u, 37289284u, 3800721675u, 2077170149u, 3151267590u, 3851014378u, 3152896681u, 46838716u, 292943027u, 2548132634u, 986830654u, 1873306481u, 674434791u, 1975748786u, 595316891u, 1245751949u, 909640754u, 3903129332u, 3378320483u, 158u,
2395184889u, 186446421u, 1823739191u, 1795916157u, 2871436064u, 2075202709u, 2879581521u, 234193583u, 1464715135u, 4150728578u, 639185976u, 776597814u, 3372173957u, 1288809338u, 2976584457u, 1933792449u, 253236475u, 2335777477u, 4006700531u, 793u,
3385989853u, 932232107u, 528761363u, 389646195u, 1472278434u, 1786078956u, 1513005719u, 1170967918u, 3028608379u, 3573773707u, 3195929884u, 3882989070u, 3975967897u, 2149079397u, 1998020398u, 1079027656u, 1266182377u, 3088952793u, 2853633473u, 3969u,
4045047377u, 366193242u, 2643806816u, 1948230975u, 3066424874u, 340460189u, 3270061301u, 1559872295u, 2258140008u, 688999354u, 3094747536u, 2235076169u, 2699970305u, 2155462397u, 1400167400u, 1100170986u, 2035944590u, 2559862078u, 1383265480u, 19848u,
3045367701u, 1830966214u, 334132192u, 1151220286u, 2447222484u, 1702300948u, 3465404617u, 3504394182u, 2700765449u, 3444996772u, 2588835792u, 2585446256u, 614949639u, 2187377396u, 2705869706u, 1205887635u, 1589788359u, 4209375800u, 2621360106u, 99241u,
2341936617u, 564896481u, 1670660962u, 1461134134u, 3646177829u, 4216537446u, 147153902u, 342101730u, 618925361u, 45114679u, 59277076u, 42329395u, 3074748198u, 2346952388u, 644446644u, 1734470882u, 3653974500u, 3867009817u, 221898646u, 496208u,
3119748493u, 2824482407u, 4058337514u, 3010703375u, 1051019962u, 3902818050u, 735769514u, 1710508650u, 3094626805u, 225573395u, 296385380u, 211646975u, 2488839102u, 3144827351u, 3222233222u, 82419818u, 1090003318u, 2155179905u, 1109493234u, 2481040u,
2713840577u, 1237510150u, 3111818389u, 2168614991u, 960132517u, 2334221067u, 3678847574u, 4257575954u, 2588232138u, 1127866978u, 1481926900u, 1058234875u, 3854260918u, 2839234869u, 3226264225u, 412099093u, 1155049294u, 2185964934u, 1252498876u, 12405201u,
684300997u, 1892583457u, 2674190058u, 2253140366u, 505695291u, 3081170744u, 1214368688u, 4108010590u, 56258806u, 1344367597u, 3114667205u, 996207080u, 2091435407u, 1311272461u, 3246419240u, 2060495468u, 1480279174u, 2339890079u, 1967527086u, 62026006u,
3421504985u, 872982693u, 486048404u, 2675767241u, 2528476457u, 2520951832u, 1776876147u, 3360183767u, 281294034u, 2426870689u, 2688434138u, 686068107u, 1867242444u, 2261395011u, 3347194313u, 1712542751u, 3106428576u, 3109515804u, 1247700840u, 310130032u,
4222623037u, 69946172u, 2430242021u, 493934317u, 4052447696u, 4014824570u, 294446145u, 3916016949u, 1406470173u, 3544418853u, 557268804u, 3430340538u, 746277628u, 2717040465u, 3851069679u, 4267746462u, 2647240993u, 2662677135u, 1943536907u, 1550650161u,
3933246001u, 349730864u, 3561275513u, 2469671587u, 3082369296u, 2894253670u, 1472230729u, 2400215561u, 2737383573u, 542225082u, 2786344024u, 4266800802u, 3731388143u, 700300437u, 2075479214u, 4158863130u, 351303081u, 428483790u, 1127749946u, 3458283511u, 1u,
2486360821u, 1748654324u, 626508381u, 3758423347u, 2526944594u, 1586366465u, 3066186352u, 3411143214u, 802015979u, 2711125413u, 1046818232u, 4154134829u, 1477071535u, 3501502189u, 1787461478u, 3614446468u, 1756515409u, 2142418950u, 1343782434u, 111548372u, 9u,
3841869513u, 153337030u, 3132541907u, 1612247551u, 4044788382u, 3636865031u, 2446029873u, 4170814185u, 4010079898u, 670725177u, 939123867u, 3590804962u, 3090390383u, 327641762u, 347372802u, 892363158u, 192642457u, 2122160160u, 2423944876u, 557741861u, 45u,
2029478381u, 766685154u, 2777807647u, 3766270462u, 3044072727u, 1004455975u, 3640214777u, 3674201743u, 2870530310u, 3353625889u, 400652039u, 774155627u, 2567050031u, 1638208813u, 1736864010u, 166848494u, 963212286u, 2020866208u, 3529789790u, 2788709307u, 225u,
1557457313u, 3833425772u, 1004136347u, 1651483129u, 2335461751u, 727312582u, 1021204702u, 1191139535u, 1467749666u, 3883227560u, 2003260198u, 3870778135u, 4245315563u, 3896076771u, 94385459u, 834242472u, 521094134u, 1514396449u, 469079768u, 1058644651u, 1128u,
3492319269u, 1987259677u, 725714443u, 3962448350u, 3087374164u, 3636562912u, 811056214u, 1660730380u, 3043781035u, 2236268617u, 1426366402u, 2174021493u, 4046708635u, 2300514675u, 471927299u, 4171212360u, 2605470670u, 3277014949u, 2345398841u, 998255959u, 5641u,
281727161u, 1346363797u, 3628572217u, 2632372566u, 2551968936u, 1002945379u, 4055281074u, 4008684604u, 2334003288u, 2591408496u, 2836864716u, 2280172874u, 3053673993u, 2912638787u, 2359636497u, 3676192616u, 142451466u, 3500172860u, 3137059616u, 696312501u, 28206u,
1408635805u, 2436851689u, 962991902u, 276960946u, 4169910091u, 719759601u, 3096536187u, 2863553840u, 3080081852u, 72140594u, 1299421695u, 2810929781u, 2383468079u, 1678292050u, 3208247896u, 1201093898u, 712257334u, 320995116u, 2800396196u, 3481562508u, 141030u,
2748211729u, 3594323854u, 519992216u, 1384804731u, 3669681271u, 3598798009u, 2597779047u, 1432867315u, 2515507375u, 360702973u, 2202141179u, 1169747018u, 3327405806u, 4096492956u, 3156337593u, 1710502197u, 3561286671u, 1604975580u, 1117079092u, 227943359u, 705154u,
856156757u, 791750089u, 2599961084u, 2629056359u, 1168537172u, 814120865u, 103993351u, 2869369282u, 3987602284u, 1803514867u, 2420771303u, 1553767796u, 3752127143u, 3302595599u, 2896786081u, 4257543692u, 626564172u, 3729910608u, 1290428165u, 1139716796u, 3525770u,
4280783785u, 3958750445u, 114903532u, 260379910u, 1547718567u, 4070604326u, 519966755u, 1461944522u, 2758142239u, 427639747u, 3513921925u, 3473871686u, 1580766532u, 3628076111u, 1599028520u, 4107849279u, 3132820864u, 1469683856u, 2157173533u, 1403616685u, 17628851u,
4224049741u, 2613883045u, 574517664u, 1301899550u, 3443625539u, 3173152447u, 2599833779u, 3014755314u, 905809308u, 2138198738u, 389740441u, 189489250u, 3608865368u, 960511372u, 3700175308u, 3359377212u, 2779202436u, 3053451987u, 2195933074u, 2723116131u, 88144256u,
3940379521u, 184513341u, 2872588323u, 2214530454u, 38258512u, 2980860351u, 114267010u, 2188874685u, 234079247u, 2101059099u, 1948702207u, 947446250u, 864457656u, 507589568u, 1321007357u, 3911984176u, 1011110295u, 2382358050u, 2389730781u, 730678769u, 440721283u,
2522028421u, 922566709u, 1478039727u, 2482717681u, 191292562u, 2019399867u, 571335053u, 2354438833u, 1170396237u, 1915360903u, 1153576445u, 442263956u, 27320985u, 2537947841u, 2310069489u, 2380051697u, 760584183u, 3321855659u, 3358719315u, 3653393847u, 2203606415u,
4020207513u, 317866251u, 3095231340u, 3823653814u, 956462812u, 1507064743u, 2856675267u, 3182259573u, 1557013891u, 986869924u, 1472914931u, 2211319781u, 136604925u, 4099804613u, 2960412855u, 3310323895u, 3802920917u, 3724376407u, 3908694690u, 1087100054u, 2428097487u, 2u,
2921168381u, 1589331259u, 2591254812u, 1938399889u, 487346768u, 3240356420u, 1398474448u, 3026395980u, 3490102162u, 639382325u, 3069607360u, 2466664314u, 683024627u, 3319153881u, 1917162391u, 3666717590u, 1834735404u, 1442012855u, 2363604270u, 1140532978u, 3550552844u, 12u,
1720940017u, 3651689002u, 71372173u, 1102064856u, 2436733842u, 3316880212u, 2697404947u, 2247078013u, 270641629u, 3196911629u, 2463134912u, 3743386981u, 3415123137u, 3710867517u, 995877366u, 1153718768u, 583742432u, 2915096981u, 3228086759u, 1407697596u, 572895037u, 64u,
14765493u, 1078575828u, 356860869u, 1215356984u, 3593734619u, 3699499174u, 602122850u, 2645455476u, 1353208147u, 3099656257u, 3725739971u, 1537065723u, 4190713801u, 1374468404u, 684419538u, 1473626545u, 2918712161u, 1690583017u, 3255531910u, 2743520687u, 2864475186u, 320u,
73827465u, 1097911844u, 1784304346u, 1781817624u, 788803912u, 1317626690u, 3010614254u, 342375492u, 2471073442u, 2613379398u, 1448830674u, 3390361323u, 3773699822u, 2577374728u, 3422097691u, 3073165429u, 1708658918u, 4157947792u, 3392757663u, 832701550u, 1437474045u, 1603u,
369137325u, 1194591924u, 331587139u, 319153530u, 3944019562u, 2293166154u, 2168169383u, 1711877463u, 3765432618u, 181995104u, 2949186077u, 4066904728u, 1688629929u, 1971756u, 4225586570u, 2480925260u, 4248327297u, 3609869777u, 4078886431u, 4163507753u, 2892402929u, 8016u,
1845686625u, 1677992324u, 1657935696u, 1595767650u, 2540228626u, 2875896182u, 2250912325u, 4264420021u, 1647293907u, 909975524u, 1861028497u, 3154654459u, 4148182353u, 9858781u, 3948063666u, 3814691712u, 4061767303u, 869479705u, 3214562975u, 3637669585u, 1577112761u, 40083u,
638498533u, 4094994326u, 3994711185u, 3683870955u, 4111208539u, 1494579024u, 2664627036u, 4142230923u, 3941502243u, 254910325u, 715207894u, 2888370409u, 3561042584u, 49293909u, 2560449146u, 1893589380u, 3128967335u, 52431233u, 3187912988u, 1008478744u, 3590596513u, 200416u,
3192492665u, 3295102446u, 2793686745u, 1239485595u, 3376173515u, 3177927828u, 438233293u, 3531285434u, 2527642035u, 1274551629u, 3576039470u, 1556950157u, 625343739u, 246469549u, 4212311138u, 878012310u, 2759934789u, 262156168u, 3054663052u, 747426427u, 773113382u, 1002084u,
3077561437u, 3590610345u, 1083531840u, 1902460682u, 3995965688u, 3004737255u, 2191166468u, 476557986u, 4048275587u, 2077790851u, 700328167u, 3489783493u, 3126718696u, 1232347745u, 3881686506u, 95094258u, 914772058u, 1310780843u, 2388413372u, 3737132138u, 3865566910u, 5010420u,
2502905297u, 773182544u, 1122691908u, 922368819u, 2799959258u, 2138784391u, 2365897751u, 2382789932u, 3061508751u, 1799019667u, 3501640837u, 269048281u, 2748691596u, 1866771432u, 2228563347u, 475471294u, 278892994u, 2258936920u, 3352132269u, 1505791508u, 2147965370u, 25052104u,
3924591893u, 3865912722u, 1318492244u, 316876800u, 1114894403u, 2103987366u, 3239554165u, 3324015070u, 2422641869u, 405163746u, 328335003u, 1345241409u, 858556092u, 743922571u, 2552882145u, 2377356472u, 1394464970u, 2704750008u, 3875759459u, 3233990247u, 2149892259u, 125260522u,
2443090281u, 2149694430u, 2297493928u, 1584384001u, 1279504719u, 1930002239u, 3312868939u, 3735173465u, 3523274756u, 2025818732u, 1641675015u, 2431239749u, 4292780461u, 3719612855u, 4174476133u, 3296847770u, 2677357556u, 638848153u, 2198928114u, 3285049351u, 2159526706u, 626302612u,
3625516813u, 2158537560u, 2897535050u, 3626952711u, 2102556300u, 1060076604u, 3679442809u, 1495998144u, 436504600u, 1539159072u, 3913407781u, 3566264154u, 4284033123u, 1418195095u, 3692511485u, 3599336966u, 501885895u, 3194240768u, 2404705978u, 3540344869u, 2207698941u, 3131513062u,
947714881u, 2202753212u, 1602773364u, 954894374u, 1922846912u, 1005415726u, 1217344862u, 3185023428u, 2182523001u, 3400828064u, 2387169722u, 651451590u, 4240296435u, 2796008183u, 1282688242u, 816815650u, 2509429479u, 3086301952u, 3433595301u, 521855163u, 2448560117u, 2772663424u, 3u,
443607109u, 2423831469u, 3718899526u, 479504575u, 1024299969u, 732111336u, 1791757015u, 3040215253u, 2322680416u, 4119238434u, 3345914021u, 3257257952u, 4021612991u, 1095139031u, 2118473917u, 4084078251u, 3957212803u, 2546607874u, 4283074620u, 2609275818u, 3652865993u, 978415234u, 18u,
2218035545u, 3529222753u, 1414628448u, 2397522879u, 826532549u, 3660556681u, 368850483u, 2316174379u, 3023467491u, 3416322988u, 3844668221u, 3401387875u, 2928195774u, 1180727863u, 2002434994u, 3240522073u, 2606194835u, 4143104782u, 4235503918u, 161477206u, 1084460784u, 597108878u, 91u,
2500243133u, 466244583u, 2778174948u, 3397679804u, 4132662747u, 1122914221u, 1844252419u, 2990937303u, 2232435569u, 4196713055u, 2043471924u, 4122037491u, 1756076985u, 1608672022u, 1422240379u, 3317708479u, 146072290u, 3535654729u, 3997650410u, 807386034u, 1127336624u, 2985544391u, 455u,
3911281073u, 2331222917u, 1005972852u, 4103497135u, 3483444554u, 1319603813u, 631327504u, 2069784629u, 2572243256u, 3803696093u, 1627425032u, 3430318273u, 190450337u, 3748392816u, 2816234600u, 3703640508u, 730361453u, 498404461u, 2808382870u, 4036930174u, 1341715824u, 2042820068u, 2278u,
2376536181u, 3066179997u, 734896966u, 3337616492u, 237353590u, 2303051773u, 3156637521u, 1758988553u, 4271281690u, 1838611283u, 3842157868u, 4266689478u, 952251688u, 1562094896u, 1196271116u, 1338333359u, 3651807269u, 2492022305u, 1157012462u, 3004781689u, 2413611828u, 1624165749u, 11392u,
3292746313u, 2445998099u, 3674484833u, 3803180572u, 1186767953u, 2925324273u, 2898285719u, 205008176u, 4176539268u, 603121827u, 2030920158u, 4153578210u, 466291148u, 3515507185u, 1686388285u, 2396699500u, 1079167162u, 3870176937u, 1490095016u, 2139006558u, 3478124551u, 3825861451u, 56961u,
3578829677u, 3640055906u, 1192554983u, 1836033680u, 1638872473u, 1741719478u, 1606526710u, 1025040883u, 3702827156u, 3015609139u, 1564666198u, 3588021868u, 2331455744u, 397666741u, 4136974133u, 3393562909u, 1100868516u, 2171015502u, 3155507788u, 2105098199u, 210753573u, 1949438075u, 284809u,
714279201u, 1020410350u, 1667807623u, 590233809u, 3899395071u, 118662799u, 3737666256u, 830237120u, 1334266597u, 2193143811u, 3528363697u, 760240157u, 3067344132u, 1988333707u, 3505001481u, 4082912661u, 1209375287u, 2265142919u, 2892637054u, 1935556406u, 1053767867u, 1157255783u, 1424047u,
3571396005u, 807084454u, 4044070820u, 2951169046u, 2317106171u, 593313999u, 1508462096u, 4151185604u, 2376365689u, 2375784464u, 461949303u, 3801200789u, 2451818772u, 1351733946u, 345138223u, 3234694125u, 1751909143u, 2735780004u, 1578283384u, 1087847441u, 973872041u, 1491311620u, 7120236u,
677110841u, 4035422274u, 3040484916u, 1870943346u, 2995596266u, 2966569997u, 3247343184u, 3576058837u, 3291893857u, 3288987730u, 2309746517u, 1826134761u, 3669159272u, 2463702436u, 1725691116u, 3288568737u, 169611126u, 793998134u, 3596449627u, 1144269910u, 574392910u, 3161590805u, 35601181u,
3385554205u, 2997242186u, 2317522696u, 764782141u, 2093079444u, 1947948100u, 3351814035u, 700425004u, 3574567401u, 3560036765u, 2958797996u, 540739215u, 1165927178u, 3728577592u, 38520990u, 3557941799u, 848055633u, 3969990670u, 802378951u, 1426382258u, 2871964551u, 2923052137u, 178005908u,
4042869137u, 2101309045u, 2997678891u, 3823910707u, 1875462628u, 1149805910u, 3874168289u, 3502125023u, 692967821u, 620314645u, 1909088096u, 2703696078u, 1534668594u, 1463018777u, 192604954u, 609839811u, 4240278169u, 2670084166u, 4011894759u, 2836943994u, 1474920868u, 1730358800u, 890029543u,
3034476501u, 1916610637u, 2103492569u, 1939684354u, 787378552u, 1454062256u, 2190972262u, 330755935u, 3464839109u, 3101573225u, 955505888u, 633578504u, 3378375677u, 3020126590u, 963024771u, 3049199055u, 4021521661u, 465518946u, 2879604614u, 1299818086u, 3079637047u, 61859409u, 155180421u, 1u,
2287480617u, 993118596u, 1927528255u, 1108487180u, 3936892762u, 2975343984u, 2364926719u, 1653779677u, 144326361u, 2622964241u, 482562147u, 3167892521u, 4006976497u, 2215731065u, 520156562u, 2361093388u, 2927739124u, 2327594734u, 1513121182u, 2204123137u, 2513283348u, 309297048u, 775902105u, 5u,
2847468493u, 670625686u, 1047706684u, 1247468606u, 2504594627u, 1991818036u, 3234699006u, 3973931091u, 721631806u, 229919317u, 2412810738u, 2954560717u, 2855013304u, 2488720737u, 2600782812u, 3215532348u, 1753793734u, 3048039081u, 3270638616u, 2430681094u, 3976482150u, 1546485242u, 3879510525u, 25u,
1352440577u, 3353128433u, 943566124u, 1942375735u, 3933038544u, 1369155590u, 3288593144u, 2689786274u, 3608159034u, 1149596585u, 3474119098u, 1887901699u, 1390164635u, 3853669096u, 119012174u, 3192759855u, 179034081u, 2355293519u, 3468291195u, 3563470881u, 2702541568u, 3437458918u, 2217683442u, 129u,
2467235589u, 3880740278u, 422863327u, 1121944084u, 2485323538u, 2550810658u, 3558063833u, 564029485u, 860925989u, 1453015633u, 190726307u, 849573907u, 2655855881u, 2088476297u, 595060874u, 3078897387u, 895170408u, 3186533003u, 161586793u, 637485225u, 627805956u, 7425409u, 2498482622u, 647u,
3746243353u, 2223832208u, 2114316639u, 1314753124u, 3836683099u, 4164118700u, 610449983u, 2820147429u, 9662649u, 2970110870u, 953631536u, 4247869535u, 394377517u, 1852446896u, 2975304372u, 2509585047u, 180884747u, 3047763128u, 807933968u, 3187426125u, 3139029780u, 37127045u, 3902478518u, 3237u,
1551347581u, 2529226452u, 1981648605u, 2278798326u, 2003546312u, 3640724320u, 3052249919u, 1215835257u, 48313248u, 1965652462u, 473190387u, 4059478492u, 1971887589u, 672299888u, 1991619974u, 3957990646u, 904423737u, 2353913752u, 4039669843u, 3052228737u, 2810247015u, 185635228u, 2332523406u, 16189u,
3461770609u, 4056197669u, 1318308435u, 2804057040u, 1427796970u, 1023752418u, 2376347711u, 1784208992u, 241566241u, 1238327718u, 2365951937u, 3117523276u, 1269503357u, 3361499442u, 1368165278u, 2610084048u, 227151393u, 3179634169u, 3018480033u, 2376241801u, 1166333190u, 928176143u, 3072682438u, 80947u,
128983861u, 3101119165u, 2296574883u, 1135383313u, 2844017557u, 823794795u, 3291803964u, 331110370u, 1207831207u, 1896671294u, 3239825094u, 2702714494u, 2052549492u, 3922595323u, 2545859097u, 165518353u, 1135756968u, 3013268957u, 2207498280u, 3291274416u, 1536698656u, 345913420u, 2478510303u, 404738u,
644919305u, 2620693937u, 2892939826u, 1381949271u, 1335185898u, 4118973978u, 3574117932u, 1655551853u, 1744188739u, 893421879u, 3314223584u, 628670585u, 1672812871u, 2433107433u, 4139360897u, 827591767u, 1383817544u, 2181442898u, 2447556811u, 3571470194u, 3388525987u, 1729567101u, 3802616923u, 2023692u,
3224596525u, 218567797u, 1579797245u, 2614779062u, 2380962195u, 3415000707u, 690720480u, 3982791973u, 131009104u, 172142101u, 3686216033u, 3143352928u, 4069097059u, 3575602574u, 3516935303u, 4137958839u, 2624120424u, 2317279899u, 3647849465u, 677481788u, 4057728051u, 57900916u, 1833215433u, 10118464u,
3238080737u, 1092838988u, 3604018929u, 188993423u, 3314876386u, 4190101649u, 3453602403u, 2734090681u, 655045524u, 860710505u, 1251210981u, 2831862756u, 3165616114u, 698143690u, 404807335u, 3509925015u, 235700236u, 2996464906u, 1059378143u, 3387408944u, 3108771071u, 289504584u, 576142573u, 50592322u,
3305501797u, 1169227647u, 840225462u, 944967119u, 3689480042u, 3770639064u, 88142835u, 785551521u, 3275227623u, 8585229u, 1961087610u, 1274411893u, 2943178685u, 3490718453u, 2024036675u, 369755891u, 1178501184u, 2097422642u, 1001923422u, 4052142833u, 2658953470u, 1447522923u, 2880712865u, 252961610u,
3642607097u, 1551170942u, 4201127311u, 429868299u, 1267531027u, 1673326140u, 440714179u, 3927757605u, 3491236227u, 42926148u, 1215503458u, 2077092171u, 1830991538u, 273723084u, 1530248787u, 1848779457u, 1597538624u, 1897178619u, 714649816u, 3080844982u, 409865466u, 2942647322u, 1518662438u, 1264808053u,
1033166301u, 3460887418u, 3825767372u, 2149341499u, 2042687839u, 4071663405u, 2203570896u, 2458918841u, 276311955u, 214630744u, 1782549994u, 1795526264u, 565023100u, 1368615422u, 3356276639u, 653962694u, 3692725826u, 895958504u, 3573249082u, 2519323022u, 2049327333u, 1828334722u, 3298344897u, 2029072970u, 1u,
870864209u, 124567907u, 1948967680u, 2156772907u, 1623504605u, 3178447843u, 2427919892u, 3704659615u, 1381559777u, 1073153720u, 322815378u, 387696730u, 2825115502u, 2548109814u, 3896481308u, 3269813473u, 1283759946u, 184825228u, 686376227u, 4006680522u, 1656702075u, 551739020u, 3606822599u, 1555430261u, 7u,
59353749u, 622839536u, 1154903808u, 2193929945u, 3822555731u, 3007337328u, 3549664871u, 1343428893u, 2612831593u, 1070801305u, 1614076891u, 1938483650u, 1240675622u, 4150614481u, 2302537358u, 3464165481u, 2123832437u, 924126141u, 3431881135u, 2853533426u, 3988543083u, 2758695101u, 854243811u, 3482184013u, 36u,
296768745u, 3114197680u, 1479551744u, 2379715134u, 1932909473u, 2151784756u, 568455174u, 2422177173u, 179256078u, 1059039232u, 3775417160u, 1102483659u, 1908410816u, 3573203222u, 2922752202u, 140958223u, 2029227597u, 325663411u, 4274503788u, 1382765245u, 2762846234u, 908573621u, 4271219058u, 231050881u, 184u,
1483843725u, 2686086512u, 3102791427u, 3308641079u, 1074612775u, 2168989190u, 2842275872u, 3520951273u, 896280392u, 1000228864u, 1697216617u, 1217451003u, 952119489u, 686146928u, 1728859126u, 704791118u, 1556203393u, 1628317057u, 4192649756u, 2618858933u, 929329283u, 247900812u, 4176226107u, 1155254409u, 920u,
3124251329u, 545530673u, 2629055250u, 3658303510u, 1078096582u, 2255011359u, 1326477474u, 424887184u, 186434668u, 706177025u, 4191115790u, 1792287720u, 465630150u, 3430734641u, 54361038u, 3523955592u, 3486049669u, 3846617990u, 3783379597u, 209392781u, 351679122u, 1239504061u, 3701261351u, 1481304753u, 4601u,
2736354757u, 2727653368u, 260374362u, 1111648369u, 1095515618u, 2685122204u, 2337420076u, 2124435921u, 932173340u, 3530885125u, 3775709766u, 371504012u, 2328150752u, 4268771317u, 271805193u, 439908776u, 250379165u, 2053220770u, 1737028805u, 1046963909u, 1758395610u, 1902553009u, 1326437572u, 3111556473u, 23006u,
796871897u, 753364955u, 1301871813u, 1263274549u, 1182610795u, 540709133u, 3097165791u, 2032245015u, 365899406u, 474556442u, 1698679650u, 1857520064u, 3050819168u, 4163987403u, 1359025969u, 2199543880u, 1251895825u, 1676169258u, 95209435u, 939852251u, 202043459u, 922830455u, 2337220566u, 2672880478u, 115033u,
3984359485u, 3766824775u, 2214391769u, 2021405450u, 1618086680u, 2703545666u, 2600927067u, 1571290486u, 1829497032u, 2372782210u, 4198430954u, 697665729u, 2369193954u, 3640067834u, 2500162553u, 2407784809u, 1964511831u, 4085878995u, 476047176u, 404293959u, 1010217296u, 319184979u, 3096168239u, 479500504u, 575168u,
2741928241u, 1654254695u, 2482024257u, 1517092660u, 3795466106u, 632826443u, 119733450u, 3561485137u, 557550569u, 3273976460u, 3812285588u, 3488328649u, 3256035178u, 1020469988u, 3910878177u, 3448989455u, 1232624565u, 3249525793u, 2380235884u, 2021469795u, 756119184u, 1595924896u, 2595939307u, 2397502523u, 2875840u,
824739317u, 3976306182u, 3820186694u, 3290496006u, 1797461347u, 3164132219u, 598667250u, 627556501u, 2787752849u, 3484980412u, 1881558759u, 261774065u, 3395274006u, 807382647u, 2374521702u, 65078095u, 1868155533u, 3362727078u, 3311244831u, 1517414385u, 3780595922u, 3684657184u, 94794648u, 3397578026u, 14379202u,
4123696585u, 2701661726u, 1921064290u, 3567578146u, 397372146u, 2935759209u, 2993336253u, 3137782505u, 1053862357u, 245032879u, 817859207u, 1308870327u, 4091468142u, 4036913238u, 3282673918u, 325390477u, 750843073u, 3928733504u, 3671322270u, 3292104632u, 1723110427u, 1243416740u, 473973244u, 4102988242u, 71896013u,
3438613741u, 623406746u, 1015386861u, 658021548u, 1986860734u, 1793894157u, 2081779380u, 2804010640u, 974344492u, 1225164396u, 4089296035u, 2249384339u, 3277471527u, 3004697010u, 3528467706u, 1626952388u, 3754215365u, 2463798336u, 1176742170u, 3575621276u, 25617546u, 1922116406u, 2369866221u, 3335072026u, 359480069u,
13199521u, 3117033734u, 781967009u, 3290107741u, 1344369078u, 379536195u, 1818962310u, 1135151314u, 576755167u, 1830854685u, 3266610992u, 2656987107u, 3502455749u, 2138583165u, 462469349u, 3839794648u, 1591207642u, 3729057092u, 1588743556u, 698237197u, 128087734u, 1020647438u, 3259396515u, 3790458244u, 1797400348u,
65997605u, 2700266782u, 3909835048u, 3565636817u, 2426878097u, 1897680976u, 504876958u, 1380789276u, 2883775836u, 564338833u, 3448153074u, 400033650u, 332409564u, 2102981237u, 2312346747u, 2019104056u, 3661070918u, 1465416277u, 3648750488u, 3491185986u, 640438670u, 808269894u, 3412080688u, 1772422039u, 397067152u, 2u,
};
/* These are the indicies of the start of each power of 5 in pow5[] */
/* The width is calculated by subtracting indices, so there is one extra */
/* generated using (pow5w 346) from testgen.scm */
static const uint16_t pow5w[] = {
0u,
1u,
2u,
3u,
4u,
5u,
6u,
7u,
8u,
9u,
10u,
11u,
12u,
13u,
14u,
16u,
18u,
20u,
22u,
24u,
26u,
28u,
30u,
32u,
34u,
36u,
38u,
40u,
42u,
45u,
48u,
51u,
54u,
57u,
60u,
63u,
66u,
69u,
72u,
75u,
78u,
81u,
84u,
88u,
92u,
96u,
100u,
104u,
108u,
112u,
116u,
120u,
124u,
128u,
132u,
136u,
140u,
145u,
150u,
155u,
160u,
165u,
170u,
175u,
180u,
185u,
190u,
195u,
200u,
205u,
211u,
217u,
223u,
229u,
235u,
241u,
247u,
253u,
259u,
265u,
271u,
277u,
283u,
289u,
296u,
303u,
310u,
317u,
324u,
331u,
338u,
345u,
352u,
359u,
366u,
373u,
380u,
387u,
395u,
403u,
411u,
419u,
427u,
435u,
443u,
451u,
459u,
467u,
475u,
483u,
491u,
499u,
508u,
517u,
526u,
535u,
544u,
553u,
562u,
571u,
580u,
589u,
598u,
607u,
616u,
625u,
635u,
645u,
655u,
665u,
675u,
685u,
695u,
705u,
715u,
725u,
735u,
745u,
755u,
766u,
777u,
788u,
799u,
810u,
821u,
832u,
843u,
854u,
865u,
876u,
887u,
898u,
909u,
921u,
933u,
945u,
957u,
969u,
981u,
993u,
1005u,
1017u,
1029u,
1041u,
1053u,
1065u,
1077u,
1090u,
1103u,
1116u,
1129u,
1142u,
1155u,
1168u,
1181u,
1194u,
1207u,
1220u,
1233u,
1246u,
1259u,
1273u,
1287u,
1301u,
1315u,
1329u,
1343u,
1357u,
1371u,
1385u,
1399u,
1413u,
1427u,
1441u,
1456u,
1471u,
1486u,
1501u,
1516u,
1531u,
1546u,
1561u,
1576u,
1591u,
1606u,
1621u,
1636u,
1651u,
1667u,
1683u,
1699u,
1715u,
1731u,
1747u,
1763u,
1779u,
1795u,
1811u,
1827u,
1843u,
1859u,
1875u,
1892u,
1909u,
1926u,
1943u,
1960u,
1977u,
1994u,
2011u,
2028u,
2045u,
2062u,
2079u,
2096u,
2113u,
2131u,
2149u,
2167u,
2185u,
2203u,
2221u,
2239u,
2257u,
2275u,
2293u,
2311u,
2329u,
2347u,
2365u,
2384u,
2403u,
2422u,
2441u,
2460u,
2479u,
2498u,
2517u,
2536u,
2555u,
2574u,
2593u,
2612u,
2632u,
2652u,
2672u,
2692u,
2712u,
2732u,
2752u,
2772u,
2792u,
2812u,
2832u,
2852u,
2872u,
2892u,
2913u,
2934u,
2955u,
2976u,
2997u,
3018u,
3039u,
3060u,
3081u,
3102u,
3123u,
3144u,
3165u,
3186u,
3208u,
3230u,
3252u,
3274u,
3296u,
3318u,
3340u,
3362u,
3384u,
3406u,
3428u,
3450u,
3472u,
3494u,
3517u,
3540u,
3563u,
3586u,
3609u,
3632u,
3655u,
3678u,
3701u,
3724u,
3747u,
3770u,
3793u,
3817u,
3841u,
3865u,
3889u,
3913u,
3937u,
3961u,
3985u,
4009u,
4033u,
4057u,
4081u,
4105u,
4129u,
4154u,
4179u,
4204u,
4229u,
4254u,
4279u,
4304u,
4329u,
4354u,
4379u,
4404u,
4429u,
4454u,
4479u,
4505u,
};
/* returns result: 0 = OK; non-zero = error */
int get_pow5 (uint32_t exp, const uint32_t **p5, int *sz_in_32bit_words)
{
if (exp <= MAX_POW5_IN_TABLE)
{
uint16_t idx = pow5w[exp];
*p5 = &pow5[idx];
*sz_in_32bit_words = pow5w[exp + 1] - idx;
return 0;
}
else
{
*p5 = &pow5[0];
*sz_in_32bit_words = 0;
return 1;
}
}
#endif

View File

@ -0,0 +1,4 @@
CONTRIB_DEFS += -DPIC_CSTRING_TO_DOUBLE=emyg_atod -DPIC_DOUBLE_TO_CSTRING=emyg_dtoa
CONTRIB_SRCS += contrib/10.roundtrip/emyg_dtoa.c \
contrib/10.roundtrip/emyg_atod.c

View File

@ -345,39 +345,12 @@ int xvfprintf(pic_state *pic, xFILE *stream, const char *fmt, va_list ap) {
ival = va_arg(ap, int);
cnt += print_int(pic, stream, ival, 10);
break;
#if PIC_ENABLE_LIBC
case 'f': {
char buf[100];
sprintf(buf, "%g", va_arg(ap, double));
char buf[64];
PIC_DOUBLE_TO_CSTRING(va_arg(ap, double), buf);
cnt += xfputs(pic, buf, stream);
break;
}
#else
# define fabs(x) ((x) >= 0 ? (x) : -(x))
case 'f': {
double dval = va_arg(ap, double);
long lval;
if (dval < 0) {
dval = -dval;
xputc(pic, '-', stream);
cnt++;
}
lval = (long)dval;
cnt += print_int(pic, stream, lval, 10);
xputc(pic, '.', stream);
cnt++;
dval -= lval;
if ((ival = fabs(dval) * 1e4 + 0.5) == 0) {
cnt += xfputs(pic, "0000", stream);
} else {
if (ival < 1000) xputc(pic, '0', stream); cnt++;
if (ival < 100) xputc(pic, '0', stream); cnt++;
if (ival < 10) xputc(pic, '0', stream); cnt++;
cnt += print_int(pic, stream, ival, 10);
}
break;
}
#endif
case 'c':
ival = va_arg(ap, int);
cnt += xfputc(pic, ival, stream);

View File

@ -213,12 +213,142 @@ strcpy(char *dst, const char *src)
return d;
}
PIC_INLINE double
atof(const char *nptr)
{
int c;
double f, g, h;
int exp, s, i, e;
unsigned u;
/* note that picrin_read always assures that *nptr is a digit, never a '+' or '-' */
/* in other words, the result of atof will always be positive */
/* mantissa */
/* pre '.' */
u = *nptr++ - '0';
while (isdigit(c = *nptr)) {
u = u * 10 + (*nptr++ - '0');
}
if (c == '.') {
nptr++;
/* after '.' */
g = 0, e = 0;
while (isdigit(c = *nptr)) {
g = g * 10 + (*nptr++ - '0');
e++;
}
h = 1.0;
while (e-- > 0) {
h /= 10;
}
f = u + g * h;
}
else {
f = u;
}
/* suffix, i.e., exponent */
s = 0;
exp = 0;
c = *nptr;
if (c == 'e' && c == 'E') {
nptr++;
switch ((c = *nptr++)) {
case '-':
s = 1;
case '+':
c = *nptr++;
default:
exp = c - '0';
while (isdigit(c = *nptr)) {
exp = exp * 10 + (*nptr++ - '0');
}
}
}
e = 10;
for (i = 0; exp; ++i) {
if ((exp & 1) != 0) {
f = s ? f / e : (f * e);
}
e *= e;
exp >>= 1;
}
return f;
}
#endif
#if PIC_ENABLE_STDIO
# include <stdio.h>
PIC_INLINE void
pic_dtoa(double dval, char *buf)
{
sprintf(buf, "%g", dval);
}
#else
PIC_INLINE void
pic_dtoa(double dval, char *buf)
{
# define fabs(x) ((x) >= 0 ? (x) : -(x))
long lval, tlval;
int ival;
int scnt, ecnt, cnt = 0;
if (dval < 0) {
dval = -dval;
buf[cnt++] = '-';
}
lval = tlval = (long)dval;
scnt = cnt;
do {
buf[cnt++] = '0' + (tlval % 10);
} while ((tlval /= 10) != 0);
ecnt = cnt;
while (scnt < ecnt) {
char c = buf[scnt];
buf[scnt++] = buf[--ecnt];
buf[ecnt] = c;
}
buf[cnt++] = '.';
dval -= lval;
if ((ival = fabs(dval) * 1e4 + 0.5) == 0) {
buf[cnt++] = '0';
buf[cnt++] = '0';
buf[cnt++] = '0';
buf[cnt++] = '0';
} else {
if (ival < 1000) buf[cnt++] = '0';
if (ival < 100) buf[cnt++] = '0';
if (ival < 10) buf[cnt++] = '0';
scnt = cnt;
do {
buf[cnt++] = '0' + (ival % 10);
} while ((ival /= 10) != 0);
ecnt = cnt;
while (scnt < ecnt) {
char c = buf[scnt];
buf[scnt++] = buf[--ecnt];
buf[ecnt] = c;
}
}
buf[cnt] = 0;
}
#endif
#ifndef PIC_DOUBLE_TO_CSTRING
#define PIC_DOUBLE_TO_CSTRING pic_dtoa
#endif
void PIC_DOUBLE_TO_CSTRING(double, char *);
#ifndef PIC_CSTRING_TO_DOUBLE
#define PIC_CSTRING_TO_DOUBLE atof
#endif
double PIC_CSTRING_TO_DOUBLE(const char *);
#if defined(__cplusplus)
}
#endif

View File

@ -237,104 +237,58 @@ read_uinteger(pic_state *pic, struct pic_port *port, int c)
return u;
}
static int
read_suffix(pic_state *pic, struct pic_port *port)
{
int c, s = 1;
c = peek(pic, port);
if (c != 'e' && c != 'E') {
return 0;
}
next(pic, port);
switch ((c = next(pic, port))) {
case '-':
s = -1;
case '+':
c = next(pic, port);
default:
return s * read_uinteger(pic, port, c);
}
}
static pic_value
read_unsigned(pic_state *pic, struct pic_port *port, int c)
{
unsigned u;
int exp, s, i, e;
#define ATOF_BUF_SIZE (64)
char buf[ATOF_BUF_SIZE];
double flt;
int idx = 0; /* index into buffer */
int dpe = 0; /* the number of '.' or 'e' characters seen */
u = read_uinteger(pic, port, c);
switch (peek(pic, port)) {
#if PIC_ENABLE_LIBC
case '.': {
char buf[256];
i = sprintf(buf, "%d", u);
buf[i++] = next(pic, port);
while (isdigit(c = peek(pic, port))) {
buf[i++] = next(pic, port);
}
sprintf(buf + i, "e%d", read_suffix(pic, port));
return pic_float_value(atof(buf));
if (! isdigit(c)) {
read_error(pic, "expected one or more digits", pic_list1(pic, pic_char_value(c)));
}
#else
case '.': {
double f, g, h;
next(pic, port);
g = 0, e = 0;
while (isdigit(c = peek(pic, port))) {
g = g * 10 + (next(pic, port) - '0');
e++;
}
h = 1.0;
while (e-- > 0) {
h /= 10;
}
f = u + g * h;
exp = read_suffix(pic, port);
if (exp >= 0) {
s = 0;
} else {
exp = -exp;
s = 1;
}
e = 10;
for (i = 0; exp; ++i) {
if ((exp & 1) != 0) {
f = s ? f / e : (f * e);
}
e *= e;
exp >>= 1;
}
return pic_float_value(f);
buf[idx++] = (char )c;
while (isdigit(c = peek(pic, port)) && idx < ATOF_BUF_SIZE) {
buf[idx++] = (char )next(pic, port);
}
#endif
default:
exp = read_suffix(pic, port);
if (exp >= 0) {
s = 0;
} else {
exp = -exp;
s = 1;
if ('.' == peek(pic, port) && idx < ATOF_BUF_SIZE) {
dpe++;
buf[idx++] = (char )next(pic, port);
while (isdigit(c = peek(pic, port)) && idx < ATOF_BUF_SIZE) {
buf[idx++] = (char )next(pic, port);
}
e = 10;
for (i = 0; exp; ++i) {
if ((exp & 1) != 0) {
u = s ? u / e : (u * e);
}
e *= e;
exp >>= 1;
}
return pic_int_value(u);
}
c = peek(pic, port);
if ((c == 'e' || c == 'E') && idx < (ATOF_BUF_SIZE - 2)) {
dpe++;
buf[idx++] = (char )next(pic, port);
switch ((c = peek(pic, port))) {
case '-':
case '+':
buf[idx++] = (char )next(pic, port);
break;
default:
break;
}
if (! isdigit(peek(pic, port))) {
read_error(pic, "expected one or more digits", pic_list1(pic, pic_char_value(c)));
}
while (isdigit(c = peek(pic, port)) && idx < ATOF_BUF_SIZE) {
buf[idx++] = (char )next(pic, port);
}
}
if (idx >= ATOF_BUF_SIZE)
read_error(pic, "number too large",
pic_obj_value(pic_make_str(pic, (const char *)buf, ATOF_BUF_SIZE)));
buf[idx] = 0;
flt = PIC_CSTRING_TO_DOUBLE(buf);
if (dpe == 0 && pic_valid_int(flt))
return pic_int_value((int )flt);
return pic_float_value(flt);
}
static pic_value
@ -346,7 +300,7 @@ read_number(pic_state *pic, struct pic_port *port, int c)
static pic_value
negate(pic_value n)
{
if (pic_int_p(n)) {
if (pic_int_p(n) && (INT_MIN != pic_int(n))) {
return pic_int_value(-pic_int(n));
} else {
return pic_float_value(-pic_float(n));

File diff suppressed because it is too large Load Diff