1 /*-------------------------------------------------------------------------
4 * An exact numeric data type for the Postgres database system
6 * Original coding 1998, Jan Wieck. Heavily revised 2003, Tom Lane.
8 * Many of the algorithmic ideas are borrowed from David M. Smith's "FM"
9 * multiple-precision math library, most recently published as Algorithm
10 * 786: Multiple-Precision Complex Arithmetic and Functions, ACM
11 * Transactions on Mathematical Software, Vol. 24, No. 4, December 1998,
14 * Copyright (c) 1998-2006, PostgreSQL Global Development Group
17 * $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.95 2006/10/03 21:25:55 momjian Exp $
19 *-------------------------------------------------------------------------
29 #include "catalog/pg_type.h"
30 #include "libpq/pqformat.h"
31 #include "utils/array.h"
32 #include "utils/builtins.h"
33 #include "utils/int8.h"
34 #include "utils/numeric.h"
37 * Uncomment the following to enable compilation of dump_numeric()
38 * and dump_var() and to get a dump of any result produced by make_result().
47 * Numeric values are represented in a base-NBASE floating point format.
48 * Each "digit" ranges from 0 to NBASE-1. The type NumericDigit is signed
49 * and wide enough to store a digit. We assume that NBASE*NBASE can fit in
50 * an int. Although the purely calculational routines could handle any even
51 * NBASE that's less than sqrt(INT_MAX), in practice we are only interested
52 * in NBASE a power of ten, so that I/O conversions and decimal rounding
53 * are easy. Also, it's actually more efficient if NBASE is rather less than
54 * sqrt(INT_MAX), so that there is "headroom" for mul_var and div_var to
55 * postpone processing carries.
62 #define DEC_DIGITS 1 /* decimal digits per NBASE digit */
63 #define MUL_GUARD_DIGITS 4 /* these are measured in NBASE digits */
64 #define DIV_GUARD_DIGITS 8
66 typedef signed char NumericDigit;
72 #define DEC_DIGITS 2 /* decimal digits per NBASE digit */
73 #define MUL_GUARD_DIGITS 3 /* these are measured in NBASE digits */
74 #define DIV_GUARD_DIGITS 6
76 typedef signed char NumericDigit;
81 #define HALF_NBASE 5000
82 #define DEC_DIGITS 4 /* decimal digits per NBASE digit */
83 #define MUL_GUARD_DIGITS 2 /* these are measured in NBASE digits */
84 #define DIV_GUARD_DIGITS 4
86 typedef int16 NumericDigit;
91 * The value represented by a NumericVar is determined by the sign, weight,
92 * ndigits, and digits[] array.
93 * Note: the first digit of a NumericVar's value is assumed to be multiplied
94 * by NBASE ** weight. Another way to say it is that there are weight+1
95 * digits before the decimal point. It is possible to have weight < 0.
97 * buf points at the physical start of the palloc'd digit buffer for the
98 * NumericVar. digits points at the first digit in actual use (the one
99 * with the specified weight). We normally leave an unused digit or two
100 * (preset to zeroes) between buf and digits, so that there is room to store
101 * a carry out of the top digit without special pushups. We just need to
102 * decrement digits (and increment weight) to make room for the carry digit.
103 * (There is no such extra space in a numeric value stored in the database,
104 * only in a NumericVar in memory.)
106 * If buf is NULL then the digit buffer isn't actually palloc'd and should
107 * not be freed --- see the constants below for an example.
109 * dscale, or display scale, is the nominal precision expressed as number
110 * of digits after the decimal point (it must always be >= 0 at present).
111 * dscale may be more than the number of physically stored fractional digits,
112 * implying that we have suppressed storage of significant trailing zeroes.
113 * It should never be less than the number of stored digits, since that would
114 * imply hiding digits that are present. NOTE that dscale is always expressed
115 * in *decimal* digits, and so it may correspond to a fractional number of
116 * base-NBASE digits --- divide by DEC_DIGITS to convert to NBASE digits.
118 * rscale, or result scale, is the target precision for a computation.
119 * Like dscale it is expressed as number of *decimal* digits after the decimal
120 * point, and is always >= 0 at present.
121 * Note that rscale is not stored in variables --- it's figured on-the-fly
122 * from the dscales of the inputs.
124 * NB: All the variable-level functions are written in a style that makes it
125 * possible to give one and the same variable as argument and destination.
126 * This is feasible because the digit buffer is separate from the variable.
129 typedef struct NumericVar
131 int ndigits; /* # of digits in digits[] - can be 0! */
132 int weight; /* weight of first digit */
133 int sign; /* NUMERIC_POS, NUMERIC_NEG, or NUMERIC_NAN */
134 int dscale; /* display scale */
135 NumericDigit *buf; /* start of palloc'd space for digits[] */
136 NumericDigit *digits; /* base-NBASE digits */
141 * Some preinitialized constants
144 static NumericDigit const_zero_data[1] = {0};
145 static NumericVar const_zero =
146 {0, 0, NUMERIC_POS, 0, NULL, const_zero_data};
148 static NumericDigit const_one_data[1] = {1};
149 static NumericVar const_one =
150 {1, 0, NUMERIC_POS, 0, NULL, const_one_data};
152 static NumericDigit const_two_data[1] = {2};
153 static NumericVar const_two =
154 {1, 0, NUMERIC_POS, 0, NULL, const_two_data};
157 static NumericDigit const_zero_point_five_data[1] = {5000};
158 #elif DEC_DIGITS == 2
159 static NumericDigit const_zero_point_five_data[1] = {50};
160 #elif DEC_DIGITS == 1
161 static NumericDigit const_zero_point_five_data[1] = {5};
163 static NumericVar const_zero_point_five =
164 {1, -1, NUMERIC_POS, 1, NULL, const_zero_point_five_data};
167 static NumericDigit const_zero_point_nine_data[1] = {9000};
168 #elif DEC_DIGITS == 2
169 static NumericDigit const_zero_point_nine_data[1] = {90};
170 #elif DEC_DIGITS == 1
171 static NumericDigit const_zero_point_nine_data[1] = {9};
173 static NumericVar const_zero_point_nine =
174 {1, -1, NUMERIC_POS, 1, NULL, const_zero_point_nine_data};
177 static NumericDigit const_zero_point_01_data[1] = {100};
178 static NumericVar const_zero_point_01 =
179 {1, -1, NUMERIC_POS, 2, NULL, const_zero_point_01_data};
180 #elif DEC_DIGITS == 2
181 static NumericDigit const_zero_point_01_data[1] = {1};
182 static NumericVar const_zero_point_01 =
183 {1, -1, NUMERIC_POS, 2, NULL, const_zero_point_01_data};
184 #elif DEC_DIGITS == 1
185 static NumericDigit const_zero_point_01_data[1] = {1};
186 static NumericVar const_zero_point_01 =
187 {1, -2, NUMERIC_POS, 2, NULL, const_zero_point_01_data};
191 static NumericDigit const_one_point_one_data[2] = {1, 1000};
192 #elif DEC_DIGITS == 2
193 static NumericDigit const_one_point_one_data[2] = {1, 10};
194 #elif DEC_DIGITS == 1
195 static NumericDigit const_one_point_one_data[2] = {1, 1};
197 static NumericVar const_one_point_one =
198 {2, 0, NUMERIC_POS, 1, NULL, const_one_point_one_data};
200 static NumericVar const_nan =
201 {0, 0, NUMERIC_NAN, 0, NULL, NULL};
204 static const int round_powers[4] = {0, 1000, 100, 10};
214 static void dump_numeric(const char *str, Numeric num);
215 static void dump_var(const char *str, NumericVar *var);
217 #define dump_numeric(s,n)
218 #define dump_var(s,v)
221 #define digitbuf_alloc(ndigits) \
222 ((NumericDigit *) palloc((ndigits) * sizeof(NumericDigit)))
223 #define digitbuf_free(buf) \
229 #define init_var(v) MemSetAligned(v, 0, sizeof(NumericVar))
231 #define NUMERIC_DIGITS(num) ((NumericDigit *)(num)->n_data)
232 #define NUMERIC_NDIGITS(num) \
233 (((num)->varlen - NUMERIC_HDRSZ) / sizeof(NumericDigit))
235 static void alloc_var(NumericVar *var, int ndigits);
236 static void free_var(NumericVar *var);
237 static void zero_var(NumericVar *var);
239 static void set_var_from_str(const char *str, NumericVar *dest);
240 static void set_var_from_num(Numeric value, NumericVar *dest);
241 static void set_var_from_var(NumericVar *value, NumericVar *dest);
242 static char *get_str_from_var(NumericVar *var, int dscale);
244 static Numeric make_result(NumericVar *var);
246 static void apply_typmod(NumericVar *var, int32 typmod);
248 static int32 numericvar_to_int4(NumericVar *var);
249 static bool numericvar_to_int8(NumericVar *var, int64 *result);
250 static void int8_to_numericvar(int64 val, NumericVar *var);
251 static double numeric_to_double_no_overflow(Numeric num);
252 static double numericvar_to_double_no_overflow(NumericVar *var);
254 static int cmp_numerics(Numeric num1, Numeric num2);
255 static int cmp_var(NumericVar *var1, NumericVar *var2);
256 static int cmp_var_common(const NumericDigit *var1digits, int var1ndigits,
257 int var1weight, int var1sign,
258 const NumericDigit *var2digits, int var2ndigits,
259 int var2weight, int var2sign);
260 static void add_var(NumericVar *var1, NumericVar *var2, NumericVar *result);
261 static void sub_var(NumericVar *var1, NumericVar *var2, NumericVar *result);
262 static void mul_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
264 static void div_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
265 int rscale, bool round);
266 static int select_div_scale(NumericVar *var1, NumericVar *var2);
267 static void mod_var(NumericVar *var1, NumericVar *var2, NumericVar *result);
268 static void ceil_var(NumericVar *var, NumericVar *result);
269 static void floor_var(NumericVar *var, NumericVar *result);
271 static void sqrt_var(NumericVar *arg, NumericVar *result, int rscale);
272 static void exp_var(NumericVar *arg, NumericVar *result, int rscale);
273 static void exp_var_internal(NumericVar *arg, NumericVar *result, int rscale);
274 static void ln_var(NumericVar *arg, NumericVar *result, int rscale);
275 static void log_var(NumericVar *base, NumericVar *num, NumericVar *result);
276 static void power_var(NumericVar *base, NumericVar *exp, NumericVar *result);
277 static void power_var_int(NumericVar *base, int exp, NumericVar *result,
280 static int cmp_abs(NumericVar *var1, NumericVar *var2);
281 static int cmp_abs_common(const NumericDigit *var1digits, int var1ndigits,
283 const NumericDigit *var2digits, int var2ndigits,
285 static void add_abs(NumericVar *var1, NumericVar *var2, NumericVar *result);
286 static void sub_abs(NumericVar *var1, NumericVar *var2, NumericVar *result);
287 static void round_var(NumericVar *var, int rscale);
288 static void trunc_var(NumericVar *var, int rscale);
289 static void strip_var(NumericVar *var);
290 static void compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
291 NumericVar *count_var, NumericVar *result_var);
294 /* ----------------------------------------------------------------------
296 * Input-, output- and rounding-functions
298 * ----------------------------------------------------------------------
305 * Input function for numeric data type
308 numeric_in(PG_FUNCTION_ARGS)
310 char *str = PG_GETARG_CSTRING(0);
313 Oid typelem = PG_GETARG_OID(1);
315 int32 typmod = PG_GETARG_INT32(2);
322 if (pg_strcasecmp(str, "NaN") == 0)
323 PG_RETURN_NUMERIC(make_result(&const_nan));
326 * Use set_var_from_str() to parse the input string and return it in the
327 * packed DB storage format
330 set_var_from_str(str, &value);
332 apply_typmod(&value, typmod);
334 res = make_result(&value);
337 PG_RETURN_NUMERIC(res);
344 * Output function for numeric data type
347 numeric_out(PG_FUNCTION_ARGS)
349 Numeric num = PG_GETARG_NUMERIC(0);
356 if (NUMERIC_IS_NAN(num))
357 PG_RETURN_CSTRING(pstrdup("NaN"));
360 * Get the number in the variable format.
362 * Even if we didn't need to change format, we'd still need to copy the
363 * value to have a modifiable copy for rounding. set_var_from_num() also
364 * guarantees there is extra digit space in case we produce a carry out
368 set_var_from_num(num, &x);
370 str = get_str_from_var(&x, x.dscale);
374 PG_RETURN_CSTRING(str);
378 * numeric_recv - converts external binary format to numeric
380 * External format is a sequence of int16's:
381 * ndigits, weight, sign, dscale, NumericDigits.
384 numeric_recv(PG_FUNCTION_ARGS)
386 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
389 Oid typelem = PG_GETARG_OID(1);
391 int32 typmod = PG_GETARG_INT32(2);
399 len = (uint16) pq_getmsgint(buf, sizeof(uint16));
400 if (len < 0 || len > NUMERIC_MAX_PRECISION + NUMERIC_MAX_RESULT_SCALE)
402 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
403 errmsg("invalid length in external \"numeric\" value")));
405 alloc_var(&value, len);
407 value.weight = (int16) pq_getmsgint(buf, sizeof(int16));
408 value.sign = (uint16) pq_getmsgint(buf, sizeof(uint16));
409 if (!(value.sign == NUMERIC_POS ||
410 value.sign == NUMERIC_NEG ||
411 value.sign == NUMERIC_NAN))
413 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
414 errmsg("invalid sign in external \"numeric\" value")));
416 value.dscale = (uint16) pq_getmsgint(buf, sizeof(uint16));
417 for (i = 0; i < len; i++)
419 NumericDigit d = pq_getmsgint(buf, sizeof(NumericDigit));
421 if (d < 0 || d >= NBASE)
423 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
424 errmsg("invalid digit in external \"numeric\" value")));
428 apply_typmod(&value, typmod);
430 res = make_result(&value);
433 PG_RETURN_NUMERIC(res);
437 * numeric_send - converts numeric to binary format
440 numeric_send(PG_FUNCTION_ARGS)
442 Numeric num = PG_GETARG_NUMERIC(0);
448 set_var_from_num(num, &x);
450 pq_begintypsend(&buf);
452 pq_sendint(&buf, x.ndigits, sizeof(int16));
453 pq_sendint(&buf, x.weight, sizeof(int16));
454 pq_sendint(&buf, x.sign, sizeof(int16));
455 pq_sendint(&buf, x.dscale, sizeof(int16));
456 for (i = 0; i < x.ndigits; i++)
457 pq_sendint(&buf, x.digits[i], sizeof(NumericDigit));
461 PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
468 * This is a special function called by the Postgres database system
469 * before a value is stored in a tuple's attribute. The precision and
470 * scale of the attribute have to be applied on the value.
473 numeric (PG_FUNCTION_ARGS)
475 Numeric num = PG_GETARG_NUMERIC(0);
476 int32 typmod = PG_GETARG_INT32(1);
488 if (NUMERIC_IS_NAN(num))
489 PG_RETURN_NUMERIC(make_result(&const_nan));
492 * If the value isn't a valid type modifier, simply return a copy of the
495 if (typmod < (int32) (VARHDRSZ))
497 new = (Numeric) palloc(num->varlen);
498 memcpy(new, num, num->varlen);
499 PG_RETURN_NUMERIC(new);
503 * Get the precision and scale out of the typmod value
505 tmp_typmod = typmod - VARHDRSZ;
506 precision = (tmp_typmod >> 16) & 0xffff;
507 scale = tmp_typmod & 0xffff;
508 maxdigits = precision - scale;
511 * If the number is certainly in bounds and due to the target scale no
512 * rounding could be necessary, just make a copy of the input and modify
513 * its scale fields. (Note we assume the existing dscale is honest...)
515 ddigits = (num->n_weight + 1) * DEC_DIGITS;
516 if (ddigits <= maxdigits && scale >= NUMERIC_DSCALE(num))
518 new = (Numeric) palloc(num->varlen);
519 memcpy(new, num, num->varlen);
520 new->n_sign_dscale = NUMERIC_SIGN(new) |
521 ((uint16) scale & NUMERIC_DSCALE_MASK);
522 PG_RETURN_NUMERIC(new);
526 * We really need to fiddle with things - unpack the number into a
527 * variable and let apply_typmod() do it.
531 set_var_from_num(num, &var);
532 apply_typmod(&var, typmod);
533 new = make_result(&var);
537 PG_RETURN_NUMERIC(new);
541 /* ----------------------------------------------------------------------
543 * Sign manipulation, rounding and the like
545 * ----------------------------------------------------------------------
549 numeric_abs(PG_FUNCTION_ARGS)
551 Numeric num = PG_GETARG_NUMERIC(0);
557 if (NUMERIC_IS_NAN(num))
558 PG_RETURN_NUMERIC(make_result(&const_nan));
561 * Do it the easy way directly on the packed format
563 res = (Numeric) palloc(num->varlen);
564 memcpy(res, num, num->varlen);
566 res->n_sign_dscale = NUMERIC_POS | NUMERIC_DSCALE(num);
568 PG_RETURN_NUMERIC(res);
573 numeric_uminus(PG_FUNCTION_ARGS)
575 Numeric num = PG_GETARG_NUMERIC(0);
581 if (NUMERIC_IS_NAN(num))
582 PG_RETURN_NUMERIC(make_result(&const_nan));
585 * Do it the easy way directly on the packed format
587 res = (Numeric) palloc(num->varlen);
588 memcpy(res, num, num->varlen);
591 * The packed format is known to be totally zero digit trimmed always. So
592 * we can identify a ZERO by the fact that there are no digits at all. Do
595 if (num->varlen != NUMERIC_HDRSZ)
597 /* Else, flip the sign */
598 if (NUMERIC_SIGN(num) == NUMERIC_POS)
599 res->n_sign_dscale = NUMERIC_NEG | NUMERIC_DSCALE(num);
601 res->n_sign_dscale = NUMERIC_POS | NUMERIC_DSCALE(num);
604 PG_RETURN_NUMERIC(res);
609 numeric_uplus(PG_FUNCTION_ARGS)
611 Numeric num = PG_GETARG_NUMERIC(0);
614 res = (Numeric) palloc(num->varlen);
615 memcpy(res, num, num->varlen);
617 PG_RETURN_NUMERIC(res);
623 * returns -1 if the argument is less than 0, 0 if the argument is equal
624 * to 0, and 1 if the argument is greater than zero.
627 numeric_sign(PG_FUNCTION_ARGS)
629 Numeric num = PG_GETARG_NUMERIC(0);
636 if (NUMERIC_IS_NAN(num))
637 PG_RETURN_NUMERIC(make_result(&const_nan));
642 * The packed format is known to be totally zero digit trimmed always. So
643 * we can identify a ZERO by the fact that there are no digits at all.
645 if (num->varlen == NUMERIC_HDRSZ)
646 set_var_from_var(&const_zero, &result);
650 * And if there are some, we return a copy of ONE with the sign of our
653 set_var_from_var(&const_one, &result);
654 result.sign = NUMERIC_SIGN(num);
657 res = make_result(&result);
660 PG_RETURN_NUMERIC(res);
667 * Round a value to have 'scale' digits after the decimal point.
668 * We allow negative 'scale', implying rounding before the decimal
669 * point --- Oracle interprets rounding that way.
672 numeric_round(PG_FUNCTION_ARGS)
674 Numeric num = PG_GETARG_NUMERIC(0);
675 int32 scale = PG_GETARG_INT32(1);
682 if (NUMERIC_IS_NAN(num))
683 PG_RETURN_NUMERIC(make_result(&const_nan));
686 * Limit the scale value to avoid possible overflow in calculations
688 scale = Max(scale, -NUMERIC_MAX_RESULT_SCALE);
689 scale = Min(scale, NUMERIC_MAX_RESULT_SCALE);
692 * Unpack the argument and round it at the proper digit position
695 set_var_from_num(num, &arg);
697 round_var(&arg, scale);
699 /* We don't allow negative output dscale */
704 * Return the rounded result
706 res = make_result(&arg);
709 PG_RETURN_NUMERIC(res);
716 * Truncate a value to have 'scale' digits after the decimal point.
717 * We allow negative 'scale', implying a truncation before the decimal
718 * point --- Oracle interprets truncation that way.
721 numeric_trunc(PG_FUNCTION_ARGS)
723 Numeric num = PG_GETARG_NUMERIC(0);
724 int32 scale = PG_GETARG_INT32(1);
731 if (NUMERIC_IS_NAN(num))
732 PG_RETURN_NUMERIC(make_result(&const_nan));
735 * Limit the scale value to avoid possible overflow in calculations
737 scale = Max(scale, -NUMERIC_MAX_RESULT_SCALE);
738 scale = Min(scale, NUMERIC_MAX_RESULT_SCALE);
741 * Unpack the argument and truncate it at the proper digit position
744 set_var_from_num(num, &arg);
746 trunc_var(&arg, scale);
748 /* We don't allow negative output dscale */
753 * Return the truncated result
755 res = make_result(&arg);
758 PG_RETURN_NUMERIC(res);
765 * Return the smallest integer greater than or equal to the argument
768 numeric_ceil(PG_FUNCTION_ARGS)
770 Numeric num = PG_GETARG_NUMERIC(0);
774 if (NUMERIC_IS_NAN(num))
775 PG_RETURN_NUMERIC(make_result(&const_nan));
779 set_var_from_num(num, &result);
780 ceil_var(&result, &result);
782 res = make_result(&result);
785 PG_RETURN_NUMERIC(res);
792 * Return the largest integer equal to or less than the argument
795 numeric_floor(PG_FUNCTION_ARGS)
797 Numeric num = PG_GETARG_NUMERIC(0);
801 if (NUMERIC_IS_NAN(num))
802 PG_RETURN_NUMERIC(make_result(&const_nan));
806 set_var_from_num(num, &result);
807 floor_var(&result, &result);
809 res = make_result(&result);
812 PG_RETURN_NUMERIC(res);
816 * width_bucket_numeric() -
818 * 'bound1' and 'bound2' are the lower and upper bounds of the
819 * histogram's range, respectively. 'count' is the number of buckets
820 * in the histogram. width_bucket() returns an integer indicating the
821 * bucket number that 'operand' belongs in for an equiwidth histogram
822 * with the specified characteristics. An operand smaller than the
823 * lower bound is assigned to bucket 0. An operand greater than the
824 * upper bound is assigned to an additional bucket (with number
828 width_bucket_numeric(PG_FUNCTION_ARGS)
830 Numeric operand = PG_GETARG_NUMERIC(0);
831 Numeric bound1 = PG_GETARG_NUMERIC(1);
832 Numeric bound2 = PG_GETARG_NUMERIC(2);
833 int32 count = PG_GETARG_INT32(3);
834 NumericVar count_var;
835 NumericVar result_var;
840 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
841 errmsg("count must be greater than zero")));
843 init_var(&result_var);
844 init_var(&count_var);
846 /* Convert 'count' to a numeric, for ease of use later */
847 int8_to_numericvar((int64) count, &count_var);
849 switch (cmp_numerics(bound1, bound2))
853 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
854 errmsg("lower bound cannot equal upper bound")));
856 /* bound1 < bound2 */
858 if (cmp_numerics(operand, bound1) < 0)
859 set_var_from_var(&const_zero, &result_var);
860 else if (cmp_numerics(operand, bound2) >= 0)
861 add_var(&count_var, &const_one, &result_var);
863 compute_bucket(operand, bound1, bound2,
864 &count_var, &result_var);
867 /* bound1 > bound2 */
869 if (cmp_numerics(operand, bound1) > 0)
870 set_var_from_var(&const_zero, &result_var);
871 else if (cmp_numerics(operand, bound2) <= 0)
872 add_var(&count_var, &const_one, &result_var);
874 compute_bucket(operand, bound1, bound2,
875 &count_var, &result_var);
879 result = numericvar_to_int4(&result_var);
881 free_var(&count_var);
882 free_var(&result_var);
884 PG_RETURN_INT32(result);
890 * If 'operand' is not outside the bucket range, determine the correct
891 * bucket for it to go. The calculations performed by this function
892 * are derived directly from the SQL2003 spec.
895 compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
896 NumericVar *count_var, NumericVar *result_var)
898 NumericVar bound1_var;
899 NumericVar bound2_var;
900 NumericVar operand_var;
902 init_var(&bound1_var);
903 init_var(&bound2_var);
904 init_var(&operand_var);
906 set_var_from_num(bound1, &bound1_var);
907 set_var_from_num(bound2, &bound2_var);
908 set_var_from_num(operand, &operand_var);
910 if (cmp_var(&bound1_var, &bound2_var) < 0)
912 sub_var(&operand_var, &bound1_var, &operand_var);
913 sub_var(&bound2_var, &bound1_var, &bound2_var);
914 div_var(&operand_var, &bound2_var, result_var,
915 select_div_scale(&operand_var, &bound2_var), true);
919 sub_var(&bound1_var, &operand_var, &operand_var);
920 sub_var(&bound1_var, &bound2_var, &bound1_var);
921 div_var(&operand_var, &bound1_var, result_var,
922 select_div_scale(&operand_var, &bound1_var), true);
925 mul_var(result_var, count_var, result_var,
926 result_var->dscale + count_var->dscale);
927 add_var(result_var, &const_one, result_var);
928 floor_var(result_var, result_var);
930 free_var(&bound1_var);
931 free_var(&bound2_var);
932 free_var(&operand_var);
935 /* ----------------------------------------------------------------------
937 * Comparison functions
939 * Note: btree indexes need these routines not to leak memory; therefore,
940 * be careful to free working copies of toasted datums. Most places don't
941 * need to be so careful.
942 * ----------------------------------------------------------------------
947 numeric_cmp(PG_FUNCTION_ARGS)
949 Numeric num1 = PG_GETARG_NUMERIC(0);
950 Numeric num2 = PG_GETARG_NUMERIC(1);
953 result = cmp_numerics(num1, num2);
955 PG_FREE_IF_COPY(num1, 0);
956 PG_FREE_IF_COPY(num2, 1);
958 PG_RETURN_INT32(result);
963 numeric_eq(PG_FUNCTION_ARGS)
965 Numeric num1 = PG_GETARG_NUMERIC(0);
966 Numeric num2 = PG_GETARG_NUMERIC(1);
969 result = cmp_numerics(num1, num2) == 0;
971 PG_FREE_IF_COPY(num1, 0);
972 PG_FREE_IF_COPY(num2, 1);
974 PG_RETURN_BOOL(result);
978 numeric_ne(PG_FUNCTION_ARGS)
980 Numeric num1 = PG_GETARG_NUMERIC(0);
981 Numeric num2 = PG_GETARG_NUMERIC(1);
984 result = cmp_numerics(num1, num2) != 0;
986 PG_FREE_IF_COPY(num1, 0);
987 PG_FREE_IF_COPY(num2, 1);
989 PG_RETURN_BOOL(result);
993 numeric_gt(PG_FUNCTION_ARGS)
995 Numeric num1 = PG_GETARG_NUMERIC(0);
996 Numeric num2 = PG_GETARG_NUMERIC(1);
999 result = cmp_numerics(num1, num2) > 0;
1001 PG_FREE_IF_COPY(num1, 0);
1002 PG_FREE_IF_COPY(num2, 1);
1004 PG_RETURN_BOOL(result);
1008 numeric_ge(PG_FUNCTION_ARGS)
1010 Numeric num1 = PG_GETARG_NUMERIC(0);
1011 Numeric num2 = PG_GETARG_NUMERIC(1);
1014 result = cmp_numerics(num1, num2) >= 0;
1016 PG_FREE_IF_COPY(num1, 0);
1017 PG_FREE_IF_COPY(num2, 1);
1019 PG_RETURN_BOOL(result);
1023 numeric_lt(PG_FUNCTION_ARGS)
1025 Numeric num1 = PG_GETARG_NUMERIC(0);
1026 Numeric num2 = PG_GETARG_NUMERIC(1);
1029 result = cmp_numerics(num1, num2) < 0;
1031 PG_FREE_IF_COPY(num1, 0);
1032 PG_FREE_IF_COPY(num2, 1);
1034 PG_RETURN_BOOL(result);
1038 numeric_le(PG_FUNCTION_ARGS)
1040 Numeric num1 = PG_GETARG_NUMERIC(0);
1041 Numeric num2 = PG_GETARG_NUMERIC(1);
1044 result = cmp_numerics(num1, num2) <= 0;
1046 PG_FREE_IF_COPY(num1, 0);
1047 PG_FREE_IF_COPY(num2, 1);
1049 PG_RETURN_BOOL(result);
1053 cmp_numerics(Numeric num1, Numeric num2)
1058 * We consider all NANs to be equal and larger than any non-NAN. This is
1059 * somewhat arbitrary; the important thing is to have a consistent sort
1062 if (NUMERIC_IS_NAN(num1))
1064 if (NUMERIC_IS_NAN(num2))
1065 result = 0; /* NAN = NAN */
1067 result = 1; /* NAN > non-NAN */
1069 else if (NUMERIC_IS_NAN(num2))
1071 result = -1; /* non-NAN < NAN */
1075 result = cmp_var_common(NUMERIC_DIGITS(num1), NUMERIC_NDIGITS(num1),
1076 num1->n_weight, NUMERIC_SIGN(num1),
1077 NUMERIC_DIGITS(num2), NUMERIC_NDIGITS(num2),
1078 num2->n_weight, NUMERIC_SIGN(num2));
1085 /* ----------------------------------------------------------------------
1087 * Basic arithmetic functions
1089 * ----------------------------------------------------------------------
1099 numeric_add(PG_FUNCTION_ARGS)
1101 Numeric num1 = PG_GETARG_NUMERIC(0);
1102 Numeric num2 = PG_GETARG_NUMERIC(1);
1111 if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
1112 PG_RETURN_NUMERIC(make_result(&const_nan));
1115 * Unpack the values, let add_var() compute the result and return it.
1121 set_var_from_num(num1, &arg1);
1122 set_var_from_num(num2, &arg2);
1124 add_var(&arg1, &arg2, &result);
1126 res = make_result(&result);
1132 PG_RETURN_NUMERIC(res);
1139 * Subtract one numeric from another
1142 numeric_sub(PG_FUNCTION_ARGS)
1144 Numeric num1 = PG_GETARG_NUMERIC(0);
1145 Numeric num2 = PG_GETARG_NUMERIC(1);
1154 if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
1155 PG_RETURN_NUMERIC(make_result(&const_nan));
1158 * Unpack the values, let sub_var() compute the result and return it.
1164 set_var_from_num(num1, &arg1);
1165 set_var_from_num(num2, &arg2);
1167 sub_var(&arg1, &arg2, &result);
1169 res = make_result(&result);
1175 PG_RETURN_NUMERIC(res);
1182 * Calculate the product of two numerics
1185 numeric_mul(PG_FUNCTION_ARGS)
1187 Numeric num1 = PG_GETARG_NUMERIC(0);
1188 Numeric num2 = PG_GETARG_NUMERIC(1);
1197 if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
1198 PG_RETURN_NUMERIC(make_result(&const_nan));
1201 * Unpack the values, let mul_var() compute the result and return it.
1202 * Unlike add_var() and sub_var(), mul_var() will round its result. In the
1203 * case of numeric_mul(), which is invoked for the * operator on numerics,
1204 * we request exact representation for the product (rscale = sum(dscale of
1205 * arg1, dscale of arg2)).
1211 set_var_from_num(num1, &arg1);
1212 set_var_from_num(num2, &arg2);
1214 mul_var(&arg1, &arg2, &result, arg1.dscale + arg2.dscale);
1216 res = make_result(&result);
1222 PG_RETURN_NUMERIC(res);
1229 * Divide one numeric into another
1232 numeric_div(PG_FUNCTION_ARGS)
1234 Numeric num1 = PG_GETARG_NUMERIC(0);
1235 Numeric num2 = PG_GETARG_NUMERIC(1);
1245 if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
1246 PG_RETURN_NUMERIC(make_result(&const_nan));
1249 * Unpack the arguments
1255 set_var_from_num(num1, &arg1);
1256 set_var_from_num(num2, &arg2);
1259 * Select scale for division result
1261 rscale = select_div_scale(&arg1, &arg2);
1264 * Do the divide and return the result
1266 div_var(&arg1, &arg2, &result, rscale, true);
1268 res = make_result(&result);
1274 PG_RETURN_NUMERIC(res);
1281 * Calculate the modulo of two numerics
1284 numeric_mod(PG_FUNCTION_ARGS)
1286 Numeric num1 = PG_GETARG_NUMERIC(0);
1287 Numeric num2 = PG_GETARG_NUMERIC(1);
1293 if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
1294 PG_RETURN_NUMERIC(make_result(&const_nan));
1300 set_var_from_num(num1, &arg1);
1301 set_var_from_num(num2, &arg2);
1303 mod_var(&arg1, &arg2, &result);
1305 res = make_result(&result);
1311 PG_RETURN_NUMERIC(res);
1318 * Increment a number by one
1321 numeric_inc(PG_FUNCTION_ARGS)
1323 Numeric num = PG_GETARG_NUMERIC(0);
1330 if (NUMERIC_IS_NAN(num))
1331 PG_RETURN_NUMERIC(make_result(&const_nan));
1334 * Compute the result and return it
1338 set_var_from_num(num, &arg);
1340 add_var(&arg, &const_one, &arg);
1342 res = make_result(&arg);
1346 PG_RETURN_NUMERIC(res);
1351 * numeric_smaller() -
1353 * Return the smaller of two numbers
1356 numeric_smaller(PG_FUNCTION_ARGS)
1358 Numeric num1 = PG_GETARG_NUMERIC(0);
1359 Numeric num2 = PG_GETARG_NUMERIC(1);
1362 * Use cmp_numerics so that this will agree with the comparison operators,
1363 * particularly as regards comparisons involving NaN.
1365 if (cmp_numerics(num1, num2) < 0)
1366 PG_RETURN_NUMERIC(num1);
1368 PG_RETURN_NUMERIC(num2);
1373 * numeric_larger() -
1375 * Return the larger of two numbers
1378 numeric_larger(PG_FUNCTION_ARGS)
1380 Numeric num1 = PG_GETARG_NUMERIC(0);
1381 Numeric num2 = PG_GETARG_NUMERIC(1);
1384 * Use cmp_numerics so that this will agree with the comparison operators,
1385 * particularly as regards comparisons involving NaN.
1387 if (cmp_numerics(num1, num2) > 0)
1388 PG_RETURN_NUMERIC(num1);
1390 PG_RETURN_NUMERIC(num2);
1394 /* ----------------------------------------------------------------------
1396 * Advanced math functions
1398 * ----------------------------------------------------------------------
1407 numeric_fac(PG_FUNCTION_ARGS)
1409 int64 num = PG_GETARG_INT64(0);
1416 res = make_result(&const_one);
1417 PG_RETURN_NUMERIC(res);
1423 int8_to_numericvar(num, &result);
1425 for (num = num - 1; num > 1; num--)
1427 int8_to_numericvar(num, &fact);
1429 mul_var(&result, &fact, &result, 0);
1432 res = make_result(&result);
1437 PG_RETURN_NUMERIC(res);
1444 * Compute the square root of a numeric.
1447 numeric_sqrt(PG_FUNCTION_ARGS)
1449 Numeric num = PG_GETARG_NUMERIC(0);
1459 if (NUMERIC_IS_NAN(num))
1460 PG_RETURN_NUMERIC(make_result(&const_nan));
1463 * Unpack the argument and determine the result scale. We choose a scale
1464 * to give at least NUMERIC_MIN_SIG_DIGITS significant digits; but in any
1465 * case not less than the input's dscale.
1470 set_var_from_num(num, &arg);
1472 /* Assume the input was normalized, so arg.weight is accurate */
1473 sweight = (arg.weight + 1) * DEC_DIGITS / 2 - 1;
1475 rscale = NUMERIC_MIN_SIG_DIGITS - sweight;
1476 rscale = Max(rscale, arg.dscale);
1477 rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
1478 rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
1481 * Let sqrt_var() do the calculation and return the result.
1483 sqrt_var(&arg, &result, rscale);
1485 res = make_result(&result);
1490 PG_RETURN_NUMERIC(res);
1497 * Raise e to the power of x
1500 numeric_exp(PG_FUNCTION_ARGS)
1502 Numeric num = PG_GETARG_NUMERIC(0);
1512 if (NUMERIC_IS_NAN(num))
1513 PG_RETURN_NUMERIC(make_result(&const_nan));
1516 * Unpack the argument and determine the result scale. We choose a scale
1517 * to give at least NUMERIC_MIN_SIG_DIGITS significant digits; but in any
1518 * case not less than the input's dscale.
1523 set_var_from_num(num, &arg);
1525 /* convert input to float8, ignoring overflow */
1526 val = numericvar_to_double_no_overflow(&arg);
1529 * log10(result) = num * log10(e), so this is approximately the decimal
1530 * weight of the result:
1532 val *= 0.434294481903252;
1534 /* limit to something that won't cause integer overflow */
1535 val = Max(val, -NUMERIC_MAX_RESULT_SCALE);
1536 val = Min(val, NUMERIC_MAX_RESULT_SCALE);
1538 rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;
1539 rscale = Max(rscale, arg.dscale);
1540 rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
1541 rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
1544 * Let exp_var() do the calculation and return the result.
1546 exp_var(&arg, &result, rscale);
1548 res = make_result(&result);
1553 PG_RETURN_NUMERIC(res);
1560 * Compute the natural logarithm of x
1563 numeric_ln(PG_FUNCTION_ARGS)
1565 Numeric num = PG_GETARG_NUMERIC(0);
1575 if (NUMERIC_IS_NAN(num))
1576 PG_RETURN_NUMERIC(make_result(&const_nan));
1581 set_var_from_num(num, &arg);
1583 /* Approx decimal digits before decimal point */
1584 dec_digits = (arg.weight + 1) * DEC_DIGITS;
1587 rscale = NUMERIC_MIN_SIG_DIGITS - (int) log10(dec_digits - 1);
1588 else if (dec_digits < 1)
1589 rscale = NUMERIC_MIN_SIG_DIGITS - (int) log10(1 - dec_digits);
1591 rscale = NUMERIC_MIN_SIG_DIGITS;
1593 rscale = Max(rscale, arg.dscale);
1594 rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
1595 rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
1597 ln_var(&arg, &result, rscale);
1599 res = make_result(&result);
1604 PG_RETURN_NUMERIC(res);
1611 * Compute the logarithm of x in a given base
1614 numeric_log(PG_FUNCTION_ARGS)
1616 Numeric num1 = PG_GETARG_NUMERIC(0);
1617 Numeric num2 = PG_GETARG_NUMERIC(1);
1626 if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
1627 PG_RETURN_NUMERIC(make_result(&const_nan));
1636 set_var_from_num(num1, &arg1);
1637 set_var_from_num(num2, &arg2);
1640 * Call log_var() to compute and return the result; note it handles scale
1643 log_var(&arg1, &arg2, &result);
1645 res = make_result(&result);
1651 PG_RETURN_NUMERIC(res);
1658 * Raise b to the power of x
1661 numeric_power(PG_FUNCTION_ARGS)
1663 Numeric num1 = PG_GETARG_NUMERIC(0);
1664 Numeric num2 = PG_GETARG_NUMERIC(1);
1668 NumericVar arg2_trunc;
1674 if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
1675 PG_RETURN_NUMERIC(make_result(&const_nan));
1682 init_var(&arg2_trunc);
1685 set_var_from_num(num1, &arg1);
1686 set_var_from_num(num2, &arg2);
1687 set_var_from_var(&arg2, &arg2_trunc);
1689 trunc_var(&arg2_trunc, 0);
1692 * Return special SQLSTATE error codes for a few conditions mandated by
1695 if ((cmp_var(&arg1, &const_zero) == 0 &&
1696 cmp_var(&arg2, &const_zero) < 0) ||
1697 (cmp_var(&arg1, &const_zero) < 0 &&
1698 cmp_var(&arg2, &arg2_trunc) != 0))
1700 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
1701 errmsg("invalid argument for power function")));
1704 * Call power_var() to compute and return the result; note it handles
1705 * scale selection itself.
1707 power_var(&arg1, &arg2, &result);
1709 res = make_result(&result);
1713 free_var(&arg2_trunc);
1716 PG_RETURN_NUMERIC(res);
1720 /* ----------------------------------------------------------------------
1722 * Type conversion functions
1724 * ----------------------------------------------------------------------
1729 int4_numeric(PG_FUNCTION_ARGS)
1731 int32 val = PG_GETARG_INT32(0);
1737 int8_to_numericvar((int64) val, &result);
1739 res = make_result(&result);
1743 PG_RETURN_NUMERIC(res);
1748 numeric_int4(PG_FUNCTION_ARGS)
1750 Numeric num = PG_GETARG_NUMERIC(0);
1754 /* XXX would it be better to return NULL? */
1755 if (NUMERIC_IS_NAN(num))
1757 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1758 errmsg("cannot convert NaN to integer")));
1760 /* Convert to variable format, then convert to int4 */
1762 set_var_from_num(num, &x);
1763 result = numericvar_to_int4(&x);
1765 PG_RETURN_INT32(result);
1769 * Given a NumericVar, convert it to an int32. If the NumericVar
1770 * exceeds the range of an int32, raise the appropriate error via
1771 * ereport(). The input NumericVar is *not* free'd.
1774 numericvar_to_int4(NumericVar *var)
1779 if (!numericvar_to_int8(var, &val))
1781 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1782 errmsg("integer out of range")));
1784 /* Down-convert to int4 */
1785 result = (int32) val;
1787 /* Test for overflow by reverse-conversion. */
1788 if ((int64) result != val)
1790 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1791 errmsg("integer out of range")));
1797 int8_numeric(PG_FUNCTION_ARGS)
1799 int64 val = PG_GETARG_INT64(0);
1805 int8_to_numericvar(val, &result);
1807 res = make_result(&result);
1811 PG_RETURN_NUMERIC(res);
1816 numeric_int8(PG_FUNCTION_ARGS)
1818 Numeric num = PG_GETARG_NUMERIC(0);
1822 /* XXX would it be better to return NULL? */
1823 if (NUMERIC_IS_NAN(num))
1825 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1826 errmsg("cannot convert NaN to bigint")));
1828 /* Convert to variable format and thence to int8 */
1830 set_var_from_num(num, &x);
1832 if (!numericvar_to_int8(&x, &result))
1834 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1835 errmsg("bigint out of range")));
1839 PG_RETURN_INT64(result);
1844 int2_numeric(PG_FUNCTION_ARGS)
1846 int16 val = PG_GETARG_INT16(0);
1852 int8_to_numericvar((int64) val, &result);
1854 res = make_result(&result);
1858 PG_RETURN_NUMERIC(res);
1863 numeric_int2(PG_FUNCTION_ARGS)
1865 Numeric num = PG_GETARG_NUMERIC(0);
1870 /* XXX would it be better to return NULL? */
1871 if (NUMERIC_IS_NAN(num))
1873 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1874 errmsg("cannot convert NaN to smallint")));
1876 /* Convert to variable format and thence to int8 */
1878 set_var_from_num(num, &x);
1880 if (!numericvar_to_int8(&x, &val))
1882 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1883 errmsg("smallint out of range")));
1887 /* Down-convert to int2 */
1888 result = (int16) val;
1890 /* Test for overflow by reverse-conversion. */
1891 if ((int64) result != val)
1893 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1894 errmsg("smallint out of range")));
1896 PG_RETURN_INT16(result);
1901 float8_numeric(PG_FUNCTION_ARGS)
1903 float8 val = PG_GETARG_FLOAT8(0);
1906 char buf[DBL_DIG + 100];
1909 PG_RETURN_NUMERIC(make_result(&const_nan));
1911 sprintf(buf, "%.*g", DBL_DIG, val);
1915 set_var_from_str(buf, &result);
1916 res = make_result(&result);
1920 PG_RETURN_NUMERIC(res);
1925 numeric_float8(PG_FUNCTION_ARGS)
1927 Numeric num = PG_GETARG_NUMERIC(0);
1931 if (NUMERIC_IS_NAN(num))
1932 PG_RETURN_FLOAT8(get_float8_nan());
1934 tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
1935 NumericGetDatum(num)));
1937 result = DirectFunctionCall1(float8in, CStringGetDatum(tmp));
1941 PG_RETURN_DATUM(result);
1945 /* Convert numeric to float8; if out of range, return +/- HUGE_VAL */
1947 numeric_float8_no_overflow(PG_FUNCTION_ARGS)
1949 Numeric num = PG_GETARG_NUMERIC(0);
1952 if (NUMERIC_IS_NAN(num))
1953 PG_RETURN_FLOAT8(get_float8_nan());
1955 val = numeric_to_double_no_overflow(num);
1957 PG_RETURN_FLOAT8(val);
1961 float4_numeric(PG_FUNCTION_ARGS)
1963 float4 val = PG_GETARG_FLOAT4(0);
1966 char buf[FLT_DIG + 100];
1969 PG_RETURN_NUMERIC(make_result(&const_nan));
1971 sprintf(buf, "%.*g", FLT_DIG, val);
1975 set_var_from_str(buf, &result);
1976 res = make_result(&result);
1980 PG_RETURN_NUMERIC(res);
1985 numeric_float4(PG_FUNCTION_ARGS)
1987 Numeric num = PG_GETARG_NUMERIC(0);
1991 if (NUMERIC_IS_NAN(num))
1992 PG_RETURN_FLOAT4(get_float4_nan());
1994 tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
1995 NumericGetDatum(num)));
1997 result = DirectFunctionCall1(float4in, CStringGetDatum(tmp));
2001 PG_RETURN_DATUM(result);
2006 text_numeric(PG_FUNCTION_ARGS)
2008 text *str = PG_GETARG_TEXT_P(0);
2013 len = (VARSIZE(str) - VARHDRSZ);
2014 s = palloc(len + 1);
2015 memcpy(s, VARDATA(str), len);
2018 result = DirectFunctionCall3(numeric_in, CStringGetDatum(s),
2019 ObjectIdGetDatum(0), Int32GetDatum(-1));
2027 numeric_text(PG_FUNCTION_ARGS)
2029 /* val is numeric, but easier to leave it as Datum */
2030 Datum val = PG_GETARG_DATUM(0);
2035 s = DatumGetCString(DirectFunctionCall1(numeric_out, val));
2038 result = (text *) palloc(VARHDRSZ + len);
2040 VARATT_SIZEP(result) = len + VARHDRSZ;
2041 memcpy(VARDATA(result), s, len);
2045 PG_RETURN_TEXT_P(result);
2049 /* ----------------------------------------------------------------------
2051 * Aggregate functions
2053 * The transition datatype for all these aggregates is a 3-element array
2054 * of Numeric, holding the values N, sum(X), sum(X*X) in that order.
2056 * We represent N as a numeric mainly to avoid having to build a special
2057 * datatype; it's unlikely it'd overflow an int4, but ...
2059 * ----------------------------------------------------------------------
2063 do_numeric_accum(ArrayType *transarray, Numeric newval)
2072 /* We assume the input is array of numeric */
2073 deconstruct_array(transarray,
2074 NUMERICOID, -1, false, 'i',
2075 &transdatums, NULL, &ndatums);
2077 elog(ERROR, "expected 3-element numeric array");
2079 sumX = transdatums[1];
2080 sumX2 = transdatums[2];
2082 N = DirectFunctionCall1(numeric_inc, N);
2083 sumX = DirectFunctionCall2(numeric_add, sumX,
2084 NumericGetDatum(newval));
2085 sumX2 = DirectFunctionCall2(numeric_add, sumX2,
2086 DirectFunctionCall2(numeric_mul,
2087 NumericGetDatum(newval),
2088 NumericGetDatum(newval)));
2091 transdatums[1] = sumX;
2092 transdatums[2] = sumX2;
2094 result = construct_array(transdatums, 3,
2095 NUMERICOID, -1, false, 'i');
2101 numeric_accum(PG_FUNCTION_ARGS)
2103 ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
2104 Numeric newval = PG_GETARG_NUMERIC(1);
2106 PG_RETURN_ARRAYTYPE_P(do_numeric_accum(transarray, newval));
2110 * Integer data types all use Numeric accumulators to share code and
2111 * avoid risk of overflow. For int2 and int4 inputs, Numeric accumulation
2112 * is overkill for the N and sum(X) values, but definitely not overkill
2113 * for the sum(X*X) value. Hence, we use int2_accum and int4_accum only
2114 * for stddev/variance --- there are faster special-purpose accumulator
2115 * routines for SUM and AVG of these datatypes.
2119 int2_accum(PG_FUNCTION_ARGS)
2121 ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
2122 Datum newval2 = PG_GETARG_DATUM(1);
2125 newval = DatumGetNumeric(DirectFunctionCall1(int2_numeric, newval2));
2127 PG_RETURN_ARRAYTYPE_P(do_numeric_accum(transarray, newval));
2131 int4_accum(PG_FUNCTION_ARGS)
2133 ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
2134 Datum newval4 = PG_GETARG_DATUM(1);
2137 newval = DatumGetNumeric(DirectFunctionCall1(int4_numeric, newval4));
2139 PG_RETURN_ARRAYTYPE_P(do_numeric_accum(transarray, newval));
2143 int8_accum(PG_FUNCTION_ARGS)
2145 ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
2146 Datum newval8 = PG_GETARG_DATUM(1);
2149 newval = DatumGetNumeric(DirectFunctionCall1(int8_numeric, newval8));
2151 PG_RETURN_ARRAYTYPE_P(do_numeric_accum(transarray, newval));
2155 numeric_avg(PG_FUNCTION_ARGS)
2157 ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
2163 /* We assume the input is array of numeric */
2164 deconstruct_array(transarray,
2165 NUMERICOID, -1, false, 'i',
2166 &transdatums, NULL, &ndatums);
2168 elog(ERROR, "expected 3-element numeric array");
2169 N = DatumGetNumeric(transdatums[0]);
2170 sumX = DatumGetNumeric(transdatums[1]);
2173 /* SQL92 defines AVG of no values to be NULL */
2174 /* N is zero iff no digits (cf. numeric_uminus) */
2175 if (N->varlen == NUMERIC_HDRSZ)
2178 PG_RETURN_DATUM(DirectFunctionCall2(numeric_div,
2179 NumericGetDatum(sumX),
2180 NumericGetDatum(N)));
2184 * Workhorse routine for the standard deviance and variance
2185 * aggregates. 'transarray' is the aggregate's transition
2186 * array. 'variance' specifies whether we should calculate the
2187 * variance or the standard deviation. 'sample' indicates whether the
2188 * caller is interested in the sample or the population
2191 * If appropriate variance statistic is undefined for the input,
2192 * *is_null is set to true and NULL is returned.
2195 numeric_stddev_internal(ArrayType *transarray,
2196 bool variance, bool sample,
2214 /* We assume the input is array of numeric */
2215 deconstruct_array(transarray,
2216 NUMERICOID, -1, false, 'i',
2217 &transdatums, NULL, &ndatums);
2219 elog(ERROR, "expected 3-element numeric array");
2220 N = DatumGetNumeric(transdatums[0]);
2221 sumX = DatumGetNumeric(transdatums[1]);
2222 sumX2 = DatumGetNumeric(transdatums[2]);
2224 if (NUMERIC_IS_NAN(N) || NUMERIC_IS_NAN(sumX) || NUMERIC_IS_NAN(sumX2))
2225 return make_result(&const_nan);
2228 set_var_from_num(N, &vN);
2231 * Sample stddev and variance are undefined when N <= 1;
2232 * population stddev is undefined when N == 0. Return NULL in
2240 if (cmp_var(&vN, comp) <= 0)
2247 init_var(&vNminus1);
2248 sub_var(&vN, &const_one, &vNminus1);
2251 set_var_from_num(sumX, &vsumX);
2253 set_var_from_num(sumX2, &vsumX2);
2255 /* compute rscale for mul_var calls */
2256 rscale = vsumX.dscale * 2;
2258 mul_var(&vsumX, &vsumX, &vsumX, rscale); /* vsumX = sumX * sumX */
2259 mul_var(&vN, &vsumX2, &vsumX2, rscale); /* vsumX2 = N * sumX2 */
2260 sub_var(&vsumX2, &vsumX, &vsumX2); /* N * sumX2 - sumX * sumX */
2262 if (cmp_var(&vsumX2, &const_zero) <= 0)
2264 /* Watch out for roundoff error producing a negative numerator */
2265 res = make_result(&const_zero);
2269 mul_var(&vN, &vNminus1, &vNminus1, 0); /* N * (N - 1) */
2270 rscale = select_div_scale(&vsumX2, &vNminus1);
2271 div_var(&vsumX2, &vNminus1, &vsumX, rscale, true); /* variance */
2273 sqrt_var(&vsumX, &vsumX, rscale); /* stddev */
2275 res = make_result(&vsumX);
2279 free_var(&vNminus1);
2287 numeric_var_samp(PG_FUNCTION_ARGS)
2292 res = numeric_stddev_internal(PG_GETARG_ARRAYTYPE_P(0),
2293 true, true, &is_null);
2298 PG_RETURN_NUMERIC(res);
2302 numeric_stddev_samp(PG_FUNCTION_ARGS)
2307 res = numeric_stddev_internal(PG_GETARG_ARRAYTYPE_P(0),
2308 false, true, &is_null);
2313 PG_RETURN_NUMERIC(res);
2317 numeric_var_pop(PG_FUNCTION_ARGS)
2322 res = numeric_stddev_internal(PG_GETARG_ARRAYTYPE_P(0),
2323 true, false, &is_null);
2328 PG_RETURN_NUMERIC(res);
2332 numeric_stddev_pop(PG_FUNCTION_ARGS)
2337 res = numeric_stddev_internal(PG_GETARG_ARRAYTYPE_P(0),
2338 false, false, &is_null);
2343 PG_RETURN_NUMERIC(res);
2347 * SUM transition functions for integer datatypes.
2349 * To avoid overflow, we use accumulators wider than the input datatype.
2350 * A Numeric accumulator is needed for int8 input; for int4 and int2
2351 * inputs, we use int8 accumulators which should be sufficient for practical
2352 * purposes. (The latter two therefore don't really belong in this file,
2353 * but we keep them here anyway.)
2355 * Because SQL92 defines the SUM() of no values to be NULL, not zero,
2356 * the initial condition of the transition data value needs to be NULL. This
2357 * means we can't rely on ExecAgg to automatically insert the first non-null
2358 * data value into the transition data: it doesn't know how to do the type
2359 * conversion. The upshot is that these routines have to be marked non-strict
2360 * and handle substitution of the first non-null input themselves.
2364 int2_sum(PG_FUNCTION_ARGS)
2368 if (PG_ARGISNULL(0))
2370 /* No non-null input seen so far... */
2371 if (PG_ARGISNULL(1))
2372 PG_RETURN_NULL(); /* still no non-null */
2373 /* This is the first non-null input. */
2374 newval = (int64) PG_GETARG_INT16(1);
2375 PG_RETURN_INT64(newval);
2379 * If we're invoked by nodeAgg, we can cheat and modify out first
2380 * parameter in-place to avoid palloc overhead. If not, we need to return
2381 * the new value of the transition variable.
2383 if (fcinfo->context && IsA(fcinfo->context, AggState))
2385 int64 *oldsum = (int64 *) PG_GETARG_POINTER(0);
2387 /* Leave the running sum unchanged in the new input is null */
2388 if (!PG_ARGISNULL(1))
2389 *oldsum = *oldsum + (int64) PG_GETARG_INT16(1);
2391 PG_RETURN_POINTER(oldsum);
2395 int64 oldsum = PG_GETARG_INT64(0);
2397 /* Leave sum unchanged if new input is null. */
2398 if (PG_ARGISNULL(1))
2399 PG_RETURN_INT64(oldsum);
2401 /* OK to do the addition. */
2402 newval = oldsum + (int64) PG_GETARG_INT16(1);
2404 PG_RETURN_INT64(newval);
2409 int4_sum(PG_FUNCTION_ARGS)
2413 if (PG_ARGISNULL(0))
2415 /* No non-null input seen so far... */
2416 if (PG_ARGISNULL(1))
2417 PG_RETURN_NULL(); /* still no non-null */
2418 /* This is the first non-null input. */
2419 newval = (int64) PG_GETARG_INT32(1);
2420 PG_RETURN_INT64(newval);
2424 * If we're invoked by nodeAgg, we can cheat and modify out first
2425 * parameter in-place to avoid palloc overhead. If not, we need to return
2426 * the new value of the transition variable.
2428 if (fcinfo->context && IsA(fcinfo->context, AggState))
2430 int64 *oldsum = (int64 *) PG_GETARG_POINTER(0);
2432 /* Leave the running sum unchanged in the new input is null */
2433 if (!PG_ARGISNULL(1))
2434 *oldsum = *oldsum + (int64) PG_GETARG_INT32(1);
2436 PG_RETURN_POINTER(oldsum);
2440 int64 oldsum = PG_GETARG_INT64(0);
2442 /* Leave sum unchanged if new input is null. */
2443 if (PG_ARGISNULL(1))
2444 PG_RETURN_INT64(oldsum);
2446 /* OK to do the addition. */
2447 newval = oldsum + (int64) PG_GETARG_INT32(1);
2449 PG_RETURN_INT64(newval);
2454 int8_sum(PG_FUNCTION_ARGS)
2459 if (PG_ARGISNULL(0))
2461 /* No non-null input seen so far... */
2462 if (PG_ARGISNULL(1))
2463 PG_RETURN_NULL(); /* still no non-null */
2464 /* This is the first non-null input. */
2465 newval = DirectFunctionCall1(int8_numeric, PG_GETARG_DATUM(1));
2466 PG_RETURN_DATUM(newval);
2470 * Note that we cannot special-case the nodeAgg case here, as we do for
2471 * int2_sum and int4_sum: numeric is of variable size, so we cannot modify
2472 * our first parameter in-place.
2475 oldsum = PG_GETARG_NUMERIC(0);
2477 /* Leave sum unchanged if new input is null. */
2478 if (PG_ARGISNULL(1))
2479 PG_RETURN_NUMERIC(oldsum);
2481 /* OK to do the addition. */
2482 newval = DirectFunctionCall1(int8_numeric, PG_GETARG_DATUM(1));
2484 PG_RETURN_DATUM(DirectFunctionCall2(numeric_add,
2485 NumericGetDatum(oldsum), newval));
2490 * Routines for avg(int2) and avg(int4). The transition datatype
2491 * is a two-element int8 array, holding count and sum.
2494 typedef struct Int8TransTypeData
2496 #ifndef INT64_IS_BUSTED
2500 /* "int64" isn't really 64 bits, so fake up properly-aligned fields */
2506 } Int8TransTypeData;
2509 int2_avg_accum(PG_FUNCTION_ARGS)
2511 ArrayType *transarray;
2512 int16 newval = PG_GETARG_INT16(1);
2513 Int8TransTypeData *transdata;
2516 * If we're invoked by nodeAgg, we can cheat and modify our first
2517 * parameter in-place to reduce palloc overhead. Otherwise we need to make
2518 * a copy of it before scribbling on it.
2520 if (fcinfo->context && IsA(fcinfo->context, AggState))
2521 transarray = PG_GETARG_ARRAYTYPE_P(0);
2523 transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
2525 if (ARR_HASNULL(transarray) ||
2526 ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
2527 elog(ERROR, "expected 2-element int8 array");
2529 transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
2531 transdata->sum += newval;
2533 PG_RETURN_ARRAYTYPE_P(transarray);
2537 int4_avg_accum(PG_FUNCTION_ARGS)
2539 ArrayType *transarray;
2540 int32 newval = PG_GETARG_INT32(1);
2541 Int8TransTypeData *transdata;
2544 * If we're invoked by nodeAgg, we can cheat and modify our first
2545 * parameter in-place to reduce palloc overhead. Otherwise we need to make
2546 * a copy of it before scribbling on it.
2548 if (fcinfo->context && IsA(fcinfo->context, AggState))
2549 transarray = PG_GETARG_ARRAYTYPE_P(0);
2551 transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
2553 if (ARR_HASNULL(transarray) ||
2554 ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
2555 elog(ERROR, "expected 2-element int8 array");
2557 transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
2559 transdata->sum += newval;
2561 PG_RETURN_ARRAYTYPE_P(transarray);
2565 int8_avg(PG_FUNCTION_ARGS)
2567 ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
2568 Int8TransTypeData *transdata;
2572 if (ARR_HASNULL(transarray) ||
2573 ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
2574 elog(ERROR, "expected 2-element int8 array");
2575 transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
2577 /* SQL92 defines AVG of no values to be NULL */
2578 if (transdata->count == 0)
2581 countd = DirectFunctionCall1(int8_numeric,
2582 Int64GetDatumFast(transdata->count));
2583 sumd = DirectFunctionCall1(int8_numeric,
2584 Int64GetDatumFast(transdata->sum));
2586 PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd));
2590 /* ----------------------------------------------------------------------
2594 * ----------------------------------------------------------------------
2597 #ifdef NUMERIC_DEBUG
2600 * dump_numeric() - Dump a value in the db storage format for debugging
2603 dump_numeric(const char *str, Numeric num)
2605 NumericDigit *digits = NUMERIC_DIGITS(num);
2609 ndigits = NUMERIC_NDIGITS(num);
2611 printf("%s: NUMERIC w=%d d=%d ", str, num->n_weight, NUMERIC_DSCALE(num));
2612 switch (NUMERIC_SIGN(num))
2624 printf("SIGN=0x%x", NUMERIC_SIGN(num));
2628 for (i = 0; i < ndigits; i++)
2629 printf(" %0*d", DEC_DIGITS, digits[i]);
2635 * dump_var() - Dump a value in the variable format for debugging
2638 dump_var(const char *str, NumericVar *var)
2642 printf("%s: VAR w=%d d=%d ", str, var->weight, var->dscale);
2655 printf("SIGN=0x%x", var->sign);
2659 for (i = 0; i < var->ndigits; i++)
2660 printf(" %0*d", DEC_DIGITS, var->digits[i]);
2664 #endif /* NUMERIC_DEBUG */
2667 /* ----------------------------------------------------------------------
2669 * Local functions follow
2671 * In general, these do not support NaNs --- callers must eliminate
2672 * the possibility of NaN first. (make_result() is an exception.)
2674 * ----------------------------------------------------------------------
2681 * Allocate a digit buffer of ndigits digits (plus a spare digit for rounding)
2684 alloc_var(NumericVar *var, int ndigits)
2686 digitbuf_free(var->buf);
2687 var->buf = digitbuf_alloc(ndigits + 1);
2688 var->buf[0] = 0; /* spare digit for rounding */
2689 var->digits = var->buf + 1;
2690 var->ndigits = ndigits;
2697 * Return the digit buffer of a variable to the free pool
2700 free_var(NumericVar *var)
2702 digitbuf_free(var->buf);
2705 var->sign = NUMERIC_NAN;
2712 * Set a variable to ZERO.
2713 * Note: its dscale is not touched.
2716 zero_var(NumericVar *var)
2718 digitbuf_free(var->buf);
2722 var->weight = 0; /* by convention; doesn't really matter */
2723 var->sign = NUMERIC_POS; /* anything but NAN... */
2728 * set_var_from_str()
2730 * Parse a string and put the number into a variable
2733 set_var_from_str(const char *str, NumericVar *dest)
2735 const char *cp = str;
2736 bool have_dp = FALSE;
2738 unsigned char *decdigits;
2739 int sign = NUMERIC_POS;
2746 NumericDigit *digits;
2749 * We first parse the string to extract decimal digits and determine the
2750 * correct decimal weight. Then convert to NBASE representation.
2753 /* skip leading spaces */
2756 if (!isspace((unsigned char) *cp))
2780 if (!isdigit((unsigned char) *cp))
2782 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2783 errmsg("invalid input syntax for type numeric: \"%s\"", str)));
2785 decdigits = (unsigned char *) palloc(strlen(cp) + DEC_DIGITS * 2);
2787 /* leading padding for digit alignment later */
2788 memset(decdigits, 0, DEC_DIGITS);
2793 if (isdigit((unsigned char) *cp))
2795 decdigits[i++] = *cp++ - '0';
2801 else if (*cp == '.')
2805 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2806 errmsg("invalid input syntax for type numeric: \"%s\"",
2815 ddigits = i - DEC_DIGITS;
2816 /* trailing padding for digit alignment later */
2817 memset(decdigits + i, 0, DEC_DIGITS - 1);
2819 /* Handle exponent, if any */
2820 if (*cp == 'e' || *cp == 'E')
2826 exponent = strtol(cp, &endptr, 10);
2829 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2830 errmsg("invalid input syntax for type numeric: \"%s\"",
2833 if (exponent > NUMERIC_MAX_PRECISION ||
2834 exponent < -NUMERIC_MAX_PRECISION)
2836 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2837 errmsg("invalid input syntax for type numeric: \"%s\"",
2839 dweight += (int) exponent;
2840 dscale -= (int) exponent;
2845 /* Should be nothing left but spaces */
2848 if (!isspace((unsigned char) *cp))
2850 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2851 errmsg("invalid input syntax for type numeric: \"%s\"",
2857 * Okay, convert pure-decimal representation to base NBASE. First we need
2858 * to determine the converted weight and ndigits. offset is the number of
2859 * decimal zeroes to insert before the first given digit to have a
2860 * correctly aligned first NBASE digit.
2863 weight = (dweight + 1 + DEC_DIGITS - 1) / DEC_DIGITS - 1;
2865 weight = -((-dweight - 1) / DEC_DIGITS + 1);
2866 offset = (weight + 1) * DEC_DIGITS - (dweight + 1);
2867 ndigits = (ddigits + offset + DEC_DIGITS - 1) / DEC_DIGITS;
2869 alloc_var(dest, ndigits);
2871 dest->weight = weight;
2872 dest->dscale = dscale;
2874 i = DEC_DIGITS - offset;
2875 digits = dest->digits;
2877 while (ndigits-- > 0)
2880 *digits++ = ((decdigits[i] * 10 + decdigits[i + 1]) * 10 +
2881 decdigits[i + 2]) * 10 + decdigits[i + 3];
2882 #elif DEC_DIGITS == 2
2883 *digits++ = decdigits[i] * 10 + decdigits[i + 1];
2884 #elif DEC_DIGITS == 1
2885 *digits++ = decdigits[i];
2887 #error unsupported NBASE
2894 /* Strip any leading/trailing zeroes, and normalize weight if zero */
2900 * set_var_from_num() -
2902 * Convert the packed db format into a variable
2905 set_var_from_num(Numeric num, NumericVar *dest)
2909 ndigits = NUMERIC_NDIGITS(num);
2911 alloc_var(dest, ndigits);
2913 dest->weight = num->n_weight;
2914 dest->sign = NUMERIC_SIGN(num);
2915 dest->dscale = NUMERIC_DSCALE(num);
2917 memcpy(dest->digits, num->n_data, ndigits * sizeof(NumericDigit));
2922 * set_var_from_var() -
2924 * Copy one variable into another
2927 set_var_from_var(NumericVar *value, NumericVar *dest)
2929 NumericDigit *newbuf;
2931 newbuf = digitbuf_alloc(value->ndigits + 1);
2932 newbuf[0] = 0; /* spare digit for rounding */
2933 memcpy(newbuf + 1, value->digits, value->ndigits * sizeof(NumericDigit));
2935 digitbuf_free(dest->buf);
2937 memmove(dest, value, sizeof(NumericVar));
2939 dest->digits = newbuf + 1;
2944 * get_str_from_var() -
2946 * Convert a var to text representation (guts of numeric_out).
2947 * CAUTION: var's contents may be modified by rounding!
2948 * Returns a palloc'd string.
2951 get_str_from_var(NumericVar *var, int dscale)
2968 * Check if we must round up before printing the value and do so.
2970 round_var(var, dscale);
2973 * Allocate space for the result.
2975 * i is set to to # of decimal digits before decimal point. dscale is the
2976 * # of decimal digits we will print after decimal point. We may generate
2977 * as many as DEC_DIGITS-1 excess digits at the end, and in addition we
2978 * need room for sign, decimal point, null terminator.
2980 i = (var->weight + 1) * DEC_DIGITS;
2984 str = palloc(i + dscale + DEC_DIGITS + 2);
2988 * Output a dash for negative values
2990 if (var->sign == NUMERIC_NEG)
2994 * Output all digits before the decimal point
2996 if (var->weight < 0)
2998 d = var->weight + 1;
3003 for (d = 0; d <= var->weight; d++)
3005 dig = (d < var->ndigits) ? var->digits[d] : 0;
3006 /* In the first digit, suppress extra leading decimal zeroes */
3009 bool putit = (d > 0);
3028 #elif DEC_DIGITS == 2
3031 if (d1 > 0 || d > 0)
3034 #elif DEC_DIGITS == 1
3037 #error unsupported NBASE
3043 * If requested, output a decimal point and all the digits that follow it.
3044 * We initially put out a multiple of DEC_DIGITS digits, then truncate if
3050 endcp = cp + dscale;
3051 for (i = 0; i < dscale; d++, i += DEC_DIGITS)
3053 dig = (d >= 0 && d < var->ndigits) ? var->digits[d] : 0;
3065 #elif DEC_DIGITS == 2
3070 #elif DEC_DIGITS == 1
3073 #error unsupported NBASE
3080 * terminate the string and return it
3090 * Create the packed db numeric format in palloc()'d memory from
3094 make_result(NumericVar *var)
3097 NumericDigit *digits = var->digits;
3098 int weight = var->weight;
3099 int sign = var->sign;
3103 if (sign == NUMERIC_NAN)
3105 result = (Numeric) palloc(NUMERIC_HDRSZ);
3107 result->varlen = NUMERIC_HDRSZ;
3108 result->n_weight = 0;
3109 result->n_sign_dscale = NUMERIC_NAN;
3111 dump_numeric("make_result()", result);
3117 /* truncate leading zeroes */
3118 while (n > 0 && *digits == 0)
3124 /* truncate trailing zeroes */
3125 while (n > 0 && digits[n - 1] == 0)
3128 /* If zero result, force to weight=0 and positive sign */
3135 /* Build the result */
3136 len = NUMERIC_HDRSZ + n * sizeof(NumericDigit);
3137 result = (Numeric) palloc(len);
3138 result->varlen = len;
3139 result->n_weight = weight;
3140 result->n_sign_dscale = sign | (var->dscale & NUMERIC_DSCALE_MASK);
3142 memcpy(result->n_data, digits, n * sizeof(NumericDigit));
3144 /* Check for overflow of int16 fields */
3145 if (result->n_weight != weight ||
3146 NUMERIC_DSCALE(result) != var->dscale)
3148 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
3149 errmsg("value overflows numeric format")));
3151 dump_numeric("make_result()", result);
3159 * Do bounds checking and rounding according to the attributes
3163 apply_typmod(NumericVar *var, int32 typmod)
3171 /* Do nothing if we have a default typmod (-1) */
3172 if (typmod < (int32) (VARHDRSZ))
3176 precision = (typmod >> 16) & 0xffff;
3177 scale = typmod & 0xffff;
3178 maxdigits = precision - scale;
3180 /* Round to target scale (and set var->dscale) */
3181 round_var(var, scale);
3184 * Check for overflow - note we can't do this before rounding, because
3185 * rounding could raise the weight. Also note that the var's weight could
3186 * be inflated by leading zeroes, which will be stripped before storage
3187 * but perhaps might not have been yet. In any case, we must recognize a
3188 * true zero, whose weight doesn't mean anything.
3190 ddigits = (var->weight + 1) * DEC_DIGITS;
3191 if (ddigits > maxdigits)
3193 /* Determine true weight; and check for all-zero result */
3194 for (i = 0; i < var->ndigits; i++)
3196 NumericDigit dig = var->digits[i];
3200 /* Adjust for any high-order decimal zero digits */
3206 else if (dig < 1000)
3208 #elif DEC_DIGITS == 2
3211 #elif DEC_DIGITS == 1
3214 #error unsupported NBASE
3216 if (ddigits > maxdigits)
3218 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
3219 errmsg("numeric field overflow"),
3220 errdetail("A field with precision %d, scale %d must round to an absolute value less than %s%d.",
3222 /* Display 10^0 as 1 */
3223 maxdigits ? "10^" : "",
3224 maxdigits ? maxdigits : 1
3228 ddigits -= DEC_DIGITS;
3234 * Convert numeric to int8, rounding if needed.
3236 * If overflow, return FALSE (no error is raised). Return TRUE if okay.
3238 * CAUTION: var's contents may be modified by rounding!
3241 numericvar_to_int8(NumericVar *var, int64 *result)
3243 NumericDigit *digits;
3251 /* Round to nearest integer */
3254 /* Check for zero input */
3256 ndigits = var->ndigits;
3264 * For input like 10000000000, we must treat stripped digits as real. So
3265 * the loop assumes there are weight+1 digits before the decimal point.
3267 weight = var->weight;
3268 Assert(weight >= 0 && ndigits <= weight + 1);
3270 /* Construct the result */
3271 digits = var->digits;
3272 neg = (var->sign == NUMERIC_NEG);
3274 for (i = 1; i <= weight; i++)
3282 * The overflow check is a bit tricky because we want to accept
3283 * INT64_MIN, which will overflow the positive accumulator. We can
3284 * detect this case easily though because INT64_MIN is the only
3285 * nonzero value for which -val == val (on a two's complement machine,
3288 if ((val / NBASE) != oldval) /* possible overflow? */
3290 if (!neg || (-val) != val || val == 0 || oldval < 0)
3295 *result = neg ? -val : val;
3300 * Convert int8 value to numeric.
3303 int8_to_numericvar(int64 val, NumericVar *var)
3310 /* int8 can require at most 19 decimal digits; add one for safety */
3311 alloc_var(var, 20 / DEC_DIGITS);
3314 var->sign = NUMERIC_NEG;
3319 var->sign = NUMERIC_POS;
3329 ptr = var->digits + var->ndigits;
3335 newuval = uval / NBASE;
3336 *ptr = uval - newuval * NBASE;
3340 var->ndigits = ndigits;
3341 var->weight = ndigits - 1;
3345 * Convert numeric to float8; if out of range, return +/- HUGE_VAL
3348 numeric_to_double_no_overflow(Numeric num)
3354 tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
3355 NumericGetDatum(num)));
3357 /* unlike float8in, we ignore ERANGE from strtod */
3358 val = strtod(tmp, &endptr);
3359 if (*endptr != '\0')
3361 /* shouldn't happen ... */
3363 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
3364 errmsg("invalid input syntax for type double precision: \"%s\"",
3373 /* As above, but work from a NumericVar */
3375 numericvar_to_double_no_overflow(NumericVar *var)
3381 tmp = get_str_from_var(var, var->dscale);
3383 /* unlike float8in, we ignore ERANGE from strtod */
3384 val = strtod(tmp, &endptr);
3385 if (*endptr != '\0')
3387 /* shouldn't happen ... */
3389 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
3390 errmsg("invalid input syntax for type double precision: \"%s\"",
3403 * Compare two values on variable level. We assume zeroes have been
3404 * truncated to no digits.
3407 cmp_var(NumericVar *var1, NumericVar *var2)
3409 return cmp_var_common(var1->digits, var1->ndigits,
3410 var1->weight, var1->sign,
3411 var2->digits, var2->ndigits,
3412 var2->weight, var2->sign);
3416 * cmp_var_common() -
3418 * Main routine of cmp_var(). This function can be used by both
3419 * NumericVar and Numeric.
3422 cmp_var_common(const NumericDigit *var1digits, int var1ndigits,
3423 int var1weight, int var1sign,
3424 const NumericDigit *var2digits, int var2ndigits,
3425 int var2weight, int var2sign)
3427 if (var1ndigits == 0)
3429 if (var2ndigits == 0)
3431 if (var2sign == NUMERIC_NEG)
3435 if (var2ndigits == 0)
3437 if (var1sign == NUMERIC_POS)
3442 if (var1sign == NUMERIC_POS)
3444 if (var2sign == NUMERIC_NEG)
3446 return cmp_abs_common(var1digits, var1ndigits, var1weight,
3447 var2digits, var2ndigits, var2weight);
3450 if (var2sign == NUMERIC_POS)
3453 return cmp_abs_common(var2digits, var2ndigits, var2weight,
3454 var1digits, var1ndigits, var1weight);
3461 * Full version of add functionality on variable level (handling signs).
3462 * result might point to one of the operands too without danger.
3465 add_var(NumericVar *var1, NumericVar *var2, NumericVar *result)
3468 * Decide on the signs of the two variables what to do
3470 if (var1->sign == NUMERIC_POS)
3472 if (var2->sign == NUMERIC_POS)
3475 * Both are positive result = +(ABS(var1) + ABS(var2))
3477 add_abs(var1, var2, result);
3478 result->sign = NUMERIC_POS;
3483 * var1 is positive, var2 is negative Must compare absolute values
3485 switch (cmp_abs(var1, var2))
3489 * ABS(var1) == ABS(var2)
3494 result->dscale = Max(var1->dscale, var2->dscale);
3499 * ABS(var1) > ABS(var2)
3500 * result = +(ABS(var1) - ABS(var2))
3503 sub_abs(var1, var2, result);
3504 result->sign = NUMERIC_POS;
3509 * ABS(var1) < ABS(var2)
3510 * result = -(ABS(var2) - ABS(var1))
3513 sub_abs(var2, var1, result);
3514 result->sign = NUMERIC_NEG;
3521 if (var2->sign == NUMERIC_POS)
3524 * var1 is negative, var2 is positive
3525 * Must compare absolute values
3528 switch (cmp_abs(var1, var2))
3532 * ABS(var1) == ABS(var2)
3537 result->dscale = Max(var1->dscale, var2->dscale);
3542 * ABS(var1) > ABS(var2)
3543 * result = -(ABS(var1) - ABS(var2))
3546 sub_abs(var1, var2, result);
3547 result->sign = NUMERIC_NEG;
3552 * ABS(var1) < ABS(var2)
3553 * result = +(ABS(var2) - ABS(var1))
3556 sub_abs(var2, var1, result);
3557 result->sign = NUMERIC_POS;
3565 * result = -(ABS(var1) + ABS(var2))
3568 add_abs(var1, var2, result);
3569 result->sign = NUMERIC_NEG;
3578 * Full version of sub functionality on variable level (handling signs).
3579 * result might point to one of the operands too without danger.
3582 sub_var(NumericVar *var1, NumericVar *var2, NumericVar *result)
3585 * Decide on the signs of the two variables what to do
3587 if (var1->sign == NUMERIC_POS)
3589 if (var2->sign == NUMERIC_NEG)
3592 * var1 is positive, var2 is negative
3593 * result = +(ABS(var1) + ABS(var2))
3596 add_abs(var1, var2, result);
3597 result->sign = NUMERIC_POS;
3603 * Must compare absolute values
3606 switch (cmp_abs(var1, var2))
3610 * ABS(var1) == ABS(var2)
3615 result->dscale = Max(var1->dscale, var2->dscale);
3620 * ABS(var1) > ABS(var2)
3621 * result = +(ABS(var1) - ABS(var2))
3624 sub_abs(var1, var2, result);
3625 result->sign = NUMERIC_POS;
3630 * ABS(var1) < ABS(var2)
3631 * result = -(ABS(var2) - ABS(var1))
3634 sub_abs(var2, var1, result);
3635 result->sign = NUMERIC_NEG;
3642 if (var2->sign == NUMERIC_NEG)
3646 * Must compare absolute values
3649 switch (cmp_abs(var1, var2))
3653 * ABS(var1) == ABS(var2)
3658 result->dscale = Max(var1->dscale, var2->dscale);
3663 * ABS(var1) > ABS(var2)
3664 * result = -(ABS(var1) - ABS(var2))
3667 sub_abs(var1, var2, result);
3668 result->sign = NUMERIC_NEG;
3673 * ABS(var1) < ABS(var2)
3674 * result = +(ABS(var2) - ABS(var1))
3677 sub_abs(var2, var1, result);
3678 result->sign = NUMERIC_POS;
3685 * var1 is negative, var2 is positive
3686 * result = -(ABS(var1) + ABS(var2))
3689 add_abs(var1, var2, result);
3690 result->sign = NUMERIC_NEG;
3699 * Multiplication on variable level. Product of var1 * var2 is stored
3700 * in result. Result is rounded to no more than rscale fractional digits.
3703 mul_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
3714 NumericDigit *res_digits;
3720 /* copy these values into local vars for speed in inner loop */
3721 int var1ndigits = var1->ndigits;
3722 int var2ndigits = var2->ndigits;
3723 NumericDigit *var1digits = var1->digits;
3724 NumericDigit *var2digits = var2->digits;
3726 if (var1ndigits == 0 || var2ndigits == 0)
3728 /* one or both inputs is zero; so is result */
3730 result->dscale = rscale;
3734 /* Determine result sign and (maximum possible) weight */
3735 if (var1->sign == var2->sign)
3736 res_sign = NUMERIC_POS;
3738 res_sign = NUMERIC_NEG;
3739 res_weight = var1->weight + var2->weight + 2;
3742 * Determine number of result digits to compute. If the exact result
3743 * would have more than rscale fractional digits, truncate the computation
3744 * with MUL_GUARD_DIGITS guard digits. We do that by pretending that one
3745 * or both inputs have fewer digits than they really do.
3747 res_ndigits = var1ndigits + var2ndigits + 1;
3748 maxdigits = res_weight + 1 + (rscale * DEC_DIGITS) + MUL_GUARD_DIGITS;
3749 if (res_ndigits > maxdigits)
3753 /* no useful precision at all in the result... */
3755 result->dscale = rscale;
3758 /* force maxdigits odd so that input ndigits can be equal */
3759 if ((maxdigits & 1) == 0)
3761 if (var1ndigits > var2ndigits)
3763 var1ndigits -= res_ndigits - maxdigits;
3764 if (var1ndigits < var2ndigits)
3765 var1ndigits = var2ndigits = (var1ndigits + var2ndigits) / 2;
3769 var2ndigits -= res_ndigits - maxdigits;
3770 if (var2ndigits < var1ndigits)
3771 var1ndigits = var2ndigits = (var1ndigits + var2ndigits) / 2;
3773 res_ndigits = maxdigits;
3774 Assert(res_ndigits == var1ndigits + var2ndigits + 1);
3778 * We do the arithmetic in an array "dig[]" of signed int's. Since
3779 * INT_MAX is noticeably larger than NBASE*NBASE, this gives us headroom
3780 * to avoid normalizing carries immediately.
3782 * maxdig tracks the maximum possible value of any dig[] entry; when this
3783 * threatens to exceed INT_MAX, we take the time to propagate carries. To
3784 * avoid overflow in maxdig itself, it actually represents the max
3785 * possible value divided by NBASE-1.
3787 dig = (int *) palloc0(res_ndigits * sizeof(int));
3790 ri = res_ndigits - 1;
3791 for (i1 = var1ndigits - 1; i1 >= 0; ri--, i1--)
3793 int var1digit = var1digits[i1];
3798 /* Time to normalize? */
3799 maxdig += var1digit;
3800 if (maxdig > INT_MAX / (NBASE - 1))
3804 for (i = res_ndigits - 1; i >= 0; i--)
3806 newdig = dig[i] + carry;
3807 if (newdig >= NBASE)
3809 carry = newdig / NBASE;
3810 newdig -= carry * NBASE;
3817 /* Reset maxdig to indicate new worst-case */
3818 maxdig = 1 + var1digit;
3821 /* Add appropriate multiple of var2 into the accumulator */
3823 for (i2 = var2ndigits - 1; i2 >= 0; i2--)
3824 dig[i--] += var1digit * var2digits[i2];
3828 * Now we do a final carry propagation pass to normalize the result, which
3829 * we combine with storing the result digits into the output. Note that
3830 * this is still done at full precision w/guard digits.
3832 alloc_var(result, res_ndigits);
3833 res_digits = result->digits;
3835 for (i = res_ndigits - 1; i >= 0; i--)
3837 newdig = dig[i] + carry;
3838 if (newdig >= NBASE)
3840 carry = newdig / NBASE;
3841 newdig -= carry * NBASE;
3845 res_digits[i] = newdig;
3852 * Finally, round the result to the requested precision.
3854 result->weight = res_weight;
3855 result->sign = res_sign;
3857 /* Round to target rscale (and set result->dscale) */
3858 round_var(result, rscale);
3860 /* Strip leading and trailing zeroes */
3868 * Division on variable level. Quotient of var1 / var2 is stored
3869 * in result. Result is rounded to no more than rscale fractional digits.
3872 div_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
3873 int rscale, bool round)
3883 NumericDigit *res_digits;
3891 /* copy these values into local vars for speed in inner loop */
3892 int var1ndigits = var1->ndigits;
3893 int var2ndigits = var2->ndigits;
3894 NumericDigit *var1digits = var1->digits;
3895 NumericDigit *var2digits = var2->digits;
3898 * First of all division by zero check; we must not be handed an
3899 * unnormalized divisor.
3901 if (var2ndigits == 0 || var2digits[0] == 0)
3903 (errcode(ERRCODE_DIVISION_BY_ZERO),
3904 errmsg("division by zero")));
3907 * Now result zero check
3909 if (var1ndigits == 0)
3912 result->dscale = rscale;
3917 * Determine the result sign, weight and number of digits to calculate
3919 if (var1->sign == var2->sign)
3920 res_sign = NUMERIC_POS;
3922 res_sign = NUMERIC_NEG;
3923 res_weight = var1->weight - var2->weight + 1;
3924 /* The number of accurate result digits we need to produce: */
3925 div_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
3926 /* Add guard digits for roundoff error */
3927 div_ndigits += DIV_GUARD_DIGITS;
3928 if (div_ndigits < DIV_GUARD_DIGITS)
3929 div_ndigits = DIV_GUARD_DIGITS;
3930 /* Must be at least var1ndigits, too, to simplify data-loading loop */
3931 if (div_ndigits < var1ndigits)
3932 div_ndigits = var1ndigits;
3935 * We do the arithmetic in an array "div[]" of signed int's. Since
3936 * INT_MAX is noticeably larger than NBASE*NBASE, this gives us headroom
3937 * to avoid normalizing carries immediately.
3939 * We start with div[] containing one zero digit followed by the
3940 * dividend's digits (plus appended zeroes to reach the desired precision
3941 * including guard digits). Each step of the main loop computes an
3942 * (approximate) quotient digit and stores it into div[], removing one
3943 * position of dividend space. A final pass of carry propagation takes
3944 * care of any mistaken quotient digits.
3946 div = (int *) palloc0((div_ndigits + 1) * sizeof(int));
3947 for (i = 0; i < var1ndigits; i++)
3948 div[i + 1] = var1digits[i];
3951 * We estimate each quotient digit using floating-point arithmetic, taking
3952 * the first four digits of the (current) dividend and divisor. This must
3953 * be float to avoid overflow.
3955 fdivisor = (double) var2digits[0];
3956 for (i = 1; i < 4; i++)
3959 if (i < var2ndigits)
3960 fdivisor += (double) var2digits[i];
3962 fdivisorinverse = 1.0 / fdivisor;
3965 * maxdiv tracks the maximum possible absolute value of any div[] entry;
3966 * when this threatens to exceed INT_MAX, we take the time to propagate
3967 * carries. To avoid overflow in maxdiv itself, it actually represents
3968 * the max possible abs. value divided by NBASE-1.
3973 * Outer loop computes next quotient digit, which will go into div[qi]
3975 for (qi = 0; qi < div_ndigits; qi++)
3977 /* Approximate the current dividend value */
3978 fdividend = (double) div[qi];
3979 for (i = 1; i < 4; i++)
3982 if (qi + i <= div_ndigits)
3983 fdividend += (double) div[qi + i];
3985 /* Compute the (approximate) quotient digit */
3986 fquotient = fdividend * fdivisorinverse;
3987 qdigit = (fquotient >= 0.0) ? ((int) fquotient) :
3988 (((int) fquotient) - 1); /* truncate towards -infinity */
3992 /* Do we need to normalize now? */
3993 maxdiv += Abs(qdigit);
3994 if (maxdiv > INT_MAX / (NBASE - 1))
3998 for (i = div_ndigits; i > qi; i--)
4000 newdig = div[i] + carry;
4003 carry = -((-newdig - 1) / NBASE) - 1;
4004 newdig -= carry * NBASE;
4006 else if (newdig >= NBASE)
4008 carry = newdig / NBASE;
4009 newdig -= carry * NBASE;
4015 newdig = div[qi] + carry;
4019 * All the div[] digits except possibly div[qi] are now in the
4022 maxdiv = Abs(newdig) / (NBASE - 1);
4023 maxdiv = Max(maxdiv, 1);
4026 * Recompute the quotient digit since new info may have
4027 * propagated into the top four dividend digits
4029 fdividend = (double) div[qi];
4030 for (i = 1; i < 4; i++)
4033 if (qi + i <= div_ndigits)
4034 fdividend += (double) div[qi + i];
4036 /* Compute the (approximate) quotient digit */
4037 fquotient = fdividend * fdivisorinverse;
4038 qdigit = (fquotient >= 0.0) ? ((int) fquotient) :
4039 (((int) fquotient) - 1); /* truncate towards -infinity */
4040 maxdiv += Abs(qdigit);
4043 /* Subtract off the appropriate multiple of the divisor */
4046 int istop = Min(var2ndigits, div_ndigits - qi + 1);
4048 for (i = 0; i < istop; i++)
4049 div[qi + i] -= qdigit * var2digits[i];
4054 * The dividend digit we are about to replace might still be nonzero.
4055 * Fold it into the next digit position. We don't need to worry about
4056 * overflow here since this should nearly cancel with the subtraction
4059 div[qi + 1] += div[qi] * NBASE;
4065 * Approximate and store the last quotient digit (div[div_ndigits])
4067 fdividend = (double) div[qi];
4068 for (i = 1; i < 4; i++)
4070 fquotient = fdividend * fdivisorinverse;
4071 qdigit = (fquotient >= 0.0) ? ((int) fquotient) :
4072 (((int) fquotient) - 1); /* truncate towards -infinity */
4076 * Now we do a final carry propagation pass to normalize the result, which
4077 * we combine with storing the result digits into the output. Note that
4078 * this is still done at full precision w/guard digits.
4080 alloc_var(result, div_ndigits + 1);
4081 res_digits = result->digits;
4083 for (i = div_ndigits; i >= 0; i--)
4085 newdig = div[i] + carry;
4088 carry = -((-newdig - 1) / NBASE) - 1;
4089 newdig -= carry * NBASE;
4091 else if (newdig >= NBASE)
4093 carry = newdig / NBASE;
4094 newdig -= carry * NBASE;
4098 res_digits[i] = newdig;
4105 * Finally, round the result to the requested precision.
4107 result->weight = res_weight;
4108 result->sign = res_sign;
4110 /* Round to target rscale (and set result->dscale) */
4112 round_var(result, rscale);
4114 trunc_var(result, rscale);
4116 /* Strip leading and trailing zeroes */
4122 * Default scale selection for division
4124 * Returns the appropriate result scale for the division result.
4127 select_div_scale(NumericVar *var1, NumericVar *var2)
4133 NumericDigit firstdigit1,
4138 * The result scale of a division isn't specified in any SQL standard. For
4139 * PostgreSQL we select a result scale that will give at least
4140 * NUMERIC_MIN_SIG_DIGITS significant digits, so that numeric gives a
4141 * result no less accurate than float8; but use a scale not less than
4142 * either input's display scale.
4145 /* Get the actual (normalized) weight and first digit of each input */
4147 weight1 = 0; /* values to use if var1 is zero */
4149 for (i = 0; i < var1->ndigits; i++)
4151 firstdigit1 = var1->digits[i];
4152 if (firstdigit1 != 0)
4154 weight1 = var1->weight - i;
4159 weight2 = 0; /* values to use if var2 is zero */
4161 for (i = 0; i < var2->ndigits; i++)
4163 firstdigit2 = var2->digits[i];
4164 if (firstdigit2 != 0)
4166 weight2 = var2->weight - i;
4172 * Estimate weight of quotient. If the two first digits are equal, we
4173 * can't be sure, but assume that var1 is less than var2.
4175 qweight = weight1 - weight2;
4176 if (firstdigit1 <= firstdigit2)
4179 /* Select result scale */
4180 rscale = NUMERIC_MIN_SIG_DIGITS - qweight * DEC_DIGITS;
4181 rscale = Max(rscale, var1->dscale);
4182 rscale = Max(rscale, var2->dscale);
4183 rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
4184 rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
4193 * Calculate the modulo of two numerics at variable level
4196 mod_var(NumericVar *var1, NumericVar *var2, NumericVar *result)
4204 * We do this using the equation
4205 * mod(x,y) = x - trunc(x/y)*y
4206 * We set rscale the same way numeric_div and numeric_mul do
4207 * to get the right answer from the equation. The final result,
4208 * however, need not be displayed to more precision than the inputs.
4211 rscale = select_div_scale(var1, var2);
4213 div_var(var1, var2, &tmp, rscale, false);
4217 mul_var(var2, &tmp, &tmp, var2->dscale + tmp.dscale);
4219 sub_var(var1, &tmp, result);
4221 round_var(result, Max(var1->dscale, var2->dscale));
4230 * Return the smallest integer greater than or equal to the argument
4234 ceil_var(NumericVar *var, NumericVar *result)
4239 set_var_from_var(var, &tmp);
4243 if (var->sign == NUMERIC_POS && cmp_var(var, &tmp) != 0)
4244 add_var(&tmp, &const_one, &tmp);
4246 set_var_from_var(&tmp, result);
4254 * Return the largest integer equal to or less than the argument
4258 floor_var(NumericVar *var, NumericVar *result)
4263 set_var_from_var(var, &tmp);
4267 if (var->sign == NUMERIC_NEG && cmp_var(var, &tmp) != 0)
4268 sub_var(&tmp, &const_one, &tmp);
4270 set_var_from_var(&tmp, result);
4278 * Compute the square root of x using Newton's algorithm
4281 sqrt_var(NumericVar *arg, NumericVar *result, int rscale)
4285 NumericVar last_val;
4289 local_rscale = rscale + 8;
4291 stat = cmp_var(arg, &const_zero);
4295 result->dscale = rscale;
4300 * SQL2003 defines sqrt() in terms of power, so we need to emit the right
4301 * SQLSTATE error code if the operand is negative.
4305 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
4306 errmsg("cannot take square root of a negative number")));
4310 init_var(&last_val);
4312 /* Copy arg in case it is the same var as result */
4313 set_var_from_var(arg, &tmp_arg);
4316 * Initialize the result to the first guess
4318 alloc_var(result, 1);
4319 result->digits[0] = tmp_arg.digits[0] / 2;
4320 if (result->digits[0] == 0)
4321 result->digits[0] = 1;
4322 result->weight = tmp_arg.weight / 2;
4323 result->sign = NUMERIC_POS;
4325 set_var_from_var(result, &last_val);
4329 div_var(&tmp_arg, result, &tmp_val, local_rscale, true);
4331 add_var(result, &tmp_val, result);
4332 mul_var(result, &const_zero_point_five, result, local_rscale);
4334 if (cmp_var(&last_val, result) == 0)
4336 set_var_from_var(result, &last_val);
4339 free_var(&last_val);
4343 /* Round to requested precision */
4344 round_var(result, rscale);
4351 * Raise e to the power of x
4354 exp_var(NumericVar *arg, NumericVar *result, int rscale)
4362 * We separate the integral and fraction parts of x, then compute
4363 * e^x = e^xint * e^xfrac
4364 * where e = exp(1) and e^xfrac = exp(xfrac) are computed by
4365 * exp_var_internal; the limited range of inputs allows that routine
4366 * to do a good job with a simple Taylor series. Raising e^xint is
4367 * done by repeated multiplications in power_var_int.
4372 set_var_from_var(arg, &x);
4374 if (x.sign == NUMERIC_NEG)
4377 x.sign = NUMERIC_POS;
4380 /* Extract the integer part, remove it from x */
4382 while (x.weight >= 0)
4387 xintval += x.digits[0];
4392 /* Guard against overflow */
4393 if (xintval >= NUMERIC_MAX_RESULT_SCALE * 3)
4395 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4396 errmsg("argument for function \"exp\" too big")));
4399 /* Select an appropriate scale for internal calculation */
4400 local_rscale = rscale + MUL_GUARD_DIGITS * 2;
4402 /* Compute e^xfrac */
4403 exp_var_internal(&x, result, local_rscale);
4405 /* If there's an integer part, multiply by e^xint */
4411 exp_var_internal(&const_one, &e, local_rscale);
4412 power_var_int(&e, xintval, &e, local_rscale);
4413 mul_var(&e, result, result, local_rscale);
4417 /* Compensate for input sign, and round to requested rscale */
4419 div_var(&const_one, result, result, rscale, true);
4421 round_var(result, rscale);
4428 * exp_var_internal() -
4430 * Raise e to the power of x, where 0 <= x <= 1
4432 * NB: the result should be good to at least rscale digits, but it has
4433 * *not* been rounded off; the caller must do that if wanted.
4436 exp_var_internal(NumericVar *arg, NumericVar *result, int rscale)
4452 set_var_from_var(arg, &x);
4454 Assert(x.sign == NUMERIC_POS);
4456 local_rscale = rscale + 8;
4458 /* Reduce input into range 0 <= x <= 0.01 */
4459 while (cmp_var(&x, &const_zero_point_01) > 0)
4463 mul_var(&x, &const_zero_point_five, &x, x.dscale + 1);
4467 * Use the Taylor series
4469 * exp(x) = 1 + x + x^2/2! + x^3/3! + ...
4471 * Given the limited range of x, this should converge reasonably quickly.
4472 * We run the series until the terms fall below the local_rscale limit.
4474 add_var(&const_one, &x, result);
4475 set_var_from_var(&x, &xpow);
4476 set_var_from_var(&const_one, &ifac);
4477 set_var_from_var(&const_one, &ni);
4481 add_var(&ni, &const_one, &ni);
4482 mul_var(&xpow, &x, &xpow, local_rscale);
4483 mul_var(&ifac, &ni, &ifac, 0);
4484 div_var(&xpow, &ifac, &elem, local_rscale, true);
4486 if (elem.ndigits == 0)
4489 add_var(result, &elem, result);
4492 /* Compensate for argument range reduction */
4494 mul_var(result, result, result, local_rscale);
4507 * Compute the natural log of x
4510 ln_var(NumericVar *arg, NumericVar *result, int rscale)
4520 cmp = cmp_var(arg, &const_zero);
4523 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
4524 errmsg("cannot take logarithm of zero")));
4527 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
4528 errmsg("cannot take logarithm of a negative number")));
4530 local_rscale = rscale + 8;
4538 set_var_from_var(arg, &x);
4539 set_var_from_var(&const_two, &fact);
4541 /* Reduce input into range 0.9 < x < 1.1 */
4542 while (cmp_var(&x, &const_zero_point_nine) <= 0)
4545 sqrt_var(&x, &x, local_rscale);
4546 mul_var(&fact, &const_two, &fact, 0);
4548 while (cmp_var(&x, &const_one_point_one) >= 0)
4551 sqrt_var(&x, &x, local_rscale);
4552 mul_var(&fact, &const_two, &fact, 0);
4556 * We use the Taylor series for 0.5 * ln((1+z)/(1-z)),
4558 * z + z^3/3 + z^5/5 + ...
4560 * where z = (x-1)/(x+1) is in the range (approximately) -0.053 .. 0.048
4561 * due to the above range-reduction of x.
4563 * The convergence of this is not as fast as one would like, but is
4564 * tolerable given that z is small.
4566 sub_var(&x, &const_one, result);
4567 add_var(&x, &const_one, &elem);
4568 div_var(result, &elem, result, local_rscale, true);
4569 set_var_from_var(result, &xx);
4570 mul_var(result, result, &x, local_rscale);
4572 set_var_from_var(&const_one, &ni);
4576 add_var(&ni, &const_two, &ni);
4577 mul_var(&xx, &x, &xx, local_rscale);
4578 div_var(&xx, &ni, &elem, local_rscale, true);
4580 if (elem.ndigits == 0)
4583 add_var(result, &elem, result);
4585 if (elem.weight < (result->weight - local_rscale * 2 / DEC_DIGITS))
4589 /* Compensate for argument range reduction, round to requested rscale */
4590 mul_var(result, &fact, result, rscale);
4603 * Compute the logarithm of num in a given base.
4605 * Note: this routine chooses dscale of the result.
4608 log_var(NumericVar *base, NumericVar *num, NumericVar *result)
4619 /* Set scale for ln() calculations --- compare numeric_ln() */
4621 /* Approx decimal digits before decimal point */
4622 dec_digits = (num->weight + 1) * DEC_DIGITS;
4625 rscale = NUMERIC_MIN_SIG_DIGITS - (int) log10(dec_digits - 1);
4626 else if (dec_digits < 1)
4627 rscale = NUMERIC_MIN_SIG_DIGITS - (int) log10(1 - dec_digits);
4629 rscale = NUMERIC_MIN_SIG_DIGITS;
4631 rscale = Max(rscale, base->dscale);
4632 rscale = Max(rscale, num->dscale);
4633 rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
4634 rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
4636 local_rscale = rscale + 8;
4638 /* Form natural logarithms */
4639 ln_var(base, &ln_base, local_rscale);
4640 ln_var(num, &ln_num, local_rscale);
4642 ln_base.dscale = rscale;
4643 ln_num.dscale = rscale;
4645 /* Select scale for division result */
4646 rscale = select_div_scale(&ln_num, &ln_base);
4648 div_var(&ln_num, &ln_base, result, rscale, true);
4658 * Raise base to the power of exp
4660 * Note: this routine chooses dscale of the result.
4663 power_var(NumericVar *base, NumericVar *exp, NumericVar *result)
4672 /* If exp can be represented as an integer, use power_var_int */
4673 if (exp->ndigits == 0 || exp->ndigits <= exp->weight + 1)
4675 /* exact integer, but does it fit in int? */
4679 /* must copy because numericvar_to_int8() scribbles on input */
4681 set_var_from_var(exp, &x);
4682 if (numericvar_to_int8(&x, &expval64))
4684 int expval = (int) expval64;
4686 /* Test for overflow by reverse-conversion. */
4687 if ((int64) expval == expval64)
4689 /* Okay, select rscale */
4690 rscale = NUMERIC_MIN_SIG_DIGITS;
4691 rscale = Max(rscale, base->dscale);
4692 rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
4693 rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
4695 power_var_int(base, expval, result, rscale);
4707 /* Set scale for ln() calculation --- need extra accuracy here */
4709 /* Approx decimal digits before decimal point */
4710 dec_digits = (base->weight + 1) * DEC_DIGITS;
4713 rscale = NUMERIC_MIN_SIG_DIGITS * 2 - (int) log10(dec_digits - 1);
4714 else if (dec_digits < 1)
4715 rscale = NUMERIC_MIN_SIG_DIGITS * 2 - (int) log10(1 - dec_digits);
4717 rscale = NUMERIC_MIN_SIG_DIGITS * 2;
4719 rscale = Max(rscale, base->dscale * 2);
4720 rscale = Max(rscale, exp->dscale * 2);
4721 rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE * 2);
4722 rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE * 2);
4724 local_rscale = rscale + 8;
4726 ln_var(base, &ln_base, local_rscale);
4728 mul_var(&ln_base, exp, &ln_num, local_rscale);
4730 /* Set scale for exp() -- compare numeric_exp() */
4732 /* convert input to float8, ignoring overflow */
4733 val = numericvar_to_double_no_overflow(&ln_num);
4736 * log10(result) = num * log10(e), so this is approximately the weight:
4738 val *= 0.434294481903252;
4740 /* limit to something that won't cause integer overflow */
4741 val = Max(val, -NUMERIC_MAX_RESULT_SCALE);
4742 val = Min(val, NUMERIC_MAX_RESULT_SCALE);
4744 rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;
4745 rscale = Max(rscale, base->dscale);
4746 rscale = Max(rscale, exp->dscale);
4747 rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
4748 rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
4750 exp_var(&ln_num, result, rscale);
4759 * Raise base to the power of exp, where exp is an integer.
4762 power_var_int(NumericVar *base, int exp, NumericVar *result, int rscale)
4765 NumericVar base_prod;
4768 /* Detect some special cases, particularly 0^0. */
4773 if (base->ndigits == 0)
4775 (errcode(ERRCODE_FLOATING_POINT_EXCEPTION),
4776 errmsg("zero raised to zero is undefined")));
4777 set_var_from_var(&const_one, result);
4778 result->dscale = rscale; /* no need to round */
4781 set_var_from_var(base, result);
4782 round_var(result, rscale);
4785 div_var(&const_one, base, result, rscale, true);
4788 mul_var(base, base, result, rscale);
4795 * The general case repeatedly multiplies base according to the bit
4796 * pattern of exp. We do the multiplications with some extra precision.
4801 local_rscale = rscale + MUL_GUARD_DIGITS * 2;
4803 init_var(&base_prod);
4804 set_var_from_var(base, &base_prod);
4807 set_var_from_var(base, result);
4809 set_var_from_var(&const_one, result);
4811 while ((exp >>= 1) > 0)
4813 mul_var(&base_prod, &base_prod, &base_prod, local_rscale);
4815 mul_var(&base_prod, result, result, local_rscale);
4818 free_var(&base_prod);
4820 /* Compensate for input sign, and round to requested rscale */
4822 div_var(&const_one, result, result, rscale, true);
4824 round_var(result, rscale);
4828 /* ----------------------------------------------------------------------
4830 * Following are the lowest level functions that operate unsigned
4831 * on the variable level
4833 * ----------------------------------------------------------------------
4840 * Compare the absolute values of var1 and var2
4841 * Returns: -1 for ABS(var1) < ABS(var2)
4842 * 0 for ABS(var1) == ABS(var2)
4843 * 1 for ABS(var1) > ABS(var2)
4847 cmp_abs(NumericVar *var1, NumericVar *var2)
4849 return cmp_abs_common(var1->digits, var1->ndigits, var1->weight,
4850 var2->digits, var2->ndigits, var2->weight);
4854 * cmp_abs_common() -
4856 * Main routine of cmp_abs(). This function can be used by both
4857 * NumericVar and Numeric.
4861 cmp_abs_common(const NumericDigit *var1digits, int var1ndigits, int var1weight,
4862 const NumericDigit *var2digits, int var2ndigits, int var2weight)
4867 /* Check any digits before the first common digit */
4869 while (var1weight > var2weight && i1 < var1ndigits)
4871 if (var1digits[i1++] != 0)
4875 while (var2weight > var1weight && i2 < var2ndigits)
4877 if (var2digits[i2++] != 0)
4882 /* At this point, either w1 == w2 or we've run out of digits */
4884 if (var1weight == var2weight)
4886 while (i1 < var1ndigits && i2 < var2ndigits)
4888 int stat = var1digits[i1++] - var2digits[i2++];
4900 * At this point, we've run out of digits on one side or the other; so any
4901 * remaining nonzero digits imply that side is larger
4903 while (i1 < var1ndigits)
4905 if (var1digits[i1++] != 0)
4908 while (i2 < var2ndigits)
4910 if (var2digits[i2++] != 0)
4921 * Add the absolute values of two variables into result.
4922 * result might point to one of the operands without danger.
4925 add_abs(NumericVar *var1, NumericVar *var2, NumericVar *result)
4927 NumericDigit *res_buf;
4928 NumericDigit *res_digits;
4940 /* copy these values into local vars for speed in inner loop */
4941 int var1ndigits = var1->ndigits;
4942 int var2ndigits = var2->ndigits;
4943 NumericDigit *var1digits = var1->digits;
4944 NumericDigit *var2digits = var2->digits;
4946 res_weight = Max(var1->weight, var2->weight) + 1;
4948 res_dscale = Max(var1->dscale, var2->dscale);
4950 /* Note: here we are figuring rscale in base-NBASE digits */
4951 rscale1 = var1->ndigits - var1->weight - 1;
4952 rscale2 = var2->ndigits - var2->weight - 1;
4953 res_rscale = Max(rscale1, rscale2);
4955 res_ndigits = res_rscale + res_weight + 1;
4956 if (res_ndigits <= 0)
4959 res_buf = digitbuf_alloc(res_ndigits + 1);
4960 res_buf[0] = 0; /* spare digit for later rounding */
4961 res_digits = res_buf + 1;
4963 i1 = res_rscale + var1->weight + 1;
4964 i2 = res_rscale + var2->weight + 1;
4965 for (i = res_ndigits - 1; i >= 0; i--)
4969 if (i1 >= 0 && i1 < var1ndigits)
4970 carry += var1digits[i1];
4971 if (i2 >= 0 && i2 < var2ndigits)
4972 carry += var2digits[i2];
4976 res_digits[i] = carry - NBASE;
4981 res_digits[i] = carry;
4986 Assert(carry == 0); /* else we failed to allow for carry out */
4988 digitbuf_free(result->buf);
4989 result->ndigits = res_ndigits;
4990 result->buf = res_buf;
4991 result->digits = res_digits;
4992 result->weight = res_weight;
4993 result->dscale = res_dscale;
4995 /* Remove leading/trailing zeroes */
5003 * Subtract the absolute value of var2 from the absolute value of var1
5004 * and store in result. result might point to one of the operands
5007 * ABS(var1) MUST BE GREATER OR EQUAL ABS(var2) !!!
5010 sub_abs(NumericVar *var1, NumericVar *var2, NumericVar *result)
5012 NumericDigit *res_buf;
5013 NumericDigit *res_digits;
5025 /* copy these values into local vars for speed in inner loop */
5026 int var1ndigits = var1->ndigits;
5027 int var2ndigits = var2->ndigits;
5028 NumericDigit *var1digits = var1->digits;
5029 NumericDigit *var2digits = var2->digits;
5031 res_weight = var1->weight;
5033 res_dscale = Max(var1->dscale, var2->dscale);
5035 /* Note: here we are figuring rscale in base-NBASE digits */
5036 rscale1 = var1->ndigits - var1->weight - 1;
5037 rscale2 = var2->ndigits - var2->weight - 1;
5038 res_rscale = Max(rscale1, rscale2);
5040 res_ndigits = res_rscale + res_weight + 1;
5041 if (res_ndigits <= 0)
5044 res_buf = digitbuf_alloc(res_ndigits + 1);
5045 res_buf[0] = 0; /* spare digit for later rounding */
5046 res_digits = res_buf + 1;
5048 i1 = res_rscale + var1->weight + 1;
5049 i2 = res_rscale + var2->weight + 1;
5050 for (i = res_ndigits - 1; i >= 0; i--)
5054 if (i1 >= 0 && i1 < var1ndigits)
5055 borrow += var1digits[i1];
5056 if (i2 >= 0 && i2 < var2ndigits)
5057 borrow -= var2digits[i2];
5061 res_digits[i] = borrow + NBASE;
5066 res_digits[i] = borrow;
5071 Assert(borrow == 0); /* else caller gave us var1 < var2 */
5073 digitbuf_free(result->buf);
5074 result->ndigits = res_ndigits;
5075 result->buf = res_buf;
5076 result->digits = res_digits;
5077 result->weight = res_weight;
5078 result->dscale = res_dscale;
5080 /* Remove leading/trailing zeroes */
5087 * Round the value of a variable to no more than rscale decimal digits
5088 * after the decimal point. NOTE: we allow rscale < 0 here, implying
5089 * rounding before the decimal point.
5092 round_var(NumericVar *var, int rscale)
5094 NumericDigit *digits = var->digits;
5099 var->dscale = rscale;
5101 /* decimal digits wanted */
5102 di = (var->weight + 1) * DEC_DIGITS + rscale;
5105 * If di = 0, the value loses all digits, but could round up to 1 if its
5106 * first extra digit is >= 5. If di < 0 the result must be 0.
5112 var->sign = NUMERIC_POS;
5116 /* NBASE digits wanted */
5117 ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS;
5119 /* 0, or number of decimal digits to keep in last NBASE digit */
5122 if (ndigits < var->ndigits ||
5123 (ndigits == var->ndigits && di > 0))
5125 var->ndigits = ndigits;
5128 /* di must be zero */
5129 carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0;
5132 carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0;
5135 /* Must round within last NBASE digit */
5140 pow10 = round_powers[di];
5141 #elif DEC_DIGITS == 2
5144 #error unsupported NBASE
5146 extra = digits[--ndigits] % pow10;
5147 digits[ndigits] -= extra;
5149 if (extra >= pow10 / 2)
5151 pow10 += digits[ndigits];
5157 digits[ndigits] = pow10;
5162 /* Propagate carry if needed */
5165 carry += digits[--ndigits];
5168 digits[ndigits] = carry - NBASE;
5173 digits[ndigits] = carry;
5180 Assert(ndigits == -1); /* better not have added > 1 digit */
5181 Assert(var->digits > var->buf);
5193 * Truncate the value of a variable at rscale decimal digits after the
5194 * decimal point. NOTE: we allow rscale < 0 here, implying
5195 * truncation before the decimal point.
5198 trunc_var(NumericVar *var, int rscale)
5203 var->dscale = rscale;
5205 /* decimal digits wanted */
5206 di = (var->weight + 1) * DEC_DIGITS + rscale;
5209 * If di <= 0, the value loses all digits.
5215 var->sign = NUMERIC_POS;
5219 /* NBASE digits wanted */
5220 ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS;
5222 if (ndigits <= var->ndigits)
5224 var->ndigits = ndigits;
5227 /* no within-digit stuff to worry about */
5229 /* 0, or number of decimal digits to keep in last NBASE digit */
5234 /* Must truncate within last NBASE digit */
5235 NumericDigit *digits = var->digits;
5240 pow10 = round_powers[di];
5241 #elif DEC_DIGITS == 2
5244 #error unsupported NBASE
5246 extra = digits[--ndigits] % pow10;
5247 digits[ndigits] -= extra;
5257 * Strip any leading and trailing zeroes from a numeric variable
5260 strip_var(NumericVar *var)
5262 NumericDigit *digits = var->digits;
5263 int ndigits = var->ndigits;
5265 /* Strip leading zeroes */
5266 while (ndigits > 0 && *digits == 0)
5273 /* Strip trailing zeroes */
5274 while (ndigits > 0 && digits[ndigits - 1] == 0)
5277 /* If it's zero, normalize the sign and weight */
5280 var->sign = NUMERIC_POS;
5284 var->digits = digits;
5285 var->ndigits = ndigits;