z[i++] = '0';
}
j = 0;
+ while( n>1 && p->a[j]==0 ){
+ j++;
+ n--;
+ }
while( n>0 ){
z[i++] = p->a[j] + '0';
j++;
decimal_free(pB);
}
-/*
-** Remove leading zeros from before the decimal and
-** trailing zeros after the decimal.
-*/
-static void decimal_normalize(Decimal *p){
- int i;
- int nSig;
- if( p==0 ) return;
- nSig = p->nDigit - p->nFrac;
- for(i=0; i<nSig && p->a[i]==0; i++){}
- if( i ){
- memmove(p->a, p->a+i, p->nDigit - i);
- p->nDigit -= i;
- }
- while( p->nFrac && p->a[p->nDigit-1]==0 ){
- p->nFrac--;
- p->nDigit--;
- }
-}
-
/*
** Expand the Decimal so that it has a least nDigit digits and nFrac
** digits to the right of the decimal point.
/*
** Add the value pB into pA.
**
-** pB might become denormalized by this routine.
+** Both pA and pB might become denormalized by this routine.
*/
static void decimal_add(Decimal *pA, Decimal *pB){
int nSig, nFrac, nDigit;
return;
}
nSig = pA->nDigit - pA->nFrac;
- if( nSig<pB->nDigit-pB->nFrac ) nSig = pB->nDigit - pB->nFrac;
+ if( nSig && pA->a[0]==0 ) nSig--;
+ if( nSig<pB->nDigit-pB->nFrac ){
+ nSig = pB->nDigit - pB->nFrac;
+ }
nFrac = pA->nFrac;
if( nFrac<pB->nFrac ) nFrac = pB->nFrac;
nDigit = nSig + nFrac + 1;
}
}
}
- decimal_normalize(pA);
}
/*
static void decimalSumValue(sqlite3_context *context){
Decimal *p = sqlite3_aggregate_context(context, 0);
if( p==0 ) return;
- decimal_normalize(p);
decimal_result(context, p);
}
static void decimalSumFinalize(sqlite3_context *context){
Decimal *p = sqlite3_aggregate_context(context, 0);
if( p==0 ) return;
- decimal_normalize(p);
decimal_result(context, p);
decimal_clear(p);
}
** SQL Function: decimal_mul(X, Y)
**
** Return the product of X and Y.
+**
+** All significant digits after the decimal point are retained.
+** Trailing zeros after the decimal point are omitted as long as
+** the number of digits after the decimal point is no less than
+** either the number of digits in either input.
*/
static void decimalMulFunc(
sqlite3_context *context,
Decimal *pB = decimal_new(context, argv[1], 0, 0);
signed char *acc = 0;
int i, j, k;
+ int minFrac;
if( pA==0 || pA->oom || pA->isNull
|| pB==0 || pB->oom || pB->isNull
){
goto mul_end;
}
memset(acc, 0, pA->nDigit + pB->nDigit + 2);
+ minFrac = pA->nFrac;
+ if( pB->nFrac<minFrac ) minFrac = pB->nFrac;
for(i=pA->nDigit-1; i>=0; i--){
signed char f = pA->a[i];
int carry = 0, x;
pA->nDigit += pB->nDigit + 2;
pA->nFrac += pB->nFrac;
pA->sign ^= pB->sign;
- decimal_normalize(pA);
+ while( pA->nFrac>minFrac && pA->a[pA->nDigit-1]==0 ){
+ pA->nFrac--;
+ pA->nDigit--;
+ }
decimal_result(context, pA);
mul_end:
B 7a876209a678a34c198b54ceef9e3c041f128a14dc73357f6a57cadadaa6cf7b
-C Add\sthe\sdecimal_mul()\sfunction.
-D 2020-06-22T21:25:37.690
+C Avoid\sunnecessary\snormalization\sin\sdecimal_sum().\s\sTrim\sexcess\strailing\nzeros\soff\sthe\sresult\sof\sdecimal_mul().
+D 2020-06-23T14:44:57.292
F Makefile.in 014ad669b4a5809752939c2dea83722992711b464aa56adebca80c5cc98cfdc2
F Makefile.msc 08c8bbedfa51e21b57153370edbfee86d35bbefb53e3773a3e086fe654facccb
F autoconf/Makefile.am a8d1d24affe52ebf8d7ddcf91aa973fa0316618ab95bb68c87cabf8faf527dc8
-F ext/misc/decimal.c 334d8d34c124a8820d814dadbe1ac3daec63f504d5b322eb63671c317d3c6a3e
+F ext/misc/decimal.c 7ddba759b25b433231d1d9ca7cfba947992856059e2eefc5664160d4163c71d2
F main.mk c99e452dd4edd0bea28547259421bd6cf24d41d928d24720737efc548958ca39
F src/build.c ba1bbe563a3dc02d5fed20537603181e5289c13ea30ae5e775f552e7557adbfa
F src/shell.c.in 7fe12fb6452de32f92bb26ee50524ec31c9d08a1c46376ca00a4ecd27472a14d
F src/test1.c fe56c4bcaa2685ca9aa25d817a0ee9345e189aff4a5a71a3d8ba946c7776feb8
-F test/decimal.test c4af0264a0f30e896f617b489d69039932fe5127b02ac221d96f8af31db13826
+F test/decimal.test 12739a01bdba4c4d79f95b323e6b67b9fad1ab6ffb56116bd2b9c81a5b19e1d9
F tool/mkautoconfamal.sh f62353eb6c06ab264da027fd4507d09914433dbdcab9cb011cdc18016f1ab3b8
-P 4c3b85607feb53462ccc8b89bea699fdb132c402eae597afa33cc40a85c32329
-R d79a1d72394e5a5f6c93e9466f2c9aa1
+P 72eee04b67268ad38fd51ff32849f08c0a54cf1b481d5ecb11d77cc9c729ee03
+R 91beb964e18be89b7d24fd58df29ec37
U drh
-Z 3092a9d89a34e083e375231f8e857b54
+Z 2211c9af276c1b9a10695b6c4b82f27a