diff options
author | drh <drh@noemail.net> | 2012-06-19 00:45:16 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2012-06-19 00:45:16 +0000 |
commit | 89f15088f0bc72252fcbda6981a56e80ba7d739c (patch) | |
tree | edc38aa6c0722a1d292a41b8b682baaf502821c2 /src | |
parent | 2ae26b759d75db1f4270b3225b30f40128e5d31b (diff) | |
download | sqlite-89f15088f0bc72252fcbda6981a56e80ba7d739c.tar.gz sqlite-89f15088f0bc72252fcbda6981a56e80ba7d739c.zip |
Improved rounding accuracy on test-to-float conversions.
FossilOrigin-Name: 699b792c6a0e989994549959b11ec1bfad8bbd92
Diffstat (limited to 'src')
-rw-r--r-- | src/test_func.c | 38 | ||||
-rw-r--r-- | src/util.c | 2 |
2 files changed, 39 insertions, 1 deletions
diff --git a/src/test_func.c b/src/test_func.c index c4fe351cb..6f9bb03dc 100644 --- a/src/test_func.c +++ b/src/test_func.c @@ -422,6 +422,43 @@ static void testHexToUtf16le( } #endif +/* +** SQL function: real2hex(X) +** +** If argument X is a real number, then convert it into a string which is +** the big-endian hexadecimal representation of the ieee754 encoding of +** that number. If X is not a real number, return NULL. +*/ +static void real2hex( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + union { + sqlite3_uint64 i; + double r; + unsigned char x[8]; + } v; + char zOut[20]; + int i; + int bigEndian; + v.i = 1; + bigEndian = v.x[0]==0; + v.r = sqlite3_value_double(argv[0]); + for(i=0; i<8; i++){ + if( bigEndian ){ + zOut[i*2] = "0123456789abcdef"[v.x[i]>>4]; + zOut[i*2+1] = "0123456789abcdef"[v.x[i]&0xf]; + }else{ + zOut[14-i*2] = "0123456789abcdef"[v.x[i]>>4]; + zOut[14-i*2+1] = "0123456789abcdef"[v.x[i]&0xf]; + } + } + zOut[16] = 0; + sqlite3_result_text(context, zOut, -1, SQLITE_TRANSIENT); +} + + static int registerTestFunctions(sqlite3 *db){ static const struct { char *zName; @@ -444,6 +481,7 @@ static int registerTestFunctions(sqlite3 *db){ { "test_eval", 1, SQLITE_UTF8, test_eval}, { "test_isolation", 2, SQLITE_UTF8, test_isolation}, { "test_counter", 1, SQLITE_UTF8, counterFunc}, + { "real2hex", 1, SQLITE_UTF8, real2hex}, }; int i; diff --git a/src/util.c b/src/util.c index dd3b08ae4..5cf8ebacb 100644 --- a/src/util.c +++ b/src/util.c @@ -371,7 +371,7 @@ do_atof_calc: /* if exponent, scale significand as appropriate ** and store in result. */ if( e ){ - double scale = 1.0; + LONGDOUBLE_TYPE scale = 1.0; /* attempt to handle extremely small/large numbers better */ if( e>307 && e<342 ){ while( e%308 ) { scale *= 1.0e+1; e -= 1; } |