|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.123 2006/03/11 01:19:22 neilc Exp $ |
| 11 | + * $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.124 2006/04/24 20:36:32 tgl Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
@@ -2373,11 +2373,22 @@ float84ge(PG_FUNCTION_ARGS)
|
2373 | 2373 | /* ========== PRIVATE ROUTINES ========== */
|
2374 | 2374 |
|
2375 | 2375 | #ifndefHAVE_CBRT
|
| 2376 | + |
2376 | 2377 | staticdouble
|
2377 | 2378 | cbrt(doublex)
|
2378 | 2379 | {
|
2379 | 2380 | intisneg= (x<0.0);
|
2380 |
| -doubletmpres=pow(fabs(x), (double)1.0 / (double)3.0); |
| 2381 | +doubleabsx=fabs(x); |
| 2382 | +doubletmpres=pow(absx, (double)1.0 / (double)3.0); |
| 2383 | + |
| 2384 | +/* |
| 2385 | + * The result is somewhat inaccurate --- not really pow()'s fault, |
| 2386 | + * as the exponent it's handed contains roundoff error. We can improve |
| 2387 | + * the accuracy by doing one iteration of Newton's formula. Beware of |
| 2388 | + * zero input however. |
| 2389 | + */ |
| 2390 | +if (tmpres>0.0) |
| 2391 | +tmpres-= (tmpres-absx/(tmpres*tmpres)) / (double)3.0; |
2381 | 2392 |
|
2382 | 2393 | returnisneg ?-tmpres :tmpres;
|
2383 | 2394 | }
|
|