aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <>2023-07-01 15:23:24 +0000
committerdrh <>2023-07-01 15:23:24 +0000
commit9ee9444a0adbf8f04081447d70d570f17c1a6e6a (patch)
treefa03bf2abe4a0407f771e5c5ff059dc7542a06fc /src
parent42d042e602233be808084e78ccbaba1b497c69a3 (diff)
downloadsqlite-9ee9444a0adbf8f04081447d70d570f17c1a6e6a.tar.gz
sqlite-9ee9444a0adbf8f04081447d70d570f17c1a6e6a.zip
Improved response to Infinity and NaN. Remove the termporary fpdecode()
function. FossilOrigin-Name: 76ab8ae809a47a66688e2d50c20dc87ce946d82e9ffebb3adda55c451fad07fc
Diffstat (limited to 'src')
-rw-r--r--src/func.c25
-rw-r--r--src/printf.c52
-rw-r--r--src/sqliteInt.h3
-rw-r--r--src/util.c22
4 files changed, 33 insertions, 69 deletions
diff --git a/src/func.c b/src/func.c
index e41af59b7..b24359186 100644
--- a/src/func.c
+++ b/src/func.c
@@ -2371,25 +2371,6 @@ static void signFunc(
sqlite3_result_int(context, x<0.0 ? -1 : x>0.0 ? +1 : 0);
}
-
-#if 1 /* Temporary prototyping logic */
-static void fpdecodeFunc(
- sqlite3_context *context,
- int argc,
- sqlite3_value **argv
-){
- double r = sqlite3_value_double(argv[0]);
- int n = 15;
- FpDecode s;
- char zBuf[50];
-
- if( argc>=2 ) n = sqlite3_value_int(argv[1]);
- sqlite3FpDecode(&s, r, n);
- sqlite3_snprintf(sizeof(zBuf), zBuf, "%c%.*s/%d", s.sign, s.n, s.z, s.iDP);
- sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
-}
-#endif /* Temporary prototyping logic */
-
/*
** All of the FuncDef structures in the aBuiltinFunc[] array above
** to the global function hash table. This occurs at start-time (as
@@ -2461,12 +2442,6 @@ void sqlite3RegisterBuiltinFunctions(void){
FUNCTION(unicode, 1, 0, 0, unicodeFunc ),
FUNCTION(char, -1, 0, 0, charFunc ),
FUNCTION(abs, 1, 0, 0, absFunc ),
-
-#if 1 /* Temporary prototyping function */
- FUNCTION(fpdecode, 1, 0, 0, fpdecodeFunc ),
- FUNCTION(fpdecode, 2, 0, 0, fpdecodeFunc ),
-#endif
-
#ifndef SQLITE_OMIT_FLOATING_POINT
FUNCTION(round, 1, 0, 0, roundFunc ),
FUNCTION(round, 2, 0, 0, roundFunc ),
diff --git a/src/printf.c b/src/printf.c
index 78f59757d..4de06c116 100644
--- a/src/printf.c
+++ b/src/printf.c
@@ -482,6 +482,7 @@ void sqlite3_str_vappendf(
case etEXP:
case etGENERIC: {
FpDecode s;
+ int iRound;
if( bArgList ){
realvalue = getDoubleArg(pArgList);
@@ -494,33 +495,36 @@ void sqlite3_str_vappendf(
precision = SQLITE_FP_PRECISION_LIMIT;
}
#endif
- switch( xtype ){
- case etFLOAT: sqlite3FpDecode(&s, realvalue, -precision); break;
- case etGENERIC: sqlite3FpDecode(&s, realvalue, precision); break;
- case etEXP: sqlite3FpDecode(&s, realvalue, precision+1); break;
- }
- if( s.isNan ){
- if( flag_zeropad ){
- bufpt = "null";
- length = 4;
- }else{
- bufpt = "NaN";
- length = 3;
- }
- break;
+ if( xtype==etFLOAT ){
+ iRound = -precision;
+ }else if( xtype==etGENERIC ){
+ iRound = precision;
+ }else{
+ iRound = precision+1;
}
- if( s.isInf ){
- if( s.sign=='-' ){
- bufpt = "-Inf";
- length = 4;
- }else if( flag_prefix=='+' ){
- bufpt = "+Inf";
- length = 4;
+ sqlite3FpDecode(&s, realvalue, iRound);
+ if( s.isSpecial ){
+ if( s.isSpecial==2 ){
+ bufpt = flag_zeropad ? "null" : "NaN";
+ length = sqlite3Strlen30(bufpt);
+ break;
+ }else if( flag_zeropad ){
+ s.z[0] = '9';
+ s.iDP = 1000;
+ s.n = 1;
}else{
- bufpt = "Inf";
- length = 3;
+ memcpy(buf, "-Inf", 5);
+ bufpt = buf;
+ if( s.sign=='-' ){
+ /* no-op */
+ }else if( flag_prefix ){
+ buf[0] = flag_prefix;
+ }else{
+ bufpt++;
+ }
+ length = sqlite3Strlen30(bufpt);
+ break;
}
- break;
}
if( s.sign=='-' ){
prefix = '-';
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 96cac978c..011a44bcb 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -4604,8 +4604,7 @@ struct PrintfArguments {
*/
struct FpDecode {
char sign; /* '+' or '-' */
- char isNan; /* True if not-a-number */
- char isInf; /* True if infinity */
+ char isSpecial; /* 1: Infinity 2: NaN */
int n; /* Significant digits in the decode */
int iDP; /* Location of the decimal point */
char z[24]; /* Significiant digits */
diff --git a/src/util.c b/src/util.c
index a648dc2d1..0950d8427 100644
--- a/src/util.c
+++ b/src/util.c
@@ -941,6 +941,7 @@ void sqlite3FpDecode(FpDecode *p, double r, int iRound){
int i;
u64 v;
int e, exp = 0;
+ p->isSpecial = 0;
if( r<0.0 ){
p->sign = '-';
r = -r;
@@ -949,8 +950,6 @@ void sqlite3FpDecode(FpDecode *p, double r, int iRound){
p->n = 1;
p->iDP = 1;
p->z[0] = '0';
- p->isNan = 0;
- p->isInf = 0;
return;
}else{
p->sign = '+';
@@ -958,24 +957,11 @@ void sqlite3FpDecode(FpDecode *p, double r, int iRound){
memcpy(&v,&r,8);
e = v>>52;
if( (e&0x7ff)==0x7ff ){
- if( v==0x7ff0000000000000L ){
- p->isInf = 1;
- p->isNan = 0;
- p->z[0] = 'I';
- p->z[1] = 'n';
- p->z[2] = 'f';
- }else{
- p->isInf = 0;
- p->isNan = 1;
- p->z[0] = 'N';
- p->z[1] = 'a';
- p->z[2] = 'N';
- }
- p->n = 3;
- p->iDP = 3;
+ p->isSpecial = 1 + (v!=0x7ff0000000000000L);
+ p->n = 0;
+ p->iDP = 0;
return;
}
- p->isNan = p->isInf = 0;
/* At this point, r is positive (non-zero) and is not Inf or NaN.
** The strategy is to multiple or divide r by powers of 10 until