Fixes default log output to console for macOS
[sqlcipher.git] / ext / misc / decimal.c
blob9365ae68b9f3aaa15752429056829ff2487cbe77
1 /*
2 ** 2020-06-22
3 **
4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
6 **
7 ** May you do good and not evil.
8 ** May you find forgiveness for yourself and forgive others.
9 ** May you share freely, never taking more than you give.
11 ******************************************************************************
13 ** Routines to implement arbitrary-precision decimal math.
15 ** The focus here is on simplicity and correctness, not performance.
17 #include "sqlite3ext.h"
18 SQLITE_EXTENSION_INIT1
19 #include <assert.h>
20 #include <string.h>
21 #include <ctype.h>
22 #include <stdlib.h>
24 /* Mark a function parameter as unused, to suppress nuisance compiler
25 ** warnings. */
26 #ifndef UNUSED_PARAMETER
27 # define UNUSED_PARAMETER(X) (void)(X)
28 #endif
31 /* A decimal object */
32 typedef struct Decimal Decimal;
33 struct Decimal {
34 char sign; /* 0 for positive, 1 for negative */
35 char oom; /* True if an OOM is encountered */
36 char isNull; /* True if holds a NULL rather than a number */
37 char isInit; /* True upon initialization */
38 int nDigit; /* Total number of digits */
39 int nFrac; /* Number of digits to the right of the decimal point */
40 signed char *a; /* Array of digits. Most significant first. */
44 ** Release memory held by a Decimal, but do not free the object itself.
46 static void decimal_clear(Decimal *p){
47 sqlite3_free(p->a);
51 ** Destroy a Decimal object
53 static void decimal_free(Decimal *p){
54 if( p ){
55 decimal_clear(p);
56 sqlite3_free(p);
61 ** Allocate a new Decimal object initialized to the text in zIn[].
62 ** Return NULL if any kind of error occurs.
64 static Decimal *decimalNewFromText(const char *zIn, int n){
65 Decimal *p = 0;
66 int i;
67 int iExp = 0;
69 p = sqlite3_malloc( sizeof(*p) );
70 if( p==0 ) goto new_from_text_failed;
71 p->sign = 0;
72 p->oom = 0;
73 p->isInit = 1;
74 p->isNull = 0;
75 p->nDigit = 0;
76 p->nFrac = 0;
77 p->a = sqlite3_malloc64( n+1 );
78 if( p->a==0 ) goto new_from_text_failed;
79 for(i=0; isspace(zIn[i]); i++){}
80 if( zIn[i]=='-' ){
81 p->sign = 1;
82 i++;
83 }else if( zIn[i]=='+' ){
84 i++;
86 while( i<n && zIn[i]=='0' ) i++;
87 while( i<n ){
88 char c = zIn[i];
89 if( c>='0' && c<='9' ){
90 p->a[p->nDigit++] = c - '0';
91 }else if( c=='.' ){
92 p->nFrac = p->nDigit + 1;
93 }else if( c=='e' || c=='E' ){
94 int j = i+1;
95 int neg = 0;
96 if( j>=n ) break;
97 if( zIn[j]=='-' ){
98 neg = 1;
99 j++;
100 }else if( zIn[j]=='+' ){
101 j++;
103 while( j<n && iExp<1000000 ){
104 if( zIn[j]>='0' && zIn[j]<='9' ){
105 iExp = iExp*10 + zIn[j] - '0';
107 j++;
109 if( neg ) iExp = -iExp;
110 break;
112 i++;
114 if( p->nFrac ){
115 p->nFrac = p->nDigit - (p->nFrac - 1);
117 if( iExp>0 ){
118 if( p->nFrac>0 ){
119 if( iExp<=p->nFrac ){
120 p->nFrac -= iExp;
121 iExp = 0;
122 }else{
123 iExp -= p->nFrac;
124 p->nFrac = 0;
127 if( iExp>0 ){
128 p->a = sqlite3_realloc64(p->a, p->nDigit + iExp + 1 );
129 if( p->a==0 ) goto new_from_text_failed;
130 memset(p->a+p->nDigit, 0, iExp);
131 p->nDigit += iExp;
133 }else if( iExp<0 ){
134 int nExtra;
135 iExp = -iExp;
136 nExtra = p->nDigit - p->nFrac - 1;
137 if( nExtra ){
138 if( nExtra>=iExp ){
139 p->nFrac += iExp;
140 iExp = 0;
141 }else{
142 iExp -= nExtra;
143 p->nFrac = p->nDigit - 1;
146 if( iExp>0 ){
147 p->a = sqlite3_realloc64(p->a, p->nDigit + iExp + 1 );
148 if( p->a==0 ) goto new_from_text_failed;
149 memmove(p->a+iExp, p->a, p->nDigit);
150 memset(p->a, 0, iExp);
151 p->nDigit += iExp;
152 p->nFrac += iExp;
155 return p;
157 new_from_text_failed:
158 if( p ){
159 if( p->a ) sqlite3_free(p->a);
160 sqlite3_free(p);
162 return 0;
165 /* Forward reference */
166 static Decimal *decimalFromDouble(double);
169 ** Allocate a new Decimal object from an sqlite3_value. Return a pointer
170 ** to the new object, or NULL if there is an error. If the pCtx argument
171 ** is not NULL, then errors are reported on it as well.
173 ** If the pIn argument is SQLITE_TEXT or SQLITE_INTEGER, it is converted
174 ** directly into a Decimal. For SQLITE_FLOAT or for SQLITE_BLOB of length
175 ** 8 bytes, the resulting double value is expanded into its decimal equivalent.
176 ** If pIn is NULL or if it is a BLOB that is not exactly 8 bytes in length,
177 ** then NULL is returned.
179 static Decimal *decimal_new(
180 sqlite3_context *pCtx, /* Report error here, if not null */
181 sqlite3_value *pIn, /* Construct the decimal object from this */
182 int bTextOnly /* Always interpret pIn as text if true */
184 Decimal *p = 0;
185 int eType = sqlite3_value_type(pIn);
186 if( bTextOnly && (eType==SQLITE_FLOAT || eType==SQLITE_BLOB) ){
187 eType = SQLITE_TEXT;
189 switch( eType ){
190 case SQLITE_TEXT:
191 case SQLITE_INTEGER: {
192 const char *zIn = (const char*)sqlite3_value_text(pIn);
193 int n = sqlite3_value_bytes(pIn);
194 p = decimalNewFromText(zIn, n);
195 if( p==0 ) goto new_failed;
196 break;
199 case SQLITE_FLOAT: {
200 p = decimalFromDouble(sqlite3_value_double(pIn));
201 break;
204 case SQLITE_BLOB: {
205 const unsigned char *x;
206 unsigned int i;
207 sqlite3_uint64 v = 0;
208 double r;
210 if( sqlite3_value_bytes(pIn)!=sizeof(r) ) break;
211 x = sqlite3_value_blob(pIn);
212 for(i=0; i<sizeof(r); i++){
213 v = (v<<8) | x[i];
215 memcpy(&r, &v, sizeof(r));
216 p = decimalFromDouble(r);
217 break;
220 case SQLITE_NULL: {
221 break;
224 return p;
226 new_failed:
227 if( pCtx ) sqlite3_result_error_nomem(pCtx);
228 sqlite3_free(p);
229 return 0;
233 ** Make the given Decimal the result.
235 static void decimal_result(sqlite3_context *pCtx, Decimal *p){
236 char *z;
237 int i, j;
238 int n;
239 if( p==0 || p->oom ){
240 sqlite3_result_error_nomem(pCtx);
241 return;
243 if( p->isNull ){
244 sqlite3_result_null(pCtx);
245 return;
247 z = sqlite3_malloc( p->nDigit+4 );
248 if( z==0 ){
249 sqlite3_result_error_nomem(pCtx);
250 return;
252 i = 0;
253 if( p->nDigit==0 || (p->nDigit==1 && p->a[0]==0) ){
254 p->sign = 0;
256 if( p->sign ){
257 z[0] = '-';
258 i = 1;
260 n = p->nDigit - p->nFrac;
261 if( n<=0 ){
262 z[i++] = '0';
264 j = 0;
265 while( n>1 && p->a[j]==0 ){
266 j++;
267 n--;
269 while( n>0 ){
270 z[i++] = p->a[j] + '0';
271 j++;
272 n--;
274 if( p->nFrac ){
275 z[i++] = '.';
277 z[i++] = p->a[j] + '0';
278 j++;
279 }while( j<p->nDigit );
281 z[i] = 0;
282 sqlite3_result_text(pCtx, z, i, sqlite3_free);
286 ** Make the given Decimal the result in an format similar to '%+#e'.
287 ** In other words, show exponential notation with leading and trailing
288 ** zeros omitted.
290 static void decimal_result_sci(sqlite3_context *pCtx, Decimal *p){
291 char *z; /* The output buffer */
292 int i; /* Loop counter */
293 int nZero; /* Number of leading zeros */
294 int nDigit; /* Number of digits not counting trailing zeros */
295 int nFrac; /* Digits to the right of the decimal point */
296 int exp; /* Exponent value */
297 signed char zero; /* Zero value */
298 signed char *a; /* Array of digits */
300 if( p==0 || p->oom ){
301 sqlite3_result_error_nomem(pCtx);
302 return;
304 if( p->isNull ){
305 sqlite3_result_null(pCtx);
306 return;
308 for(nDigit=p->nDigit; nDigit>0 && p->a[nDigit-1]==0; nDigit--){}
309 for(nZero=0; nZero<nDigit && p->a[nZero]==0; nZero++){}
310 nFrac = p->nFrac + (nDigit - p->nDigit);
311 nDigit -= nZero;
312 z = sqlite3_malloc( nDigit+20 );
313 if( z==0 ){
314 sqlite3_result_error_nomem(pCtx);
315 return;
317 if( nDigit==0 ){
318 zero = 0;
319 a = &zero;
320 nDigit = 1;
321 nFrac = 0;
322 }else{
323 a = &p->a[nZero];
325 if( p->sign && nDigit>0 ){
326 z[0] = '-';
327 }else{
328 z[0] = '+';
330 z[1] = a[0]+'0';
331 z[2] = '.';
332 if( nDigit==1 ){
333 z[3] = '0';
334 i = 4;
335 }else{
336 for(i=1; i<nDigit; i++){
337 z[2+i] = a[i]+'0';
339 i = nDigit+2;
341 exp = nDigit - nFrac - 1;
342 sqlite3_snprintf(nDigit+20-i, &z[i], "e%+03d", exp);
343 sqlite3_result_text(pCtx, z, -1, sqlite3_free);
347 ** Compare to Decimal objects. Return negative, 0, or positive if the
348 ** first object is less than, equal to, or greater than the second.
350 ** Preconditions for this routine:
352 ** pA!=0
353 ** pA->isNull==0
354 ** pB!=0
355 ** pB->isNull==0
357 static int decimal_cmp(const Decimal *pA, const Decimal *pB){
358 int nASig, nBSig, rc, n;
359 if( pA->sign!=pB->sign ){
360 return pA->sign ? -1 : +1;
362 if( pA->sign ){
363 const Decimal *pTemp = pA;
364 pA = pB;
365 pB = pTemp;
367 nASig = pA->nDigit - pA->nFrac;
368 nBSig = pB->nDigit - pB->nFrac;
369 if( nASig!=nBSig ){
370 return nASig - nBSig;
372 n = pA->nDigit;
373 if( n>pB->nDigit ) n = pB->nDigit;
374 rc = memcmp(pA->a, pB->a, n);
375 if( rc==0 ){
376 rc = pA->nDigit - pB->nDigit;
378 return rc;
382 ** SQL Function: decimal_cmp(X, Y)
384 ** Return negative, zero, or positive if X is less then, equal to, or
385 ** greater than Y.
387 static void decimalCmpFunc(
388 sqlite3_context *context,
389 int argc,
390 sqlite3_value **argv
392 Decimal *pA = 0, *pB = 0;
393 int rc;
395 UNUSED_PARAMETER(argc);
396 pA = decimal_new(context, argv[0], 1);
397 if( pA==0 || pA->isNull ) goto cmp_done;
398 pB = decimal_new(context, argv[1], 1);
399 if( pB==0 || pB->isNull ) goto cmp_done;
400 rc = decimal_cmp(pA, pB);
401 if( rc<0 ) rc = -1;
402 else if( rc>0 ) rc = +1;
403 sqlite3_result_int(context, rc);
404 cmp_done:
405 decimal_free(pA);
406 decimal_free(pB);
410 ** Expand the Decimal so that it has a least nDigit digits and nFrac
411 ** digits to the right of the decimal point.
413 static void decimal_expand(Decimal *p, int nDigit, int nFrac){
414 int nAddSig;
415 int nAddFrac;
416 if( p==0 ) return;
417 nAddFrac = nFrac - p->nFrac;
418 nAddSig = (nDigit - p->nDigit) - nAddFrac;
419 if( nAddFrac==0 && nAddSig==0 ) return;
420 p->a = sqlite3_realloc64(p->a, nDigit+1);
421 if( p->a==0 ){
422 p->oom = 1;
423 return;
425 if( nAddSig ){
426 memmove(p->a+nAddSig, p->a, p->nDigit);
427 memset(p->a, 0, nAddSig);
428 p->nDigit += nAddSig;
430 if( nAddFrac ){
431 memset(p->a+p->nDigit, 0, nAddFrac);
432 p->nDigit += nAddFrac;
433 p->nFrac += nAddFrac;
438 ** Add the value pB into pA. A := A + B.
440 ** Both pA and pB might become denormalized by this routine.
442 static void decimal_add(Decimal *pA, Decimal *pB){
443 int nSig, nFrac, nDigit;
444 int i, rc;
445 if( pA==0 ){
446 return;
448 if( pA->oom || pB==0 || pB->oom ){
449 pA->oom = 1;
450 return;
452 if( pA->isNull || pB->isNull ){
453 pA->isNull = 1;
454 return;
456 nSig = pA->nDigit - pA->nFrac;
457 if( nSig && pA->a[0]==0 ) nSig--;
458 if( nSig<pB->nDigit-pB->nFrac ){
459 nSig = pB->nDigit - pB->nFrac;
461 nFrac = pA->nFrac;
462 if( nFrac<pB->nFrac ) nFrac = pB->nFrac;
463 nDigit = nSig + nFrac + 1;
464 decimal_expand(pA, nDigit, nFrac);
465 decimal_expand(pB, nDigit, nFrac);
466 if( pA->oom || pB->oom ){
467 pA->oom = 1;
468 }else{
469 if( pA->sign==pB->sign ){
470 int carry = 0;
471 for(i=nDigit-1; i>=0; i--){
472 int x = pA->a[i] + pB->a[i] + carry;
473 if( x>=10 ){
474 carry = 1;
475 pA->a[i] = x - 10;
476 }else{
477 carry = 0;
478 pA->a[i] = x;
481 }else{
482 signed char *aA, *aB;
483 int borrow = 0;
484 rc = memcmp(pA->a, pB->a, nDigit);
485 if( rc<0 ){
486 aA = pB->a;
487 aB = pA->a;
488 pA->sign = !pA->sign;
489 }else{
490 aA = pA->a;
491 aB = pB->a;
493 for(i=nDigit-1; i>=0; i--){
494 int x = aA[i] - aB[i] - borrow;
495 if( x<0 ){
496 pA->a[i] = x+10;
497 borrow = 1;
498 }else{
499 pA->a[i] = x;
500 borrow = 0;
508 ** Multiply A by B. A := A * B
510 ** All significant digits after the decimal point are retained.
511 ** Trailing zeros after the decimal point are omitted as long as
512 ** the number of digits after the decimal point is no less than
513 ** either the number of digits in either input.
515 static void decimalMul(Decimal *pA, Decimal *pB){
516 signed char *acc = 0;
517 int i, j, k;
518 int minFrac;
520 if( pA==0 || pA->oom || pA->isNull
521 || pB==0 || pB->oom || pB->isNull
523 goto mul_end;
525 acc = sqlite3_malloc64( pA->nDigit + pB->nDigit + 2 );
526 if( acc==0 ){
527 pA->oom = 1;
528 goto mul_end;
530 memset(acc, 0, pA->nDigit + pB->nDigit + 2);
531 minFrac = pA->nFrac;
532 if( pB->nFrac<minFrac ) minFrac = pB->nFrac;
533 for(i=pA->nDigit-1; i>=0; i--){
534 signed char f = pA->a[i];
535 int carry = 0, x;
536 for(j=pB->nDigit-1, k=i+j+3; j>=0; j--, k--){
537 x = acc[k] + f*pB->a[j] + carry;
538 acc[k] = x%10;
539 carry = x/10;
541 x = acc[k] + carry;
542 acc[k] = x%10;
543 acc[k-1] += x/10;
545 sqlite3_free(pA->a);
546 pA->a = acc;
547 acc = 0;
548 pA->nDigit += pB->nDigit + 2;
549 pA->nFrac += pB->nFrac;
550 pA->sign ^= pB->sign;
551 while( pA->nFrac>minFrac && pA->a[pA->nDigit-1]==0 ){
552 pA->nFrac--;
553 pA->nDigit--;
556 mul_end:
557 sqlite3_free(acc);
561 ** Create a new Decimal object that contains an integer power of 2.
563 static Decimal *decimalPow2(int N){
564 Decimal *pA = 0; /* The result to be returned */
565 Decimal *pX = 0; /* Multiplier */
566 if( N<-20000 || N>20000 ) goto pow2_fault;
567 pA = decimalNewFromText("1.0", 3);
568 if( pA==0 || pA->oom ) goto pow2_fault;
569 if( N==0 ) return pA;
570 if( N>0 ){
571 pX = decimalNewFromText("2.0", 3);
572 }else{
573 N = -N;
574 pX = decimalNewFromText("0.5", 3);
576 if( pX==0 || pX->oom ) goto pow2_fault;
577 while( 1 /* Exit by break */ ){
578 if( N & 1 ){
579 decimalMul(pA, pX);
580 if( pA->oom ) goto pow2_fault;
582 N >>= 1;
583 if( N==0 ) break;
584 decimalMul(pX, pX);
586 decimal_free(pX);
587 return pA;
589 pow2_fault:
590 decimal_free(pA);
591 decimal_free(pX);
592 return 0;
596 ** Use an IEEE754 binary64 ("double") to generate a new Decimal object.
598 static Decimal *decimalFromDouble(double r){
599 sqlite3_int64 m, a;
600 int e;
601 int isNeg;
602 Decimal *pA;
603 Decimal *pX;
604 char zNum[100];
605 if( r<0.0 ){
606 isNeg = 1;
607 r = -r;
608 }else{
609 isNeg = 0;
611 memcpy(&a,&r,sizeof(a));
612 if( a==0 ){
613 e = 0;
614 m = 0;
615 }else{
616 e = a>>52;
617 m = a & ((((sqlite3_int64)1)<<52)-1);
618 if( e==0 ){
619 m <<= 1;
620 }else{
621 m |= ((sqlite3_int64)1)<<52;
623 while( e<1075 && m>0 && (m&1)==0 ){
624 m >>= 1;
625 e++;
627 if( isNeg ) m = -m;
628 e = e - 1075;
629 if( e>971 ){
630 return 0; /* A NaN or an Infinity */
634 /* At this point m is the integer significand and e is the exponent */
635 sqlite3_snprintf(sizeof(zNum), zNum, "%lld", m);
636 pA = decimalNewFromText(zNum, (int)strlen(zNum));
637 pX = decimalPow2(e);
638 decimalMul(pA, pX);
639 decimal_free(pX);
640 return pA;
644 ** SQL Function: decimal(X)
645 ** OR: decimal_exp(X)
647 ** Convert input X into decimal and then back into text.
649 ** If X is originally a float, then a full decimal expansion of that floating
650 ** point value is done. Or if X is an 8-byte blob, it is interpreted
651 ** as a float and similarly expanded.
653 ** The decimal_exp(X) function returns the result in exponential notation.
654 ** decimal(X) returns a complete decimal, without the e+NNN at the end.
656 static void decimalFunc(
657 sqlite3_context *context,
658 int argc,
659 sqlite3_value **argv
661 Decimal *p = decimal_new(context, argv[0], 0);
662 UNUSED_PARAMETER(argc);
663 if( p ){
664 if( sqlite3_user_data(context)!=0 ){
665 decimal_result_sci(context, p);
666 }else{
667 decimal_result(context, p);
669 decimal_free(p);
674 ** Compare text in decimal order.
676 static int decimalCollFunc(
677 void *notUsed,
678 int nKey1, const void *pKey1,
679 int nKey2, const void *pKey2
681 const unsigned char *zA = (const unsigned char*)pKey1;
682 const unsigned char *zB = (const unsigned char*)pKey2;
683 Decimal *pA = decimalNewFromText((const char*)zA, nKey1);
684 Decimal *pB = decimalNewFromText((const char*)zB, nKey2);
685 int rc;
686 UNUSED_PARAMETER(notUsed);
687 if( pA==0 || pB==0 ){
688 rc = 0;
689 }else{
690 rc = decimal_cmp(pA, pB);
692 decimal_free(pA);
693 decimal_free(pB);
694 return rc;
699 ** SQL Function: decimal_add(X, Y)
700 ** decimal_sub(X, Y)
702 ** Return the sum or difference of X and Y.
704 static void decimalAddFunc(
705 sqlite3_context *context,
706 int argc,
707 sqlite3_value **argv
709 Decimal *pA = decimal_new(context, argv[0], 1);
710 Decimal *pB = decimal_new(context, argv[1], 1);
711 UNUSED_PARAMETER(argc);
712 decimal_add(pA, pB);
713 decimal_result(context, pA);
714 decimal_free(pA);
715 decimal_free(pB);
717 static void decimalSubFunc(
718 sqlite3_context *context,
719 int argc,
720 sqlite3_value **argv
722 Decimal *pA = decimal_new(context, argv[0], 1);
723 Decimal *pB = decimal_new(context, argv[1], 1);
724 UNUSED_PARAMETER(argc);
725 if( pB ){
726 pB->sign = !pB->sign;
727 decimal_add(pA, pB);
728 decimal_result(context, pA);
730 decimal_free(pA);
731 decimal_free(pB);
734 /* Aggregate funcion: decimal_sum(X)
736 ** Works like sum() except that it uses decimal arithmetic for unlimited
737 ** precision.
739 static void decimalSumStep(
740 sqlite3_context *context,
741 int argc,
742 sqlite3_value **argv
744 Decimal *p;
745 Decimal *pArg;
746 UNUSED_PARAMETER(argc);
747 p = sqlite3_aggregate_context(context, sizeof(*p));
748 if( p==0 ) return;
749 if( !p->isInit ){
750 p->isInit = 1;
751 p->a = sqlite3_malloc(2);
752 if( p->a==0 ){
753 p->oom = 1;
754 }else{
755 p->a[0] = 0;
757 p->nDigit = 1;
758 p->nFrac = 0;
760 if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
761 pArg = decimal_new(context, argv[0], 1);
762 decimal_add(p, pArg);
763 decimal_free(pArg);
765 static void decimalSumInverse(
766 sqlite3_context *context,
767 int argc,
768 sqlite3_value **argv
770 Decimal *p;
771 Decimal *pArg;
772 UNUSED_PARAMETER(argc);
773 p = sqlite3_aggregate_context(context, sizeof(*p));
774 if( p==0 ) return;
775 if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
776 pArg = decimal_new(context, argv[0], 1);
777 if( pArg ) pArg->sign = !pArg->sign;
778 decimal_add(p, pArg);
779 decimal_free(pArg);
781 static void decimalSumValue(sqlite3_context *context){
782 Decimal *p = sqlite3_aggregate_context(context, 0);
783 if( p==0 ) return;
784 decimal_result(context, p);
786 static void decimalSumFinalize(sqlite3_context *context){
787 Decimal *p = sqlite3_aggregate_context(context, 0);
788 if( p==0 ) return;
789 decimal_result(context, p);
790 decimal_clear(p);
794 ** SQL Function: decimal_mul(X, Y)
796 ** Return the product of X and Y.
798 static void decimalMulFunc(
799 sqlite3_context *context,
800 int argc,
801 sqlite3_value **argv
803 Decimal *pA = decimal_new(context, argv[0], 1);
804 Decimal *pB = decimal_new(context, argv[1], 1);
805 UNUSED_PARAMETER(argc);
806 if( pA==0 || pA->oom || pA->isNull
807 || pB==0 || pB->oom || pB->isNull
809 goto mul_end;
811 decimalMul(pA, pB);
812 if( pA->oom ){
813 goto mul_end;
815 decimal_result(context, pA);
817 mul_end:
818 decimal_free(pA);
819 decimal_free(pB);
823 ** SQL Function: decimal_pow2(N)
825 ** Return the N-th power of 2. N must be an integer.
827 static void decimalPow2Func(
828 sqlite3_context *context,
829 int argc,
830 sqlite3_value **argv
832 UNUSED_PARAMETER(argc);
833 if( sqlite3_value_type(argv[0])==SQLITE_INTEGER ){
834 Decimal *pA = decimalPow2(sqlite3_value_int(argv[0]));
835 decimal_result_sci(context, pA);
836 decimal_free(pA);
840 #ifdef _WIN32
841 __declspec(dllexport)
842 #endif
843 int sqlite3_decimal_init(
844 sqlite3 *db,
845 char **pzErrMsg,
846 const sqlite3_api_routines *pApi
848 int rc = SQLITE_OK;
849 static const struct {
850 const char *zFuncName;
851 int nArg;
852 int iArg;
853 void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
854 } aFunc[] = {
855 { "decimal", 1, 0, decimalFunc },
856 { "decimal_exp", 1, 1, decimalFunc },
857 { "decimal_cmp", 2, 0, decimalCmpFunc },
858 { "decimal_add", 2, 0, decimalAddFunc },
859 { "decimal_sub", 2, 0, decimalSubFunc },
860 { "decimal_mul", 2, 0, decimalMulFunc },
861 { "decimal_pow2", 1, 0, decimalPow2Func },
863 unsigned int i;
864 (void)pzErrMsg; /* Unused parameter */
866 SQLITE_EXTENSION_INIT2(pApi);
868 for(i=0; i<(int)(sizeof(aFunc)/sizeof(aFunc[0])) && rc==SQLITE_OK; i++){
869 rc = sqlite3_create_function(db, aFunc[i].zFuncName, aFunc[i].nArg,
870 SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
871 aFunc[i].iArg ? db : 0, aFunc[i].xFunc, 0, 0);
873 if( rc==SQLITE_OK ){
874 rc = sqlite3_create_window_function(db, "decimal_sum", 1,
875 SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC, 0,
876 decimalSumStep, decimalSumFinalize,
877 decimalSumValue, decimalSumInverse, 0);
879 if( rc==SQLITE_OK ){
880 rc = sqlite3_create_collation(db, "decimal", SQLITE_UTF8,
881 0, decimalCollFunc);
883 return rc;