diff options
author | shane <shane@noemail.net> | 2009-09-07 03:48:52 +0000 |
---|---|---|
committer | shane <shane@noemail.net> | 2009-09-07 03:48:52 +0000 |
commit | e025d1d7e51f20eca45730c0a54066eaa3336b15 (patch) | |
tree | 905e5a0a5dc4f12e6d71ea521e91c0a402df1c0f /src/util.c | |
parent | dcabfcee270e66766305ff728b7ddfaa683efe35 (diff) | |
download | sqlite-e025d1d7e51f20eca45730c0a54066eaa3336b15.tar.gz sqlite-e025d1d7e51f20eca45730c0a54066eaa3336b15.zip |
Attempt to handle numbers at the limits of the IEEE 754 range better (nan.test now passes).
FossilOrigin-Name: 2a74ae1969aeec93576a44e11177677e6f3cea9c
Diffstat (limited to 'src/util.c')
-rw-r--r-- | src/util.c | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/src/util.c b/src/util.c index 085d7140e..d12bcd536 100644 --- a/src/util.c +++ b/src/util.c @@ -375,14 +375,26 @@ int sqlite3AtoF(const char *z, double *pResult){ ** and store in result. */
if( e ){
double scale = 1.0;
- /* 1.0e+22 is the largest power of 10 than can be
- ** represented exactly. */
- while( e%22 ) { scale *= 1.0e+1; e -= 1; }
- while( e>0 ) { scale *= 1.0e+22; e -= 22; }
- if( esign<0 ){
- result = s / scale;
+ /* attempt to handle extremely small/large numbers better */
+ if( e>307 && e<342 ){
+ while( e%308 ) { scale *= 1.0e+1; e -= 1; }
+ if( esign<0 ){
+ result = s / scale;
+ result /= 1.0e+308;
+ }else{
+ result = s * scale;
+ result *= 1.0e+308;
+ }
}else{
- result = s * scale;
+ /* 1.0e+22 is the largest power of 10 than can be
+ ** represented exactly. */
+ while( e%22 ) { scale *= 1.0e+1; e -= 1; }
+ while( e>0 ) { scale *= 1.0e+22; e -= 22; }
+ if( esign<0 ){
+ result = s / scale;
+ }else{
+ result = s * scale;
+ }
}
} else {
result = (double)s;
|