Have numeric 0 ^ 4.3 return 1, rather than an error, and have 0 ^ 0.0
authorBruce Momjian <bruce@momjian.us>
Thu, 8 May 2008 19:25:38 +0000 (19:25 +0000)
committerBruce Momjian <bruce@momjian.us>
Thu, 8 May 2008 19:25:38 +0000 (19:25 +0000)
return 1, rather than error.

This was already the float8 behavior.

src/backend/utils/adt/numeric.c

index c5801ade2a06cc2163c85c24766489ea7cc154a1..defdc623cdc63a6c855d2205bd2cb4391e64a428 100644 (file)
@@ -14,7 +14,7 @@
  * Copyright (c) 1998-2008, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.110 2008/04/21 00:26:45 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/utils/adt/numeric.c,v 1.111 2008/05/08 19:25:38 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -5170,6 +5170,21 @@ power_var(NumericVar *base, NumericVar *exp, NumericVar *result)
    int         local_rscale;
    double      val;
 
+   /*
+    *  This avoids log(0) for cases of 0 raised to a non-integer.
+    *  Also, while 0 ^ 0 can be either 1 or indeterminate (error), we
+    *  treat it as one because most programming languages do this.
+    *  http://en.wikipedia.org/wiki/Exponentiation#Zero_to_the_zero_power
+    */
+   if (cmp_var(base, &const_zero) == 0)
+   {
+       if (cmp_var(exp, &const_zero) == 0)
+           set_var_from_var(&const_one, result);
+       else
+           set_var_from_var(&const_zero, result);
+       return;
+   }
+   
    /* If exp can be represented as an integer, use power_var_int */
    if (exp->ndigits == 0 || exp->ndigits <= exp->weight + 1)
    {
@@ -5266,15 +5281,9 @@ power_var_int(NumericVar *base, int exp, NumericVar *result, int rscale)
    NumericVar  base_prod;
    int         local_rscale;
 
-   /* Detect some special cases, particularly 0^0. */
-
    switch (exp)
    {
        case 0:
-           if (base->ndigits == 0)
-               ereport(ERROR,
-                       (errcode(ERRCODE_FLOATING_POINT_EXCEPTION),
-                        errmsg("zero raised to zero is undefined")));
            set_var_from_var(&const_one, result);
            result->dscale = rscale;    /* no need to round */
            return;