diff options
author | drh <> | 2023-07-01 15:23:24 +0000 |
---|---|---|
committer | drh <> | 2023-07-01 15:23:24 +0000 |
commit | 9ee9444a0adbf8f04081447d70d570f17c1a6e6a (patch) | |
tree | fa03bf2abe4a0407f771e5c5ff059dc7542a06fc /src | |
parent | 42d042e602233be808084e78ccbaba1b497c69a3 (diff) | |
download | sqlite-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.c | 25 | ||||
-rw-r--r-- | src/printf.c | 52 | ||||
-rw-r--r-- | src/sqliteInt.h | 3 | ||||
-rw-r--r-- | src/util.c | 22 |
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 |