aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2006-04-24 20:36:41 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2006-04-24 20:36:41 +0000
commit2c4abf11e1c28d908eca1ab2006641a472ba6664 (patch)
tree446d99c1b6a0178ed9a2c72f4f01936c4fa545f6 /src
parente37c0d2eb84d96ef4decc64504c93c7f114e9ac2 (diff)
downloadpostgresql-2c4abf11e1c28d908eca1ab2006641a472ba6664.tar.gz
postgresql-2c4abf11e1c28d908eca1ab2006641a472ba6664.zip
Improve our private implementation of cbrt() to give results of the
accuracy expected by the regression tests. Per suggestion from Martijn van Oosterhout.
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/float.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c
index fb37e36624e..d80b3d4ef49 100644
--- a/src/backend/utils/adt/float.c
+++ b/src/backend/utils/adt/float.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.115 2005/10/15 02:49:28 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.115.2.1 2006/04/24 20:36:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -2321,11 +2321,22 @@ float84ge(PG_FUNCTION_ARGS)
/* ========== PRIVATE ROUTINES ========== */
#ifndef HAVE_CBRT
+
static double
cbrt(double x)
{
int isneg = (x < 0.0);
- double tmpres = pow(fabs(x), (double) 1.0 / (double) 3.0);
+ double absx = fabs(x);
+ double tmpres = pow(absx, (double) 1.0 / (double) 3.0);
+
+ /*
+ * The result is somewhat inaccurate --- not really pow()'s fault,
+ * as the exponent it's handed contains roundoff error. We can improve
+ * the accuracy by doing one iteration of Newton's formula. Beware of
+ * zero input however.
+ */
+ if (tmpres > 0.0)
+ tmpres -= (tmpres - absx/(tmpres*tmpres)) / (double) 3.0;
return isneg ? -tmpres : tmpres;
}