Add the ieee754_mantissa() and ieee754_exponent() functions to the iee754

extension.  Build the ieee754 extension into the CLI.

FossilOrigin-Name: db2f0836b64cd2e119684f1cf75fa3b19a84ca6aca1a239f7e2b9298016e2c95
This commit is contained in:
drh 2020-06-24 15:06:29 +00:00
parent ec18b6e5b9
commit 8cda77d44a
7 changed files with 104 additions and 31 deletions

View File

@ -1082,10 +1082,11 @@ keywordhash.h: $(TOP)/tool/mkkeywordhash.c
SHELL_SRC = \
$(TOP)/src/shell.c.in \
$(TOP)/ext/misc/appendvfs.c \
$(TOP)/ext/misc/shathree.c \
$(TOP)/ext/misc/completion.c \
$(TOP)/ext/misc/decimal.c \
$(TOP)/ext/misc/fileio.c \
$(TOP)/ext/misc/completion.c \
$(TOP)/ext/misc/ieee754.c \
$(TOP)/ext/misc/shathree.c \
$(TOP)/ext/misc/sqlar.c \
$(TOP)/ext/misc/uint.c \
$(TOP)/ext/expert/sqlite3expert.c \

View File

@ -2204,10 +2204,11 @@ keywordhash.h: $(TOP)\tool\mkkeywordhash.c mkkeywordhash.exe
SHELL_SRC = \
$(TOP)\src\shell.c.in \
$(TOP)\ext\misc\appendvfs.c \
$(TOP)\ext\misc\shathree.c \
$(TOP)\ext\misc\completion.c \
$(TOP)\ext\misc\decimal.c \
$(TOP)\ext\misc\fileio.c \
$(TOP)\ext\misc\completion.c \
$(TOP)\ext\misc\ieee754.c \
$(TOP)\ext\misc\shathree.c \
$(TOP)\ext\misc\uint.c \
$(TOP)\ext\expert\sqlite3expert.c \
$(TOP)\ext\expert\sqlite3expert.h \

View File

@ -26,10 +26,59 @@
**
** 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
@ -88,10 +137,20 @@ static void ieee754func(
}
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;
@ -133,16 +192,25 @@ int sqlite3_ieee_init(
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;
}

View File

@ -742,10 +742,11 @@ keywordhash.h: $(TOP)/tool/mkkeywordhash.c
SHELL_SRC = \
$(TOP)/src/shell.c.in \
$(TOP)/ext/misc/appendvfs.c \
$(TOP)/ext/misc/shathree.c \
$(TOP)/ext/misc/completion.c \
$(TOP)/ext/misc/decimal.c \
$(TOP)/ext/misc/fileio.c \
$(TOP)/ext/misc/completion.c \
$(TOP)/ext/misc/ieee754.c \
$(TOP)/ext/misc/shathree.c \
$(TOP)/ext/misc/sqlar.c \
$(TOP)/ext/misc/uint.c \
$(TOP)/ext/expert/sqlite3expert.c \

View File

@ -1,22 +1,22 @@
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

View File

@ -1 +1 @@
838817b680f02b3845d6d56f85d5d36fa5ae7453afef7a1a5a24624255f2dc3e
db2f0836b64cd2e119684f1cf75fa3b19a84ca6aca1a239f7e2b9298016e2c95

View File

@ -1012,6 +1012,7 @@ INCLUDE ../ext/misc/appendvfs.c
INCLUDE ../ext/misc/memtrace.c
INCLUDE ../ext/misc/uint.c
INCLUDE ../ext/misc/decimal.c
INCLUDE ../ext/misc/ieee754.c
#ifdef SQLITE_HAVE_ZLIB
INCLUDE ../ext/misc/zipfile.c
INCLUDE ../ext/misc/sqlar.c
@ -4558,6 +4559,7 @@ static void open_db(ShellState *p, int openFlags){
sqlite3_completion_init(p->db, 0, 0);
sqlite3_uint_init(p->db, 0, 0);
sqlite3_decimal_init(p->db, 0, 0);
sqlite3_ieee_init(p->db, 0, 0);
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
sqlite3_dbdata_init(p->db, 0, 0);
#endif