1
0
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:
drh
2024-12-07 14:48:55 +00:00
parent ef636cc3cd
commit 1a4b2117f1
4 changed files with 56 additions and 12 deletions

View File

@@ -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;