** 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. */
| 5041 | ** either the number of digits in either input. |
| 5042 | */ |
| 5043 | static void decimalMulFunc( |
| 5044 | sqlite3_context *context, |
| 5045 | int argc, |
| 5046 | sqlite3_value **argv |
| 5047 | ){ |
| 5048 | Decimal *pA = decimal_new(context, argv[0], 0, 0); |
| 5049 | Decimal *pB = decimal_new(context, argv[1], 0, 0); |
| 5050 | signed char *acc = 0; |
| 5051 | int i, j, k; |
| 5052 | int minFrac; |
| 5053 | UNUSED_PARAMETER(argc); |
| 5054 | if( pA==0 || pA->oom || pA->isNull |
| 5055 | || pB==0 || pB->oom || pB->isNull |
| 5056 | ){ |
| 5057 | goto mul_end; |
| 5058 | } |
| 5059 | acc = sqlite3_malloc64( pA->nDigit + pB->nDigit + 2 ); |
| 5060 | if( acc==0 ){ |
| 5061 | sqlite3_result_error_nomem(context); |
| 5062 | goto mul_end; |
| 5063 | } |
| 5064 | memset(acc, 0, pA->nDigit + pB->nDigit + 2); |
| 5065 | minFrac = pA->nFrac; |
| 5066 | if( pB->nFrac<minFrac ) minFrac = pB->nFrac; |
| 5067 | for(i=pA->nDigit-1; i>=0; i--){ |
| 5068 | signed char f = pA->a[i]; |
| 5069 | int carry = 0, x; |
| 5070 | for(j=pB->nDigit-1, k=i+j+3; j>=0; j--, k--){ |
| 5071 | x = acc[k] + f*pB->a[j] + carry; |
| 5072 | acc[k] = x%10; |
| 5073 | carry = x/10; |
| 5074 | } |
| 5075 | x = acc[k] + carry; |
| 5076 | acc[k] = x%10; |
| 5077 | acc[k-1] += x/10; |
| 5078 | } |
| 5079 | sqlite3_free(pA->a); |
| 5080 | pA->a = acc; |
| 5081 | acc = 0; |
| 5082 | pA->nDigit += pB->nDigit + 2; |
| 5083 | pA->nFrac += pB->nFrac; |
| 5084 | pA->sign ^= pB->sign; |
| 5085 | while( pA->nFrac>minFrac && pA->a[pA->nDigit-1]==0 ){ |
| 5086 | pA->nFrac--; |
| 5087 | pA->nDigit--; |
| 5088 | } |
| 5089 | decimal_result(context, pA); |
| 5090 | |
| 5091 | mul_end: |
| 5092 | sqlite3_free(acc); |
| 5093 | decimal_free(pA); |
| 5094 | decimal_free(pB); |
| 5095 | } |
| 5096 | |
| 5097 | #ifdef _WIN32 |
| 5098 |
nothing calls this directly
no test coverage detected