From: drh Date: Fri, 26 Jun 2020 15:32:29 +0000 (+0000) Subject: Add the ieee754_to_blob() and ieee754_from_blob() functions. Fix the handling X-Git-Tag: version-3.33.0~96 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=85c47546971940dae84b22a77254a4a42cbdbc98;p=thirdparty%2Fsqlite.git Add the ieee754_to_blob() and ieee754_from_blob() functions. Fix the handling of subnormal forms in the two-argument version of ieee754(). FossilOrigin-Name: c78cbf2e86850cc6882d3f0bd5415f6e731c3c675ffe77bb343682c619cb8cd9 --- diff --git a/ext/misc/ieee754.c b/ext/misc/ieee754.c index 40744052b1..cb274c3f7b 100644 --- a/ext/misc/ieee754.c +++ b/ext/misc/ieee754.c @@ -37,6 +37,11 @@ ** ieee754_mantissa(45.25) -> 181 ** ieee754_exponent(45.25) -> -2 ** +** These functions convert binary64 numbers into blobs and back again. +** +** ieee754_from_blob(x'3ff0000000000000') -> 1.0 +** ieee754_to_blob(1.0) -> x'3ff0000000000000' +** ** In all single-argument functions, if the argument is an 8-byte blob ** then that blob is interpreted as a big-endian binary64 value. ** @@ -160,7 +165,7 @@ static void ieee754func( isNeg = 1; m = -m; if( m<0 ) return; - }else if( m==0 && e>1000 && e<1000 ){ + }else if( m==0 && e>-1000 && e<1000 ){ sqlite3_result_double(context, 0.0); return; } @@ -173,8 +178,13 @@ static void ieee754func( e--; } e += 1075; - if( e<0 ) e = m = 0; - if( e>0x7ff ) e = 0x7ff; + if( e<=0 ){ + /* Subnormal */ + m >>= 1-e; + e = 0; + }else if( e>0x7ff ){ + e = 0x7ff; + } a = m & ((((sqlite3_int64)1)<<52)-1); a |= e<<52; if( isNeg ) a |= ((sqlite3_uint64)1)<<63; @@ -183,6 +193,49 @@ static void ieee754func( } } +/* +** Functions to convert between blobs and floats. +*/ +static void ieee754func_from_blob( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + if( sqlite3_value_type(argv[0])==SQLITE_BLOB + && sqlite3_value_bytes(argv[0])==sizeof(double) + ){ + double r; + const unsigned char *x = sqlite3_value_blob(argv[0]); + int i; + sqlite3_uint64 v = 0; + for(i=0; i>= 8; + } + sqlite3_result_blob(context, a, sizeof(r), SQLITE_TRANSIENT); + } +} + #ifdef _WIN32 __declspec(dllexport) @@ -196,11 +249,15 @@ int sqlite3_ieee_init( char *zFName; int nArg; int iAux; + void (*xFunc)(sqlite3_context*,int,sqlite3_value**); } aFunc[] = { - { "ieee754", 1, 0 }, - { "ieee754", 2, 0 }, - { "ieee754_mantissa", 1, 1 }, - { "ieee754_exponent", 1, 2 }, + { "ieee754", 1, 0, ieee754func }, + { "ieee754", 2, 0, ieee754func }, + { "ieee754_mantissa", 1, 1, ieee754func }, + { "ieee754_exponent", 1, 2, ieee754func }, + { "ieee754_to_blob", 1, 0, ieee754func_to_blob }, + { "ieee754_from_blob", 1, 0, ieee754func_from_blob }, + }; int i; int rc = SQLITE_OK; @@ -210,7 +267,7 @@ int sqlite3_ieee_init( rc = sqlite3_create_function(db, aFunc[i].zFName, aFunc[i].nArg, SQLITE_UTF8|SQLITE_INNOCUOUS, (void*)&aFunc[i].iAux, - ieee754func, 0, 0); + aFunc[i].xFunc, 0, 0); } return rc; } diff --git a/manifest b/manifest index 68df1f1b75..2ba4e69f8d 100644 --- a/manifest +++ b/manifest @@ -1,12 +1,12 @@ B 7a876209a678a34c198b54ceef9e3c041f128a14dc73357f6a57cadadaa6cf7b -C Fix\sa\spossible\snull\spointer\sderef\sfollowing\sOOM.\s\sDiscovered\sby\sdbsqlfuzz. -D 2020-06-26T04:34:28.728 +C Add\sthe\sieee754_to_blob()\sand\sieee754_from_blob()\sfunctions.\s\sFix\sthe\shandling\nof\ssubnormal\sforms\sin\sthe\stwo-argument\sversion\sof\sieee754(). +D 2020-06-26T15:32:29.122 F Makefile.in 19374a5db06c3199ec1bab71ab74a103d8abf21053c05e9389255dc58083f806 F Makefile.msc 48f5a3fc32672c09ad73795749f6253e406a31526935fbbffd8f021108d54574 F autoconf/Makefile.am a8d1d24affe52ebf8d7ddcf91aa973fa0316618ab95bb68c87cabf8faf527dc8 F ext/lsm1/lsm_unix.c 11e0a5c19d754a4e1d93dfad06de8cc201f10f886b8e61a4c599ed34e334fc24 F ext/misc/decimal.c c1897f624893d1c12e3c879d97ca7d1c4a36cae10d32afe632779de78c4aaa4f -F ext/misc/ieee754.c 7303cc27dfaf08dbe187bd63185dae7310e73f63f2e0aaa1d3bd8cee65173281 +F ext/misc/ieee754.c bb6bd8e9eeeda5a7ac82839fcab5c0b8156b0532165387cc5458a97f60047b5d F main.mk b1cd0bc6aedad7ebb667b7f74f835f932f60ee33be2a5c3051fd93eb465f5c75 F src/build.c ba1bbe563a3dc02d5fed20537603181e5289c13ea30ae5e775f552e7557adbfa F src/expr.c a3ab84399b3415f66d2d0c25f5bcd98ef465c0c07ea1f19bf2a418b1c8fcad74 @@ -14,12 +14,13 @@ F src/shell.c.in d663152487d4bfddea0f6d21ebc2ed51575d22657a02c6828afd344bbd4651a F src/test1.c fe56c4bcaa2685ca9aa25d817a0ee9345e189aff4a5a71a3d8ba946c7776feb8 F test/decimal.test 12739a01bdba4c4d79f95b323e6b67b9fad1ab6ffb56116bd2b9c81a5b19e1d9 F test/fuzzdata8.db 0ae860b36b79fd41cafddc9e6602358b2d5c331cf200283221e659f86e196c0c +F test/ieee754.test b0945d12be7d255f3dfa18e2511b17ca37e0edd2b803231c52d05b86c04ab26e F test/speedtest1.c ea201573f9b27542ea1e74a68e74f121e0eb04c89e67039f40ed68f1b833339f F tool/mkautoconfamal.sh f62353eb6c06ab264da027fd4507d09914433dbdcab9cb011cdc18016f1ab3b8 F tool/mksqlite3c.tcl f4ef476510eca4124c874a72029f1e01bc54a896b1724e8f9eef0d8bfae0e84c F tool/mksqlite3h.tcl 1f5e4a1dbbbc43c83cc6e74fe32c6c620502240b66c7c0f33a51378e78fc4edf F tool/showlocks.c 9cc5e66d4ebbf2d194f39db2527ece92077e86ae627ddd233ee48e16e8142564 -P adb7484f93329c7a94cd84e30bc4a8dbf2d6e901eba17cc3454afb8ba346cbf4 -R 75144d9ad27fa13b3371c63198b17db4 +P cc888878ea8d5bc754c69de523819d32d6d9853857e31d7287f9dbfd723428db +R f9fe5af62ab3ae1046135e82fbe40688 U drh -Z 11caf1c9a5c1ea5e3c3cf8efb37ecca6 +Z e965f5dba0fbca5306547d1182c19c0d diff --git a/manifest.uuid b/manifest.uuid index 75d305c546..7da6a41c7e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cc888878ea8d5bc754c69de523819d32d6d9853857e31d7287f9dbfd723428db \ No newline at end of file +c78cbf2e86850cc6882d3f0bd5415f6e731c3c675ffe77bb343682c619cb8cd9 \ No newline at end of file diff --git a/test/ieee754.test b/test/ieee754.test index bf0676429b..bd806d2cf3 100644 --- a/test/ieee754.test +++ b/test/ieee754.test @@ -23,8 +23,8 @@ foreach {id float rep} { 3 0.5 1,-1 4 1.5 3,-1 5 0.0 0,-1075 - 6 4.9406564584124654e-324 4503599627370497,-1075 - 7 2.2250738585072009e-308 9007199254740991,-1075 + 6 4.9406564584124654e-324 1,-1074 + 7 2.2250738585072009e-308 4503599627370495,-1074 8 2.2250738585072014e-308 1,-1022 } { do_test ieee754-100-$id-1 {