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-2008, PostgreSQL Global Development Group
17 * $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.109 2008/04/04 18:45:36 tgl Exp $
19 *-------------------------------------------------------------------------
29 #include "access/hash.h"
30 #include "catalog/pg_type.h"
31 #include "libpq/pqformat.h"
32 #include "miscadmin.h"
33 #include "utils/array.h"
34 #include "utils/builtins.h"
35 #include "utils/int8.h"
36 #include "utils/numeric.h"
39 * Uncomment the following to enable compilation of dump_numeric()
40 * and dump_var() and to get a dump of any result produced by make_result().
49 * Numeric values are represented in a base-NBASE floating point format.
50 * Each "digit" ranges from 0 to NBASE-1. The type NumericDigit is signed
51 * and wide enough to store a digit. We assume that NBASE*NBASE can fit in
52 * an int. Although the purely calculational routines could handle any even
53 * NBASE that's less than sqrt(INT_MAX), in practice we are only interested
54 * in NBASE a power of ten, so that I/O conversions and decimal rounding
55 * are easy. Also, it's actually more efficient if NBASE is rather less than
56 * sqrt(INT_MAX), so that there is "headroom" for mul_var and div_var_fast to
57 * postpone processing carries.
64 #define DEC_DIGITS 1 /* decimal digits per NBASE digit */
65 #define MUL_GUARD_DIGITS 4 /* these are measured in NBASE digits */
66 #define DIV_GUARD_DIGITS 8
68 typedef signed char NumericDigit;
74 #define DEC_DIGITS 2 /* decimal digits per NBASE digit */
75 #define MUL_GUARD_DIGITS 3 /* these are measured in NBASE digits */
76 #define DIV_GUARD_DIGITS 6
78 typedef signed char NumericDigit;
83 #define HALF_NBASE 5000
84 #define DEC_DIGITS 4 /* decimal digits per NBASE digit */
85 #define MUL_GUARD_DIGITS 2 /* these are measured in NBASE digits */
86 #define DIV_GUARD_DIGITS 4
88 typedef int16 NumericDigit;
93 * NumericVar is the format we use for arithmetic. The digit-array part
94 * is the same as the NumericData storage format, but the header is more
97 * The value represented by a NumericVar is determined by the sign, weight,
98 * ndigits, and digits[] array.
99 * Note: the first digit of a NumericVar's value is assumed to be multiplied
100 * by NBASE ** weight. Another way to say it is that there are weight+1
101 * digits before the decimal point. It is possible to have weight < 0.
103 * buf points at the physical start of the palloc'd digit buffer for the
104 * NumericVar. digits points at the first digit in actual use (the one
105 * with the specified weight). We normally leave an unused digit or two
106 * (preset to zeroes) between buf and digits, so that there is room to store
107 * a carry out of the top digit without reallocating space. We just need to
108 * decrement digits (and increment weight) to make room for the carry digit.
109 * (There is no such extra space in a numeric value stored in the database,
110 * only in a NumericVar in memory.)
112 * If buf is NULL then the digit buffer isn't actually palloc'd and should
113 * not be freed --- see the constants below for an example.
115 * dscale, or display scale, is the nominal precision expressed as number
116 * of digits after the decimal point (it must always be >= 0 at present).
117 * dscale may be more than the number of physically stored fractional digits,
118 * implying that we have suppressed storage of significant trailing zeroes.
119 * It should never be less than the number of stored digits, since that would
120 * imply hiding digits that are present. NOTE that dscale is always expressed
121 * in *decimal* digits, and so it may correspond to a fractional number of
122 * base-NBASE digits --- divide by DEC_DIGITS to convert to NBASE digits.
124 * rscale, or result scale, is the target precision for a computation.
125 * Like dscale it is expressed as number of *decimal* digits after the decimal
126 * point, and is always >= 0 at present.
127 * Note that rscale is not stored in variables --- it's figured on-the-fly
128 * from the dscales of the inputs.
130 * NB: All the variable-level functions are written in a style that makes it
131 * possible to give one and the same variable as argument and destination.
132 * This is feasible because the digit buffer is separate from the variable.
135 typedef struct NumericVar
137 int ndigits; /* # of digits in digits[] - can be 0! */
138 int weight; /* weight of first digit */
139 int sign; /* NUMERIC_POS, NUMERIC_NEG, or NUMERIC_NAN */
140 int dscale; /* display scale */
141 NumericDigit *buf; /* start of palloc'd space for digits[] */
142 NumericDigit *digits; /* base-NBASE digits */
147 * Some preinitialized constants
150 static NumericDigit const_zero_data[1] = {0};
151 static NumericVar const_zero =
152 {0, 0, NUMERIC_POS, 0, NULL, const_zero_data};
154 static NumericDigit const_one_data[1] = {1};
155 static NumericVar const_one =
156 {1, 0, NUMERIC_POS, 0, NULL, const_one_data};
158 static NumericDigit const_two_data[1] = {2};
159 static NumericVar const_two =
160 {1, 0, NUMERIC_POS, 0, NULL, const_two_data};
163 static NumericDigit const_zero_point_five_data[1] = {5000};
164 #elif DEC_DIGITS == 2
165 static NumericDigit const_zero_point_five_data[1] = {50};
166 #elif DEC_DIGITS == 1
167 static NumericDigit const_zero_point_five_data[1] = {5};
169 static NumericVar const_zero_point_five =
170 {1, -1, NUMERIC_POS, 1, NULL, const_zero_point_five_data};
173 static NumericDigit const_zero_point_nine_data[1] = {9000};
174 #elif DEC_DIGITS == 2
175 static NumericDigit const_zero_point_nine_data[1] = {90};
176 #elif DEC_DIGITS == 1
177 static NumericDigit const_zero_point_nine_data[1] = {9};
179 static NumericVar const_zero_point_nine =
180 {1, -1, NUMERIC_POS, 1, NULL, const_zero_point_nine_data};
183 static NumericDigit const_zero_point_01_data[1] = {100};
184 static NumericVar const_zero_point_01 =
185 {1, -1, NUMERIC_POS, 2, NULL, const_zero_point_01_data};
186 #elif DEC_DIGITS == 2
187 static NumericDigit const_zero_point_01_data[1] = {1};
188 static NumericVar const_zero_point_01 =
189 {1, -1, NUMERIC_POS, 2, NULL, const_zero_point_01_data};
190 #elif DEC_DIGITS == 1
191 static NumericDigit const_zero_point_01_data[1] = {1};
192 static NumericVar const_zero_point_01 =
193 {1, -2, NUMERIC_POS, 2, NULL, const_zero_point_01_data};
197 static NumericDigit const_one_point_one_data[2] = {1, 1000};
198 #elif DEC_DIGITS == 2
199 static NumericDigit const_one_point_one_data[2] = {1, 10};
200 #elif DEC_DIGITS == 1
201 static NumericDigit const_one_point_one_data[2] = {1, 1};
203 static NumericVar const_one_point_one =
204 {2, 0, NUMERIC_POS, 1, NULL, const_one_point_one_data};
206 static NumericVar const_nan =
207 {0, 0, NUMERIC_NAN, 0, NULL, NULL};
210 static const int round_powers[4] = {0, 1000, 100, 10};
220 static void dump_numeric(const char *str, Numeric num);
221 static void dump_var(const char *str, NumericVar *var);
223 #define dump_numeric(s,n)
224 #define dump_var(s,v)
227 #define digitbuf_alloc(ndigits) \
228 ((NumericDigit *) palloc((ndigits) * sizeof(NumericDigit)))
229 #define digitbuf_free(buf) \
235 #define init_var(v) MemSetAligned(v, 0, sizeof(NumericVar))
237 #define NUMERIC_DIGITS(num) ((NumericDigit *)(num)->n_data)
238 #define NUMERIC_NDIGITS(num) \
239 ((VARSIZE(num) - NUMERIC_HDRSZ) / sizeof(NumericDigit))
241 static void alloc_var(NumericVar *var, int ndigits);
242 static void free_var(NumericVar *var);
243 static void zero_var(NumericVar *var);
245 static void set_var_from_str(const char *str, NumericVar *dest);
246 static void set_var_from_num(Numeric value, NumericVar *dest);
247 static void set_var_from_var(NumericVar *value, NumericVar *dest);
248 static char *get_str_from_var(NumericVar *var, int dscale);
250 static Numeric make_result(NumericVar *var);
252 static void apply_typmod(NumericVar *var, int32 typmod);
254 static int32 numericvar_to_int4(NumericVar *var);
255 static bool numericvar_to_int8(NumericVar *var, int64 *result);
256 static void int8_to_numericvar(int64 val, NumericVar *var);
257 static double numeric_to_double_no_overflow(Numeric num);
258 static double numericvar_to_double_no_overflow(NumericVar *var);
260 static int cmp_numerics(Numeric num1, Numeric num2);
261 static int cmp_var(NumericVar *var1, NumericVar *var2);
262 static int cmp_var_common(const NumericDigit *var1digits, int var1ndigits,
263 int var1weight, int var1sign,
264 const NumericDigit *var2digits, int var2ndigits,
265 int var2weight, int var2sign);
266 static void add_var(NumericVar *var1, NumericVar *var2, NumericVar *result);
267 static void sub_var(NumericVar *var1, NumericVar *var2, NumericVar *result);
268 static void mul_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
270 static void div_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
271 int rscale, bool round);
272 static void div_var_fast(NumericVar *var1, NumericVar *var2, NumericVar *result,
273 int rscale, bool round);
274 static int select_div_scale(NumericVar *var1, NumericVar *var2);
275 static void mod_var(NumericVar *var1, NumericVar *var2, NumericVar *result);
276 static void ceil_var(NumericVar *var, NumericVar *result);
277 static void floor_var(NumericVar *var, NumericVar *result);
279 static void sqrt_var(NumericVar *arg, NumericVar *result, int rscale);
280 static void exp_var(NumericVar *arg, NumericVar *result, int rscale);
281 static void exp_var_internal(NumericVar *arg, NumericVar *result, int rscale);
282 static void ln_var(NumericVar *arg, NumericVar *result, int rscale);
283 static void log_var(NumericVar *base, NumericVar *num, NumericVar *result);
284 static void power_var(NumericVar *base, NumericVar *exp, NumericVar *result);
285 static void power_var_int(NumericVar *base, int exp, NumericVar *result,
288 static int cmp_abs(NumericVar *var1, NumericVar *var2);
289 static int cmp_abs_common(const NumericDigit *var1digits, int var1ndigits,
291 const NumericDigit *var2digits, int var2ndigits,
293 static void add_abs(NumericVar *var1, NumericVar *var2, NumericVar *result);
294 static void sub_abs(NumericVar *var1, NumericVar *var2, NumericVar *result);
295 static void round_var(NumericVar *var, int rscale);
296 static void trunc_var(NumericVar *var, int rscale);
297 static void strip_var(NumericVar *var);
298 static void compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
299 NumericVar *count_var, NumericVar *result_var);
302 /* ----------------------------------------------------------------------
304 * Input-, output- and rounding-functions
306 * ----------------------------------------------------------------------
313 * Input function for numeric data type
316 numeric_in(PG_FUNCTION_ARGS)
318 char *str = PG_GETARG_CSTRING(0);
321 Oid typelem = PG_GETARG_OID(1);
323 int32 typmod = PG_GETARG_INT32(2);
330 if (pg_strcasecmp(str, "NaN") == 0)
331 PG_RETURN_NUMERIC(make_result(&const_nan));
334 * Use set_var_from_str() to parse the input string and return it in the
335 * packed DB storage format
338 set_var_from_str(str, &value);
340 apply_typmod(&value, typmod);
342 res = make_result(&value);
345 PG_RETURN_NUMERIC(res);
352 * Output function for numeric data type
355 numeric_out(PG_FUNCTION_ARGS)
357 Numeric num = PG_GETARG_NUMERIC(0);
364 if (NUMERIC_IS_NAN(num))
365 PG_RETURN_CSTRING(pstrdup("NaN"));
368 * Get the number in the variable format.
370 * Even if we didn't need to change format, we'd still need to copy the
371 * value to have a modifiable copy for rounding. set_var_from_num() also
372 * guarantees there is extra digit space in case we produce a carry out
376 set_var_from_num(num, &x);
378 str = get_str_from_var(&x, x.dscale);
382 PG_RETURN_CSTRING(str);
386 * numeric_recv - converts external binary format to numeric
388 * External format is a sequence of int16's:
389 * ndigits, weight, sign, dscale, NumericDigits.
392 numeric_recv(PG_FUNCTION_ARGS)
394 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
397 Oid typelem = PG_GETARG_OID(1);
399 int32 typmod = PG_GETARG_INT32(2);
407 len = (uint16) pq_getmsgint(buf, sizeof(uint16));
408 if (len < 0 || len > NUMERIC_MAX_PRECISION + NUMERIC_MAX_RESULT_SCALE)
410 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
411 errmsg("invalid length in external \"numeric\" value")));
413 alloc_var(&value, len);
415 value.weight = (int16) pq_getmsgint(buf, sizeof(int16));
416 value.sign = (uint16) pq_getmsgint(buf, sizeof(uint16));
417 if (!(value.sign == NUMERIC_POS ||
418 value.sign == NUMERIC_NEG ||
419 value.sign == NUMERIC_NAN))
421 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
422 errmsg("invalid sign in external \"numeric\" value")));
424 value.dscale = (uint16) pq_getmsgint(buf, sizeof(uint16));
425 for (i = 0; i < len; i++)
427 NumericDigit d = pq_getmsgint(buf, sizeof(NumericDigit));
429 if (d < 0 || d >= NBASE)
431 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
432 errmsg("invalid digit in external \"numeric\" value")));
436 apply_typmod(&value, typmod);
438 res = make_result(&value);
441 PG_RETURN_NUMERIC(res);
445 * numeric_send - converts numeric to binary format
448 numeric_send(PG_FUNCTION_ARGS)
450 Numeric num = PG_GETARG_NUMERIC(0);
456 set_var_from_num(num, &x);
458 pq_begintypsend(&buf);
460 pq_sendint(&buf, x.ndigits, sizeof(int16));
461 pq_sendint(&buf, x.weight, sizeof(int16));
462 pq_sendint(&buf, x.sign, sizeof(int16));
463 pq_sendint(&buf, x.dscale, sizeof(int16));
464 for (i = 0; i < x.ndigits; i++)
465 pq_sendint(&buf, x.digits[i], sizeof(NumericDigit));
469 PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
476 * This is a special function called by the Postgres database system
477 * before a value is stored in a tuple's attribute. The precision and
478 * scale of the attribute have to be applied on the value.
481 numeric (PG_FUNCTION_ARGS)
483 Numeric num = PG_GETARG_NUMERIC(0);
484 int32 typmod = PG_GETARG_INT32(1);
496 if (NUMERIC_IS_NAN(num))
497 PG_RETURN_NUMERIC(make_result(&const_nan));
500 * If the value isn't a valid type modifier, simply return a copy of the
503 if (typmod < (int32) (VARHDRSZ))
505 new = (Numeric) palloc(VARSIZE(num));
506 memcpy(new, num, VARSIZE(num));
507 PG_RETURN_NUMERIC(new);
511 * Get the precision and scale out of the typmod value
513 tmp_typmod = typmod - VARHDRSZ;
514 precision = (tmp_typmod >> 16) & 0xffff;
515 scale = tmp_typmod & 0xffff;
516 maxdigits = precision - scale;
519 * If the number is certainly in bounds and due to the target scale no
520 * rounding could be necessary, just make a copy of the input and modify
521 * its scale fields. (Note we assume the existing dscale is honest...)
523 ddigits = (num->n_weight + 1) * DEC_DIGITS;
524 if (ddigits <= maxdigits && scale >= NUMERIC_DSCALE(num))
526 new = (Numeric) palloc(VARSIZE(num));
527 memcpy(new, num, VARSIZE(num));
528 new->n_sign_dscale = NUMERIC_SIGN(new) |
529 ((uint16) scale & NUMERIC_DSCALE_MASK);
530 PG_RETURN_NUMERIC(new);
534 * We really need to fiddle with things - unpack the number into a
535 * variable and let apply_typmod() do it.
539 set_var_from_num(num, &var);
540 apply_typmod(&var, typmod);
541 new = make_result(&var);
545 PG_RETURN_NUMERIC(new);
549 numerictypmodin(PG_FUNCTION_ARGS)
551 ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
556 tl = ArrayGetIntegerTypmods(ta, &n);
560 if (tl[0] < 1 || tl[0] > NUMERIC_MAX_PRECISION)
562 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
563 errmsg("NUMERIC precision %d must be between 1 and %d",
564 tl[0], NUMERIC_MAX_PRECISION)));
565 if (tl[1] < 0 || tl[1] > tl[0])
567 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
568 errmsg("NUMERIC scale %d must be between 0 and precision %d",
570 typmod = ((tl[0] << 16) | tl[1]) + VARHDRSZ;
574 if (tl[0] < 1 || tl[0] > NUMERIC_MAX_PRECISION)
576 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
577 errmsg("NUMERIC precision %d must be between 1 and %d",
578 tl[0], NUMERIC_MAX_PRECISION)));
579 /* scale defaults to zero */
580 typmod = (tl[0] << 16) + VARHDRSZ;
585 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
586 errmsg("invalid NUMERIC type modifier")));
587 typmod = 0; /* keep compiler quiet */
590 PG_RETURN_INT32(typmod);
594 numerictypmodout(PG_FUNCTION_ARGS)
596 int32 typmod = PG_GETARG_INT32(0);
597 char *res = (char *) palloc(64);
600 snprintf(res, 64, "(%d,%d)",
601 ((typmod - VARHDRSZ) >> 16) & 0xffff,
602 (typmod - VARHDRSZ) & 0xffff);
606 PG_RETURN_CSTRING(res);
610 /* ----------------------------------------------------------------------
612 * Sign manipulation, rounding and the like
614 * ----------------------------------------------------------------------
618 numeric_abs(PG_FUNCTION_ARGS)
620 Numeric num = PG_GETARG_NUMERIC(0);
626 if (NUMERIC_IS_NAN(num))
627 PG_RETURN_NUMERIC(make_result(&const_nan));
630 * Do it the easy way directly on the packed format
632 res = (Numeric) palloc(VARSIZE(num));
633 memcpy(res, num, VARSIZE(num));
635 res->n_sign_dscale = NUMERIC_POS | NUMERIC_DSCALE(num);
637 PG_RETURN_NUMERIC(res);
642 numeric_uminus(PG_FUNCTION_ARGS)
644 Numeric num = PG_GETARG_NUMERIC(0);
650 if (NUMERIC_IS_NAN(num))
651 PG_RETURN_NUMERIC(make_result(&const_nan));
654 * Do it the easy way directly on the packed format
656 res = (Numeric) palloc(VARSIZE(num));
657 memcpy(res, num, VARSIZE(num));
660 * The packed format is known to be totally zero digit trimmed always. So
661 * we can identify a ZERO by the fact that there are no digits at all. Do
664 if (VARSIZE(num) != NUMERIC_HDRSZ)
666 /* Else, flip the sign */
667 if (NUMERIC_SIGN(num) == NUMERIC_POS)
668 res->n_sign_dscale = NUMERIC_NEG | NUMERIC_DSCALE(num);
670 res->n_sign_dscale = NUMERIC_POS | NUMERIC_DSCALE(num);
673 PG_RETURN_NUMERIC(res);
678 numeric_uplus(PG_FUNCTION_ARGS)
680 Numeric num = PG_GETARG_NUMERIC(0);
683 res = (Numeric) palloc(VARSIZE(num));
684 memcpy(res, num, VARSIZE(num));
686 PG_RETURN_NUMERIC(res);
692 * returns -1 if the argument is less than 0, 0 if the argument is equal
693 * to 0, and 1 if the argument is greater than zero.
696 numeric_sign(PG_FUNCTION_ARGS)
698 Numeric num = PG_GETARG_NUMERIC(0);
705 if (NUMERIC_IS_NAN(num))
706 PG_RETURN_NUMERIC(make_result(&const_nan));
711 * The packed format is known to be totally zero digit trimmed always. So
712 * we can identify a ZERO by the fact that there are no digits at all.
714 if (VARSIZE(num) == NUMERIC_HDRSZ)
715 set_var_from_var(&const_zero, &result);
719 * And if there are some, we return a copy of ONE with the sign of our
722 set_var_from_var(&const_one, &result);
723 result.sign = NUMERIC_SIGN(num);
726 res = make_result(&result);
729 PG_RETURN_NUMERIC(res);
736 * Round a value to have 'scale' digits after the decimal point.
737 * We allow negative 'scale', implying rounding before the decimal
738 * point --- Oracle interprets rounding that way.
741 numeric_round(PG_FUNCTION_ARGS)
743 Numeric num = PG_GETARG_NUMERIC(0);
744 int32 scale = PG_GETARG_INT32(1);
751 if (NUMERIC_IS_NAN(num))
752 PG_RETURN_NUMERIC(make_result(&const_nan));
755 * Limit the scale value to avoid possible overflow in calculations
757 scale = Max(scale, -NUMERIC_MAX_RESULT_SCALE);
758 scale = Min(scale, NUMERIC_MAX_RESULT_SCALE);
761 * Unpack the argument and round it at the proper digit position
764 set_var_from_num(num, &arg);
766 round_var(&arg, scale);
768 /* We don't allow negative output dscale */
773 * Return the rounded result
775 res = make_result(&arg);
778 PG_RETURN_NUMERIC(res);
785 * Truncate a value to have 'scale' digits after the decimal point.
786 * We allow negative 'scale', implying a truncation before the decimal
787 * point --- Oracle interprets truncation that way.
790 numeric_trunc(PG_FUNCTION_ARGS)
792 Numeric num = PG_GETARG_NUMERIC(0);
793 int32 scale = PG_GETARG_INT32(1);
800 if (NUMERIC_IS_NAN(num))
801 PG_RETURN_NUMERIC(make_result(&const_nan));
804 * Limit the scale value to avoid possible overflow in calculations
806 scale = Max(scale, -NUMERIC_MAX_RESULT_SCALE);
807 scale = Min(scale, NUMERIC_MAX_RESULT_SCALE);
810 * Unpack the argument and truncate it at the proper digit position
813 set_var_from_num(num, &arg);
815 trunc_var(&arg, scale);
817 /* We don't allow negative output dscale */
822 * Return the truncated result
824 res = make_result(&arg);
827 PG_RETURN_NUMERIC(res);
834 * Return the smallest integer greater than or equal to the argument
837 numeric_ceil(PG_FUNCTION_ARGS)
839 Numeric num = PG_GETARG_NUMERIC(0);
843 if (NUMERIC_IS_NAN(num))
844 PG_RETURN_NUMERIC(make_result(&const_nan));
848 set_var_from_num(num, &result);
849 ceil_var(&result, &result);
851 res = make_result(&result);
854 PG_RETURN_NUMERIC(res);
861 * Return the largest integer equal to or less than the argument
864 numeric_floor(PG_FUNCTION_ARGS)
866 Numeric num = PG_GETARG_NUMERIC(0);
870 if (NUMERIC_IS_NAN(num))
871 PG_RETURN_NUMERIC(make_result(&const_nan));
875 set_var_from_num(num, &result);
876 floor_var(&result, &result);
878 res = make_result(&result);
881 PG_RETURN_NUMERIC(res);
885 * Implements the numeric version of the width_bucket() function
886 * defined by SQL2003. See also width_bucket_float8().
888 * 'bound1' and 'bound2' are the lower and upper bounds of the
889 * histogram's range, respectively. 'count' is the number of buckets
890 * in the histogram. width_bucket() returns an integer indicating the
891 * bucket number that 'operand' belongs to in an equiwidth histogram
892 * with the specified characteristics. An operand smaller than the
893 * lower bound is assigned to bucket 0. An operand greater than the
894 * upper bound is assigned to an additional bucket (with number
895 * count+1). We don't allow "NaN" for any of the numeric arguments.
898 width_bucket_numeric(PG_FUNCTION_ARGS)
900 Numeric operand = PG_GETARG_NUMERIC(0);
901 Numeric bound1 = PG_GETARG_NUMERIC(1);
902 Numeric bound2 = PG_GETARG_NUMERIC(2);
903 int32 count = PG_GETARG_INT32(3);
904 NumericVar count_var;
905 NumericVar result_var;
910 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
911 errmsg("count must be greater than zero")));
913 if (NUMERIC_IS_NAN(operand) ||
914 NUMERIC_IS_NAN(bound1) ||
915 NUMERIC_IS_NAN(bound2))
917 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
918 errmsg("operand, lower bound and upper bound cannot be NaN")));
920 init_var(&result_var);
921 init_var(&count_var);
923 /* Convert 'count' to a numeric, for ease of use later */
924 int8_to_numericvar((int64) count, &count_var);
926 switch (cmp_numerics(bound1, bound2))
930 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION),
931 errmsg("lower bound cannot equal upper bound")));
933 /* bound1 < bound2 */
935 if (cmp_numerics(operand, bound1) < 0)
936 set_var_from_var(&const_zero, &result_var);
937 else if (cmp_numerics(operand, bound2) >= 0)
938 add_var(&count_var, &const_one, &result_var);
940 compute_bucket(operand, bound1, bound2,
941 &count_var, &result_var);
944 /* bound1 > bound2 */
946 if (cmp_numerics(operand, bound1) > 0)
947 set_var_from_var(&const_zero, &result_var);
948 else if (cmp_numerics(operand, bound2) <= 0)
949 add_var(&count_var, &const_one, &result_var);
951 compute_bucket(operand, bound1, bound2,
952 &count_var, &result_var);
956 /* if result exceeds the range of a legal int4, we ereport here */
957 result = numericvar_to_int4(&result_var);
959 free_var(&count_var);
960 free_var(&result_var);
962 PG_RETURN_INT32(result);
966 * If 'operand' is not outside the bucket range, determine the correct
967 * bucket for it to go. The calculations performed by this function
968 * are derived directly from the SQL2003 spec.
971 compute_bucket(Numeric operand, Numeric bound1, Numeric bound2,
972 NumericVar *count_var, NumericVar *result_var)
974 NumericVar bound1_var;
975 NumericVar bound2_var;
976 NumericVar operand_var;
978 init_var(&bound1_var);
979 init_var(&bound2_var);
980 init_var(&operand_var);
982 set_var_from_num(bound1, &bound1_var);
983 set_var_from_num(bound2, &bound2_var);
984 set_var_from_num(operand, &operand_var);
986 if (cmp_var(&bound1_var, &bound2_var) < 0)
988 sub_var(&operand_var, &bound1_var, &operand_var);
989 sub_var(&bound2_var, &bound1_var, &bound2_var);
990 div_var(&operand_var, &bound2_var, result_var,
991 select_div_scale(&operand_var, &bound2_var), true);
995 sub_var(&bound1_var, &operand_var, &operand_var);
996 sub_var(&bound1_var, &bound2_var, &bound1_var);
997 div_var(&operand_var, &bound1_var, result_var,
998 select_div_scale(&operand_var, &bound1_var), true);
1001 mul_var(result_var, count_var, result_var,
1002 result_var->dscale + count_var->dscale);
1003 add_var(result_var, &const_one, result_var);
1004 floor_var(result_var, result_var);
1006 free_var(&bound1_var);
1007 free_var(&bound2_var);
1008 free_var(&operand_var);
1011 /* ----------------------------------------------------------------------
1013 * Comparison functions
1015 * Note: btree indexes need these routines not to leak memory; therefore,
1016 * be careful to free working copies of toasted datums. Most places don't
1017 * need to be so careful.
1018 * ----------------------------------------------------------------------
1023 numeric_cmp(PG_FUNCTION_ARGS)
1025 Numeric num1 = PG_GETARG_NUMERIC(0);
1026 Numeric num2 = PG_GETARG_NUMERIC(1);
1029 result = cmp_numerics(num1, num2);
1031 PG_FREE_IF_COPY(num1, 0);
1032 PG_FREE_IF_COPY(num2, 1);
1034 PG_RETURN_INT32(result);
1039 numeric_eq(PG_FUNCTION_ARGS)
1041 Numeric num1 = PG_GETARG_NUMERIC(0);
1042 Numeric num2 = PG_GETARG_NUMERIC(1);
1045 result = cmp_numerics(num1, num2) == 0;
1047 PG_FREE_IF_COPY(num1, 0);
1048 PG_FREE_IF_COPY(num2, 1);
1050 PG_RETURN_BOOL(result);
1054 numeric_ne(PG_FUNCTION_ARGS)
1056 Numeric num1 = PG_GETARG_NUMERIC(0);
1057 Numeric num2 = PG_GETARG_NUMERIC(1);
1060 result = cmp_numerics(num1, num2) != 0;
1062 PG_FREE_IF_COPY(num1, 0);
1063 PG_FREE_IF_COPY(num2, 1);
1065 PG_RETURN_BOOL(result);
1069 numeric_gt(PG_FUNCTION_ARGS)
1071 Numeric num1 = PG_GETARG_NUMERIC(0);
1072 Numeric num2 = PG_GETARG_NUMERIC(1);
1075 result = cmp_numerics(num1, num2) > 0;
1077 PG_FREE_IF_COPY(num1, 0);
1078 PG_FREE_IF_COPY(num2, 1);
1080 PG_RETURN_BOOL(result);
1084 numeric_ge(PG_FUNCTION_ARGS)
1086 Numeric num1 = PG_GETARG_NUMERIC(0);
1087 Numeric num2 = PG_GETARG_NUMERIC(1);
1090 result = cmp_numerics(num1, num2) >= 0;
1092 PG_FREE_IF_COPY(num1, 0);
1093 PG_FREE_IF_COPY(num2, 1);
1095 PG_RETURN_BOOL(result);
1099 numeric_lt(PG_FUNCTION_ARGS)
1101 Numeric num1 = PG_GETARG_NUMERIC(0);
1102 Numeric num2 = PG_GETARG_NUMERIC(1);
1105 result = cmp_numerics(num1, num2) < 0;
1107 PG_FREE_IF_COPY(num1, 0);
1108 PG_FREE_IF_COPY(num2, 1);
1110 PG_RETURN_BOOL(result);
1114 numeric_le(PG_FUNCTION_ARGS)
1116 Numeric num1 = PG_GETARG_NUMERIC(0);
1117 Numeric num2 = PG_GETARG_NUMERIC(1);
1120 result = cmp_numerics(num1, num2) <= 0;
1122 PG_FREE_IF_COPY(num1, 0);
1123 PG_FREE_IF_COPY(num2, 1);
1125 PG_RETURN_BOOL(result);
1129 cmp_numerics(Numeric num1, Numeric num2)
1134 * We consider all NANs to be equal and larger than any non-NAN. This is
1135 * somewhat arbitrary; the important thing is to have a consistent sort
1138 if (NUMERIC_IS_NAN(num1))
1140 if (NUMERIC_IS_NAN(num2))
1141 result = 0; /* NAN = NAN */
1143 result = 1; /* NAN > non-NAN */
1145 else if (NUMERIC_IS_NAN(num2))
1147 result = -1; /* non-NAN < NAN */
1151 result = cmp_var_common(NUMERIC_DIGITS(num1), NUMERIC_NDIGITS(num1),
1152 num1->n_weight, NUMERIC_SIGN(num1),
1153 NUMERIC_DIGITS(num2), NUMERIC_NDIGITS(num2),
1154 num2->n_weight, NUMERIC_SIGN(num2));
1161 hash_numeric(PG_FUNCTION_ARGS)
1163 Numeric key = PG_GETARG_NUMERIC(0);
1172 /* If it's NaN, don't try to hash the rest of the fields */
1173 if (NUMERIC_IS_NAN(key))
1174 PG_RETURN_UINT32(0);
1176 weight = key->n_weight;
1181 * Omit any leading or trailing zeros from the input to the hash. The
1182 * numeric implementation *should* guarantee that leading and trailing
1183 * zeros are suppressed, but we're paranoid. Note that we measure the
1184 * starting and ending offsets in units of NumericDigits, not bytes.
1186 for (i = 0; i < NUMERIC_NDIGITS(key); i++)
1188 if (NUMERIC_DIGITS(key)[i] != (NumericDigit) 0)
1194 * The weight is effectively the # of digits before the decimal point,
1195 * so decrement it for each leading zero we skip.
1201 * If there are no non-zero digits, then the value of the number is zero,
1202 * regardless of any other fields.
1204 if (NUMERIC_NDIGITS(key) == start_offset)
1205 PG_RETURN_UINT32(-1);
1207 for (i = NUMERIC_NDIGITS(key) - 1; i >= 0; i--)
1209 if (NUMERIC_DIGITS(key)[i] != (NumericDigit) 0)
1215 /* If we get here, there should be at least one non-zero digit */
1216 Assert(start_offset + end_offset < NUMERIC_NDIGITS(key));
1219 * Note that we don't hash on the Numeric's scale, since two numerics can
1220 * compare equal but have different scales. We also don't hash on the
1221 * sign, although we could: since a sign difference implies inequality,
1222 * this shouldn't affect correctness.
1224 hash_len = NUMERIC_NDIGITS(key) - start_offset - end_offset;
1225 digit_hash = hash_any((unsigned char *) (NUMERIC_DIGITS(key) + start_offset),
1226 hash_len * sizeof(NumericDigit));
1228 /* Mix in the weight, via XOR */
1229 result = digit_hash ^ weight;
1231 PG_RETURN_DATUM(result);
1235 /* ----------------------------------------------------------------------
1237 * Basic arithmetic functions
1239 * ----------------------------------------------------------------------
1249 numeric_add(PG_FUNCTION_ARGS)
1251 Numeric num1 = PG_GETARG_NUMERIC(0);
1252 Numeric num2 = PG_GETARG_NUMERIC(1);
1261 if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
1262 PG_RETURN_NUMERIC(make_result(&const_nan));
1265 * Unpack the values, let add_var() compute the result and return it.
1271 set_var_from_num(num1, &arg1);
1272 set_var_from_num(num2, &arg2);
1274 add_var(&arg1, &arg2, &result);
1276 res = make_result(&result);
1282 PG_RETURN_NUMERIC(res);
1289 * Subtract one numeric from another
1292 numeric_sub(PG_FUNCTION_ARGS)
1294 Numeric num1 = PG_GETARG_NUMERIC(0);
1295 Numeric num2 = PG_GETARG_NUMERIC(1);
1304 if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
1305 PG_RETURN_NUMERIC(make_result(&const_nan));
1308 * Unpack the values, let sub_var() compute the result and return it.
1314 set_var_from_num(num1, &arg1);
1315 set_var_from_num(num2, &arg2);
1317 sub_var(&arg1, &arg2, &result);
1319 res = make_result(&result);
1325 PG_RETURN_NUMERIC(res);
1332 * Calculate the product of two numerics
1335 numeric_mul(PG_FUNCTION_ARGS)
1337 Numeric num1 = PG_GETARG_NUMERIC(0);
1338 Numeric num2 = PG_GETARG_NUMERIC(1);
1347 if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
1348 PG_RETURN_NUMERIC(make_result(&const_nan));
1351 * Unpack the values, let mul_var() compute the result and return it.
1352 * Unlike add_var() and sub_var(), mul_var() will round its result. In the
1353 * case of numeric_mul(), which is invoked for the * operator on numerics,
1354 * we request exact representation for the product (rscale = sum(dscale of
1355 * arg1, dscale of arg2)).
1361 set_var_from_num(num1, &arg1);
1362 set_var_from_num(num2, &arg2);
1364 mul_var(&arg1, &arg2, &result, arg1.dscale + arg2.dscale);
1366 res = make_result(&result);
1372 PG_RETURN_NUMERIC(res);
1379 * Divide one numeric into another
1382 numeric_div(PG_FUNCTION_ARGS)
1384 Numeric num1 = PG_GETARG_NUMERIC(0);
1385 Numeric num2 = PG_GETARG_NUMERIC(1);
1395 if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
1396 PG_RETURN_NUMERIC(make_result(&const_nan));
1399 * Unpack the arguments
1405 set_var_from_num(num1, &arg1);
1406 set_var_from_num(num2, &arg2);
1409 * Select scale for division result
1411 rscale = select_div_scale(&arg1, &arg2);
1414 * Do the divide and return the result
1416 div_var(&arg1, &arg2, &result, rscale, true);
1418 res = make_result(&result);
1424 PG_RETURN_NUMERIC(res);
1429 * numeric_div_trunc() -
1431 * Divide one numeric into another, truncating the result to an integer
1434 numeric_div_trunc(PG_FUNCTION_ARGS)
1436 Numeric num1 = PG_GETARG_NUMERIC(0);
1437 Numeric num2 = PG_GETARG_NUMERIC(1);
1446 if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
1447 PG_RETURN_NUMERIC(make_result(&const_nan));
1450 * Unpack the arguments
1456 set_var_from_num(num1, &arg1);
1457 set_var_from_num(num2, &arg2);
1460 * Do the divide and return the result
1462 div_var(&arg1, &arg2, &result, 0, false);
1464 res = make_result(&result);
1470 PG_RETURN_NUMERIC(res);
1477 * Calculate the modulo of two numerics
1480 numeric_mod(PG_FUNCTION_ARGS)
1482 Numeric num1 = PG_GETARG_NUMERIC(0);
1483 Numeric num2 = PG_GETARG_NUMERIC(1);
1489 if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
1490 PG_RETURN_NUMERIC(make_result(&const_nan));
1496 set_var_from_num(num1, &arg1);
1497 set_var_from_num(num2, &arg2);
1499 mod_var(&arg1, &arg2, &result);
1501 res = make_result(&result);
1507 PG_RETURN_NUMERIC(res);
1514 * Increment a number by one
1517 numeric_inc(PG_FUNCTION_ARGS)
1519 Numeric num = PG_GETARG_NUMERIC(0);
1526 if (NUMERIC_IS_NAN(num))
1527 PG_RETURN_NUMERIC(make_result(&const_nan));
1530 * Compute the result and return it
1534 set_var_from_num(num, &arg);
1536 add_var(&arg, &const_one, &arg);
1538 res = make_result(&arg);
1542 PG_RETURN_NUMERIC(res);
1547 * numeric_smaller() -
1549 * Return the smaller of two numbers
1552 numeric_smaller(PG_FUNCTION_ARGS)
1554 Numeric num1 = PG_GETARG_NUMERIC(0);
1555 Numeric num2 = PG_GETARG_NUMERIC(1);
1558 * Use cmp_numerics so that this will agree with the comparison operators,
1559 * particularly as regards comparisons involving NaN.
1561 if (cmp_numerics(num1, num2) < 0)
1562 PG_RETURN_NUMERIC(num1);
1564 PG_RETURN_NUMERIC(num2);
1569 * numeric_larger() -
1571 * Return the larger of two numbers
1574 numeric_larger(PG_FUNCTION_ARGS)
1576 Numeric num1 = PG_GETARG_NUMERIC(0);
1577 Numeric num2 = PG_GETARG_NUMERIC(1);
1580 * Use cmp_numerics so that this will agree with the comparison operators,
1581 * particularly as regards comparisons involving NaN.
1583 if (cmp_numerics(num1, num2) > 0)
1584 PG_RETURN_NUMERIC(num1);
1586 PG_RETURN_NUMERIC(num2);
1590 /* ----------------------------------------------------------------------
1592 * Advanced math functions
1594 * ----------------------------------------------------------------------
1603 numeric_fac(PG_FUNCTION_ARGS)
1605 int64 num = PG_GETARG_INT64(0);
1612 res = make_result(&const_one);
1613 PG_RETURN_NUMERIC(res);
1615 /* Fail immediately if the result would overflow */
1618 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1619 errmsg("value overflows numeric format")));
1624 int8_to_numericvar(num, &result);
1626 for (num = num - 1; num > 1; num--)
1628 /* this loop can take awhile, so allow it to be interrupted */
1629 CHECK_FOR_INTERRUPTS();
1631 int8_to_numericvar(num, &fact);
1633 mul_var(&result, &fact, &result, 0);
1636 res = make_result(&result);
1641 PG_RETURN_NUMERIC(res);
1648 * Compute the square root of a numeric.
1651 numeric_sqrt(PG_FUNCTION_ARGS)
1653 Numeric num = PG_GETARG_NUMERIC(0);
1663 if (NUMERIC_IS_NAN(num))
1664 PG_RETURN_NUMERIC(make_result(&const_nan));
1667 * Unpack the argument and determine the result scale. We choose a scale
1668 * to give at least NUMERIC_MIN_SIG_DIGITS significant digits; but in any
1669 * case not less than the input's dscale.
1674 set_var_from_num(num, &arg);
1676 /* Assume the input was normalized, so arg.weight is accurate */
1677 sweight = (arg.weight + 1) * DEC_DIGITS / 2 - 1;
1679 rscale = NUMERIC_MIN_SIG_DIGITS - sweight;
1680 rscale = Max(rscale, arg.dscale);
1681 rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
1682 rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
1685 * Let sqrt_var() do the calculation and return the result.
1687 sqrt_var(&arg, &result, rscale);
1689 res = make_result(&result);
1694 PG_RETURN_NUMERIC(res);
1701 * Raise e to the power of x
1704 numeric_exp(PG_FUNCTION_ARGS)
1706 Numeric num = PG_GETARG_NUMERIC(0);
1716 if (NUMERIC_IS_NAN(num))
1717 PG_RETURN_NUMERIC(make_result(&const_nan));
1720 * Unpack the argument and determine the result scale. We choose a scale
1721 * to give at least NUMERIC_MIN_SIG_DIGITS significant digits; but in any
1722 * case not less than the input's dscale.
1727 set_var_from_num(num, &arg);
1729 /* convert input to float8, ignoring overflow */
1730 val = numericvar_to_double_no_overflow(&arg);
1733 * log10(result) = num * log10(e), so this is approximately the decimal
1734 * weight of the result:
1736 val *= 0.434294481903252;
1738 /* limit to something that won't cause integer overflow */
1739 val = Max(val, -NUMERIC_MAX_RESULT_SCALE);
1740 val = Min(val, NUMERIC_MAX_RESULT_SCALE);
1742 rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;
1743 rscale = Max(rscale, arg.dscale);
1744 rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
1745 rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
1748 * Let exp_var() do the calculation and return the result.
1750 exp_var(&arg, &result, rscale);
1752 res = make_result(&result);
1757 PG_RETURN_NUMERIC(res);
1764 * Compute the natural logarithm of x
1767 numeric_ln(PG_FUNCTION_ARGS)
1769 Numeric num = PG_GETARG_NUMERIC(0);
1779 if (NUMERIC_IS_NAN(num))
1780 PG_RETURN_NUMERIC(make_result(&const_nan));
1785 set_var_from_num(num, &arg);
1787 /* Approx decimal digits before decimal point */
1788 dec_digits = (arg.weight + 1) * DEC_DIGITS;
1791 rscale = NUMERIC_MIN_SIG_DIGITS - (int) log10(dec_digits - 1);
1792 else if (dec_digits < 1)
1793 rscale = NUMERIC_MIN_SIG_DIGITS - (int) log10(1 - dec_digits);
1795 rscale = NUMERIC_MIN_SIG_DIGITS;
1797 rscale = Max(rscale, arg.dscale);
1798 rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
1799 rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
1801 ln_var(&arg, &result, rscale);
1803 res = make_result(&result);
1808 PG_RETURN_NUMERIC(res);
1815 * Compute the logarithm of x in a given base
1818 numeric_log(PG_FUNCTION_ARGS)
1820 Numeric num1 = PG_GETARG_NUMERIC(0);
1821 Numeric num2 = PG_GETARG_NUMERIC(1);
1830 if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
1831 PG_RETURN_NUMERIC(make_result(&const_nan));
1840 set_var_from_num(num1, &arg1);
1841 set_var_from_num(num2, &arg2);
1844 * Call log_var() to compute and return the result; note it handles scale
1847 log_var(&arg1, &arg2, &result);
1849 res = make_result(&result);
1855 PG_RETURN_NUMERIC(res);
1862 * Raise b to the power of x
1865 numeric_power(PG_FUNCTION_ARGS)
1867 Numeric num1 = PG_GETARG_NUMERIC(0);
1868 Numeric num2 = PG_GETARG_NUMERIC(1);
1872 NumericVar arg2_trunc;
1878 if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
1879 PG_RETURN_NUMERIC(make_result(&const_nan));
1886 init_var(&arg2_trunc);
1889 set_var_from_num(num1, &arg1);
1890 set_var_from_num(num2, &arg2);
1891 set_var_from_var(&arg2, &arg2_trunc);
1893 trunc_var(&arg2_trunc, 0);
1896 * Return special SQLSTATE error codes for a few conditions mandated by
1899 if ((cmp_var(&arg1, &const_zero) == 0 &&
1900 cmp_var(&arg2, &const_zero) < 0) ||
1901 (cmp_var(&arg1, &const_zero) < 0 &&
1902 cmp_var(&arg2, &arg2_trunc) != 0))
1904 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
1905 errmsg("invalid argument for power function")));
1908 * Call power_var() to compute and return the result; note it handles
1909 * scale selection itself.
1911 power_var(&arg1, &arg2, &result);
1913 res = make_result(&result);
1917 free_var(&arg2_trunc);
1920 PG_RETURN_NUMERIC(res);
1924 /* ----------------------------------------------------------------------
1926 * Type conversion functions
1928 * ----------------------------------------------------------------------
1933 int4_numeric(PG_FUNCTION_ARGS)
1935 int32 val = PG_GETARG_INT32(0);
1941 int8_to_numericvar((int64) val, &result);
1943 res = make_result(&result);
1947 PG_RETURN_NUMERIC(res);
1952 numeric_int4(PG_FUNCTION_ARGS)
1954 Numeric num = PG_GETARG_NUMERIC(0);
1958 /* XXX would it be better to return NULL? */
1959 if (NUMERIC_IS_NAN(num))
1961 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1962 errmsg("cannot convert NaN to integer")));
1964 /* Convert to variable format, then convert to int4 */
1966 set_var_from_num(num, &x);
1967 result = numericvar_to_int4(&x);
1969 PG_RETURN_INT32(result);
1973 * Given a NumericVar, convert it to an int32. If the NumericVar
1974 * exceeds the range of an int32, raise the appropriate error via
1975 * ereport(). The input NumericVar is *not* free'd.
1978 numericvar_to_int4(NumericVar *var)
1983 if (!numericvar_to_int8(var, &val))
1985 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1986 errmsg("integer out of range")));
1988 /* Down-convert to int4 */
1989 result = (int32) val;
1991 /* Test for overflow by reverse-conversion. */
1992 if ((int64) result != val)
1994 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1995 errmsg("integer out of range")));
2001 int8_numeric(PG_FUNCTION_ARGS)
2003 int64 val = PG_GETARG_INT64(0);
2009 int8_to_numericvar(val, &result);
2011 res = make_result(&result);
2015 PG_RETURN_NUMERIC(res);
2020 numeric_int8(PG_FUNCTION_ARGS)
2022 Numeric num = PG_GETARG_NUMERIC(0);
2026 /* XXX would it be better to return NULL? */
2027 if (NUMERIC_IS_NAN(num))
2029 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2030 errmsg("cannot convert NaN to bigint")));
2032 /* Convert to variable format and thence to int8 */
2034 set_var_from_num(num, &x);
2036 if (!numericvar_to_int8(&x, &result))
2038 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
2039 errmsg("bigint out of range")));
2043 PG_RETURN_INT64(result);
2048 int2_numeric(PG_FUNCTION_ARGS)
2050 int16 val = PG_GETARG_INT16(0);
2056 int8_to_numericvar((int64) val, &result);
2058 res = make_result(&result);
2062 PG_RETURN_NUMERIC(res);
2067 numeric_int2(PG_FUNCTION_ARGS)
2069 Numeric num = PG_GETARG_NUMERIC(0);
2074 /* XXX would it be better to return NULL? */
2075 if (NUMERIC_IS_NAN(num))
2077 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2078 errmsg("cannot convert NaN to smallint")));
2080 /* Convert to variable format and thence to int8 */
2082 set_var_from_num(num, &x);
2084 if (!numericvar_to_int8(&x, &val))
2086 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
2087 errmsg("smallint out of range")));
2091 /* Down-convert to int2 */
2092 result = (int16) val;
2094 /* Test for overflow by reverse-conversion. */
2095 if ((int64) result != val)
2097 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
2098 errmsg("smallint out of range")));
2100 PG_RETURN_INT16(result);
2105 float8_numeric(PG_FUNCTION_ARGS)
2107 float8 val = PG_GETARG_FLOAT8(0);
2110 char buf[DBL_DIG + 100];
2113 PG_RETURN_NUMERIC(make_result(&const_nan));
2115 sprintf(buf, "%.*g", DBL_DIG, val);
2119 set_var_from_str(buf, &result);
2120 res = make_result(&result);
2124 PG_RETURN_NUMERIC(res);
2129 numeric_float8(PG_FUNCTION_ARGS)
2131 Numeric num = PG_GETARG_NUMERIC(0);
2135 if (NUMERIC_IS_NAN(num))
2136 PG_RETURN_FLOAT8(get_float8_nan());
2138 tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
2139 NumericGetDatum(num)));
2141 result = DirectFunctionCall1(float8in, CStringGetDatum(tmp));
2145 PG_RETURN_DATUM(result);
2149 /* Convert numeric to float8; if out of range, return +/- HUGE_VAL */
2151 numeric_float8_no_overflow(PG_FUNCTION_ARGS)
2153 Numeric num = PG_GETARG_NUMERIC(0);
2156 if (NUMERIC_IS_NAN(num))
2157 PG_RETURN_FLOAT8(get_float8_nan());
2159 val = numeric_to_double_no_overflow(num);
2161 PG_RETURN_FLOAT8(val);
2165 float4_numeric(PG_FUNCTION_ARGS)
2167 float4 val = PG_GETARG_FLOAT4(0);
2170 char buf[FLT_DIG + 100];
2173 PG_RETURN_NUMERIC(make_result(&const_nan));
2175 sprintf(buf, "%.*g", FLT_DIG, val);
2179 set_var_from_str(buf, &result);
2180 res = make_result(&result);
2184 PG_RETURN_NUMERIC(res);
2189 numeric_float4(PG_FUNCTION_ARGS)
2191 Numeric num = PG_GETARG_NUMERIC(0);
2195 if (NUMERIC_IS_NAN(num))
2196 PG_RETURN_FLOAT4(get_float4_nan());
2198 tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
2199 NumericGetDatum(num)));
2201 result = DirectFunctionCall1(float4in, CStringGetDatum(tmp));
2205 PG_RETURN_DATUM(result);
2209 /* ----------------------------------------------------------------------
2211 * Aggregate functions
2213 * The transition datatype for all these aggregates is a 3-element array
2214 * of Numeric, holding the values N, sum(X), sum(X*X) in that order.
2216 * We represent N as a numeric mainly to avoid having to build a special
2217 * datatype; it's unlikely it'd overflow an int4, but ...
2219 * ----------------------------------------------------------------------
2223 do_numeric_accum(ArrayType *transarray, Numeric newval)
2232 /* We assume the input is array of numeric */
2233 deconstruct_array(transarray,
2234 NUMERICOID, -1, false, 'i',
2235 &transdatums, NULL, &ndatums);
2237 elog(ERROR, "expected 3-element numeric array");
2239 sumX = transdatums[1];
2240 sumX2 = transdatums[2];
2242 N = DirectFunctionCall1(numeric_inc, N);
2243 sumX = DirectFunctionCall2(numeric_add, sumX,
2244 NumericGetDatum(newval));
2245 sumX2 = DirectFunctionCall2(numeric_add, sumX2,
2246 DirectFunctionCall2(numeric_mul,
2247 NumericGetDatum(newval),
2248 NumericGetDatum(newval)));
2251 transdatums[1] = sumX;
2252 transdatums[2] = sumX2;
2254 result = construct_array(transdatums, 3,
2255 NUMERICOID, -1, false, 'i');
2261 * Improve avg performance by not caclulating sum(X*X).
2264 do_numeric_avg_accum(ArrayType *transarray, Numeric newval)
2272 /* We assume the input is array of numeric */
2273 deconstruct_array(transarray,
2274 NUMERICOID, -1, false, 'i',
2275 &transdatums, NULL, &ndatums);
2277 elog(ERROR, "expected 2-element numeric array");
2279 sumX = transdatums[1];
2281 N = DirectFunctionCall1(numeric_inc, N);
2282 sumX = DirectFunctionCall2(numeric_add, sumX,
2283 NumericGetDatum(newval));
2286 transdatums[1] = sumX;
2288 result = construct_array(transdatums, 2,
2289 NUMERICOID, -1, false, 'i');
2295 numeric_accum(PG_FUNCTION_ARGS)
2297 ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
2298 Numeric newval = PG_GETARG_NUMERIC(1);
2300 PG_RETURN_ARRAYTYPE_P(do_numeric_accum(transarray, newval));
2304 * Optimized case for average of numeric.
2307 numeric_avg_accum(PG_FUNCTION_ARGS)
2309 ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
2310 Numeric newval = PG_GETARG_NUMERIC(1);
2312 PG_RETURN_ARRAYTYPE_P(do_numeric_avg_accum(transarray, newval));
2316 * Integer data types all use Numeric accumulators to share code and
2317 * avoid risk of overflow. For int2 and int4 inputs, Numeric accumulation
2318 * is overkill for the N and sum(X) values, but definitely not overkill
2319 * for the sum(X*X) value. Hence, we use int2_accum and int4_accum only
2320 * for stddev/variance --- there are faster special-purpose accumulator
2321 * routines for SUM and AVG of these datatypes.
2325 int2_accum(PG_FUNCTION_ARGS)
2327 ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
2328 Datum newval2 = PG_GETARG_DATUM(1);
2331 newval = DatumGetNumeric(DirectFunctionCall1(int2_numeric, newval2));
2333 PG_RETURN_ARRAYTYPE_P(do_numeric_accum(transarray, newval));
2337 int4_accum(PG_FUNCTION_ARGS)
2339 ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
2340 Datum newval4 = PG_GETARG_DATUM(1);
2343 newval = DatumGetNumeric(DirectFunctionCall1(int4_numeric, newval4));
2345 PG_RETURN_ARRAYTYPE_P(do_numeric_accum(transarray, newval));
2349 int8_accum(PG_FUNCTION_ARGS)
2351 ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
2352 Datum newval8 = PG_GETARG_DATUM(1);
2355 newval = DatumGetNumeric(DirectFunctionCall1(int8_numeric, newval8));
2357 PG_RETURN_ARRAYTYPE_P(do_numeric_accum(transarray, newval));
2361 * Optimized case for average of int8.
2364 int8_avg_accum(PG_FUNCTION_ARGS)
2366 ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
2367 Datum newval8 = PG_GETARG_DATUM(1);
2370 newval = DatumGetNumeric(DirectFunctionCall1(int8_numeric, newval8));
2372 PG_RETURN_ARRAYTYPE_P(do_numeric_avg_accum(transarray, newval));
2377 numeric_avg(PG_FUNCTION_ARGS)
2379 ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
2385 /* We assume the input is array of numeric */
2386 deconstruct_array(transarray,
2387 NUMERICOID, -1, false, 'i',
2388 &transdatums, NULL, &ndatums);
2390 elog(ERROR, "expected 2-element numeric array");
2391 N = DatumGetNumeric(transdatums[0]);
2392 sumX = DatumGetNumeric(transdatums[1]);
2394 /* SQL92 defines AVG of no values to be NULL */
2395 /* N is zero iff no digits (cf. numeric_uminus) */
2396 if (VARSIZE(N) == NUMERIC_HDRSZ)
2399 PG_RETURN_DATUM(DirectFunctionCall2(numeric_div,
2400 NumericGetDatum(sumX),
2401 NumericGetDatum(N)));
2405 * Workhorse routine for the standard deviance and variance
2406 * aggregates. 'transarray' is the aggregate's transition
2407 * array. 'variance' specifies whether we should calculate the
2408 * variance or the standard deviation. 'sample' indicates whether the
2409 * caller is interested in the sample or the population
2412 * If appropriate variance statistic is undefined for the input,
2413 * *is_null is set to true and NULL is returned.
2416 numeric_stddev_internal(ArrayType *transarray,
2417 bool variance, bool sample,
2435 /* We assume the input is array of numeric */
2436 deconstruct_array(transarray,
2437 NUMERICOID, -1, false, 'i',
2438 &transdatums, NULL, &ndatums);
2440 elog(ERROR, "expected 3-element numeric array");
2441 N = DatumGetNumeric(transdatums[0]);
2442 sumX = DatumGetNumeric(transdatums[1]);
2443 sumX2 = DatumGetNumeric(transdatums[2]);
2445 if (NUMERIC_IS_NAN(N) || NUMERIC_IS_NAN(sumX) || NUMERIC_IS_NAN(sumX2))
2446 return make_result(&const_nan);
2449 set_var_from_num(N, &vN);
2452 * Sample stddev and variance are undefined when N <= 1; population stddev
2453 * is undefined when N == 0. Return NULL in either case.
2460 if (cmp_var(&vN, comp) <= 0)
2467 init_var(&vNminus1);
2468 sub_var(&vN, &const_one, &vNminus1);
2471 set_var_from_num(sumX, &vsumX);
2473 set_var_from_num(sumX2, &vsumX2);
2475 /* compute rscale for mul_var calls */
2476 rscale = vsumX.dscale * 2;
2478 mul_var(&vsumX, &vsumX, &vsumX, rscale); /* vsumX = sumX * sumX */
2479 mul_var(&vN, &vsumX2, &vsumX2, rscale); /* vsumX2 = N * sumX2 */
2480 sub_var(&vsumX2, &vsumX, &vsumX2); /* N * sumX2 - sumX * sumX */
2482 if (cmp_var(&vsumX2, &const_zero) <= 0)
2484 /* Watch out for roundoff error producing a negative numerator */
2485 res = make_result(&const_zero);
2490 mul_var(&vN, &vNminus1, &vNminus1, 0); /* N * (N - 1) */
2492 mul_var(&vN, &vN, &vNminus1, 0); /* N * N */
2493 rscale = select_div_scale(&vsumX2, &vNminus1);
2494 div_var(&vsumX2, &vNminus1, &vsumX, rscale, true); /* variance */
2496 sqrt_var(&vsumX, &vsumX, rscale); /* stddev */
2498 res = make_result(&vsumX);
2502 free_var(&vNminus1);
2510 numeric_var_samp(PG_FUNCTION_ARGS)
2515 res = numeric_stddev_internal(PG_GETARG_ARRAYTYPE_P(0),
2516 true, true, &is_null);
2521 PG_RETURN_NUMERIC(res);
2525 numeric_stddev_samp(PG_FUNCTION_ARGS)
2530 res = numeric_stddev_internal(PG_GETARG_ARRAYTYPE_P(0),
2531 false, true, &is_null);
2536 PG_RETURN_NUMERIC(res);
2540 numeric_var_pop(PG_FUNCTION_ARGS)
2545 res = numeric_stddev_internal(PG_GETARG_ARRAYTYPE_P(0),
2546 true, false, &is_null);
2551 PG_RETURN_NUMERIC(res);
2555 numeric_stddev_pop(PG_FUNCTION_ARGS)
2560 res = numeric_stddev_internal(PG_GETARG_ARRAYTYPE_P(0),
2561 false, false, &is_null);
2566 PG_RETURN_NUMERIC(res);
2570 * SUM transition functions for integer datatypes.
2572 * To avoid overflow, we use accumulators wider than the input datatype.
2573 * A Numeric accumulator is needed for int8 input; for int4 and int2
2574 * inputs, we use int8 accumulators which should be sufficient for practical
2575 * purposes. (The latter two therefore don't really belong in this file,
2576 * but we keep them here anyway.)
2578 * Because SQL92 defines the SUM() of no values to be NULL, not zero,
2579 * the initial condition of the transition data value needs to be NULL. This
2580 * means we can't rely on ExecAgg to automatically insert the first non-null
2581 * data value into the transition data: it doesn't know how to do the type
2582 * conversion. The upshot is that these routines have to be marked non-strict
2583 * and handle substitution of the first non-null input themselves.
2587 int2_sum(PG_FUNCTION_ARGS)
2591 if (PG_ARGISNULL(0))
2593 /* No non-null input seen so far... */
2594 if (PG_ARGISNULL(1))
2595 PG_RETURN_NULL(); /* still no non-null */
2596 /* This is the first non-null input. */
2597 newval = (int64) PG_GETARG_INT16(1);
2598 PG_RETURN_INT64(newval);
2602 * If we're invoked by nodeAgg, we can cheat and modify out first
2603 * parameter in-place to avoid palloc overhead. If not, we need to return
2604 * the new value of the transition variable.
2606 if (fcinfo->context && IsA(fcinfo->context, AggState))
2608 int64 *oldsum = (int64 *) PG_GETARG_POINTER(0);
2610 /* Leave the running sum unchanged in the new input is null */
2611 if (!PG_ARGISNULL(1))
2612 *oldsum = *oldsum + (int64) PG_GETARG_INT16(1);
2614 PG_RETURN_POINTER(oldsum);
2618 int64 oldsum = PG_GETARG_INT64(0);
2620 /* Leave sum unchanged if new input is null. */
2621 if (PG_ARGISNULL(1))
2622 PG_RETURN_INT64(oldsum);
2624 /* OK to do the addition. */
2625 newval = oldsum + (int64) PG_GETARG_INT16(1);
2627 PG_RETURN_INT64(newval);
2632 int4_sum(PG_FUNCTION_ARGS)
2636 if (PG_ARGISNULL(0))
2638 /* No non-null input seen so far... */
2639 if (PG_ARGISNULL(1))
2640 PG_RETURN_NULL(); /* still no non-null */
2641 /* This is the first non-null input. */
2642 newval = (int64) PG_GETARG_INT32(1);
2643 PG_RETURN_INT64(newval);
2647 * If we're invoked by nodeAgg, we can cheat and modify out first
2648 * parameter in-place to avoid palloc overhead. If not, we need to return
2649 * the new value of the transition variable.
2651 if (fcinfo->context && IsA(fcinfo->context, AggState))
2653 int64 *oldsum = (int64 *) PG_GETARG_POINTER(0);
2655 /* Leave the running sum unchanged in the new input is null */
2656 if (!PG_ARGISNULL(1))
2657 *oldsum = *oldsum + (int64) PG_GETARG_INT32(1);
2659 PG_RETURN_POINTER(oldsum);
2663 int64 oldsum = PG_GETARG_INT64(0);
2665 /* Leave sum unchanged if new input is null. */
2666 if (PG_ARGISNULL(1))
2667 PG_RETURN_INT64(oldsum);
2669 /* OK to do the addition. */
2670 newval = oldsum + (int64) PG_GETARG_INT32(1);
2672 PG_RETURN_INT64(newval);
2677 int8_sum(PG_FUNCTION_ARGS)
2682 if (PG_ARGISNULL(0))
2684 /* No non-null input seen so far... */
2685 if (PG_ARGISNULL(1))
2686 PG_RETURN_NULL(); /* still no non-null */
2687 /* This is the first non-null input. */
2688 newval = DirectFunctionCall1(int8_numeric, PG_GETARG_DATUM(1));
2689 PG_RETURN_DATUM(newval);
2693 * Note that we cannot special-case the nodeAgg case here, as we do for
2694 * int2_sum and int4_sum: numeric is of variable size, so we cannot modify
2695 * our first parameter in-place.
2698 oldsum = PG_GETARG_NUMERIC(0);
2700 /* Leave sum unchanged if new input is null. */
2701 if (PG_ARGISNULL(1))
2702 PG_RETURN_NUMERIC(oldsum);
2704 /* OK to do the addition. */
2705 newval = DirectFunctionCall1(int8_numeric, PG_GETARG_DATUM(1));
2707 PG_RETURN_DATUM(DirectFunctionCall2(numeric_add,
2708 NumericGetDatum(oldsum), newval));
2713 * Routines for avg(int2) and avg(int4). The transition datatype
2714 * is a two-element int8 array, holding count and sum.
2717 typedef struct Int8TransTypeData
2719 #ifndef INT64_IS_BUSTED
2723 /* "int64" isn't really 64 bits, so fake up properly-aligned fields */
2729 } Int8TransTypeData;
2732 int2_avg_accum(PG_FUNCTION_ARGS)
2734 ArrayType *transarray;
2735 int16 newval = PG_GETARG_INT16(1);
2736 Int8TransTypeData *transdata;
2739 * If we're invoked by nodeAgg, we can cheat and modify our first
2740 * parameter in-place to reduce palloc overhead. Otherwise we need to make
2741 * a copy of it before scribbling on it.
2743 if (fcinfo->context && IsA(fcinfo->context, AggState))
2744 transarray = PG_GETARG_ARRAYTYPE_P(0);
2746 transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
2748 if (ARR_HASNULL(transarray) ||
2749 ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
2750 elog(ERROR, "expected 2-element int8 array");
2752 transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
2754 transdata->sum += newval;
2756 PG_RETURN_ARRAYTYPE_P(transarray);
2760 int4_avg_accum(PG_FUNCTION_ARGS)
2762 ArrayType *transarray;
2763 int32 newval = PG_GETARG_INT32(1);
2764 Int8TransTypeData *transdata;
2767 * If we're invoked by nodeAgg, we can cheat and modify our first
2768 * parameter in-place to reduce palloc overhead. Otherwise we need to make
2769 * a copy of it before scribbling on it.
2771 if (fcinfo->context && IsA(fcinfo->context, AggState))
2772 transarray = PG_GETARG_ARRAYTYPE_P(0);
2774 transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
2776 if (ARR_HASNULL(transarray) ||
2777 ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
2778 elog(ERROR, "expected 2-element int8 array");
2780 transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
2782 transdata->sum += newval;
2784 PG_RETURN_ARRAYTYPE_P(transarray);
2788 int8_avg(PG_FUNCTION_ARGS)
2790 ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0);
2791 Int8TransTypeData *transdata;
2795 if (ARR_HASNULL(transarray) ||
2796 ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
2797 elog(ERROR, "expected 2-element int8 array");
2798 transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
2800 /* SQL92 defines AVG of no values to be NULL */
2801 if (transdata->count == 0)
2804 countd = DirectFunctionCall1(int8_numeric,
2805 Int64GetDatumFast(transdata->count));
2806 sumd = DirectFunctionCall1(int8_numeric,
2807 Int64GetDatumFast(transdata->sum));
2809 PG_RETURN_DATUM(DirectFunctionCall2(numeric_div, sumd, countd));
2813 /* ----------------------------------------------------------------------
2817 * ----------------------------------------------------------------------
2820 #ifdef NUMERIC_DEBUG
2823 * dump_numeric() - Dump a value in the db storage format for debugging
2826 dump_numeric(const char *str, Numeric num)
2828 NumericDigit *digits = NUMERIC_DIGITS(num);
2832 ndigits = NUMERIC_NDIGITS(num);
2834 printf("%s: NUMERIC w=%d d=%d ", str, num->n_weight, NUMERIC_DSCALE(num));
2835 switch (NUMERIC_SIGN(num))
2847 printf("SIGN=0x%x", NUMERIC_SIGN(num));
2851 for (i = 0; i < ndigits; i++)
2852 printf(" %0*d", DEC_DIGITS, digits[i]);
2858 * dump_var() - Dump a value in the variable format for debugging
2861 dump_var(const char *str, NumericVar *var)
2865 printf("%s: VAR w=%d d=%d ", str, var->weight, var->dscale);
2878 printf("SIGN=0x%x", var->sign);
2882 for (i = 0; i < var->ndigits; i++)
2883 printf(" %0*d", DEC_DIGITS, var->digits[i]);
2887 #endif /* NUMERIC_DEBUG */
2890 /* ----------------------------------------------------------------------
2892 * Local functions follow
2894 * In general, these do not support NaNs --- callers must eliminate
2895 * the possibility of NaN first. (make_result() is an exception.)
2897 * ----------------------------------------------------------------------
2904 * Allocate a digit buffer of ndigits digits (plus a spare digit for rounding)
2907 alloc_var(NumericVar *var, int ndigits)
2909 digitbuf_free(var->buf);
2910 var->buf = digitbuf_alloc(ndigits + 1);
2911 var->buf[0] = 0; /* spare digit for rounding */
2912 var->digits = var->buf + 1;
2913 var->ndigits = ndigits;
2920 * Return the digit buffer of a variable to the free pool
2923 free_var(NumericVar *var)
2925 digitbuf_free(var->buf);
2928 var->sign = NUMERIC_NAN;
2935 * Set a variable to ZERO.
2936 * Note: its dscale is not touched.
2939 zero_var(NumericVar *var)
2941 digitbuf_free(var->buf);
2945 var->weight = 0; /* by convention; doesn't really matter */
2946 var->sign = NUMERIC_POS; /* anything but NAN... */
2951 * set_var_from_str()
2953 * Parse a string and put the number into a variable
2956 set_var_from_str(const char *str, NumericVar *dest)
2958 const char *cp = str;
2959 bool have_dp = FALSE;
2961 unsigned char *decdigits;
2962 int sign = NUMERIC_POS;
2969 NumericDigit *digits;
2972 * We first parse the string to extract decimal digits and determine the
2973 * correct decimal weight. Then convert to NBASE representation.
2976 /* skip leading spaces */
2979 if (!isspace((unsigned char) *cp))
3003 if (!isdigit((unsigned char) *cp))
3005 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
3006 errmsg("invalid input syntax for type numeric: \"%s\"", str)));
3008 decdigits = (unsigned char *) palloc(strlen(cp) + DEC_DIGITS * 2);
3010 /* leading padding for digit alignment later */
3011 memset(decdigits, 0, DEC_DIGITS);
3016 if (isdigit((unsigned char) *cp))
3018 decdigits[i++] = *cp++ - '0';
3024 else if (*cp == '.')
3028 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
3029 errmsg("invalid input syntax for type numeric: \"%s\"",
3038 ddigits = i - DEC_DIGITS;
3039 /* trailing padding for digit alignment later */
3040 memset(decdigits + i, 0, DEC_DIGITS - 1);
3042 /* Handle exponent, if any */
3043 if (*cp == 'e' || *cp == 'E')
3049 exponent = strtol(cp, &endptr, 10);
3052 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
3053 errmsg("invalid input syntax for type numeric: \"%s\"",
3056 if (exponent > NUMERIC_MAX_PRECISION ||
3057 exponent < -NUMERIC_MAX_PRECISION)
3059 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
3060 errmsg("invalid input syntax for type numeric: \"%s\"",
3062 dweight += (int) exponent;
3063 dscale -= (int) exponent;
3068 /* Should be nothing left but spaces */
3071 if (!isspace((unsigned char) *cp))
3073 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
3074 errmsg("invalid input syntax for type numeric: \"%s\"",
3080 * Okay, convert pure-decimal representation to base NBASE. First we need
3081 * to determine the converted weight and ndigits. offset is the number of
3082 * decimal zeroes to insert before the first given digit to have a
3083 * correctly aligned first NBASE digit.
3086 weight = (dweight + 1 + DEC_DIGITS - 1) / DEC_DIGITS - 1;
3088 weight = -((-dweight - 1) / DEC_DIGITS + 1);
3089 offset = (weight + 1) * DEC_DIGITS - (dweight + 1);
3090 ndigits = (ddigits + offset + DEC_DIGITS - 1) / DEC_DIGITS;
3092 alloc_var(dest, ndigits);
3094 dest->weight = weight;
3095 dest->dscale = dscale;
3097 i = DEC_DIGITS - offset;
3098 digits = dest->digits;
3100 while (ndigits-- > 0)
3103 *digits++ = ((decdigits[i] * 10 + decdigits[i + 1]) * 10 +
3104 decdigits[i + 2]) * 10 + decdigits[i + 3];
3105 #elif DEC_DIGITS == 2
3106 *digits++ = decdigits[i] * 10 + decdigits[i + 1];
3107 #elif DEC_DIGITS == 1
3108 *digits++ = decdigits[i];
3110 #error unsupported NBASE
3117 /* Strip any leading/trailing zeroes, and normalize weight if zero */
3123 * set_var_from_num() -
3125 * Convert the packed db format into a variable
3128 set_var_from_num(Numeric num, NumericVar *dest)
3132 ndigits = NUMERIC_NDIGITS(num);
3134 alloc_var(dest, ndigits);
3136 dest->weight = num->n_weight;
3137 dest->sign = NUMERIC_SIGN(num);
3138 dest->dscale = NUMERIC_DSCALE(num);
3140 memcpy(dest->digits, num->n_data, ndigits * sizeof(NumericDigit));
3145 * set_var_from_var() -
3147 * Copy one variable into another
3150 set_var_from_var(NumericVar *value, NumericVar *dest)
3152 NumericDigit *newbuf;
3154 newbuf = digitbuf_alloc(value->ndigits + 1);
3155 newbuf[0] = 0; /* spare digit for rounding */
3156 memcpy(newbuf + 1, value->digits, value->ndigits * sizeof(NumericDigit));
3158 digitbuf_free(dest->buf);
3160 memmove(dest, value, sizeof(NumericVar));
3162 dest->digits = newbuf + 1;
3167 * get_str_from_var() -
3169 * Convert a var to text representation (guts of numeric_out).
3170 * CAUTION: var's contents may be modified by rounding!
3171 * Returns a palloc'd string.
3174 get_str_from_var(NumericVar *var, int dscale)
3191 * Check if we must round up before printing the value and do so.
3193 round_var(var, dscale);
3196 * Allocate space for the result.
3198 * i is set to to # of decimal digits before decimal point. dscale is the
3199 * # of decimal digits we will print after decimal point. We may generate
3200 * as many as DEC_DIGITS-1 excess digits at the end, and in addition we
3201 * need room for sign, decimal point, null terminator.
3203 i = (var->weight + 1) * DEC_DIGITS;
3207 str = palloc(i + dscale + DEC_DIGITS + 2);
3211 * Output a dash for negative values
3213 if (var->sign == NUMERIC_NEG)
3217 * Output all digits before the decimal point
3219 if (var->weight < 0)
3221 d = var->weight + 1;
3226 for (d = 0; d <= var->weight; d++)
3228 dig = (d < var->ndigits) ? var->digits[d] : 0;
3229 /* In the first digit, suppress extra leading decimal zeroes */
3232 bool putit = (d > 0);
3251 #elif DEC_DIGITS == 2
3254 if (d1 > 0 || d > 0)
3257 #elif DEC_DIGITS == 1
3260 #error unsupported NBASE
3266 * If requested, output a decimal point and all the digits that follow it.
3267 * We initially put out a multiple of DEC_DIGITS digits, then truncate if
3273 endcp = cp + dscale;
3274 for (i = 0; i < dscale; d++, i += DEC_DIGITS)
3276 dig = (d >= 0 && d < var->ndigits) ? var->digits[d] : 0;
3288 #elif DEC_DIGITS == 2
3293 #elif DEC_DIGITS == 1
3296 #error unsupported NBASE
3303 * terminate the string and return it
3313 * Create the packed db numeric format in palloc()'d memory from
3317 make_result(NumericVar *var)
3320 NumericDigit *digits = var->digits;
3321 int weight = var->weight;
3322 int sign = var->sign;
3326 if (sign == NUMERIC_NAN)
3328 result = (Numeric) palloc(NUMERIC_HDRSZ);
3330 SET_VARSIZE(result, NUMERIC_HDRSZ);
3331 result->n_weight = 0;
3332 result->n_sign_dscale = NUMERIC_NAN;
3334 dump_numeric("make_result()", result);
3340 /* truncate leading zeroes */
3341 while (n > 0 && *digits == 0)
3347 /* truncate trailing zeroes */
3348 while (n > 0 && digits[n - 1] == 0)
3351 /* If zero result, force to weight=0 and positive sign */
3358 /* Build the result */
3359 len = NUMERIC_HDRSZ + n * sizeof(NumericDigit);
3360 result = (Numeric) palloc(len);
3361 SET_VARSIZE(result, len);
3362 result->n_weight = weight;
3363 result->n_sign_dscale = sign | (var->dscale & NUMERIC_DSCALE_MASK);
3365 memcpy(result->n_data, digits, n * sizeof(NumericDigit));
3367 /* Check for overflow of int16 fields */
3368 if (result->n_weight != weight ||
3369 NUMERIC_DSCALE(result) != var->dscale)
3371 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
3372 errmsg("value overflows numeric format")));
3374 dump_numeric("make_result()", result);
3382 * Do bounds checking and rounding according to the attributes
3386 apply_typmod(NumericVar *var, int32 typmod)
3394 /* Do nothing if we have a default typmod (-1) */
3395 if (typmod < (int32) (VARHDRSZ))
3399 precision = (typmod >> 16) & 0xffff;
3400 scale = typmod & 0xffff;
3401 maxdigits = precision - scale;
3403 /* Round to target scale (and set var->dscale) */
3404 round_var(var, scale);
3407 * Check for overflow - note we can't do this before rounding, because
3408 * rounding could raise the weight. Also note that the var's weight could
3409 * be inflated by leading zeroes, which will be stripped before storage
3410 * but perhaps might not have been yet. In any case, we must recognize a
3411 * true zero, whose weight doesn't mean anything.
3413 ddigits = (var->weight + 1) * DEC_DIGITS;
3414 if (ddigits > maxdigits)
3416 /* Determine true weight; and check for all-zero result */
3417 for (i = 0; i < var->ndigits; i++)
3419 NumericDigit dig = var->digits[i];
3423 /* Adjust for any high-order decimal zero digits */
3429 else if (dig < 1000)
3431 #elif DEC_DIGITS == 2
3434 #elif DEC_DIGITS == 1
3437 #error unsupported NBASE
3439 if (ddigits > maxdigits)
3441 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
3442 errmsg("numeric field overflow"),
3443 errdetail("A field with precision %d, scale %d must round to an absolute value less than %s%d.",
3445 /* Display 10^0 as 1 */
3446 maxdigits ? "10^" : "",
3447 maxdigits ? maxdigits : 1
3451 ddigits -= DEC_DIGITS;
3457 * Convert numeric to int8, rounding if needed.
3459 * If overflow, return FALSE (no error is raised). Return TRUE if okay.
3461 * CAUTION: var's contents may be modified by rounding!
3464 numericvar_to_int8(NumericVar *var, int64 *result)
3466 NumericDigit *digits;
3474 /* Round to nearest integer */
3477 /* Check for zero input */
3479 ndigits = var->ndigits;
3487 * For input like 10000000000, we must treat stripped digits as real. So
3488 * the loop assumes there are weight+1 digits before the decimal point.
3490 weight = var->weight;
3491 Assert(weight >= 0 && ndigits <= weight + 1);
3493 /* Construct the result */
3494 digits = var->digits;
3495 neg = (var->sign == NUMERIC_NEG);
3497 for (i = 1; i <= weight; i++)
3505 * The overflow check is a bit tricky because we want to accept
3506 * INT64_MIN, which will overflow the positive accumulator. We can
3507 * detect this case easily though because INT64_MIN is the only
3508 * nonzero value for which -val == val (on a two's complement machine,
3511 if ((val / NBASE) != oldval) /* possible overflow? */
3513 if (!neg || (-val) != val || val == 0 || oldval < 0)
3518 *result = neg ? -val : val;
3523 * Convert int8 value to numeric.
3526 int8_to_numericvar(int64 val, NumericVar *var)
3533 /* int8 can require at most 19 decimal digits; add one for safety */
3534 alloc_var(var, 20 / DEC_DIGITS);
3537 var->sign = NUMERIC_NEG;
3542 var->sign = NUMERIC_POS;
3552 ptr = var->digits + var->ndigits;
3558 newuval = uval / NBASE;
3559 *ptr = uval - newuval * NBASE;
3563 var->ndigits = ndigits;
3564 var->weight = ndigits - 1;
3568 * Convert numeric to float8; if out of range, return +/- HUGE_VAL
3571 numeric_to_double_no_overflow(Numeric num)
3577 tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
3578 NumericGetDatum(num)));
3580 /* unlike float8in, we ignore ERANGE from strtod */
3581 val = strtod(tmp, &endptr);
3582 if (*endptr != '\0')
3584 /* shouldn't happen ... */
3586 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
3587 errmsg("invalid input syntax for type double precision: \"%s\"",
3596 /* As above, but work from a NumericVar */
3598 numericvar_to_double_no_overflow(NumericVar *var)
3604 tmp = get_str_from_var(var, var->dscale);
3606 /* unlike float8in, we ignore ERANGE from strtod */
3607 val = strtod(tmp, &endptr);
3608 if (*endptr != '\0')
3610 /* shouldn't happen ... */
3612 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
3613 errmsg("invalid input syntax for type double precision: \"%s\"",
3626 * Compare two values on variable level. We assume zeroes have been
3627 * truncated to no digits.
3630 cmp_var(NumericVar *var1, NumericVar *var2)
3632 return cmp_var_common(var1->digits, var1->ndigits,
3633 var1->weight, var1->sign,
3634 var2->digits, var2->ndigits,
3635 var2->weight, var2->sign);
3639 * cmp_var_common() -
3641 * Main routine of cmp_var(). This function can be used by both
3642 * NumericVar and Numeric.
3645 cmp_var_common(const NumericDigit *var1digits, int var1ndigits,
3646 int var1weight, int var1sign,
3647 const NumericDigit *var2digits, int var2ndigits,
3648 int var2weight, int var2sign)
3650 if (var1ndigits == 0)
3652 if (var2ndigits == 0)
3654 if (var2sign == NUMERIC_NEG)
3658 if (var2ndigits == 0)
3660 if (var1sign == NUMERIC_POS)
3665 if (var1sign == NUMERIC_POS)
3667 if (var2sign == NUMERIC_NEG)
3669 return cmp_abs_common(var1digits, var1ndigits, var1weight,
3670 var2digits, var2ndigits, var2weight);
3673 if (var2sign == NUMERIC_POS)
3676 return cmp_abs_common(var2digits, var2ndigits, var2weight,
3677 var1digits, var1ndigits, var1weight);
3684 * Full version of add functionality on variable level (handling signs).
3685 * result might point to one of the operands too without danger.
3688 add_var(NumericVar *var1, NumericVar *var2, NumericVar *result)
3691 * Decide on the signs of the two variables what to do
3693 if (var1->sign == NUMERIC_POS)
3695 if (var2->sign == NUMERIC_POS)
3698 * Both are positive result = +(ABS(var1) + ABS(var2))
3700 add_abs(var1, var2, result);
3701 result->sign = NUMERIC_POS;
3706 * var1 is positive, var2 is negative Must compare absolute values
3708 switch (cmp_abs(var1, var2))
3712 * ABS(var1) == ABS(var2)
3717 result->dscale = Max(var1->dscale, var2->dscale);
3722 * ABS(var1) > ABS(var2)
3723 * result = +(ABS(var1) - ABS(var2))
3726 sub_abs(var1, var2, result);
3727 result->sign = NUMERIC_POS;
3732 * ABS(var1) < ABS(var2)
3733 * result = -(ABS(var2) - ABS(var1))
3736 sub_abs(var2, var1, result);
3737 result->sign = NUMERIC_NEG;
3744 if (var2->sign == NUMERIC_POS)
3747 * var1 is negative, var2 is positive
3748 * Must compare absolute values
3751 switch (cmp_abs(var1, var2))
3755 * ABS(var1) == ABS(var2)
3760 result->dscale = Max(var1->dscale, var2->dscale);
3765 * ABS(var1) > ABS(var2)
3766 * result = -(ABS(var1) - ABS(var2))
3769 sub_abs(var1, var2, result);
3770 result->sign = NUMERIC_NEG;
3775 * ABS(var1) < ABS(var2)
3776 * result = +(ABS(var2) - ABS(var1))
3779 sub_abs(var2, var1, result);
3780 result->sign = NUMERIC_POS;
3788 * result = -(ABS(var1) + ABS(var2))
3791 add_abs(var1, var2, result);
3792 result->sign = NUMERIC_NEG;
3801 * Full version of sub functionality on variable level (handling signs).
3802 * result might point to one of the operands too without danger.
3805 sub_var(NumericVar *var1, NumericVar *var2, NumericVar *result)
3808 * Decide on the signs of the two variables what to do
3810 if (var1->sign == NUMERIC_POS)
3812 if (var2->sign == NUMERIC_NEG)
3815 * var1 is positive, var2 is negative
3816 * result = +(ABS(var1) + ABS(var2))
3819 add_abs(var1, var2, result);
3820 result->sign = NUMERIC_POS;
3826 * Must compare absolute values
3829 switch (cmp_abs(var1, var2))
3833 * ABS(var1) == ABS(var2)
3838 result->dscale = Max(var1->dscale, var2->dscale);
3843 * ABS(var1) > ABS(var2)
3844 * result = +(ABS(var1) - ABS(var2))
3847 sub_abs(var1, var2, result);
3848 result->sign = NUMERIC_POS;
3853 * ABS(var1) < ABS(var2)
3854 * result = -(ABS(var2) - ABS(var1))
3857 sub_abs(var2, var1, result);
3858 result->sign = NUMERIC_NEG;
3865 if (var2->sign == NUMERIC_NEG)
3869 * Must compare absolute values
3872 switch (cmp_abs(var1, var2))
3876 * ABS(var1) == ABS(var2)
3881 result->dscale = Max(var1->dscale, var2->dscale);
3886 * ABS(var1) > ABS(var2)
3887 * result = -(ABS(var1) - ABS(var2))
3890 sub_abs(var1, var2, result);
3891 result->sign = NUMERIC_NEG;
3896 * ABS(var1) < ABS(var2)
3897 * result = +(ABS(var2) - ABS(var1))
3900 sub_abs(var2, var1, result);
3901 result->sign = NUMERIC_POS;
3908 * var1 is negative, var2 is positive
3909 * result = -(ABS(var1) + ABS(var2))
3912 add_abs(var1, var2, result);
3913 result->sign = NUMERIC_NEG;
3922 * Multiplication on variable level. Product of var1 * var2 is stored
3923 * in result. Result is rounded to no more than rscale fractional digits.
3926 mul_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
3937 NumericDigit *res_digits;
3943 /* copy these values into local vars for speed in inner loop */
3944 int var1ndigits = var1->ndigits;
3945 int var2ndigits = var2->ndigits;
3946 NumericDigit *var1digits = var1->digits;
3947 NumericDigit *var2digits = var2->digits;
3949 if (var1ndigits == 0 || var2ndigits == 0)
3951 /* one or both inputs is zero; so is result */
3953 result->dscale = rscale;
3957 /* Determine result sign and (maximum possible) weight */
3958 if (var1->sign == var2->sign)
3959 res_sign = NUMERIC_POS;
3961 res_sign = NUMERIC_NEG;
3962 res_weight = var1->weight + var2->weight + 2;
3965 * Determine number of result digits to compute. If the exact result
3966 * would have more than rscale fractional digits, truncate the computation
3967 * with MUL_GUARD_DIGITS guard digits. We do that by pretending that one
3968 * or both inputs have fewer digits than they really do.
3970 res_ndigits = var1ndigits + var2ndigits + 1;
3971 maxdigits = res_weight + 1 + (rscale * DEC_DIGITS) + MUL_GUARD_DIGITS;
3972 if (res_ndigits > maxdigits)
3976 /* no useful precision at all in the result... */
3978 result->dscale = rscale;
3981 /* force maxdigits odd so that input ndigits can be equal */
3982 if ((maxdigits & 1) == 0)
3984 if (var1ndigits > var2ndigits)
3986 var1ndigits -= res_ndigits - maxdigits;
3987 if (var1ndigits < var2ndigits)
3988 var1ndigits = var2ndigits = (var1ndigits + var2ndigits) / 2;
3992 var2ndigits -= res_ndigits - maxdigits;
3993 if (var2ndigits < var1ndigits)
3994 var1ndigits = var2ndigits = (var1ndigits + var2ndigits) / 2;
3996 res_ndigits = maxdigits;
3997 Assert(res_ndigits == var1ndigits + var2ndigits + 1);
4001 * We do the arithmetic in an array "dig[]" of signed int's. Since
4002 * INT_MAX is noticeably larger than NBASE*NBASE, this gives us headroom
4003 * to avoid normalizing carries immediately.
4005 * maxdig tracks the maximum possible value of any dig[] entry; when this
4006 * threatens to exceed INT_MAX, we take the time to propagate carries. To
4007 * avoid overflow in maxdig itself, it actually represents the max
4008 * possible value divided by NBASE-1.
4010 dig = (int *) palloc0(res_ndigits * sizeof(int));
4013 ri = res_ndigits - 1;
4014 for (i1 = var1ndigits - 1; i1 >= 0; ri--, i1--)
4016 int var1digit = var1digits[i1];
4021 /* Time to normalize? */
4022 maxdig += var1digit;
4023 if (maxdig > INT_MAX / (NBASE - 1))
4027 for (i = res_ndigits - 1; i >= 0; i--)
4029 newdig = dig[i] + carry;
4030 if (newdig >= NBASE)
4032 carry = newdig / NBASE;
4033 newdig -= carry * NBASE;
4040 /* Reset maxdig to indicate new worst-case */
4041 maxdig = 1 + var1digit;
4044 /* Add appropriate multiple of var2 into the accumulator */
4046 for (i2 = var2ndigits - 1; i2 >= 0; i2--)
4047 dig[i--] += var1digit * var2digits[i2];
4051 * Now we do a final carry propagation pass to normalize the result, which
4052 * we combine with storing the result digits into the output. Note that
4053 * this is still done at full precision w/guard digits.
4055 alloc_var(result, res_ndigits);
4056 res_digits = result->digits;
4058 for (i = res_ndigits - 1; i >= 0; i--)
4060 newdig = dig[i] + carry;
4061 if (newdig >= NBASE)
4063 carry = newdig / NBASE;
4064 newdig -= carry * NBASE;
4068 res_digits[i] = newdig;
4075 * Finally, round the result to the requested precision.
4077 result->weight = res_weight;
4078 result->sign = res_sign;
4080 /* Round to target rscale (and set result->dscale) */
4081 round_var(result, rscale);
4083 /* Strip leading and trailing zeroes */
4091 * Division on variable level. Quotient of var1 / var2 is stored in result.
4092 * The quotient is figured to exactly rscale fractional digits.
4093 * If round is true, it is rounded at the rscale'th digit; if false, it
4094 * is truncated (towards zero) at that digit.
4097 div_var(NumericVar *var1, NumericVar *var2, NumericVar *result,
4098 int rscale, bool round)
4108 NumericDigit *dividend;
4109 NumericDigit *divisor;
4110 NumericDigit *res_digits;
4114 /* copy these values into local vars for speed in inner loop */
4115 int var1ndigits = var1->ndigits;
4116 int var2ndigits = var2->ndigits;
4119 * First of all division by zero check; we must not be handed an
4120 * unnormalized divisor.
4122 if (var2ndigits == 0 || var2->digits[0] == 0)
4124 (errcode(ERRCODE_DIVISION_BY_ZERO),
4125 errmsg("division by zero")));
4128 * Now result zero check
4130 if (var1ndigits == 0)
4133 result->dscale = rscale;
4138 * Determine the result sign, weight and number of digits to calculate.
4139 * The weight figured here is correct if the emitted quotient has no
4140 * leading zero digits; otherwise strip_var() will fix things up.
4142 if (var1->sign == var2->sign)
4143 res_sign = NUMERIC_POS;
4145 res_sign = NUMERIC_NEG;
4146 res_weight = var1->weight - var2->weight;
4147 /* The number of accurate result digits we need to produce: */
4148 res_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
4149 /* ... but always at least 1 */
4150 res_ndigits = Max(res_ndigits, 1);
4151 /* If rounding needed, figure one more digit to ensure correct result */
4155 * The working dividend normally requires res_ndigits + var2ndigits
4156 * digits, but make it at least var1ndigits so we can load all of var1
4157 * into it. (There will be an additional digit dividend[0] in the
4158 * dividend space, but for consistency with Knuth's notation we don't
4159 * count that in div_ndigits.)
4161 div_ndigits = res_ndigits + var2ndigits;
4162 div_ndigits = Max(div_ndigits, var1ndigits);
4165 * We need a workspace with room for the working dividend (div_ndigits+1
4166 * digits) plus room for the possibly-normalized divisor (var2ndigits
4167 * digits). It is convenient also to have a zero at divisor[0] with
4168 * the actual divisor data in divisor[1 .. var2ndigits]. Transferring the
4169 * digits into the workspace also allows us to realloc the result (which
4170 * might be the same as either input var) before we begin the main loop.
4171 * Note that we use palloc0 to ensure that divisor[0], dividend[0], and
4172 * any additional dividend positions beyond var1ndigits, start out 0.
4174 dividend = (NumericDigit *)
4175 palloc0((div_ndigits + var2ndigits + 2) * sizeof(NumericDigit));
4176 divisor = dividend + (div_ndigits + 1);
4177 memcpy(dividend + 1, var1->digits, var1ndigits * sizeof(NumericDigit));
4178 memcpy(divisor + 1, var2->digits, var2ndigits * sizeof(NumericDigit));
4181 * Now we can realloc the result to hold the generated quotient digits.
4183 alloc_var(result, res_ndigits);
4184 res_digits = result->digits;
4186 if (var2ndigits == 1)
4189 * If there's only a single divisor digit, we can use a fast path
4190 * (cf. Knuth section 4.3.1 exercise 16).
4192 divisor1 = divisor[1];
4194 for (i = 0; i < res_ndigits; i++)
4196 carry = carry * NBASE + dividend[i + 1];
4197 res_digits[i] = carry / divisor1;
4198 carry = carry % divisor1;
4204 * The full multiple-place algorithm is taken from Knuth volume 2,
4207 * We need the first divisor digit to be >= NBASE/2. If it isn't,
4208 * make it so by scaling up both the divisor and dividend by the
4209 * factor "d". (The reason for allocating dividend[0] above is to
4210 * leave room for possible carry here.)
4212 if (divisor[1] < HALF_NBASE)
4214 int d = NBASE / (divisor[1] + 1);
4217 for (i = var2ndigits; i > 0; i--)
4219 carry += divisor[i] * d;
4220 divisor[i] = carry % NBASE;
4221 carry = carry / NBASE;
4225 /* at this point only var1ndigits of dividend can be nonzero */
4226 for (i = var1ndigits; i >= 0; i--)
4228 carry += dividend[i] * d;
4229 dividend[i] = carry % NBASE;
4230 carry = carry / NBASE;
4233 Assert(divisor[1] >= HALF_NBASE);
4235 /* First 2 divisor digits are used repeatedly in main loop */
4236 divisor1 = divisor[1];
4237 divisor2 = divisor[2];
4240 * Begin the main loop. Each iteration of this loop produces the
4241 * j'th quotient digit by dividing dividend[j .. j + var2ndigits]
4242 * by the divisor; this is essentially the same as the common manual
4243 * procedure for long division.
4245 for (j = 0; j < res_ndigits; j++)
4247 /* Estimate quotient digit from the first two dividend digits */
4248 int next2digits = dividend[j] * NBASE + dividend[j+1];
4252 * If next2digits are 0, then quotient digit must be 0 and there's
4253 * no need to adjust the working dividend. It's worth testing
4254 * here to fall out ASAP when processing trailing zeroes in
4257 if (next2digits == 0)
4263 if (dividend[j] == divisor1)
4266 qhat = next2digits / divisor1;
4268 * Adjust quotient digit if it's too large. Knuth proves that
4269 * after this step, the quotient digit will be either correct
4270 * or just one too large. (Note: it's OK to use dividend[j+2]
4271 * here because we know the divisor length is at least 2.)
4273 while (divisor2 * qhat >
4274 (next2digits - qhat * divisor1) * NBASE + dividend[j+2])
4277 /* As above, need do nothing more when quotient digit is 0 */
4281 * Multiply the divisor by qhat, and subtract that from the
4282 * working dividend. "carry" tracks the multiplication,
4283 * "borrow" the subtraction (could we fold these together?)
4287 for (i = var2ndigits; i >= 0; i--)
4289 carry += divisor[i] * qhat;
4290 borrow -= carry % NBASE;
4291 carry = carry / NBASE;
4292 borrow += dividend[j + i];
4295 dividend[j + i] = borrow + NBASE;
4300 dividend[j + i] = borrow;
4307 * If we got a borrow out of the top dividend digit, then
4308 * indeed qhat was one too large. Fix it, and add back the
4309 * divisor to correct the working dividend. (Knuth proves
4310 * that this will occur only about 3/NBASE of the time; hence,
4311 * it's a good idea to test this code with small NBASE to be
4312 * sure this section gets exercised.)
4318 for (i = var2ndigits; i >= 0; i--)
4320 carry += dividend[j + i] + divisor[i];
4323 dividend[j + i] = carry - NBASE;
4328 dividend[j + i] = carry;
4332 /* A carry should occur here to cancel the borrow above */
4337 /* And we're done with this quotient digit */
4338 res_digits[j] = qhat;
4345 * Finally, round or truncate the result to the requested precision.
4347 result->weight = res_weight;
4348 result->sign = res_sign;
4350 /* Round or truncate to target rscale (and set result->dscale) */
4352 round_var(result, rscale);
4354 trunc_var(result, rscale);
4356 /* Strip leading and trailing zeroes */
4364 * This has the same API as div_var, but is implemented using the division
4365 * algorithm from the "FM" library, rather than Knuth's schoolbook-division
4366 * approach. This is significantly faster but can produce inaccurate
4367 * results, because it sometimes has to propagate rounding to the left,
4368 * and so we can never be entirely sure that we know the requested digits
4369 * exactly. We compute DIV_GUARD_DIGITS extra digits, but there is
4370 * no certainty that that's enough. We use this only in the transcendental
4371 * function calculation routines, where everything is approximate anyway.
4374 div_var_fast(NumericVar *var1, NumericVar *var2, NumericVar *result,
4375 int rscale, bool round)
4385 NumericDigit *res_digits;
4393 /* copy these values into local vars for speed in inner loop */
4394 int var1ndigits = var1->ndigits;
4395 int var2ndigits = var2->ndigits;
4396 NumericDigit *var1digits = var1->digits;
4397 NumericDigit *var2digits = var2->digits;
4400 * First of all division by zero check; we must not be handed an
4401 * unnormalized divisor.
4403 if (var2ndigits == 0 || var2digits[0] == 0)
4405 (errcode(ERRCODE_DIVISION_BY_ZERO),
4406 errmsg("division by zero")));
4409 * Now result zero check
4411 if (var1ndigits == 0)
4414 result->dscale = rscale;
4419 * Determine the result sign, weight and number of digits to calculate
4421 if (var1->sign == var2->sign)
4422 res_sign = NUMERIC_POS;
4424 res_sign = NUMERIC_NEG;
4425 res_weight = var1->weight - var2->weight + 1;
4426 /* The number of accurate result digits we need to produce: */
4427 div_ndigits = res_weight + 1 + (rscale + DEC_DIGITS - 1) / DEC_DIGITS;
4428 /* Add guard digits for roundoff error */
4429 div_ndigits += DIV_GUARD_DIGITS;
4430 if (div_ndigits < DIV_GUARD_DIGITS)
4431 div_ndigits = DIV_GUARD_DIGITS;
4432 /* Must be at least var1ndigits, too, to simplify data-loading loop */
4433 if (div_ndigits < var1ndigits)
4434 div_ndigits = var1ndigits;
4437 * We do the arithmetic in an array "div[]" of signed int's. Since
4438 * INT_MAX is noticeably larger than NBASE*NBASE, this gives us headroom
4439 * to avoid normalizing carries immediately.
4441 * We start with div[] containing one zero digit followed by the
4442 * dividend's digits (plus appended zeroes to reach the desired precision
4443 * including guard digits). Each step of the main loop computes an
4444 * (approximate) quotient digit and stores it into div[], removing one
4445 * position of dividend space. A final pass of carry propagation takes
4446 * care of any mistaken quotient digits.
4448 div = (int *) palloc0((div_ndigits + 1) * sizeof(int));
4449 for (i = 0; i < var1ndigits; i++)
4450 div[i + 1] = var1digits[i];
4453 * We estimate each quotient digit using floating-point arithmetic, taking
4454 * the first four digits of the (current) dividend and divisor. This must
4455 * be float to avoid overflow.
4457 fdivisor = (double) var2digits[0];
4458 for (i = 1; i < 4; i++)
4461 if (i < var2ndigits)
4462 fdivisor += (double) var2digits[i];
4464 fdivisorinverse = 1.0 / fdivisor;
4467 * maxdiv tracks the maximum possible absolute value of any div[] entry;
4468 * when this threatens to exceed INT_MAX, we take the time to propagate
4469 * carries. To avoid overflow in maxdiv itself, it actually represents
4470 * the max possible abs. value divided by NBASE-1.
4475 * Outer loop computes next quotient digit, which will go into div[qi]
4477 for (qi = 0; qi < div_ndigits; qi++)
4479 /* Approximate the current dividend value */
4480 fdividend = (double) div[qi];
4481 for (i = 1; i < 4; i++)
4484 if (qi + i <= div_ndigits)
4485 fdividend += (double) div[qi + i];
4487 /* Compute the (approximate) quotient digit */
4488 fquotient = fdividend * fdivisorinverse;
4489 qdigit = (fquotient >= 0.0) ? ((int) fquotient) :
4490 (((int) fquotient) - 1); /* truncate towards -infinity */
4494 /* Do we need to normalize now? */
4495 maxdiv += Abs(qdigit);
4496 if (maxdiv > INT_MAX / (NBASE - 1))
4500 for (i = div_ndigits; i > qi; i--)
4502 newdig = div[i] + carry;
4505 carry = -((-newdig - 1) / NBASE) - 1;
4506 newdig -= carry * NBASE;
4508 else if (newdig >= NBASE)
4510 carry = newdig / NBASE;
4511 newdig -= carry * NBASE;
4517 newdig = div[qi] + carry;
4521 * All the div[] digits except possibly div[qi] are now in the
4524 maxdiv = Abs(newdig) / (NBASE - 1);
4525 maxdiv = Max(maxdiv, 1);
4528 * Recompute the quotient digit since new info may have
4529 * propagated into the top four dividend digits
4531 fdividend = (double) div[qi];
4532 for (i = 1; i < 4; i++)
4535 if (qi + i <= div_ndigits)
4536 fdividend += (double) div[qi + i];
4538 /* Compute the (approximate) quotient digit */
4539 fquotient = fdividend * fdivisorinverse;
4540 qdigit = (fquotient >= 0.0) ? ((int) fquotient) :
4541 (((int) fquotient) - 1); /* truncate towards -infinity */
4542 maxdiv += Abs(qdigit);
4545 /* Subtract off the appropriate multiple of the divisor */
4548 int istop = Min(var2ndigits, div_ndigits - qi + 1);
4550 for (i = 0; i < istop; i++)
4551 div[qi + i] -= qdigit * var2digits[i];
4556 * The dividend digit we are about to replace might still be nonzero.
4557 * Fold it into the next digit position. We don't need to worry about
4558 * overflow here since this should nearly cancel with the subtraction
4561 div[qi + 1] += div[qi] * NBASE;
4567 * Approximate and store the last quotient digit (div[div_ndigits])
4569 fdividend = (double) div[qi];
4570 for (i = 1; i < 4; i++)
4572 fquotient = fdividend * fdivisorinverse;
4573 qdigit = (fquotient >= 0.0) ? ((int) fquotient) :
4574 (((int) fquotient) - 1); /* truncate towards -infinity */
4578 * Now we do a final carry propagation pass to normalize the result, which
4579 * we combine with storing the result digits into the output. Note that
4580 * this is still done at full precision w/guard digits.
4582 alloc_var(result, div_ndigits + 1);
4583 res_digits = result->digits;
4585 for (i = div_ndigits; i >= 0; i--)
4587 newdig = div[i] + carry;
4590 carry = -((-newdig - 1) / NBASE) - 1;
4591 newdig -= carry * NBASE;
4593 else if (newdig >= NBASE)
4595 carry = newdig / NBASE;
4596 newdig -= carry * NBASE;
4600 res_digits[i] = newdig;
4607 * Finally, round the result to the requested precision.
4609 result->weight = res_weight;
4610 result->sign = res_sign;
4612 /* Round to target rscale (and set result->dscale) */
4614 round_var(result, rscale);
4616 trunc_var(result, rscale);
4618 /* Strip leading and trailing zeroes */
4624 * Default scale selection for division
4626 * Returns the appropriate result scale for the division result.
4629 select_div_scale(NumericVar *var1, NumericVar *var2)
4635 NumericDigit firstdigit1,
4640 * The result scale of a division isn't specified in any SQL standard. For
4641 * PostgreSQL we select a result scale that will give at least
4642 * NUMERIC_MIN_SIG_DIGITS significant digits, so that numeric gives a
4643 * result no less accurate than float8; but use a scale not less than
4644 * either input's display scale.
4647 /* Get the actual (normalized) weight and first digit of each input */
4649 weight1 = 0; /* values to use if var1 is zero */
4651 for (i = 0; i < var1->ndigits; i++)
4653 firstdigit1 = var1->digits[i];
4654 if (firstdigit1 != 0)
4656 weight1 = var1->weight - i;
4661 weight2 = 0; /* values to use if var2 is zero */
4663 for (i = 0; i < var2->ndigits; i++)
4665 firstdigit2 = var2->digits[i];
4666 if (firstdigit2 != 0)
4668 weight2 = var2->weight - i;
4674 * Estimate weight of quotient. If the two first digits are equal, we
4675 * can't be sure, but assume that var1 is less than var2.
4677 qweight = weight1 - weight2;
4678 if (firstdigit1 <= firstdigit2)
4681 /* Select result scale */
4682 rscale = NUMERIC_MIN_SIG_DIGITS - qweight * DEC_DIGITS;
4683 rscale = Max(rscale, var1->dscale);
4684 rscale = Max(rscale, var2->dscale);
4685 rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
4686 rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
4695 * Calculate the modulo of two numerics at variable level
4698 mod_var(NumericVar *var1, NumericVar *var2, NumericVar *result)
4705 * We do this using the equation
4706 * mod(x,y) = x - trunc(x/y)*y
4707 * div_var can be persuaded to give us trunc(x/y) directly.
4710 div_var(var1, var2, &tmp, 0, false);
4712 mul_var(var2, &tmp, &tmp, var2->dscale);
4714 sub_var(var1, &tmp, result);
4723 * Return the smallest integer greater than or equal to the argument
4727 ceil_var(NumericVar *var, NumericVar *result)
4732 set_var_from_var(var, &tmp);
4736 if (var->sign == NUMERIC_POS && cmp_var(var, &tmp) != 0)
4737 add_var(&tmp, &const_one, &tmp);
4739 set_var_from_var(&tmp, result);
4747 * Return the largest integer equal to or less than the argument
4751 floor_var(NumericVar *var, NumericVar *result)
4756 set_var_from_var(var, &tmp);
4760 if (var->sign == NUMERIC_NEG && cmp_var(var, &tmp) != 0)
4761 sub_var(&tmp, &const_one, &tmp);
4763 set_var_from_var(&tmp, result);
4771 * Compute the square root of x using Newton's algorithm
4774 sqrt_var(NumericVar *arg, NumericVar *result, int rscale)
4778 NumericVar last_val;
4782 local_rscale = rscale + 8;
4784 stat = cmp_var(arg, &const_zero);
4788 result->dscale = rscale;
4793 * SQL2003 defines sqrt() in terms of power, so we need to emit the right
4794 * SQLSTATE error code if the operand is negative.
4798 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION),
4799 errmsg("cannot take square root of a negative number")));
4803 init_var(&last_val);
4805 /* Copy arg in case it is the same var as result */
4806 set_var_from_var(arg, &tmp_arg);
4809 * Initialize the result to the first guess
4811 alloc_var(result, 1);
4812 result->digits[0] = tmp_arg.digits[0] / 2;
4813 if (result->digits[0] == 0)
4814 result->digits[0] = 1;
4815 result->weight = tmp_arg.weight / 2;
4816 result->sign = NUMERIC_POS;
4818 set_var_from_var(result, &last_val);
4822 div_var_fast(&tmp_arg, result, &tmp_val, local_rscale, true);
4824 add_var(result, &tmp_val, result);
4825 mul_var(result, &const_zero_point_five, result, local_rscale);
4827 if (cmp_var(&last_val, result) == 0)
4829 set_var_from_var(result, &last_val);
4832 free_var(&last_val);
4836 /* Round to requested precision */
4837 round_var(result, rscale);
4844 * Raise e to the power of x
4847 exp_var(NumericVar *arg, NumericVar *result, int rscale)
4855 * We separate the integral and fraction parts of x, then compute
4856 * e^x = e^xint * e^xfrac
4857 * where e = exp(1) and e^xfrac = exp(xfrac) are computed by
4858 * exp_var_internal; the limited range of inputs allows that routine
4859 * to do a good job with a simple Taylor series. Raising e^xint is
4860 * done by repeated multiplications in power_var_int.
4865 set_var_from_var(arg, &x);
4867 if (x.sign == NUMERIC_NEG)
4870 x.sign = NUMERIC_POS;
4873 /* Extract the integer part, remove it from x */
4875 while (x.weight >= 0)
4880 xintval += x.digits[0];
4885 /* Guard against overflow */
4886 if (xintval >= NUMERIC_MAX_RESULT_SCALE * 3)
4888 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
4889 errmsg("argument for function \"exp\" too big")));
4892 /* Select an appropriate scale for internal calculation */
4893 local_rscale = rscale + MUL_GUARD_DIGITS * 2;
4895 /* Compute e^xfrac */
4896 exp_var_internal(&x, result, local_rscale);
4898 /* If there's an integer part, multiply by e^xint */
4904 exp_var_internal(&const_one, &e, local_rscale);
4905 power_var_int(&e, xintval, &e, local_rscale);
4906 mul_var(&e, result, result, local_rscale);
4910 /* Compensate for input sign, and round to requested rscale */
4912 div_var_fast(&const_one, result, result, rscale, true);
4914 round_var(result, rscale);
4921 * exp_var_internal() -
4923 * Raise e to the power of x, where 0 <= x <= 1
4925 * NB: the result should be good to at least rscale digits, but it has
4926 * *not* been rounded off; the caller must do that if wanted.
4929 exp_var_internal(NumericVar *arg, NumericVar *result, int rscale)
4945 set_var_from_var(arg, &x);
4947 Assert(x.sign == NUMERIC_POS);
4949 local_rscale = rscale + 8;
4951 /* Reduce input into range 0 <= x <= 0.01 */
4952 while (cmp_var(&x, &const_zero_point_01) > 0)
4956 mul_var(&x, &const_zero_point_five, &x, x.dscale + 1);
4960 * Use the Taylor series
4962 * exp(x) = 1 + x + x^2/2! + x^3/3! + ...
4964 * Given the limited range of x, this should converge reasonably quickly.
4965 * We run the series until the terms fall below the local_rscale limit.
4967 add_var(&const_one, &x, result);
4968 set_var_from_var(&x, &xpow);
4969 set_var_from_var(&const_one, &ifac);
4970 set_var_from_var(&const_one, &ni);
4974 add_var(&ni, &const_one, &ni);
4975 mul_var(&xpow, &x, &xpow, local_rscale);
4976 mul_var(&ifac, &ni, &ifac, 0);
4977 div_var_fast(&xpow, &ifac, &elem, local_rscale, true);
4979 if (elem.ndigits == 0)
4982 add_var(result, &elem, result);
4985 /* Compensate for argument range reduction */
4987 mul_var(result, result, result, local_rscale);
5000 * Compute the natural log of x
5003 ln_var(NumericVar *arg, NumericVar *result, int rscale)
5013 cmp = cmp_var(arg, &const_zero);
5016 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
5017 errmsg("cannot take logarithm of zero")));
5020 (errcode(ERRCODE_INVALID_ARGUMENT_FOR_LOG),
5021 errmsg("cannot take logarithm of a negative number")));
5023 local_rscale = rscale + 8;
5031 set_var_from_var(arg, &x);
5032 set_var_from_var(&const_two, &fact);
5034 /* Reduce input into range 0.9 < x < 1.1 */
5035 while (cmp_var(&x, &const_zero_point_nine) <= 0)
5038 sqrt_var(&x, &x, local_rscale);
5039 mul_var(&fact, &const_two, &fact, 0);
5041 while (cmp_var(&x, &const_one_point_one) >= 0)
5044 sqrt_var(&x, &x, local_rscale);
5045 mul_var(&fact, &const_two, &fact, 0);
5049 * We use the Taylor series for 0.5 * ln((1+z)/(1-z)),
5051 * z + z^3/3 + z^5/5 + ...
5053 * where z = (x-1)/(x+1) is in the range (approximately) -0.053 .. 0.048
5054 * due to the above range-reduction of x.
5056 * The convergence of this is not as fast as one would like, but is
5057 * tolerable given that z is small.
5059 sub_var(&x, &const_one, result);
5060 add_var(&x, &const_one, &elem);
5061 div_var_fast(result, &elem, result, local_rscale, true);
5062 set_var_from_var(result, &xx);
5063 mul_var(result, result, &x, local_rscale);
5065 set_var_from_var(&const_one, &ni);
5069 add_var(&ni, &const_two, &ni);
5070 mul_var(&xx, &x, &xx, local_rscale);
5071 div_var_fast(&xx, &ni, &elem, local_rscale, true);
5073 if (elem.ndigits == 0)
5076 add_var(result, &elem, result);
5078 if (elem.weight < (result->weight - local_rscale * 2 / DEC_DIGITS))
5082 /* Compensate for argument range reduction, round to requested rscale */
5083 mul_var(result, &fact, result, rscale);
5096 * Compute the logarithm of num in a given base.
5098 * Note: this routine chooses dscale of the result.
5101 log_var(NumericVar *base, NumericVar *num, NumericVar *result)
5112 /* Set scale for ln() calculations --- compare numeric_ln() */
5114 /* Approx decimal digits before decimal point */
5115 dec_digits = (num->weight + 1) * DEC_DIGITS;
5118 rscale = NUMERIC_MIN_SIG_DIGITS - (int) log10(dec_digits - 1);
5119 else if (dec_digits < 1)
5120 rscale = NUMERIC_MIN_SIG_DIGITS - (int) log10(1 - dec_digits);
5122 rscale = NUMERIC_MIN_SIG_DIGITS;
5124 rscale = Max(rscale, base->dscale);
5125 rscale = Max(rscale, num->dscale);
5126 rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
5127 rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
5129 local_rscale = rscale + 8;
5131 /* Form natural logarithms */
5132 ln_var(base, &ln_base, local_rscale);
5133 ln_var(num, &ln_num, local_rscale);
5135 ln_base.dscale = rscale;
5136 ln_num.dscale = rscale;
5138 /* Select scale for division result */
5139 rscale = select_div_scale(&ln_num, &ln_base);
5141 div_var_fast(&ln_num, &ln_base, result, rscale, true);
5151 * Raise base to the power of exp
5153 * Note: this routine chooses dscale of the result.
5156 power_var(NumericVar *base, NumericVar *exp, NumericVar *result)
5165 /* If exp can be represented as an integer, use power_var_int */
5166 if (exp->ndigits == 0 || exp->ndigits <= exp->weight + 1)
5168 /* exact integer, but does it fit in int? */
5172 /* must copy because numericvar_to_int8() scribbles on input */
5174 set_var_from_var(exp, &x);
5175 if (numericvar_to_int8(&x, &expval64))
5177 int expval = (int) expval64;
5179 /* Test for overflow by reverse-conversion. */
5180 if ((int64) expval == expval64)
5182 /* Okay, select rscale */
5183 rscale = NUMERIC_MIN_SIG_DIGITS;
5184 rscale = Max(rscale, base->dscale);
5185 rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
5186 rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
5188 power_var_int(base, expval, result, rscale);
5200 /* Set scale for ln() calculation --- need extra accuracy here */
5202 /* Approx decimal digits before decimal point */
5203 dec_digits = (base->weight + 1) * DEC_DIGITS;
5206 rscale = NUMERIC_MIN_SIG_DIGITS * 2 - (int) log10(dec_digits - 1);
5207 else if (dec_digits < 1)
5208 rscale = NUMERIC_MIN_SIG_DIGITS * 2 - (int) log10(1 - dec_digits);
5210 rscale = NUMERIC_MIN_SIG_DIGITS * 2;
5212 rscale = Max(rscale, base->dscale * 2);
5213 rscale = Max(rscale, exp->dscale * 2);
5214 rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE * 2);
5215 rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE * 2);
5217 local_rscale = rscale + 8;
5219 ln_var(base, &ln_base, local_rscale);
5221 mul_var(&ln_base, exp, &ln_num, local_rscale);
5223 /* Set scale for exp() -- compare numeric_exp() */
5225 /* convert input to float8, ignoring overflow */
5226 val = numericvar_to_double_no_overflow(&ln_num);
5229 * log10(result) = num * log10(e), so this is approximately the weight:
5231 val *= 0.434294481903252;
5233 /* limit to something that won't cause integer overflow */
5234 val = Max(val, -NUMERIC_MAX_RESULT_SCALE);
5235 val = Min(val, NUMERIC_MAX_RESULT_SCALE);
5237 rscale = NUMERIC_MIN_SIG_DIGITS - (int) val;
5238 rscale = Max(rscale, base->dscale);
5239 rscale = Max(rscale, exp->dscale);
5240 rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
5241 rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
5243 exp_var(&ln_num, result, rscale);
5252 * Raise base to the power of exp, where exp is an integer.
5255 power_var_int(NumericVar *base, int exp, NumericVar *result, int rscale)
5258 NumericVar base_prod;
5261 /* Detect some special cases, particularly 0^0. */
5266 if (base->ndigits == 0)
5268 (errcode(ERRCODE_FLOATING_POINT_EXCEPTION),
5269 errmsg("zero raised to zero is undefined")));
5270 set_var_from_var(&const_one, result);
5271 result->dscale = rscale; /* no need to round */
5274 set_var_from_var(base, result);
5275 round_var(result, rscale);
5278 div_var(&const_one, base, result, rscale, true);
5281 mul_var(base, base, result, rscale);
5288 * The general case repeatedly multiplies base according to the bit
5289 * pattern of exp. We do the multiplications with some extra precision.
5294 local_rscale = rscale + MUL_GUARD_DIGITS * 2;
5296 init_var(&base_prod);
5297 set_var_from_var(base, &base_prod);
5300 set_var_from_var(base, result);
5302 set_var_from_var(&const_one, result);
5304 while ((exp >>= 1) > 0)
5306 mul_var(&base_prod, &base_prod, &base_prod, local_rscale);
5308 mul_var(&base_prod, result, result, local_rscale);
5311 free_var(&base_prod);
5313 /* Compensate for input sign, and round to requested rscale */
5315 div_var_fast(&const_one, result, result, rscale, true);
5317 round_var(result, rscale);
5321 /* ----------------------------------------------------------------------
5323 * Following are the lowest level functions that operate unsigned
5324 * on the variable level
5326 * ----------------------------------------------------------------------
5333 * Compare the absolute values of var1 and var2
5334 * Returns: -1 for ABS(var1) < ABS(var2)
5335 * 0 for ABS(var1) == ABS(var2)
5336 * 1 for ABS(var1) > ABS(var2)
5340 cmp_abs(NumericVar *var1, NumericVar *var2)
5342 return cmp_abs_common(var1->digits, var1->ndigits, var1->weight,
5343 var2->digits, var2->ndigits, var2->weight);
5347 * cmp_abs_common() -
5349 * Main routine of cmp_abs(). This function can be used by both
5350 * NumericVar and Numeric.
5354 cmp_abs_common(const NumericDigit *var1digits, int var1ndigits, int var1weight,
5355 const NumericDigit *var2digits, int var2ndigits, int var2weight)
5360 /* Check any digits before the first common digit */
5362 while (var1weight > var2weight && i1 < var1ndigits)
5364 if (var1digits[i1++] != 0)
5368 while (var2weight > var1weight && i2 < var2ndigits)
5370 if (var2digits[i2++] != 0)
5375 /* At this point, either w1 == w2 or we've run out of digits */
5377 if (var1weight == var2weight)
5379 while (i1 < var1ndigits && i2 < var2ndigits)
5381 int stat = var1digits[i1++] - var2digits[i2++];
5393 * At this point, we've run out of digits on one side or the other; so any
5394 * remaining nonzero digits imply that side is larger
5396 while (i1 < var1ndigits)
5398 if (var1digits[i1++] != 0)
5401 while (i2 < var2ndigits)
5403 if (var2digits[i2++] != 0)
5414 * Add the absolute values of two variables into result.
5415 * result might point to one of the operands without danger.
5418 add_abs(NumericVar *var1, NumericVar *var2, NumericVar *result)
5420 NumericDigit *res_buf;
5421 NumericDigit *res_digits;
5433 /* copy these values into local vars for speed in inner loop */
5434 int var1ndigits = var1->ndigits;
5435 int var2ndigits = var2->ndigits;
5436 NumericDigit *var1digits = var1->digits;
5437 NumericDigit *var2digits = var2->digits;
5439 res_weight = Max(var1->weight, var2->weight) + 1;
5441 res_dscale = Max(var1->dscale, var2->dscale);
5443 /* Note: here we are figuring rscale in base-NBASE digits */
5444 rscale1 = var1->ndigits - var1->weight - 1;
5445 rscale2 = var2->ndigits - var2->weight - 1;
5446 res_rscale = Max(rscale1, rscale2);
5448 res_ndigits = res_rscale + res_weight + 1;
5449 if (res_ndigits <= 0)
5452 res_buf = digitbuf_alloc(res_ndigits + 1);
5453 res_buf[0] = 0; /* spare digit for later rounding */
5454 res_digits = res_buf + 1;
5456 i1 = res_rscale + var1->weight + 1;
5457 i2 = res_rscale + var2->weight + 1;
5458 for (i = res_ndigits - 1; i >= 0; i--)
5462 if (i1 >= 0 && i1 < var1ndigits)
5463 carry += var1digits[i1];
5464 if (i2 >= 0 && i2 < var2ndigits)
5465 carry += var2digits[i2];
5469 res_digits[i] = carry - NBASE;
5474 res_digits[i] = carry;
5479 Assert(carry == 0); /* else we failed to allow for carry out */
5481 digitbuf_free(result->buf);
5482 result->ndigits = res_ndigits;
5483 result->buf = res_buf;
5484 result->digits = res_digits;
5485 result->weight = res_weight;
5486 result->dscale = res_dscale;
5488 /* Remove leading/trailing zeroes */
5496 * Subtract the absolute value of var2 from the absolute value of var1
5497 * and store in result. result might point to one of the operands
5500 * ABS(var1) MUST BE GREATER OR EQUAL ABS(var2) !!!
5503 sub_abs(NumericVar *var1, NumericVar *var2, NumericVar *result)
5505 NumericDigit *res_buf;
5506 NumericDigit *res_digits;
5518 /* copy these values into local vars for speed in inner loop */
5519 int var1ndigits = var1->ndigits;
5520 int var2ndigits = var2->ndigits;
5521 NumericDigit *var1digits = var1->digits;
5522 NumericDigit *var2digits = var2->digits;
5524 res_weight = var1->weight;
5526 res_dscale = Max(var1->dscale, var2->dscale);
5528 /* Note: here we are figuring rscale in base-NBASE digits */
5529 rscale1 = var1->ndigits - var1->weight - 1;
5530 rscale2 = var2->ndigits - var2->weight - 1;
5531 res_rscale = Max(rscale1, rscale2);
5533 res_ndigits = res_rscale + res_weight + 1;
5534 if (res_ndigits <= 0)
5537 res_buf = digitbuf_alloc(res_ndigits + 1);
5538 res_buf[0] = 0; /* spare digit for later rounding */
5539 res_digits = res_buf + 1;
5541 i1 = res_rscale + var1->weight + 1;
5542 i2 = res_rscale + var2->weight + 1;
5543 for (i = res_ndigits - 1; i >= 0; i--)
5547 if (i1 >= 0 && i1 < var1ndigits)
5548 borrow += var1digits[i1];
5549 if (i2 >= 0 && i2 < var2ndigits)
5550 borrow -= var2digits[i2];
5554 res_digits[i] = borrow + NBASE;
5559 res_digits[i] = borrow;
5564 Assert(borrow == 0); /* else caller gave us var1 < var2 */
5566 digitbuf_free(result->buf);
5567 result->ndigits = res_ndigits;
5568 result->buf = res_buf;
5569 result->digits = res_digits;
5570 result->weight = res_weight;
5571 result->dscale = res_dscale;
5573 /* Remove leading/trailing zeroes */
5580 * Round the value of a variable to no more than rscale decimal digits
5581 * after the decimal point. NOTE: we allow rscale < 0 here, implying
5582 * rounding before the decimal point.
5585 round_var(NumericVar *var, int rscale)
5587 NumericDigit *digits = var->digits;
5592 var->dscale = rscale;
5594 /* decimal digits wanted */
5595 di = (var->weight + 1) * DEC_DIGITS + rscale;
5598 * If di = 0, the value loses all digits, but could round up to 1 if its
5599 * first extra digit is >= 5. If di < 0 the result must be 0.
5605 var->sign = NUMERIC_POS;
5609 /* NBASE digits wanted */
5610 ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS;
5612 /* 0, or number of decimal digits to keep in last NBASE digit */
5615 if (ndigits < var->ndigits ||
5616 (ndigits == var->ndigits && di > 0))
5618 var->ndigits = ndigits;
5621 /* di must be zero */
5622 carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0;
5625 carry = (digits[ndigits] >= HALF_NBASE) ? 1 : 0;
5628 /* Must round within last NBASE digit */
5633 pow10 = round_powers[di];
5634 #elif DEC_DIGITS == 2
5637 #error unsupported NBASE
5639 extra = digits[--ndigits] % pow10;
5640 digits[ndigits] -= extra;
5642 if (extra >= pow10 / 2)
5644 pow10 += digits[ndigits];
5650 digits[ndigits] = pow10;
5655 /* Propagate carry if needed */
5658 carry += digits[--ndigits];
5661 digits[ndigits] = carry - NBASE;
5666 digits[ndigits] = carry;
5673 Assert(ndigits == -1); /* better not have added > 1 digit */
5674 Assert(var->digits > var->buf);
5686 * Truncate (towards zero) the value of a variable at rscale decimal digits
5687 * after the decimal point. NOTE: we allow rscale < 0 here, implying
5688 * truncation before the decimal point.
5691 trunc_var(NumericVar *var, int rscale)
5696 var->dscale = rscale;
5698 /* decimal digits wanted */
5699 di = (var->weight + 1) * DEC_DIGITS + rscale;
5702 * If di <= 0, the value loses all digits.
5708 var->sign = NUMERIC_POS;
5712 /* NBASE digits wanted */
5713 ndigits = (di + DEC_DIGITS - 1) / DEC_DIGITS;
5715 if (ndigits <= var->ndigits)
5717 var->ndigits = ndigits;
5720 /* no within-digit stuff to worry about */
5722 /* 0, or number of decimal digits to keep in last NBASE digit */
5727 /* Must truncate within last NBASE digit */
5728 NumericDigit *digits = var->digits;
5733 pow10 = round_powers[di];
5734 #elif DEC_DIGITS == 2
5737 #error unsupported NBASE
5739 extra = digits[--ndigits] % pow10;
5740 digits[ndigits] -= extra;
5750 * Strip any leading and trailing zeroes from a numeric variable
5753 strip_var(NumericVar *var)
5755 NumericDigit *digits = var->digits;
5756 int ndigits = var->ndigits;
5758 /* Strip leading zeroes */
5759 while (ndigits > 0 && *digits == 0)
5766 /* Strip trailing zeroes */
5767 while (ndigits > 0 && digits[ndigits - 1] == 0)
5770 /* If it's zero, normalize the sign and weight */
5773 var->sign = NUMERIC_POS;
5777 var->digits = digits;
5778 var->ndigits = ndigits;