diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2006-04-24 20:36:41 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2006-04-24 20:36:41 +0000 |
commit | 2c4abf11e1c28d908eca1ab2006641a472ba6664 (patch) | |
tree | 446d99c1b6a0178ed9a2c72f4f01936c4fa545f6 /src | |
parent | e37c0d2eb84d96ef4decc64504c93c7f114e9ac2 (diff) | |
download | postgresql-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.c | 15 |
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; } |