[Moving this to -hackers]

> On 13/10/2022 18:20 CEST Adrian Klaver <adrian.kla...@aklaver.com> wrote:
> > select power(10, -18::numeric);
> > power
> > --------------------
> > 0.0000000000000000
> >

On Thu, 13 Oct 2022 at 18:17, Tom Lane <t...@sss.pgh.pa.us> wrote:
>
> An inexact result isn't surprising, but it shouldn't be *that* inexact.
>
> I'm inclined to think that we should push the responsibility for choosing
> its rscale into power_var_int(), because internally that already does
> estimate the result weight, so with a little code re-ordering we won't
> need duplicative estimates.  Don't have time to work on that right now
> though ... Dean, are you interested in fixing this?
>

Here's a patch along those lines, bringing power_var_int() more in
line with neighbouring functions by having it choose its own result
scale.

It was necessary to also move the overflow/underflow tests up, in
order to avoid a potential integer overflow when deciding the rscale.

Looking more closely at the upper limit of the overflow test, it turns
out it was far too large. I'm not sure where the "3 * SHRT_MAX" came
from, but I suspect it was just a thinko on my part, back in
7d9a4737c2. I've replaced that with SHRT_MAX + 1, which kicks in much
sooner without changing the actual maximum result allowed, which is <
10^131072 (the absolute upper limit of the numeric type).

The first half the the underflow test condition "f + 1 < -rscale" goes
away, since this is now being done before rscale is computed, and the
choice of rscale makes that condition false. In fact, the new choice
of rscale now ensures that when sig_digits is computed further down,
it is guaranteed to be strictly greater than 0, rather than merely
being >= 0 as before, which is good.

As expected, various regression test results change, since the number
of significant digits computed is now different, but I think the new
results look a lot better, and more consistent. I regenerated the
numeric_big test results by re-running the bc script and rounding to
the new output precisions, and the results from power_var_int()
exactly match in every case. This already included a number of cases
that used to round to zero, and now produce much more reasonable
results.

The test cases where the result actually does round to zero now output
1000 zeros after the decimal point. That looks a little messy, but I
think it's the right thing to do in fixed-point arithmetic -- it's
consistent with the fractional power case, and with exp(numeric),
reflecting the fact that the result is zero to 1000 decimal places,
whilst not being exactly zero.

Overall, I'm quite happy with these results. The question is, should
this be back-patched?

In the past, I think I've only back-patched numeric bug-fixes where
the digits output by the old code were incorrect or an error was
thrown, not changes that resulted in a different number of digits
being output, changing the precision of already-correct results.
However, having 10.0^(-18) produce zero seems pretty bad, so my
inclination is to back-patch, unless anyone objects.

Regards,
Dean
diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c
new file mode 100644
index cafe1ac..af0d94b
--- a/src/backend/utils/adt/numeric.c
+++ b/src/backend/utils/adt/numeric.c
@@ -571,8 +571,7 @@ static void log_var(const NumericVar *ba
 					NumericVar *result);
 static void power_var(const NumericVar *base, const NumericVar *exp,
 					  NumericVar *result);
-static void power_var_int(const NumericVar *base, int exp, NumericVar *result,
-						  int rscale);
+static void power_var_int(const NumericVar *base, int exp, NumericVar *result);
 static void power_ten_int(int exp, NumericVar *result);
 
 static int	cmp_abs(const NumericVar *var1, const NumericVar *var2);
