]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the ieee754_to_blob() and ieee754_from_blob() functions. Fix the handling
authordrh <drh@noemail.net>
Fri, 26 Jun 2020 15:32:29 +0000 (15:32 +0000)
committerdrh <drh@noemail.net>
Fri, 26 Jun 2020 15:32:29 +0000 (15:32 +0000)
of subnormal forms in the two-argument version of ieee754().

FossilOrigin-Name: c78cbf2e86850cc6882d3f0bd5415f6e731c3c675ffe77bb343682c619cb8cd9

ext/misc/ieee754.c
manifest
manifest.uuid
test/ieee754.test

index 40744052b10c735c57f424f3844266062b06536c..cb274c3f7be6fce952bcee8ede08cf7ce4a173c2 100644 (file)
 **     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<sizeof(r); i++){
+      v = (v<<8) | x[i];
+    }
+    memcpy(&r, &v, sizeof(r));
+    sqlite3_result_double(context, r);
+  }
+}
+static void ieee754func_to_blob(
+  sqlite3_context *context,
+  int argc,
+  sqlite3_value **argv
+){
+  if( sqlite3_value_type(argv[0])==SQLITE_FLOAT
+   || sqlite3_value_type(argv[0])==SQLITE_INTEGER
+  ){
+    double r = sqlite3_value_double(argv[0]);
+    sqlite3_uint64 v;
+    unsigned char a[sizeof(r)];
+    int i;
+    memcpy(&v, &r, sizeof(r));
+    for(i=1; i<=sizeof(r); i++){
+      a[sizeof(r)-i] = v&0xff;
+      v >>= 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;
 }
index 68df1f1b757e657373d4a4a53a4514d828a9ad2f..2ba4e69f8d68370c544cdf1642b168a6ee80123c 100644 (file)
--- 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
index 75d305c546877d0ab885464aeca9798249ebc67c..7da6a41c7e16760f763ea8ee698959e5c1432113 100644 (file)
@@ -1 +1 @@
-cc888878ea8d5bc754c69de523819d32d6d9853857e31d7287f9dbfd723428db
\ No newline at end of file
+c78cbf2e86850cc6882d3f0bd5415f6e731c3c675ffe77bb343682c619cb8cd9
\ No newline at end of file
index bf0676429b7b30794e8c56a7da9e69658d7b5cda..bd806d2cf3386d9f7ac764cc2c1b37a654584004 100644 (file)
@@ -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 {