1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-27 20:41:58 +03:00

Add the decimal_sci(X) function to the Decimal extension for showing a decimal

value in scientific notation:  +D.DDDDDe+DD

FossilOrigin-Name: 61d4923913e88b980ce93db4f3f9f9d7ba3baaac724995c36c9b887c034accdc
This commit is contained in:
drh
2023-06-29 14:49:23 +00:00
parent 7f5fe1faf3
commit 9ea7632cca
3 changed files with 84 additions and 7 deletions

View File

@ -230,6 +230,67 @@ static void decimal_result(sqlite3_context *pCtx, Decimal *p){
sqlite3_result_text(pCtx, z, i, sqlite3_free);
}
/*
** Make the given Decimal the result in an format similar to '%+#e'.
** In other words, show exponential notation with leading and trailing
** zeros omitted.
*/
static void decimal_result_sci(sqlite3_context *pCtx, Decimal *p){
char *z; /* The output buffer */
int i; /* Loop counter */
int nZero; /* Number of leading zeros */
int nDigit; /* Number of digits not counting trailing zeros */
int nFrac; /* Digits to the right of the decimal point */
int exp; /* Exponent value */
signed char zero; /* Zero value */
signed char *a; /* Array of digits */
if( p==0 || p->oom ){
sqlite3_result_error_nomem(pCtx);
return;
}
if( p->isNull ){
sqlite3_result_null(pCtx);
return;
}
for(nDigit=p->nDigit; nDigit>0 && p->a[nDigit-1]==0; nDigit--){}
for(nZero=0; nZero<nDigit && p->a[nZero]==0; nZero++){}
nFrac = p->nFrac + (nDigit - p->nDigit);
nDigit -= nZero;
z = sqlite3_malloc( nDigit+20 );
if( z==0 ){
sqlite3_result_error_nomem(pCtx);
return;
}
if( nDigit==0 ){
zero = 0;
a = &zero;
nDigit = 1;
nFrac = 0;
}else{
a = &p->a[nZero];
}
if( p->sign && nDigit>0 ){
z[0] = '-';
}else{
z[0] = '+';
}
z[1] = a[0]+'0';
z[2] = '.';
if( nDigit==1 ){
z[3] = '0';
i = 4;
}else{
for(i=1; i<nDigit; i++){
z[2+i] = a[i]+'0';
}
i = nDigit+2;
}
exp = nDigit - nFrac - 1;
sqlite3_snprintf(nDigit+20-i, &z[i], "e%+03d", exp);
sqlite3_result_text(pCtx, z, -1, sqlite3_free);
}
/*
** SQL Function: decimal(X)
**
@ -591,6 +652,21 @@ mul_end:
decimal_free(pB);
}
/*
** SQL Function: decimal_sci(X)
**
** Convert decimal number X into scientific notation ("+N.NNNe+NN").
*/
static void decimalSciFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
Decimal *pA = decimal_new(context, argv[0], 0, 0);
decimal_result_sci(context, pA);
decimal_free(pA);
}
#ifdef _WIN32
__declspec(dllexport)
#endif
@ -610,6 +686,7 @@ int sqlite3_decimal_init(
{ "decimal_add", 2, decimalAddFunc },
{ "decimal_sub", 2, decimalSubFunc },
{ "decimal_mul", 2, decimalMulFunc },
{ "decimal_sci", 1, decimalSciFunc },
};
unsigned int i;
(void)pzErrMsg; /* Unused parameter */