@@ -10335,13 +10334,8 @@ power_var(const NumericVar *base, const
 		{
 			if (expval64 >= PG_INT32_MIN && expval64 <= PG_INT32_MAX)
 			{
-				/* Okay, select rscale */
-				rscale = NUMERIC_MIN_SIG_DIGITS;
-				rscale = Max(rscale, base->dscale);
-				rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
-				rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
-
-				power_var_int(base, (int) expval64, result, rscale);
+				/* Okay, use power_var_int */
+				power_var_int(base, (int) expval64, result);
 				return;
 			}
 		}
@@ -10475,19 +10469,74 @@ power_var(const NumericVar *base, const
  * power_var_int() -
  *
  *	Raise base to the power of exp, where exp is an integer.
+ *
+ *	Note: this routine chooses dscale of the result.
  */
 static void
-power_var_int(const NumericVar *base, int exp, NumericVar *result, int rscale)
+power_var_int(const NumericVar *base, int exp, NumericVar *result)
 {
 	double		f;
 	int			p;
 	int			i;
+	int			rscale;
 	int			sig_digits;
 	unsigned int mask;
 	bool		neg;
 	NumericVar	base_prod;
 	int			local_rscale;
 
+	/*
+	 * Choose the result scale.  For this we need an estimate of the decimal
+	 * weight of the result, which we obtain by approximating using double
+	 * precision arithmetic.
+	 *
+	 * We also perform crude overflow/underflow tests here so that we can exit
+	 * early if the result is sure to overflow/underflow, and to guard against
+	 * integer overflow when choosing the result scale.
+	 */
+	if (base->ndigits != 0)
+	{
+		/*----------
+		 * Choose f (double) and p (int) such that base ~= f * 10^p.
+		 * Then log10(result) = log10(base^exp) ~= exp * (log10(f) + p).
+		 *----------
+		 */
+		f = base->digits[0];
+		p = base->weight * DEC_DIGITS;
+
+		for (i = 1; i < base->ndigits && i * DEC_DIGITS < 16; i++)
+		{
+			f = f * NBASE + base->digits[i];
+			p -= DEC_DIGITS;
+		}
+
+		f = exp * (log10(f) + p);	/* approximate decimal result weight */
+	}
+	else
+		f = 0;					/* result is 0 or 1 (weight 0), or error */
+
+	/* overflow/underflow tests with fuzz factors */
+	if (f > (SHRT_MAX + 1) * DEC_DIGITS)
+		ereport(ERROR,
+				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+				 errmsg("value overflows numeric format")));
+	if (f + 1 < -NUMERIC_MAX_DISPLAY_SCALE)
+	{
+		zero_var(result);
+		result->dscale = NUMERIC_MAX_DISPLAY_SCALE;
+		return;
+	}
+
+	/*
+	 * Choose the result scale in the same way as power_var(), so it has at
+	 * least NUMERIC_MIN_SIG_DIGITS significant digits and is not less than
+	 * dscale of base.
+	 */
+	rscale = NUMERIC_MIN_SIG_DIGITS - (int) f;
+	rscale = Max(rscale, base->dscale);
+	rscale = Max(rscale, NUMERIC_MIN_DISPLAY_SCALE);
+	rscale = Min(rscale, NUMERIC_MAX_DISPLAY_SCALE);
+
 	/* Handle some common special cases, as well as corner cases */
 	switch (exp)
 	{
@@ -10532,43 +10581,15 @@ power_var_int(const NumericVar *base, in
 	 * The general case repeatedly multiplies base according to the bit
 	 * pattern of exp.
 	 *
-	 * First we need to estimate the weight of the result so that we know how
-	 * many significant digits are needed.
-	 */
-	f = base->digits[0];
-	p = base->weight * DEC_DIGITS;
-
-	for (i = 1; i < base->ndigits && i * DEC_DIGITS < 16; i++)
-	{
-		f = f * NBASE + base->digits[i];
-		p -= DEC_DIGITS;
-	}
-
-	/*----------
-	 * We have base ~= f * 10^p
-	 * so log10(result) = log10(base^exp) ~= exp * (log10(f) + p)
-	 *----------
-	 */
-	f = exp * (log10(f) + p);
-
-	/*
-	 * Apply crude overflow/underflow tests so we can exit early if the result
-	 * certainly will overflow/underflow.
+	 * The local rscale used for each multiplication is varied to keep a fixed
+	 * number of significant digits, sufficient to give the required result
+	 * scale.
 	 */
-	if (f > 3 * SHRT_MAX * DEC_DIGITS)
-		ereport(ERROR,
-				(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
-				 errmsg("value overflows numeric format")));
-	if (f + 1 < -rscale || f + 1 < -NUMERIC_MAX_DISPLAY_SCALE)
-	{
-		zero_var(result);
-		result->dscale = rscale;
-		return;
-	}
 
 	/*
 	 * Approximate number of significant digits in the result.  Note that the
-	 * underflow test above means that this is necessarily >= 0.
+	 * underflow test above, together with the choice of rscale, ensures that
+	 * this is necessarily > 0.
 	 */
 	sig_digits = 1 + rscale + (int) f;
 
diff --git a/src/test/regress/expected/numeric.out b/src/test/regress/expected/numeric.out
new file mode 100644
index e224eff..dc3238f
--- a/src/test/regress/expected/numeric.out
+++ b/src/test/regress/expected/numeric.out
@@ -952,44 +952,44 @@ WITH v(x) AS
 SELECT x1, x2,
   power(x1, x2)
 FROM v AS v1(x1), v AS v2(x2) WHERE x1 != 0 OR x2 >= 0;
-    x1    |    x2    |        power        
-----------+----------+---------------------
-        0 |        0 |  1.0000000000000000
-        0 |        1 |  0.0000000000000000
-        0 |        2 |  0.0000000000000000
-        0 |      4.2 |  0.0000000000000000
-        0 | Infinity |                   0
-        0 |      NaN |                 NaN
-        1 |        0 |  1.0000000000000000
-        1 |        1 |  1.0000000000000000
-        1 |        2 |  1.0000000000000000
-        1 |      4.2 |  1.0000000000000000
-        1 | Infinity |                   1
-        1 |      NaN |                   1
-        2 |        0 |  1.0000000000000000
-        2 |        1 |  2.0000000000000000
-        2 |        2 |  4.0000000000000000
-        2 |      4.2 |  18.379173679952560
-        2 | Infinity |            Infinity
-        2 |      NaN |                 NaN
-      4.2 |        0 |  1.0000000000000000
-      4.2 |        1 |  4.2000000000000000
-      4.2 |        2 | 17.6400000000000000
-      4.2 |      4.2 |  414.61691860129675
-      4.2 | Infinity |            Infinity
-      4.2 |      NaN |                 NaN
- Infinity |        0 |                   1
- Infinity |        1 |            Infinity
- Infinity |        2 |            Infinity
- Infinity |      4.2 |            Infinity
- Infinity | Infinity |            Infinity
- Infinity |      NaN |                 NaN
-      NaN |        0 |                   1
-      NaN |        1 |                 NaN
-      NaN |        2 |                 NaN
-      NaN |      4.2 |                 NaN
-      NaN | Infinity |                 NaN
-      NaN |      NaN |                 NaN
+    x1    |    x2    |       power        
+----------+----------+--------------------
+        0 |        0 | 1.0000000000000000
+        0 |        1 | 0.0000000000000000
+        0 |        2 | 0.0000000000000000
+        0 |      4.2 | 0.0000000000000000
+        0 | Infinity |                  0
+        0 |      NaN |                NaN
+        1 |        0 | 1.0000000000000000
+        1 |        1 | 1.0000000000000000
+        1 |        2 | 1.0000000000000000
+        1 |      4.2 | 1.0000000000000000
+        1 | Infinity |                  1
+        1 |      NaN |                  1
+        2 |        0 | 1.0000000000000000
+        2 |        1 | 2.0000000000000000
+        2 |        2 | 4.0000000000000000
+        2 |      4.2 | 18.379173679952560
+        2 | Infinity |           Infinity
+        2 |      NaN |                NaN
+      4.2 |        0 | 1.0000000000000000
+      4.2 |        1 | 4.2000000000000000
+      4.2 |        2 | 17.640000000000000
+      4.2 |      4.2 | 414.61691860129675
+      4.2 | Infinity |           Infinity
+      4.2 |      NaN |                NaN
+ Infinity |        0 |                  1
+ Infinity |        1 |           Infinity
+ Infinity |        2 |           Infinity
+ Infinity |      4.2 |           Infinity
+ Infinity | Infinity |           Infinity
+ Infinity |      NaN |                NaN
+      NaN |        0 |                  1
+      NaN |        1 |                NaN
+      NaN |        2 |                NaN
+      NaN |      4.2 |                NaN
+      NaN | Infinity |                NaN
+      NaN |      NaN |                NaN
 (36 rows)
 
 SELECT power('0'::numeric, '-1');
@@ -2431,15 +2431,15 @@ select sqrt(8015491789940783531003294973
 -- Test code path for raising to integer powers
 --
 select 10.0 ^ -2147483648 as rounds_to_zero;
-   rounds_to_zero   
---------------------
- 0.0000000000000000
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               rounds_to_zero                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 (1 row)
 
 select 10.0 ^ -2147483647 as rounds_to_zero;
-   rounds_to_zero   
---------------------
- 0.0000000000000000
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               rounds_to_zero                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 (1 row)
 
 select 10.0 ^ 2147483647 as overflows;
@@ -2448,27 +2448,27 @@ select 117743296169.0 ^ 1000000000 as ov
 ERROR:  value overflows numeric format
 -- cases that used to return inaccurate results
 select 3.789 ^ 21;
-            ?column?            
---------------------------------
- 1409343026052.8716016316022141
+      ?column?      
+--------------------
+ 1409343026052.8716
 (1 row)
 
 select 3.789 ^ 35;
-                ?column?                
-----------------------------------------
- 177158169650516670809.3820586142670135
+         ?column?          
+---------------------------
+ 177158169650516670809.382
 (1 row)
 
 select 1.2 ^ 345;
-                   ?column?                    
------------------------------------------------
- 2077446682327378559843444695.5827049735727869
+            ?column?            
+--------------------------------
+ 2077446682327378559843444695.6
 (1 row)
 
 select 0.12 ^ (-20);
-               ?column?               
---------------------------------------
- 2608405330458882702.5529619561355838
+        ?column?        
+------------------------
+ 2608405330458882702.55
 (1 row)
 
 select 1.000000000123 ^ (-2147483648);
@@ -2491,15 +2491,15 @@ select round(((1 - 1.500012345678e-1000)
 
 -- cases that used to error out
 select 0.12 ^ (-25);
-                 ?column?                  
--------------------------------------------
- 104825960103961013959336.4983657883169110
+          ?column?           
+-----------------------------
+ 104825960103961013959336.50
 (1 row)
 
 select 0.5678 ^ (-85);
-                ?column?                
-----------------------------------------
- 782333637740774446257.7719390061997396
+          ?column?          
+----------------------------
+ 782333637740774446257.7719
 (1 row)
 
 select coalesce(nullif(0.9999999999 ^ 70000000000000, 0), 0) as underflows;
@@ -2539,6 +2539,54 @@ select (-1.0) ^ 1000000000000001;
  -1.0000000000000000
 (1 row)
 
+-- integer powers of 10
+select n, 10.0 ^ n as "10^n", (10.0 ^ n) * (10.0 ^ (-n)) = 1 as ok
+from generate_series(-20, 20) n;
+  n  |                  10^n                  | ok 
+-----+----------------------------------------+----
+ -20 | 0.000000000000000000010000000000000000 | t
+ -19 |  0.00000000000000000010000000000000000 | t
+ -18 |   0.0000000000000000010000000000000000 | t
+ -17 |    0.000000000000000010000000000000000 | t
+ -16 |     0.00000000000000010000000000000000 | t
+ -15 |      0.0000000000000010000000000000000 | t
+ -14 |       0.000000000000010000000000000000 | t
+ -13 |        0.00000000000010000000000000000 | t
+ -12 |         0.0000000000010000000000000000 | t
+ -11 |          0.000000000010000000000000000 | t
+ -10 |           0.00000000010000000000000000 | t
+  -9 |            0.0000000010000000000000000 | t
+  -8 |             0.000000010000000000000000 | t
+  -7 |              0.00000010000000000000000 | t
+  -6 |               0.0000010000000000000000 | t
+  -5 |                0.000010000000000000000 | t
+  -4 |                 0.00010000000000000000 | t
+  -3 |                  0.0010000000000000000 | t
+  -2 |                   0.010000000000000000 | t
+  -1 |                    0.10000000000000000 | t
+   0 |                     1.0000000000000000 | t
+   1 |                     10.000000000000000 | t
+   2 |                     100.00000000000000 | t
+   3 |                     1000.0000000000000 | t
+   4 |                     10000.000000000000 | t
+   5 |                     100000.00000000000 | t
+   6 |                     1000000.0000000000 | t
+   7 |                     10000000.000000000 | t
+   8 |                     100000000.00000000 | t
+   9 |                     1000000000.0000000 | t
+  10 |                     10000000000.000000 | t
+  11 |                     100000000000.00000 | t
+  12 |                     1000000000000.0000 | t
+  13 |                     10000000000000.000 | t
+  14 |                     100000000000000.00 | t
+  15 |                     1000000000000000.0 | t
+  16 |                    10000000000000000.0 | t
+  17 |                   100000000000000000.0 | t
+  18 |                  1000000000000000000.0 | t
+  19 |                 10000000000000000000.0 | t
+  20 |                100000000000000000000.0 | t
+(41 rows)
+
 --
 -- Tests for raising to non-integer powers
 --
@@ -2630,9 +2678,9 @@ select 12.3 ^ (-45.6);
 
 -- big test
 select 1.234 ^ 5678;
-                                                                                                                                                                                                                                                                         ?column?                                                                                                                                                                                                                                                                         
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- 307239295662090741644584872593956173493568238595074141254349565406661439636598896798876823220904084953233015553994854875890890858118656468658643918169805277399402542281777901029346337707622181574346585989613344285010764501017625366742865066948856161360224801370482171458030533346309750557140549621313515752078638620714732831815297168231790779296290266207315344008883935010274044001522606235576584215999260117523114297033944018699691024106823438431754073086813382242140602291215149759520833200152654884259619588924545324.5973362312547382
+                                                                                                                                                                                                                                                                  ?column?                                                                                                                                                                                                                                                                   
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ 307239295662090741644584872593956173493568238595074141254349565406661439636598896798876823220904084953233015553994854875890890858118656468658643918169805277399402542281777901029346337707622181574346585989613344285010764501017625366742865066948856161360224801370482171458030533346309750557140549621313515752078638620714732831815297168231790779296290266207315344008883935010274044001522606235576584215999260117523114297033944018699691024106823438431754073086813382242140602291215149759520833200152654884259619588924545324.597
 (1 row)
 
 --
diff --git a/src/test/regress/expected/numeric_big.out b/src/test/regress/expected/numeric_big.out
new file mode 100644
index 468c602..12ff35b
--- a/src/test/regress/expected/numeric_big.out
+++ b/src/test/regress/expected/numeric_big.out
@@ -686,91 +686,91 @@ SELECT t1.id1, t1.result, t2.expected
 --   echo "($b, $p, $r),"
 -- done
 WITH t(b, p, bc_result) AS (VALUES
-(0.084738, -20, 2744326694304960114888.7859130502035257),
-(0.084738, -19, 232548755422013710215.4459407000481464),
-(0.084738, -18, 19705716436950597776.2364581230406798),
-(0.084738, -17, 1669822999434319754.3627249884302211),
-(0.084738, -16, 141497461326065387.3451885900696001),
-(0.084738, -15, 11990211877848128.7928565907453178),
-(0.084738, -14, 1016026574105094.7376490817865767),
-(0.084738, -13, 86096059836517.5178789078924309),
-(0.084738, -12, 7295607918426.8214300228969888),
-(0.084738, -11, 618215223791.6519943372802450),
-(0.084738, -10, 52386321633.6570066961524534),
-(0.084738, -9, 4439112122.5928274334185666),
-(0.084738, -8, 376161483.0442710110530225),
-(0.084738, -7, 31875171.7502054369346110),
-(0.084738, -6, 2701038.3037689083149651),
-(0.084738, -5, 228880.5837847697527935),
-(0.084738, -4, 19394.8829087538193122),
-(0.084738, -3, 1643.4835879219811409),
-(0.084738, -2, 139.2655122733328379),
-(0.084738, -1, 11.8010809790176780),
+(0.084738, -20, 2744326694304960114888.785913),
+(0.084738, -19, 232548755422013710215.445941),
+(0.084738, -18, 19705716436950597776.236458),
+(0.084738, -17, 1669822999434319754.362725),
+(0.084738, -16, 141497461326065387.345189),
+(0.084738, -15, 11990211877848128.792857),
+(0.084738, -14, 1016026574105094.737649),
+(0.084738, -13, 86096059836517.517879),
+(0.084738, -12, 7295607918426.821430),
+(0.084738, -11, 618215223791.651994),
+(0.084738, -10, 52386321633.657007),
+(0.084738, -9, 4439112122.5928274),
+(0.084738, -8, 376161483.04427101),
+(0.084738, -7, 31875171.750205437),
+(0.084738, -6, 2701038.3037689083),
+(0.084738, -5, 228880.58378476975),
+(0.084738, -4, 19394.882908753819),
+(0.084738, -3, 1643.4835879219811),
+(0.084738, -2, 139.26551227333284),
+(0.084738, -1, 11.801080979017678),
 (0.084738, 0, 1),
 (0.084738, 1, .084738),
 (0.084738, 2, .007180528644),
-(0.084738, 3, .0006084636362353),
-(0.084738, 4, .0000515599916073),
-(0.084738, 5, .0000043690905688),
-(0.084738, 6, .0000003702279966),
-(0.084738, 7, .0000000313723800),
-(0.084738, 8, .0000000026584327),
-(0.084738, 9, .0000000002252703),
-(0.084738, 10, .0000000000190890),
-(0.084738, 11, .0000000000016176),
-(0.084738, 12, .0000000000001371),
-(0.084738, 13, .0000000000000116),
-(0.084738, 14, .0000000000000010),
-(0.084738, 15, .0000000000000001),
-(0.084738, 16, .0000000000000000),
-(0.084738, 17, .0000000000000000),
-(0.084738, 18, .0000000000000000),
-(0.084738, 19, .0000000000000000),
-(0.084738, 20, .0000000000000000))
+(0.084738, 3, .000608463636235272),
+(0.084738, 4, .00005155999160730448),
+(0.084738, 5, .000004369090568819767),
+(0.084738, 6, .0000003702279966206494),
+(0.084738, 7, .00000003137237997764059),
+(0.084738, 8, .000000002658432734545308),
+(0.084738, 9, .0000000002252702730599003),
+(0.084738, 10, .00000000001908895239854983),
+(0.084738, 11, .000000000001617559648348316),
+(0.084738, 12, .0000000000001370687694817396),
+(0.084738, 13, .00000000000001161493338834365),
+(0.084738, 14, .0000000000000009842262254614642),
+(0.084738, 15, .00000000000000008340136189315355),
+(0.084738, 16, .000000000000000007067264604102046),
+(0.084738, 17, .0000000000000000005988658680223991),
+(0.084738, 18, .00000000000000000005074669592448206),
+(0.084738, 19, .000000000000000000004300173519248761),
+(0.084738, 20, .0000000000000000000003643881036741015))
 SELECT b, p, bc_result, b^p AS power, b^p - bc_result AS diff FROM t;
-    b     |  p  |                bc_result                |                  power                  |        diff        
-----------+-----+-----------------------------------------+-----------------------------------------+--------------------
- 0.084738 | -20 | 2744326694304960114888.7859130502035257 | 2744326694304960114888.7859130502035257 | 0.0000000000000000
- 0.084738 | -19 |  232548755422013710215.4459407000481464 |  232548755422013710215.4459407000481464 | 0.0000000000000000
- 0.084738 | -18 |   19705716436950597776.2364581230406798 |   19705716436950597776.2364581230406798 | 0.0000000000000000
- 0.084738 | -17 |    1669822999434319754.3627249884302211 |    1669822999434319754.3627249884302211 | 0.0000000000000000
- 0.084738 | -16 |     141497461326065387.3451885900696001 |     141497461326065387.3451885900696001 | 0.0000000000000000
- 0.084738 | -15 |      11990211877848128.7928565907453178 |      11990211877848128.7928565907453178 | 0.0000000000000000
- 0.084738 | -14 |       1016026574105094.7376490817865767 |       1016026574105094.7376490817865767 | 0.0000000000000000
- 0.084738 | -13 |         86096059836517.5178789078924309 |         86096059836517.5178789078924309 | 0.0000000000000000
- 0.084738 | -12 |          7295607918426.8214300228969888 |          7295607918426.8214300228969888 | 0.0000000000000000
- 0.084738 | -11 |           618215223791.6519943372802450 |           618215223791.6519943372802450 | 0.0000000000000000
- 0.084738 | -10 |            52386321633.6570066961524534 |            52386321633.6570066961524534 | 0.0000000000000000
- 0.084738 |  -9 |             4439112122.5928274334185666 |             4439112122.5928274334185666 | 0.0000000000000000
- 0.084738 |  -8 |              376161483.0442710110530225 |              376161483.0442710110530225 | 0.0000000000000000
- 0.084738 |  -7 |               31875171.7502054369346110 |               31875171.7502054369346110 | 0.0000000000000000
- 0.084738 |  -6 |                2701038.3037689083149651 |                2701038.3037689083149651 | 0.0000000000000000
- 0.084738 |  -5 |                 228880.5837847697527935 |                 228880.5837847697527935 | 0.0000000000000000
- 0.084738 |  -4 |                  19394.8829087538193122 |                  19394.8829087538193122 | 0.0000000000000000
- 0.084738 |  -3 |                   1643.4835879219811409 |                   1643.4835879219811409 | 0.0000000000000000
- 0.084738 |  -2 |                    139.2655122733328379 |                    139.2655122733328379 | 0.0000000000000000
- 0.084738 |  -1 |                     11.8010809790176780 |                     11.8010809790176780 | 0.0000000000000000
- 0.084738 |   0 |                                       1 |                      1.0000000000000000 | 0.0000000000000000
- 0.084738 |   1 |                                0.084738 |                      0.0847380000000000 | 0.0000000000000000
- 0.084738 |   2 |                          0.007180528644 |                      0.0071805286440000 | 0.0000000000000000
- 0.084738 |   3 |                      0.0006084636362353 |                      0.0006084636362353 | 0.0000000000000000
- 0.084738 |   4 |                      0.0000515599916073 |                      0.0000515599916073 | 0.0000000000000000
- 0.084738 |   5 |                      0.0000043690905688 |                      0.0000043690905688 | 0.0000000000000000
- 0.084738 |   6 |                      0.0000003702279966 |                      0.0000003702279966 | 0.0000000000000000
- 0.084738 |   7 |                      0.0000000313723800 |                      0.0000000313723800 | 0.0000000000000000
- 0.084738 |   8 |                      0.0000000026584327 |                      0.0000000026584327 | 0.0000000000000000
- 0.084738 |   9 |                      0.0000000002252703 |                      0.0000000002252703 | 0.0000000000000000
- 0.084738 |  10 |                      0.0000000000190890 |                      0.0000000000190890 | 0.0000000000000000
- 0.084738 |  11 |                      0.0000000000016176 |                      0.0000000000016176 | 0.0000000000000000
- 0.084738 |  12 |                      0.0000000000001371 |                      0.0000000000001371 | 0.0000000000000000
- 0.084738 |  13 |                      0.0000000000000116 |                      0.0000000000000116 | 0.0000000000000000
- 0.084738 |  14 |                      0.0000000000000010 |                      0.0000000000000010 | 0.0000000000000000
- 0.084738 |  15 |                      0.0000000000000001 |                      0.0000000000000001 | 0.0000000000000000
- 0.084738 |  16 |                      0.0000000000000000 |                      0.0000000000000000 | 0.0000000000000000
- 0.084738 |  17 |                      0.0000000000000000 |                      0.0000000000000000 | 0.0000000000000000
- 0.084738 |  18 |                      0.0000000000000000 |                      0.0000000000000000 | 0.0000000000000000
- 0.084738 |  19 |                      0.0000000000000000 |                      0.0000000000000000 | 0.0000000000000000
- 0.084738 |  20 |                      0.0000000000000000 |                      0.0000000000000000 | 0.0000000000000000
+    b     |  p  |                bc_result                |                  power                  |                  diff                   
+----------+-----+-----------------------------------------+-----------------------------------------+-----------------------------------------
+ 0.084738 | -20 |           2744326694304960114888.785913 |           2744326694304960114888.785913 |                                0.000000
+ 0.084738 | -19 |            232548755422013710215.445941 |            232548755422013710215.445941 |                                0.000000
+ 0.084738 | -18 |             19705716436950597776.236458 |             19705716436950597776.236458 |                                0.000000
+ 0.084738 | -17 |              1669822999434319754.362725 |              1669822999434319754.362725 |                                0.000000
+ 0.084738 | -16 |               141497461326065387.345189 |               141497461326065387.345189 |                                0.000000
+ 0.084738 | -15 |                11990211877848128.792857 |                11990211877848128.792857 |                                0.000000
+ 0.084738 | -14 |                 1016026574105094.737649 |                 1016026574105094.737649 |                                0.000000
+ 0.084738 | -13 |                   86096059836517.517879 |                   86096059836517.517879 |                                0.000000
+ 0.084738 | -12 |                    7295607918426.821430 |                    7295607918426.821430 |                                0.000000
+ 0.084738 | -11 |                     618215223791.651994 |                     618215223791.651994 |                                0.000000
+ 0.084738 | -10 |                      52386321633.657007 |                      52386321633.657007 |                                0.000000
+ 0.084738 |  -9 |                      4439112122.5928274 |                      4439112122.5928274 |                               0.0000000
+ 0.084738 |  -8 |                      376161483.04427101 |                      376161483.04427101 |                              0.00000000
+ 0.084738 |  -7 |                      31875171.750205437 |                      31875171.750205437 |                             0.000000000
+ 0.084738 |  -6 |                      2701038.3037689083 |                      2701038.3037689083 |                            0.0000000000
+ 0.084738 |  -5 |                      228880.58378476975 |                      228880.58378476975 |                           0.00000000000
+ 0.084738 |  -4 |                      19394.882908753819 |                      19394.882908753819 |                          0.000000000000
+ 0.084738 |  -3 |                      1643.4835879219811 |                      1643.4835879219811 |                         0.0000000000000
+ 0.084738 |  -2 |                      139.26551227333284 |                      139.26551227333284 |                        0.00000000000000
+ 0.084738 |  -1 |                      11.801080979017678 |                      11.801080979017678 |                       0.000000000000000
+ 0.084738 |   0 |                                       1 |                      1.0000000000000000 |                      0.0000000000000000
+ 0.084738 |   1 |                                0.084738 |                     0.08473800000000000 |                     0.00000000000000000
+ 0.084738 |   2 |                          0.007180528644 |                    0.007180528644000000 |                    0.000000000000000000
+ 0.084738 |   3 |                    0.000608463636235272 |                   0.0006084636362352720 |                   0.0000000000000000000
+ 0.084738 |   4 |                  0.00005155999160730448 |                  0.00005155999160730448 |                  0.00000000000000000000
+ 0.084738 |   5 |                 0.000004369090568819767 |                 0.000004369090568819767 |                 0.000000000000000000000
+ 0.084738 |   6 |                0.0000003702279966206494 |                0.0000003702279966206494 |                0.0000000000000000000000
+ 0.084738 |   7 |               0.00000003137237997764059 |               0.00000003137237997764059 |               0.00000000000000000000000
+ 0.084738 |   8 |              0.000000002658432734545308 |              0.000000002658432734545308 |              0.000000000000000000000000
+ 0.084738 |   9 |             0.0000000002252702730599003 |             0.0000000002252702730599003 |             0.0000000000000000000000000
+ 0.084738 |  10 |            0.00000000001908895239854983 |            0.00000000001908895239854983 |            0.00000000000000000000000000
+ 0.084738 |  11 |           0.000000000001617559648348316 |           0.000000000001617559648348316 |           0.000000000000000000000000000
+ 0.084738 |  12 |          0.0000000000001370687694817396 |          0.0000000000001370687694817396 |          0.0000000000000000000000000000
+ 0.084738 |  13 |         0.00000000000001161493338834365 |         0.00000000000001161493338834365 |         0.00000000000000000000000000000
+ 0.084738 |  14 |       0.0000000000000009842262254614642 |       0.0000000000000009842262254614642 |       0.0000000000000000000000000000000
+ 0.084738 |  15 |      0.00000000000000008340136189315355 |      0.00000000000000008340136189315355 |      0.00000000000000000000000000000000
+ 0.084738 |  16 |     0.000000000000000007067264604102046 |     0.000000000000000007067264604102046 |     0.000000000000000000000000000000000
+ 0.084738 |  17 |    0.0000000000000000005988658680223991 |    0.0000000000000000005988658680223991 |    0.0000000000000000000000000000000000
+ 0.084738 |  18 |   0.00000000000000000005074669592448206 |   0.00000000000000000005074669592448206 |   0.00000000000000000000000000000000000
+ 0.084738 |  19 |  0.000000000000000000004300173519248761 |  0.000000000000000000004300173519248761 |  0.000000000000000000000000000000000000
+ 0.084738 |  20 | 0.0000000000000000000003643881036741015 | 0.0000000000000000000003643881036741015 | 0.0000000000000000000000000000000000000
 (41 rows)
 
 -- base greater than 1
@@ -785,91 +785,91 @@ SELECT b, p, bc_result, b^p AS power, b^
 --   echo "($b, $p, $r),"
 -- done
 WITH t(b, p, bc_result) AS (VALUES
-(37.821637, -20, .0000000000000000),
-(37.821637, -19, .0000000000000000),
-(37.821637, -18, .0000000000000000),
-(37.821637, -17, .0000000000000000),
-(37.821637, -16, .0000000000000000),
-(37.821637, -15, .0000000000000000),
-(37.821637, -14, .0000000000000000),
-(37.821637, -13, .0000000000000000),
-(37.821637, -12, .0000000000000000),
-(37.821637, -11, .0000000000000000),
-(37.821637, -10, .0000000000000002),
-(37.821637, -9, .0000000000000063),
-(37.821637, -8, .0000000000002388),
-(37.821637, -7, .0000000000090327),
-(37.821637, -6, .0000000003416316),
-(37.821637, -5, .0000000129210673),
-(37.821637, -4, .0000004886959182),
-(37.821637, -3, .0000184832796213),
-(37.821637, -2, .0006990678924066),
-(37.821637, -1, .0264398920649574),
+(37.821637, -20, .00000000000000000000000000000002787363175065101),
+(37.821637, -19, .000000000000000000000000000001054226381944797),
+(37.821637, -18, .00000000000000000000000000003987256753373947),
+(37.821637, -17, .000000000000000000000000001508045775519079),
+(37.821637, -16, .00000000000000000000000005703675990106610),
+(37.821637, -15, .000000000000000000000002157223628634278),
+(37.821637, -14, .00000000000000000000008158972901002847),
+(37.821637, -13, .000000000000000000003085857113545666),
+(37.821637, -12, .0000000000000000001167121675823920),
+(37.821637, -11, .000000000000000004414245235784397),
+(37.821637, -10, .0000000000000001669539809368169),
+(37.821637, -9, .000000000000006314472862697207),
+(37.821637, -8, .0000000000002388237004592846),
+(37.821637, -7, .000000000009032703305767796),
+(37.821637, -6, .0000000003416316255594496),
+(37.821637, -5, .00000001292106732962942),
+(37.821637, -4, .0000004886959181938034),
+(37.821637, -3, .00001848327962130773),
+(37.821637, -2, .0006990678924065984),
+(37.821637, -1, .02643989206495742),
 (37.821637, 0, 1),
 (37.821637, 1, 37.821637),
 (37.821637, 2, 1430.476225359769),
-(37.821637, 3, 54102.9525326873775219),
-(37.821637, 4, 2046262.2313195326271135),
-(37.821637, 5, 77392987.3197773940323425),
-(37.821637, 6, 2927129472.7542235178972258),
-(37.821637, 7, 110708828370.5116321107718772),
-(37.821637, 8, 4187189119324.7924539711577286),
-(37.821637, 9, 158366346921451.9852944363360812),
-(37.821637, 10, 5989674486279224.5007355092228730),
-(37.821637, 11, 226539294168214309.7083246628376531),
-(37.821637, 12, 8568086950266418559.9938312759931069),
-(37.821637, 13, 324059074417413536066.1494087598581043),
-(37.821637, 14, 12256444679171401239980.3109258799733927),
-(37.821637, 15, 463558801566202198479885.2069857662592280),
-(37.821637, 16, 17532552720991931019508170.1002855156233684),
-(37.821637, 17, 663109844696719094948877928.0672523682648687),
-(37.821637, 18, 25079899837245684700124994552.6717306599041850),
-(37.821637, 19, 948562867640665366544581398598.1275771806665398),
-(37.821637, 20, 35876200451584291931921101974730.6901038166532866))
+(37.821637, 3, 54102.952532687378),
+(37.821637, 4, 2046262.2313195326),
+(37.821637, 5, 77392987.319777394),
+(37.821637, 6, 2927129472.7542235),
+(37.821637, 7, 110708828370.511632),
+(37.821637, 8, 4187189119324.792454),
+(37.821637, 9, 158366346921451.985294),
+(37.821637, 10, 5989674486279224.500736),
+(37.821637, 11, 226539294168214309.708325),
+(37.821637, 12, 8568086950266418559.993831),
+(37.821637, 13, 324059074417413536066.149409),
+(37.821637, 14, 12256444679171401239980.310926),
+(37.821637, 15, 463558801566202198479885.206986),
+(37.821637, 16, 17532552720991931019508170.100286),
+(37.821637, 17, 663109844696719094948877928.067252),
+(37.821637, 18, 25079899837245684700124994552.671731),
+(37.821637, 19, 948562867640665366544581398598.127577),
+(37.821637, 20, 35876200451584291931921101974730.690104))
 SELECT b, p, bc_result, b^p AS power, b^p - bc_result AS diff FROM t;
-     b     |  p  |                     bc_result                     |                       power                       |        diff        
------------+-----+---------------------------------------------------+---------------------------------------------------+--------------------
- 37.821637 | -20 |                                0.0000000000000000 |                                0.0000000000000000 | 0.0000000000000000
- 37.821637 | -19 |                                0.0000000000000000 |                                0.0000000000000000 | 0.0000000000000000
- 37.821637 | -18 |                                0.0000000000000000 |                                0.0000000000000000 | 0.0000000000000000
- 37.821637 | -17 |                                0.0000000000000000 |                                0.0000000000000000 | 0.0000000000000000
- 37.821637 | -16 |                                0.0000000000000000 |                                0.0000000000000000 | 0.0000000000000000
- 37.821637 | -15 |                                0.0000000000000000 |                                0.0000000000000000 | 0.0000000000000000
- 37.821637 | -14 |                                0.0000000000000000 |                                0.0000000000000000 | 0.0000000000000000
- 37.821637 | -13 |                                0.0000000000000000 |                                0.0000000000000000 | 0.0000000000000000
- 37.821637 | -12 |                                0.0000000000000000 |                                0.0000000000000000 | 0.0000000000000000
- 37.821637 | -11 |                                0.0000000000000000 |                                0.0000000000000000 | 0.0000000000000000
- 37.821637 | -10 |                                0.0000000000000002 |                                0.0000000000000002 | 0.0000000000000000
- 37.821637 |  -9 |                                0.0000000000000063 |                                0.0000000000000063 | 0.0000000000000000
- 37.821637 |  -8 |                                0.0000000000002388 |                                0.0000000000002388 | 0.0000000000000000
- 37.821637 |  -7 |                                0.0000000000090327 |                                0.0000000000090327 | 0.0000000000000000
- 37.821637 |  -6 |                                0.0000000003416316 |                                0.0000000003416316 | 0.0000000000000000
- 37.821637 |  -5 |                                0.0000000129210673 |                                0.0000000129210673 | 0.0000000000000000
- 37.821637 |  -4 |                                0.0000004886959182 |                                0.0000004886959182 | 0.0000000000000000
- 37.821637 |  -3 |                                0.0000184832796213 |                                0.0000184832796213 | 0.0000000000000000
- 37.821637 |  -2 |                                0.0006990678924066 |                                0.0006990678924066 | 0.0000000000000000
- 37.821637 |  -1 |                                0.0264398920649574 |                                0.0264398920649574 | 0.0000000000000000
- 37.821637 |   0 |                                                 1 |                                1.0000000000000000 | 0.0000000000000000
- 37.821637 |   1 |                                         37.821637 |                               37.8216370000000000 | 0.0000000000000000
- 37.821637 |   2 |                                 1430.476225359769 |                             1430.4762253597690000 | 0.0000000000000000
- 37.821637 |   3 |                            54102.9525326873775219 |                            54102.9525326873775219 | 0.0000000000000000
- 37.821637 |   4 |                          2046262.2313195326271135 |                          2046262.2313195326271135 | 0.0000000000000000
- 37.821637 |   5 |                         77392987.3197773940323425 |                         77392987.3197773940323425 | 0.0000000000000000
- 37.821637 |   6 |                       2927129472.7542235178972258 |                       2927129472.7542235178972258 | 0.0000000000000000
- 37.821637 |   7 |                     110708828370.5116321107718772 |                     110708828370.5116321107718772 | 0.0000000000000000
- 37.821637 |   8 |                    4187189119324.7924539711577286 |                    4187189119324.7924539711577286 | 0.0000000000000000
- 37.821637 |   9 |                  158366346921451.9852944363360812 |                  158366346921451.9852944363360812 | 0.0000000000000000
- 37.821637 |  10 |                 5989674486279224.5007355092228730 |                 5989674486279224.5007355092228730 | 0.0000000000000000
- 37.821637 |  11 |               226539294168214309.7083246628376531 |               226539294168214309.7083246628376531 | 0.0000000000000000
- 37.821637 |  12 |              8568086950266418559.9938312759931069 |              8568086950266418559.9938312759931069 | 0.0000000000000000
- 37.821637 |  13 |            324059074417413536066.1494087598581043 |            324059074417413536066.1494087598581043 | 0.0000000000000000
- 37.821637 |  14 |          12256444679171401239980.3109258799733927 |          12256444679171401239980.3109258799733927 | 0.0000000000000000
- 37.821637 |  15 |         463558801566202198479885.2069857662592280 |         463558801566202198479885.2069857662592280 | 0.0000000000000000
- 37.821637 |  16 |       17532552720991931019508170.1002855156233684 |       17532552720991931019508170.1002855156233684 | 0.0000000000000000
- 37.821637 |  17 |      663109844696719094948877928.0672523682648687 |      663109844696719094948877928.0672523682648687 | 0.0000000000000000
- 37.821637 |  18 |    25079899837245684700124994552.6717306599041850 |    25079899837245684700124994552.6717306599041850 | 0.0000000000000000
- 37.821637 |  19 |   948562867640665366544581398598.1275771806665398 |   948562867640665366544581398598.1275771806665398 | 0.0000000000000000
- 37.821637 |  20 | 35876200451584291931921101974730.6901038166532866 | 35876200451584291931921101974730.6901038166532866 | 0.0000000000000000
+     b     |  p  |                     bc_result                     |                       power                       |                       diff                        
+-----------+-----+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------
+ 37.821637 | -20 | 0.00000000000000000000000000000002787363175065101 | 0.00000000000000000000000000000002787363175065101 | 0.00000000000000000000000000000000000000000000000
+ 37.821637 | -19 |   0.000000000000000000000000000001054226381944797 |   0.000000000000000000000000000001054226381944797 |   0.000000000000000000000000000000000000000000000
+ 37.821637 | -18 |    0.00000000000000000000000000003987256753373947 |    0.00000000000000000000000000003987256753373947 |    0.00000000000000000000000000000000000000000000
+ 37.821637 | -17 |      0.000000000000000000000000001508045775519079 |      0.000000000000000000000000001508045775519079 |      0.000000000000000000000000000000000000000000
+ 37.821637 | -16 |       0.00000000000000000000000005703675990106610 |       0.00000000000000000000000005703675990106610 |       0.00000000000000000000000000000000000000000
+ 37.821637 | -15 |         0.000000000000000000000002157223628634278 |         0.000000000000000000000002157223628634278 |         0.000000000000000000000000000000000000000
+ 37.821637 | -14 |          0.00000000000000000000008158972901002847 |          0.00000000000000000000008158972901002847 |          0.00000000000000000000000000000000000000
+ 37.821637 | -13 |            0.000000000000000000003085857113545666 |            0.000000000000000000003085857113545666 |            0.000000000000000000000000000000000000
+ 37.821637 | -12 |              0.0000000000000000001167121675823920 |              0.0000000000000000001167121675823920 |              0.0000000000000000000000000000000000
+ 37.821637 | -11 |               0.000000000000000004414245235784397 |               0.000000000000000004414245235784397 |               0.000000000000000000000000000000000
+ 37.821637 | -10 |                 0.0000000000000001669539809368169 |                 0.0000000000000001669539809368169 |                 0.0000000000000000000000000000000
+ 37.821637 |  -9 |                  0.000000000000006314472862697207 |                  0.000000000000006314472862697207 |                  0.000000000000000000000000000000
+ 37.821637 |  -8 |                    0.0000000000002388237004592846 |                    0.0000000000002388237004592846 |                    0.0000000000000000000000000000
+ 37.821637 |  -7 |                     0.000000000009032703305767796 |                     0.000000000009032703305767796 |                     0.000000000000000000000000000
+ 37.821637 |  -6 |                       0.0000000003416316255594496 |                       0.0000000003416316255594496 |                       0.0000000000000000000000000
+ 37.821637 |  -5 |                         0.00000001292106732962942 |                         0.00000001292106732962942 |                         0.00000000000000000000000
+ 37.821637 |  -4 |                          0.0000004886959181938034 |                          0.0000004886959181938034 |                          0.0000000000000000000000
+ 37.821637 |  -3 |                            0.00001848327962130773 |                            0.00001848327962130773 |                            0.00000000000000000000
+ 37.821637 |  -2 |                             0.0006990678924065984 |                             0.0006990678924065984 |                             0.0000000000000000000
+ 37.821637 |  -1 |                               0.02643989206495742 |                               0.02643989206495742 |                               0.00000000000000000
+ 37.821637 |   0 |                                                 1 |                                1.0000000000000000 |                                0.0000000000000000
+ 37.821637 |   1 |                                         37.821637 |                                37.821637000000000 |                                 0.000000000000000
+ 37.821637 |   2 |                                 1430.476225359769 |                                1430.4762253597690 |                                   0.0000000000000
+ 37.821637 |   3 |                                54102.952532687378 |                                54102.952532687378 |                                    0.000000000000
+ 37.821637 |   4 |                                2046262.2313195326 |                                2046262.2313195326 |                                      0.0000000000
+ 37.821637 |   5 |                                77392987.319777394 |                                77392987.319777394 |                                       0.000000000
+ 37.821637 |   6 |                                2927129472.7542235 |                                2927129472.7542235 |                                         0.0000000
+ 37.821637 |   7 |                               110708828370.511632 |                               110708828370.511632 |                                          0.000000
+ 37.821637 |   8 |                              4187189119324.792454 |                              4187189119324.792454 |                                          0.000000
+ 37.821637 |   9 |                            158366346921451.985294 |                            158366346921451.985294 |                                          0.000000
+ 37.821637 |  10 |                           5989674486279224.500736 |                           5989674486279224.500736 |                                          0.000000
+ 37.821637 |  11 |                         226539294168214309.708325 |                         226539294168214309.708325 |                                          0.000000
+ 37.821637 |  12 |                        8568086950266418559.993831 |                        8568086950266418559.993831 |                                          0.000000
+ 37.821637 |  13 |                      324059074417413536066.149409 |                      324059074417413536066.149409 |                                          0.000000
+ 37.821637 |  14 |                    12256444679171401239980.310926 |                    12256444679171401239980.310926 |                                          0.000000
+ 37.821637 |  15 |                   463558801566202198479885.206986 |                   463558801566202198479885.206986 |                                          0.000000
+ 37.821637 |  16 |                 17532552720991931019508170.100286 |                 17532552720991931019508170.100286 |                                          0.000000
+ 37.821637 |  17 |                663109844696719094948877928.067252 |                663109844696719094948877928.067252 |                                          0.000000
+ 37.821637 |  18 |              25079899837245684700124994552.671731 |              25079899837245684700124994552.671731 |                                          0.000000
+ 37.821637 |  19 |             948562867640665366544581398598.127577 |             948562867640665366544581398598.127577 |                                          0.000000
+ 37.821637 |  20 |           35876200451584291931921101974730.690104 |           35876200451584291931921101974730.690104 |                                          0.000000
 (41 rows)
 
 --
diff --git a/src/test/regress/sql/numeric.sql b/src/test/regress/sql/numeric.sql
new file mode 100644
index eeca63d..d328b4b
--- a/src/test/regress/sql/numeric.sql
+++ b/src/test/regress/sql/numeric.sql
@@ -1162,6 +1162,10 @@ select (-1.0) ^ 2147483648;
 select (-1.0) ^ 1000000000000000;
 select (-1.0) ^ 1000000000000001;
 
+-- integer powers of 10
+select n, 10.0 ^ n as "10^n", (10.0 ^ n) * (10.0 ^ (-n)) = 1 as ok
+from generate_series(-20, 20) n;
+
 --
 -- Tests for raising to non-integer powers
 --
diff --git a/src/test/regress/sql/numeric_big.sql b/src/test/regress/sql/numeric_big.sql
new file mode 100644
index c9d52d0..d67d9e8
--- a/src/test/regress/sql/numeric_big.sql
+++ b/src/test/regress/sql/numeric_big.sql
@@ -664,47 +664,47 @@ SELECT t1.id1, t1.result, t2.expected
 -- done
 
 WITH t(b, p, bc_result) AS (VALUES
-(0.084738, -20, 2744326694304960114888.7859130502035257),
-(0.084738, -19, 232548755422013710215.4459407000481464),
-(0.084738, -18, 19705716436950597776.2364581230406798),
-(0.084738, -17, 1669822999434319754.3627249884302211),
-(0.084738, -16, 141497461326065387.3451885900696001),
-(0.084738, -15, 11990211877848128.7928565907453178),
-(0.084738, -14, 1016026574105094.7376490817865767),
-(0.084738, -13, 86096059836517.5178789078924309),
-(0.084738, -12, 7295607918426.8214300228969888),
-(0.084738, -11, 618215223791.6519943372802450),
-(0.084738, -10, 52386321633.6570066961524534),
-(0.084738, -9, 4439112122.5928274334185666),
-(0.084738, -8, 376161483.0442710110530225),
-(0.084738, -7, 31875171.7502054369346110),
-(0.084738, -6, 2701038.3037689083149651),
-(0.084738, -5, 228880.5837847697527935),
-(0.084738, -4, 19394.8829087538193122),
-(0.084738, -3, 1643.4835879219811409),
-(0.084738, -2, 139.2655122733328379),
-(0.084738, -1, 11.8010809790176780),
+(0.084738, -20, 2744326694304960114888.785913),
+(0.084738, -19, 232548755422013710215.445941),
+(0.084738, -18, 19705716436950597776.236458),
+(0.084738, -17, 1669822999434319754.362725),
+(0.084738, -16, 141497461326065387.345189),
+(0.084738, -15, 11990211877848128.792857),
+(0.084738, -14, 1016026574105094.737649),
+(0.084738, -13, 86096059836517.517879),
+(0.084738, -12, 7295607918426.821430),
+(0.084738, -11, 618215223791.651994),
+(0.084738, -10, 52386321633.657007),
+(0.084738, -9, 4439112122.5928274),
+(0.084738, -8, 376161483.04427101),
+(0.084738, -7, 31875171.750205437),
+(0.084738, -6, 2701038.3037689083),
+(0.084738, -5, 228880.58378476975),
+(0.084738, -4, 19394.882908753819),
+(0.084738, -3, 1643.4835879219811),
+(0.084738, -2, 139.26551227333284),
+(0.084738, -1, 11.801080979017678),
 (0.084738, 0, 1),
 (0.084738, 1, .084738),
 (0.084738, 2, .007180528644),
-(0.084738, 3, .0006084636362353),
-(0.084738, 4, .0000515599916073),
-(0.084738, 5, .0000043690905688),
-(0.084738, 6, .0000003702279966),
-(0.084738, 7, .0000000313723800),
-(0.084738, 8, .0000000026584327),
-(0.084738, 9, .0000000002252703),
-(0.084738, 10, .0000000000190890),
-(0.084738, 11, .0000000000016176),
-(0.084738, 12, .0000000000001371),
-(0.084738, 13, .0000000000000116),
-(0.084738, 14, .0000000000000010),
-(0.084738, 15, .0000000000000001),
-(0.084738, 16, .0000000000000000),
-(0.084738, 17, .0000000000000000),
-(0.084738, 18, .0000000000000000),
-(0.084738, 19, .0000000000000000),
-(0.084738, 20, .0000000000000000))
+(0.084738, 3, .000608463636235272),
+(0.084738, 4, .00005155999160730448),
+(0.084738, 5, .000004369090568819767),
+(0.084738, 6, .0000003702279966206494),
+(0.084738, 7, .00000003137237997764059),
+(0.084738, 8, .000000002658432734545308),
+(0.084738, 9, .0000000002252702730599003),
+(0.084738, 10, .00000000001908895239854983),
+(0.084738, 11, .000000000001617559648348316),
+(0.084738, 12, .0000000000001370687694817396),
+(0.084738, 13, .00000000000001161493338834365),
+(0.084738, 14, .0000000000000009842262254614642),
+(0.084738, 15, .00000000000000008340136189315355),
+(0.084738, 16, .000000000000000007067264604102046),
+(0.084738, 17, .0000000000000000005988658680223991),
+(0.084738, 18, .00000000000000000005074669592448206),
+(0.084738, 19, .000000000000000000004300173519248761),
+(0.084738, 20, .0000000000000000000003643881036741015))
 SELECT b, p, bc_result, b^p AS power, b^p - bc_result AS diff FROM t;
 
 -- base greater than 1
@@ -720,47 +720,47 @@ SELECT b, p, bc_result, b^p AS power, b^
 -- done
 
 WITH t(b, p, bc_result) AS (VALUES
-(37.821637, -20, .0000000000000000),
-(37.821637, -19, .0000000000000000),
-(37.821637, -18, .0000000000000000),
-(37.821637, -17, .0000000000000000),
-(37.821637, -16, .0000000000000000),
-(37.821637, -15, .0000000000000000),
-(37.821637, -14, .0000000000000000),
-(37.821637, -13, .0000000000000000),
-(37.821637, -12, .0000000000000000),
-(37.821637, -11, .0000000000000000),
-(37.821637, -10, .0000000000000002),
-(37.821637, -9, .0000000000000063),
-(37.821637, -8, .0000000000002388),
-(37.821637, -7, .0000000000090327),
-(37.821637, -6, .0000000003416316),
-(37.821637, -5, .0000000129210673),
-(37.821637, -4, .0000004886959182),
-(37.821637, -3, .0000184832796213),
-(37.821637, -2, .0006990678924066),
-(37.821637, -1, .0264398920649574),
+(37.821637, -20, .00000000000000000000000000000002787363175065101),
+(37.821637, -19, .000000000000000000000000000001054226381944797),
+(37.821637, -18, .00000000000000000000000000003987256753373947),
+(37.821637, -17, .000000000000000000000000001508045775519079),
+(37.821637, -16, .00000000000000000000000005703675990106610),
+(37.821637, -15, .000000000000000000000002157223628634278),
+(37.821637, -14, .00000000000000000000008158972901002847),
+(37.821637, -13, .000000000000000000003085857113545666),
+(37.821637, -12, .0000000000000000001167121675823920),
+(37.821637, -11, .000000000000000004414245235784397),
+(37.821637, -10, .0000000000000001669539809368169),
+(37.821637, -9, .000000000000006314472862697207),
+(37.821637, -8, .0000000000002388237004592846),
+(37.821637, -7, .000000000009032703305767796),
+(37.821637, -6, .0000000003416316255594496),
+(37.821637, -5, .00000001292106732962942),
+(37.821637, -4, .0000004886959181938034),
+(37.821637, -3, .00001848327962130773),
+(37.821637, -2, .0006990678924065984),
+(37.821637, -1, .02643989206495742),
 (37.821637, 0, 1),
 (37.821637, 1, 37.821637),
 (37.821637, 2, 1430.476225359769),
-(37.821637, 3, 54102.9525326873775219),
-(37.821637, 4, 2046262.2313195326271135),
-(37.821637, 5, 77392987.3197773940323425),
-(37.821637, 6, 2927129472.7542235178972258),
-(37.821637, 7, 110708828370.5116321107718772),
-(37.821637, 8, 4187189119324.7924539711577286),
-(37.821637, 9, 158366346921451.9852944363360812),
-(37.821637, 10, 5989674486279224.5007355092228730),
-(37.821637, 11, 226539294168214309.7083246628376531),
-(37.821637, 12, 8568086950266418559.9938312759931069),
-(37.821637, 13, 324059074417413536066.1494087598581043),
-(37.821637, 14, 12256444679171401239980.3109258799733927),
-(37.821637, 15, 463558801566202198479885.2069857662592280),
-(37.821637, 16, 17532552720991931019508170.1002855156233684),
-(37.821637, 17, 663109844696719094948877928.0672523682648687),
-(37.821637, 18, 25079899837245684700124994552.6717306599041850),
-(37.821637, 19, 948562867640665366544581398598.1275771806665398),
-(37.821637, 20, 35876200451584291931921101974730.6901038166532866))
+(37.821637, 3, 54102.952532687378),
+(37.821637, 4, 2046262.2313195326),
+(37.821637, 5, 77392987.319777394),
+(37.821637, 6, 2927129472.7542235),
+(37.821637, 7, 110708828370.511632),
+(37.821637, 8, 4187189119324.792454),
+(37.821637, 9, 158366346921451.985294),
+(37.821637, 10, 5989674486279224.500736),
+(37.821637, 11, 226539294168214309.708325),
+(37.821637, 12, 8568086950266418559.993831),
+(37.821637, 13, 324059074417413536066.149409),
+(37.821637, 14, 12256444679171401239980.310926),
+(37.821637, 15, 463558801566202198479885.206986),
+(37.821637, 16, 17532552720991931019508170.100286),
+(37.821637, 17, 663109844696719094948877928.067252),
+(37.821637, 18, 25079899837245684700124994552.671731),
+(37.821637, 19, 948562867640665366544581398598.127577),
+(37.821637, 20, 35876200451584291931921101974730.690104))
 SELECT b, p, bc_result, b^p AS power, b^p - bc_result AS diff FROM t;
 
 --

Reply via email to