diff options
author | drh <drh@noemail.net> | 2018-01-23 17:33:42 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2018-01-23 17:33:42 +0000 |
commit | d15046ac080f4633186fe0e31712525a4326a4bc (patch) | |
tree | 57d5158ea9507d652523c7feec34206b6b5b5181 /src | |
parent | a916b570137f728a04d4a3be0cb792dd5a22cf63 (diff) | |
download | sqlite-d15046ac080f4633186fe0e31712525a4326a4bc.tar.gz sqlite-d15046ac080f4633186fe0e31712525a4326a4bc.zip |
Work around a problem with GCC on 32-bit machines that cause the CAST
operator to generate a floating-point result for strings that could be
represented as very large integers.
FossilOrigin-Name: 1b02731962c21bb097a88801ece76ff441bf882519a821a246da84f4e2a33455
Diffstat (limited to 'src')
-rw-r--r-- | src/vdbemem.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/src/vdbemem.c b/src/vdbemem.c index d8f1e6432..e2912b3a6 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -582,6 +582,18 @@ int sqlite3VdbeMemRealify(Mem *pMem){ return SQLITE_OK; } +/* Compare a floating point value to an integer. Return true if the two +** values are the same within the precision of the floating point value. +** +** For some versions of GCC on 32-bit machines, if you do the more obvious +** comparison of "r1==(double)i" you sometimes get an answer of false even +** though the r1 and (double)i values are bit-for-bit the same. +*/ +static int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){ + double r2 = (double)i; + return memcmp(&r1, &r2, sizeof(r1))==0; +} + /* ** Convert pMem so that it has types MEM_Real or MEM_Int or both. ** Invalidate any prior representations. @@ -601,7 +613,7 @@ int sqlite3VdbeMemNumerify(Mem *pMem){ }else{ i64 i = pMem->u.i; sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc); - if( rc==1 && pMem->u.r==(double)i ){ + if( rc==1 && sqlite3RealSameAsInt(pMem->u.r, i) ){ pMem->u.i = i; MemSetTypeFlag(pMem, MEM_Int); }else{ |