**
** Examples:
**
-** ieee754(2.0) -> 'ieee754(2,0)'
-** ieee754(45.25) -> 'ieee754(181,-2)'
-** ieee754(2, 0) -> 2.0
-** ieee754(181, -2) -> 45.25
+** ieee754(2.0) -> 'ieee754(2,0)'
+** ieee754(45.25) -> 'ieee754(181,-2)'
+** ieee754(2, 0) -> 2.0
+** ieee754(181, -2) -> 45.25
+**
+** Two additional functions break apart the one-argument ieee754()
+** result into separate integer values:
+**
+** ieee754_mantissa(45.25) -> 181
+** ieee754_exponent(45.25) -> -2
+**
+** In all single-argument functions, if the argument is an 8-byte blob
+** then that blob is interpreted as a big-endian binary64 value.
+**
+**
+** EXACT DECIMAL REPRESENTATION OF BINARY64 VALUES
+** -----------------------------------------------
+**
+** This extension in combination with the separate 'decimal' extension
+** can be used to compute the exact decimal representation of binary64
+** values. To begin, first compute a table of exponent values:
+**
+** CREATE TABLE pow2(x INTEGER PRIMARY KEY, v TEXT);
+** WITH RECURSIVE c(x,v) AS (
+** VALUES(0,'1')
+** UNION ALL
+** SELECT x+1, decimal_mul(v,'2') FROM c WHERE x+1<=971
+** ) INSERT INTO pow2(x,v) SELECT x, v FROM c;
+** WITH RECURSIVE c(x,v) AS (
+** VALUES(-1,'0.5')
+** UNION ALL
+** SELECT x-1, decimal_mul(v,'0.5') FROM c WHERE x-1>=-1075
+** ) INSERT INTO pow2(x,v) SELECT x, v FROM c;
+**
+** Then, to compute the exact decimal representation of a floating
+** point value (the value 47.49 is used in the example) do:
+**
+** WITH c(n) AS (VALUES(47.49))
+** ---------------^^^^^---- Replace with whatever you want
+** SELECT decimal_mul(ieee754_mantissa(c.n),pow2.v)
+** FROM pow2, c WHERE pow2.x=ieee754_exponent(c.n);
+**
+** Here is a query to show various boundry values for the binary64
+** number format:
+**
+** WITH c(name,bin) AS (VALUES
+** ('minimum positive value', x'0000000000000001'),
+** ('maximum subnormal value', x'000fffffffffffff'),
+** ('mininum positive nornal value', x'0010000000000000'),
+** ('maximum value', x'7fefffffffffffff'))
+** SELECT c.name, decimal_mul(ieee754_mantissa(c.bin),pow2.v)
+** FROM pow2, c WHERE pow2.x=ieee754_exponent(c.bin);
+**
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
}
if( isNeg ) m = -m;
}
- sqlite3_snprintf(sizeof(zResult), zResult, "ieee754(%lld,%d)",
- m, e-1075);
- sqlite3_result_text(context, zResult, -1, SQLITE_TRANSIENT);
- }else if( argc==2 ){
+ switch( *(int*)sqlite3_user_data(context) ){
+ case 0:
+ sqlite3_snprintf(sizeof(zResult), zResult, "ieee754(%lld,%d)",
+ m, e-1075);
+ sqlite3_result_text(context, zResult, -1, SQLITE_TRANSIENT);
+ break;
+ case 1:
+ sqlite3_result_int64(context, m);
+ break;
+ case 2:
+ sqlite3_result_int(context, e-1075);
+ break;
+ }
+ }else{
sqlite3_int64 m, e, a;
double r;
int isNeg = 0;
char **pzErrMsg,
const sqlite3_api_routines *pApi
){
+ static const struct {
+ char *zFName;
+ int nArg;
+ int iAux;
+ } aFunc[] = {
+ { "ieee754", 1, 0 },
+ { "ieee754", 2, 0 },
+ { "ieee754_mantissa", 1, 1 },
+ { "ieee754_exponent", 1, 2 },
+ };
+ int i;
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
(void)pzErrMsg; /* Unused parameter */
- rc = sqlite3_create_function(db, "ieee754", 1,
- SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
+ for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
+ rc = sqlite3_create_function(db, aFunc[i].zFName, aFunc[i].nArg,
+ SQLITE_UTF8|SQLITE_INNOCUOUS,
+ (void*)&aFunc[i].iAux,
ieee754func, 0, 0);
- if( rc==SQLITE_OK ){
- rc = sqlite3_create_function(db, "ieee754", 2,
- SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
- ieee754func, 0, 0);
}
return rc;
}
B 7a876209a678a34c198b54ceef9e3c041f128a14dc73357f6a57cadadaa6cf7b
-C Fix\sthe\sdecoding\sof\ssubnormal\svalues\sin\sthe\sieee754\sextension.
-D 2020-06-24T13:52:10.631
-F Makefile.in 014ad669b4a5809752939c2dea83722992711b464aa56adebca80c5cc98cfdc2
-F Makefile.msc 08c8bbedfa51e21b57153370edbfee86d35bbefb53e3773a3e086fe654facccb
+C Add\sthe\sieee754_mantissa()\sand\sieee754_exponent()\sfunctions\sto\sthe\siee754\nextension.\s\sBuild\sthe\sieee754\sextension\sinto\sthe\sCLI.
+D 2020-06-24T15:06:29.041
+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 94846ee4b2e7a77faf9980b36b9862b67735991448665a1ef9888254697e60db
-F main.mk c99e452dd4edd0bea28547259421bd6cf24d41d928d24720737efc548958ca39
+F ext/misc/ieee754.c 7303cc27dfaf08dbe187bd63185dae7310e73f63f2e0aaa1d3bd8cee65173281
+F main.mk b1cd0bc6aedad7ebb667b7f74f835f932f60ee33be2a5c3051fd93eb465f5c75
F src/build.c ba1bbe563a3dc02d5fed20537603181e5289c13ea30ae5e775f552e7557adbfa
-F src/shell.c.in a46df1496dea229614a14ca1c517f9e4bfecf6e3867cc6a4a129b311f3ad8c9c
+F src/shell.c.in d663152487d4bfddea0f6d21ebc2ed51575d22657a02c6828afd344bbd4651af
F src/test1.c fe56c4bcaa2685ca9aa25d817a0ee9345e189aff4a5a71a3d8ba946c7776feb8
F test/decimal.test 12739a01bdba4c4d79f95b323e6b67b9fad1ab6ffb56116bd2b9c81a5b19e1d9
F test/speedtest1.c ea201573f9b27542ea1e74a68e74f121e0eb04c89e67039f40ed68f1b833339f
F tool/mkautoconfamal.sh f62353eb6c06ab264da027fd4507d09914433dbdcab9cb011cdc18016f1ab3b8
F tool/mksqlite3c.tcl f4ef476510eca4124c874a72029f1e01bc54a896b1724e8f9eef0d8bfae0e84c
F tool/mksqlite3h.tcl 1f5e4a1dbbbc43c83cc6e74fe32c6c620502240b66c7c0f33a51378e78fc4edf
-P 4199c1e8aa47d77df3ef598cb6f5418f67970dd00f34823463c85eabfc8d2b77
-R ba2656328834bfd4a44f83b197706ae6
+P 838817b680f02b3845d6d56f85d5d36fa5ae7453afef7a1a5a24624255f2dc3e
+R 6e286f8b0cf2dcbbb10b38a65d995df9
U drh
-Z 3f979f9393c7d6c04f34a16bcf1ccd28
+Z 549c83ceeab0b10ef9bb12772423a56c