aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/float.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2006-04-24 20:36:32 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2006-04-24 20:36:32 +0000
commit332ea60d2378ef8d567c93502fa7b95eccd962e5 (patch)
tree99aecc056139e4a60200d9cc8b18bf7c7f6a963d /src/backend/utils/adt/float.c
parent7e97b419df2001efe8cf4880ca547f814a5dd7d2 (diff)
downloadpostgresql-332ea60d2378ef8d567c93502fa7b95eccd962e5.tar.gz
postgresql-332ea60d2378ef8d567c93502fa7b95eccd962e5.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/backend/utils/adt/float.c')
-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 3382b86ba0d..b5147c9aa45 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.123 2006/03/11 01:19:22 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.124 2006/04/24 20:36:32 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -2373,11 +2373,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;
}