mirror of
https://github.com/sqlite/sqlite.git
synced 2026-01-06 08:01:16 +03:00
On x64 hardware, round-trip uint64_t→double→uint64_t conversions
fail for values greater than UINT64_MAX-2047. This caused the SQLite text-to-float converter routine to give incorrect results for values between '1.8446744073709550592eNNN' and '1.8446744073709551609eNNN' for any exponent NNN. This problem was introduced by check-in [761d8fd18b0ee868] and first appeared in version 3.47.0 and was reported by [forum:/forumpost/569a7209179a7f5e|forum post 569a7209179a7f5e]. Fixed by this check-in. FossilOrigin-Name: 81342fa6dd03fffbe7d4d699ff049dcef4d30344578bb6f91cb58a4e5a4f6036
This commit is contained in:
14
src/util.c
14
src/util.c
@@ -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,17 @@ do_atof_calc:
|
||||
}
|
||||
|
||||
rr[0] = (double)s;
|
||||
s2 = (u64)rr[0];
|
||||
if( s<(LARGEST_UINT64-0x7ff) ){
|
||||
s2 = (u64)rr[0];
|
||||
#if defined(_MSC_VER) && _MSC_VER<1700
|
||||
if( s2==0x8000000000000000LL ){ s2 = 2*(u64)(0.5*rr[0]); }
|
||||
if( s2==0x8000000000000000LL ){ s2 = 2*(u64)(0.5*rr[0]); }
|
||||
#endif
|
||||
rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s);
|
||||
rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s);
|
||||
}else{
|
||||
s2 = s;
|
||||
rr[1] = 0.0;
|
||||
}
|
||||
|
||||
if( e>0 ){
|
||||
while( e>=100 ){
|
||||
e -= 100;
|
||||
|
||||
Reference in New Issue
Block a user