aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/numeric.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/numeric.c')
-rw-r--r--src/backend/utils/adt/numeric.c126
1 files changed, 66 insertions, 60 deletions
diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c
index 4d46992e403..36e333e1217 100644
--- a/src/backend/utils/adt/numeric.c
+++ b/src/backend/utils/adt/numeric.c
@@ -5,7 +5,7 @@
*
* 1998 Jan Wieck
*
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/numeric.c,v 1.26 2000/03/13 02:31:13 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/numeric.c,v 1.27 2000/04/12 17:15:50 momjian Exp $
*
* ----------
*/
@@ -59,8 +59,8 @@
* *after* the decimal point. Scales are always >= 0.)
*
* buf points at the physical start of the palloc'd digit buffer for the
- * NumericVar. digits points at the first digit in actual use (the one
- * with the specified weight). We normally leave an unused byte or two
+ * NumericVar. digits points at the first digit in actual use (the one
+ * with the specified weight). We normally leave an unused byte or two
* (preset to zeroes) between buf and digits, so that there is room to store
* a carry out of the top digit without special pushups. We just need to
* decrement digits (and increment weight) to make room for the carry digit.
@@ -77,11 +77,13 @@ typedef unsigned char NumericDigit;
typedef struct NumericVar
{
- int ndigits; /* number of digits in digits[] - can be 0! */
+ int ndigits; /* number of digits in digits[] - can be
+ * 0! */
int weight; /* weight of first digit */
int rscale; /* result scale */
int dscale; /* display scale */
- int sign; /* NUMERIC_POS, NUMERIC_NEG, or NUMERIC_NAN */
+ int sign; /* NUMERIC_POS, NUMERIC_NEG, or
+ * NUMERIC_NAN */
NumericDigit *buf; /* start of palloc'd space for digits[] */
NumericDigit *digits; /* decimal digits */
} NumericVar;
@@ -122,13 +124,14 @@ static NumericVar const_nan =
#ifdef NUMERIC_DEBUG
static void dump_numeric(char *str, Numeric num);
static void dump_var(char *str, NumericVar *var);
+
#else
#define dump_numeric(s,n)
#define dump_var(s,v)
#endif
#define digitbuf_alloc(size) ((NumericDigit *) palloc(size))
-#define digitbuf_free(buf) \
+#define digitbuf_free(buf) \
do { \
if ((buf) != NULL) \
pfree(buf); \
@@ -535,16 +538,16 @@ numeric_round(Numeric num, int32 scale)
if (i < arg.ndigits)
{
- /* If i = 0, the value loses all digits, but could round up if its
- * first digit is more than 4. If i < 0 the result must be 0.
+
+ /*
+ * If i = 0, the value loses all digits, but could round up if its
+ * first digit is more than 4. If i < 0 the result must be 0.
*/
if (i < 0)
- {
arg.ndigits = 0;
- }
else
{
- int carry = (arg.digits[i] > 4) ? 1 : 0;
+ int carry = (arg.digits[i] > 4) ? 1 : 0;
arg.ndigits = i;
@@ -557,7 +560,7 @@ numeric_round(Numeric num, int32 scale)
if (i < 0)
{
- Assert(i == -1); /* better not have added more than 1 digit */
+ Assert(i == -1);/* better not have added more than 1 digit */
Assert(arg.digits > arg.buf);
arg.digits--;
arg.ndigits++;
@@ -728,10 +731,10 @@ numeric_cmp(Numeric num1, Numeric num2)
NumericVar arg2;
if (num1 == NULL || num2 == NULL)
- return (int32)0;
+ return (int32) 0;
if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
- return (int32)0;
+ return (int32) 0;
init_var(&arg1);
init_var(&arg2);
@@ -744,7 +747,7 @@ numeric_cmp(Numeric num1, Numeric num2)
free_var(&arg1);
free_var(&arg2);
- return (int32)((result == 0) ? 0 : ((result < 0) ? -1 : 1));
+ return (int32) ((result == 0) ? 0 : ((result < 0) ? -1 : 1));
}
@@ -1742,7 +1745,7 @@ numeric_int4(Numeric num)
init_var(&x);
set_var_from_num(num, &x);
- str = get_str_from_var(&x, 0); /* dscale = 0 produces rounding */
+ str = get_str_from_var(&x, 0); /* dscale = 0 produces rounding */
free_var(&x);
@@ -1793,7 +1796,7 @@ numeric_int8(Numeric num)
init_var(&x);
set_var_from_num(num, &x);
- str = get_str_from_var(&x, 0); /* dscale = 0 produces rounding */
+ str = get_str_from_var(&x, 0); /* dscale = 0 produces rounding */
free_var(&x);
@@ -1844,7 +1847,7 @@ numeric_int2(Numeric num)
init_var(&x);
set_var_from_num(num, &x);
- str = get_str_from_var(&x, 0); /* dscale = 0 produces rounding */
+ str = get_str_from_var(&x, 0); /* dscale = 0 produces rounding */
free_var(&x);
@@ -2130,7 +2133,7 @@ set_var_from_str(char *str, NumericVar *dest)
cp++;
}
- if (! isdigit(*cp))
+ if (!isdigit(*cp))
elog(ERROR, "Bad numeric input format '%s'", str);
while (*cp)
@@ -2158,8 +2161,8 @@ set_var_from_str(char *str, NumericVar *dest)
/* Handle exponent, if any */
if (*cp == 'e' || *cp == 'E')
{
- long exponent;
- char *endptr;
+ long exponent;
+ char *endptr;
cp++;
exponent = strtol(cp, &endptr, 10);
@@ -2210,7 +2213,8 @@ set_var_from_num(Numeric num, NumericVar *dest)
int i;
int n;
- n = num->varlen - NUMERIC_HDRSZ; /* number of digit-pairs in packed fmt */
+ n = num->varlen - NUMERIC_HDRSZ; /* number of digit-pairs in packed
+ * fmt */
alloc_var(dest, n * 2);
@@ -2224,6 +2228,7 @@ set_var_from_num(Numeric num, NumericVar *dest)
for (i = 0; i < n; i++)
{
unsigned char digitpair = num->n_data[i];
+
*digit++ = (digitpair >> 4) & 0x0f;
*digit++ = digitpair & 0x0f;
}
@@ -2278,7 +2283,7 @@ get_str_from_var(NumericVar *var, int dscale)
i = dscale + var->weight + 1;
if (i >= 0 && var->ndigits > i)
{
- int carry = (var->digits[i] > 4) ? 1 : 0;
+ int carry = (var->digits[i] > 4) ? 1 : 0;
var->ndigits = i;
@@ -2421,6 +2426,7 @@ make_result(NumericVar *var)
while (j < n)
{
unsigned char digitpair = digit[j++] << 4;
+
if (j < n)
digitpair |= digit[j++];
result->n_data[i++] = digitpair;
@@ -2459,7 +2465,7 @@ apply_typmod(NumericVar *var, int32 typmod)
i = scale + var->weight + 1;
if (i >= 0 && var->ndigits > i)
{
- int carry = (var->digits[i] > 4) ? 1 : 0;
+ int carry = (var->digits[i] > 4) ? 1 : 0;
var->ndigits = i;
@@ -2494,7 +2500,7 @@ apply_typmod(NumericVar *var, int32 typmod)
if (var->weight >= maxweight)
{
/* Determine true weight; and check for all-zero result */
- int tweight = var->weight;
+ int tweight = var->weight;
for (i = 0; i < var->ndigits; i++)
{
@@ -2502,10 +2508,10 @@ apply_typmod(NumericVar *var, int32 typmod)
break;
tweight--;
}
-
+
if (tweight >= maxweight && i < var->ndigits)
elog(ERROR, "overflow on numeric "
- "ABS(value) >= 10^%d for field with precision %d scale %d",
+ "ABS(value) >= 10^%d for field with precision %d scale %d",
tweight, precision, scale);
}
@@ -2588,20 +2594,20 @@ add_var(NumericVar *var1, NumericVar *var2, NumericVar *result)
switch (cmp_abs(var1, var2))
{
case 0: /* ----------
- * ABS(var1) == ABS(var2)
- * result = ZERO
- * ----------
- */
+ * ABS(var1) == ABS(var2)
+ * result = ZERO
+ * ----------
+ */
zero_var(result);
result->rscale = MAX(var1->rscale, var2->rscale);
result->dscale = MAX(var1->dscale, var2->dscale);
break;
case 1: /* ----------
- * ABS(var1) > ABS(var2)
- * result = +(ABS(var1) - ABS(var2))
- * ----------
- */
+ * ABS(var1) > ABS(var2)
+ * result = +(ABS(var1) - ABS(var2))
+ * ----------
+ */
sub_abs(var1, var2, result);
result->sign = NUMERIC_POS;
break;
@@ -2629,20 +2635,20 @@ add_var(NumericVar *var1, NumericVar *var2, NumericVar *result)
switch (cmp_abs(var1, var2))
{
case 0: /* ----------
- * ABS(var1) == ABS(var2)
- * result = ZERO
- * ----------
- */
+ * ABS(var1) == ABS(var2)
+ * result = ZERO
+ * ----------
+ */
zero_var(result);
result->rscale = MAX(var1->rscale, var2->rscale);
result->dscale = MAX(var1->dscale, var2->dscale);
break;
case 1: /* ----------
- * ABS(var1) > ABS(var2)
- * result = -(ABS(var1) - ABS(var2))
- * ----------
- */
+ * ABS(var1) > ABS(var2)
+ * result = -(ABS(var1) - ABS(var2))
+ * ----------
+ */
sub_abs(var1, var2, result);
result->sign = NUMERIC_NEG;
break;
@@ -2707,20 +2713,20 @@ sub_var(NumericVar *var1, NumericVar *var2, NumericVar *result)
switch (cmp_abs(var1, var2))
{
case 0: /* ----------
- * ABS(var1) == ABS(var2)
- * result = ZERO
- * ----------
- */
+ * ABS(var1) == ABS(var2)
+ * result = ZERO
+ * ----------
+ */
zero_var(result);
result->rscale = MAX(var1->rscale, var2->rscale);
result->dscale = MAX(var1->dscale, var2->dscale);
break;
case 1: /* ----------
- * ABS(var1) > ABS(var2)
- * result = +(ABS(var1) - ABS(var2))
- * ----------
- */
+ * ABS(var1) > ABS(var2)
+ * result = +(ABS(var1) - ABS(var2))
+ * ----------
+ */
sub_abs(var1, var2, result);
result->sign = NUMERIC_POS;
break;
@@ -2748,20 +2754,20 @@ sub_var(NumericVar *var1, NumericVar *var2, NumericVar *result)
switch (cmp_abs(var1, var2))
{
case 0: /* ----------
- * ABS(var1) == ABS(var2)
- * result = ZERO
- * ----------
- */
+ * ABS(var1) == ABS(var2)
+ * result = ZERO
+ * ----------
+ */
zero_var(result);
result->rscale = MAX(var1->rscale, var2->rscale);
result->dscale = MAX(var1->dscale, var2->dscale);
break;
case 1: /* ----------
- * ABS(var1) > ABS(var2)
- * result = -(ABS(var1) - ABS(var2))
- * ----------
- */
+ * ABS(var1) > ABS(var2)
+ * result = -(ABS(var1) - ABS(var2))
+ * ----------
+ */
sub_abs(var1, var2, result);
result->sign = NUMERIC_NEG;
break;
@@ -3054,7 +3060,7 @@ div_var(NumericVar *var1, NumericVar *var2, NumericVar *result)
result->ndigits = ri + 1;
if (ri == res_ndigits + 1)
{
- int carry = (res_digits[ri] > 4) ? 1 : 0;
+ int carry = (res_digits[ri] > 4) ? 1 : 0;
result->ndigits = ri;
res_digits[ri] = 0;