mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Add the decimal_mul() function.
FossilOrigin-Name: 72eee04b67268ad38fd51ff32849f08c0a54cf1b481d5ecb11d77cc9c729ee03
This commit is contained in:
@ -298,7 +298,8 @@ cmp_done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Remove leading zeros from the Decimal
|
** Remove leading zeros from before the decimal and
|
||||||
|
** trailing zeros after the decimal.
|
||||||
*/
|
*/
|
||||||
static void decimal_normalize(Decimal *p){
|
static void decimal_normalize(Decimal *p){
|
||||||
int i;
|
int i;
|
||||||
@ -310,6 +311,10 @@ static void decimal_normalize(Decimal *p){
|
|||||||
memmove(p->a, p->a+i, p->nDigit - i);
|
memmove(p->a, p->a+i, p->nDigit - i);
|
||||||
p->nDigit -= i;
|
p->nDigit -= i;
|
||||||
}
|
}
|
||||||
|
while( p->nFrac && p->a[p->nDigit-1]==0 ){
|
||||||
|
p->nFrac--;
|
||||||
|
p->nDigit--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -523,7 +528,58 @@ static void decimalSumFinalize(sqlite3_context *context){
|
|||||||
decimal_result(context, p);
|
decimal_result(context, p);
|
||||||
decimal_clear(p);
|
decimal_clear(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** SQL Function: decimal_mul(X, Y)
|
||||||
|
**
|
||||||
|
** Return the product of X and Y.
|
||||||
|
*/
|
||||||
|
static void decimalMulFunc(
|
||||||
|
sqlite3_context *context,
|
||||||
|
int argc,
|
||||||
|
sqlite3_value **argv
|
||||||
|
){
|
||||||
|
Decimal *pA = decimal_new(context, argv[0], 0, 0);
|
||||||
|
Decimal *pB = decimal_new(context, argv[1], 0, 0);
|
||||||
|
signed char *acc = 0;
|
||||||
|
int i, j, k;
|
||||||
|
if( pA==0 || pA->oom || pA->isNull
|
||||||
|
|| pB==0 || pB->oom || pB->isNull
|
||||||
|
){
|
||||||
|
goto mul_end;
|
||||||
|
}
|
||||||
|
acc = sqlite3_malloc64( pA->nDigit + pB->nDigit + 2 );
|
||||||
|
if( acc==0 ){
|
||||||
|
sqlite3_result_error_nomem(context);
|
||||||
|
goto mul_end;
|
||||||
|
}
|
||||||
|
memset(acc, 0, pA->nDigit + pB->nDigit + 2);
|
||||||
|
for(i=pA->nDigit-1; i>=0; i--){
|
||||||
|
signed char f = pA->a[i];
|
||||||
|
int carry = 0, x;
|
||||||
|
for(j=pB->nDigit-1, k=i+j+3; j>=0; j--, k--){
|
||||||
|
int x = acc[k] + f*pB->a[j] + carry;
|
||||||
|
acc[k] = x%10;
|
||||||
|
carry = x/10;
|
||||||
|
}
|
||||||
|
x = acc[k] + carry;
|
||||||
|
acc[k] = x%10;
|
||||||
|
acc[k-1] += x/10;
|
||||||
|
}
|
||||||
|
sqlite3_free(pA->a);
|
||||||
|
pA->a = acc;
|
||||||
|
acc = 0;
|
||||||
|
pA->nDigit += pB->nDigit + 2;
|
||||||
|
pA->nFrac += pB->nFrac;
|
||||||
|
pA->sign ^= pB->sign;
|
||||||
|
decimal_normalize(pA);
|
||||||
|
decimal_result(context, pA);
|
||||||
|
|
||||||
|
mul_end:
|
||||||
|
sqlite3_free(acc);
|
||||||
|
decimal_free(pA);
|
||||||
|
decimal_free(pB);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
__declspec(dllexport)
|
__declspec(dllexport)
|
||||||
@ -544,6 +600,7 @@ int sqlite3_decimal_init(
|
|||||||
{ "decimal_cmp", 2, decimalCmpFunc },
|
{ "decimal_cmp", 2, decimalCmpFunc },
|
||||||
{ "decimal_add", 2, decimalAddFunc },
|
{ "decimal_add", 2, decimalAddFunc },
|
||||||
{ "decimal_sub", 2, decimalSubFunc },
|
{ "decimal_sub", 2, decimalSubFunc },
|
||||||
|
{ "decimal_mul", 2, decimalMulFunc },
|
||||||
};
|
};
|
||||||
int i;
|
int i;
|
||||||
(void)pzErrMsg; /* Unused parameter */
|
(void)pzErrMsg; /* Unused parameter */
|
||||||
|
17
manifest
17
manifest
@ -1,20 +1,17 @@
|
|||||||
B 7a876209a678a34c198b54ceef9e3c041f128a14dc73357f6a57cadadaa6cf7b
|
B 7a876209a678a34c198b54ceef9e3c041f128a14dc73357f6a57cadadaa6cf7b
|
||||||
C An\sextension\sfor\sdoing\sdecimal\sarithmetic\son\sstrings.
|
C Add\sthe\sdecimal_mul()\sfunction.
|
||||||
D 2020-06-22T19:12:23.405
|
D 2020-06-22T21:25:37.690
|
||||||
F Makefile.in 014ad669b4a5809752939c2dea83722992711b464aa56adebca80c5cc98cfdc2
|
F Makefile.in 014ad669b4a5809752939c2dea83722992711b464aa56adebca80c5cc98cfdc2
|
||||||
F Makefile.msc 08c8bbedfa51e21b57153370edbfee86d35bbefb53e3773a3e086fe654facccb
|
F Makefile.msc 08c8bbedfa51e21b57153370edbfee86d35bbefb53e3773a3e086fe654facccb
|
||||||
F autoconf/Makefile.am a8d1d24affe52ebf8d7ddcf91aa973fa0316618ab95bb68c87cabf8faf527dc8
|
F autoconf/Makefile.am a8d1d24affe52ebf8d7ddcf91aa973fa0316618ab95bb68c87cabf8faf527dc8
|
||||||
F ext/misc/decimal.c ba7054d9719ceb034012e1744f6e9c1ca5fe2a00a2b83e34faf0c08a43204a64
|
F ext/misc/decimal.c 334d8d34c124a8820d814dadbe1ac3daec63f504d5b322eb63671c317d3c6a3e
|
||||||
F main.mk c99e452dd4edd0bea28547259421bd6cf24d41d928d24720737efc548958ca39
|
F main.mk c99e452dd4edd0bea28547259421bd6cf24d41d928d24720737efc548958ca39
|
||||||
F src/build.c ba1bbe563a3dc02d5fed20537603181e5289c13ea30ae5e775f552e7557adbfa
|
F src/build.c ba1bbe563a3dc02d5fed20537603181e5289c13ea30ae5e775f552e7557adbfa
|
||||||
F src/shell.c.in 7fe12fb6452de32f92bb26ee50524ec31c9d08a1c46376ca00a4ecd27472a14d
|
F src/shell.c.in 7fe12fb6452de32f92bb26ee50524ec31c9d08a1c46376ca00a4ecd27472a14d
|
||||||
F src/test1.c fe56c4bcaa2685ca9aa25d817a0ee9345e189aff4a5a71a3d8ba946c7776feb8
|
F src/test1.c fe56c4bcaa2685ca9aa25d817a0ee9345e189aff4a5a71a3d8ba946c7776feb8
|
||||||
F test/decimal.test 5c486a6baa87fe0cd1c119ffa190bcc70a23e2dd6617baa201eab9e0b0ef2efd
|
F test/decimal.test c4af0264a0f30e896f617b489d69039932fe5127b02ac221d96f8af31db13826
|
||||||
F tool/mkautoconfamal.sh f62353eb6c06ab264da027fd4507d09914433dbdcab9cb011cdc18016f1ab3b8
|
F tool/mkautoconfamal.sh f62353eb6c06ab264da027fd4507d09914433dbdcab9cb011cdc18016f1ab3b8
|
||||||
P 067291143a63db924ead4810defb4bc6f195557412f5d1c22299f30d2d9f2a79
|
P 4c3b85607feb53462ccc8b89bea699fdb132c402eae597afa33cc40a85c32329
|
||||||
R 4df2ada42f27e695d7e98ee101d73989
|
R d79a1d72394e5a5f6c93e9466f2c9aa1
|
||||||
T *branch * decimal
|
|
||||||
T *sym-decimal *
|
|
||||||
T -sym-trunk *
|
|
||||||
U drh
|
U drh
|
||||||
Z ac0625ef3228b5eb95c4972028cf8994
|
Z 3092a9d89a34e083e375231f8e857b54
|
||||||
|
@ -1 +1 @@
|
|||||||
4c3b85607feb53462ccc8b89bea699fdb132c402eae597afa33cc40a85c32329
|
72eee04b67268ad38fd51ff32849f08c0a54cf1b481d5ecb11d77cc9c729ee03
|
@ -115,4 +115,14 @@ do_execsql_test 4010 {
|
|||||||
FROM t3;
|
FROM t3;
|
||||||
} {1505500000000000000015055.00000000000000015055}
|
} {1505500000000000000015055.00000000000000015055}
|
||||||
|
|
||||||
|
do_execsql_test 5000 {
|
||||||
|
WITH RECURSIVE c(x,y,z) AS (
|
||||||
|
VALUES(0,'1','1')
|
||||||
|
UNION ALL
|
||||||
|
SELECT x+1, decimal_mul(y,'2'), decimal_mul(z,'0.5')
|
||||||
|
FROM c WHERE x<32
|
||||||
|
)
|
||||||
|
SELECT count(*) FROM c WHERE decimal_mul(y,z)='1';
|
||||||
|
} {33}
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
Reference in New Issue
Block a user