diff options
author | dan <Dan Kennedy> | 2024-12-10 17:36:20 +0000 |
---|---|---|
committer | dan <Dan Kennedy> | 2024-12-10 17:36:20 +0000 |
commit | 50ebf16dd630caa89e0eb87332b1c9926399496b (patch) | |
tree | 2455b588899e787422364b7801e5f26f740858a9 /src/util.c | |
parent | 9c750fe3a3c70db6e596ebbf3a4bf8c442302231 (diff) | |
parent | 6e53f67c63771b72d5419265038f428c34fa99d5 (diff) | |
download | sqlite-50ebf16dd630caa89e0eb87332b1c9926399496b.tar.gz sqlite-50ebf16dd630caa89e0eb87332b1c9926399496b.zip |
Merge latest trunk changes into this branch.
FossilOrigin-Name: d67a42d62555cf9294e11a04d3c7cfdf11ca7978d60fc085f5a73e36aff8313e
Diffstat (limited to 'src/util.c')
-rw-r--r-- | src/util.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/src/util.c b/src/util.c index 52c2a744c..ecce460e0 100644 --- a/src/util.c +++ b/src/util.c @@ -539,8 +539,8 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ int eValid = 1; /* True exponent is either not used or is well-formed */ int nDigit = 0; /* Number of digits processed */ int eType = 1; /* 1: pure integer, 2+: fractional -1 or less: bad UTF16 */ + u64 s2; /* round-tripped significand */ double rr[2]; - u64 s2; assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); *pResult = 0.0; /* Default return value, in case of an error */ @@ -643,7 +643,7 @@ do_atof_calc: e = (e*esign) + d; /* Try to adjust the exponent to make it smaller */ - while( e>0 && s<(LARGEST_UINT64/10) ){ + while( e>0 && s<((LARGEST_UINT64-0x7ff)/10) ){ s *= 10; e--; } @@ -653,11 +653,22 @@ do_atof_calc: } rr[0] = (double)s; - s2 = (u64)rr[0]; -#if defined(_MSC_VER) && _MSC_VER<1700 - if( s2==0x8000000000000000LL ){ s2 = 2*(u64)(0.5*rr[0]); } + assert( sizeof(s2)==sizeof(rr[0]) ); +#ifdef SQLITE_DEBUG + rr[1] = 18446744073709549568.0; + memcpy(&s2, &rr[1], sizeof(s2)); + assert( s2==0x43efffffffffffffLL ); #endif - rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); + /* Largest double that can be safely converted to u64 + ** vvvvvvvvvvvvvvvvvvvvvv */ + if( rr[0]<=18446744073709549568.0 ){ + s2 = (u64)rr[0]; + rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); + }else{ + rr[1] = 0.0; + } + assert( rr[1]<=1.0e-10*rr[0] ); /* Equal only when rr[0]==0.0 */ + if( e>0 ){ while( e>=100 ){ e -= 100; |