88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.100 2004/03/14 05:22:52 neilc Exp $
11+ * $PostgreSQL: pgsql/src/backend/utils/adt/float.c,v 1.101 2004/03/15 03:29:22 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
5454
5555#include <ctype.h>
5656#include <errno.h>
57- #include <float.h> /* faked on sunos4 */
57+ #include <float.h>
5858#include <math.h>
59-
6059#include <limits.h>
6160/* for finite() on Solaris */
6261#ifdef HAVE_IEEEFP_H
7069#include "utils/builtins.h"
7170
7271
73- #ifndef HAVE_CBRT
74- static double cbrt (double x );
75- #endif /* HAVE_CBRT */
76-
7772#ifndef M_PI
7873/* from my RH5.2 gcc math.h file - thomas 2000-04-03 */
7974#define M_PI 3.14159265358979323846
8075#endif
8176
82- #ifndef NAN
83- #define NAN (0.0/0.0)
84- #endif
85-
8677#ifndef SHRT_MAX
8778#define SHRT_MAX 32767
8879#endif
@@ -109,9 +100,78 @@ intextra_float_digits = 0;/* Added to DBL_DIG or FLT_DIG */
109100
110101static void CheckFloat4Val (double val );
111102static void CheckFloat8Val (double val );
112- static int is_infinite (double val );
113103static int float4_cmp_internal (float4 a ,float4 b );
114104static int float8_cmp_internal (float8 a ,float8 b );
105+ #ifndef HAVE_CBRT
106+ static double cbrt (double x );
107+ #endif /* HAVE_CBRT */
108+
109+
110+ /*
111+ * Routines to provide reasonably platform-independent handling of
112+ * infinity and NaN. We assume that isinf() and isnan() are available
113+ * and work per spec. (On some platforms, we have to supply our own;
114+ * see src/port.) However, generating an Infinity or NaN in the first
115+ * place is less well standardized; pre-C99 systems tend not to have C99's
116+ * INFINITY and NAN macros. We centralize our workarounds for this here.
117+ */
118+
119+ double
120+ get_float8_infinity (void )
121+ {
122+ #ifdef INFINITY
123+ /* C99 standard way */
124+ return (double )INFINITY ;
125+ #else
126+ /*
127+ * On some platforms, HUGE_VAL is an infinity, elsewhere it's just the
128+ * largest normal double. We assume forcing an overflow will get us
129+ * a true infinity.
130+ */
131+ return (double ) (HUGE_VAL * HUGE_VAL );
132+ #endif
133+ }
134+
135+ float
136+ get_float4_infinity (void )
137+ {
138+ #ifdef INFINITY
139+ /* C99 standard way */
140+ return (float )INFINITY ;
141+ #else
142+ /*
143+ * On some platforms, HUGE_VAL is an infinity, elsewhere it's just the
144+ * largest normal double. We assume forcing an overflow will get us
145+ * a true infinity.
146+ */
147+ return (float ) (HUGE_VAL * HUGE_VAL );
148+ #endif
149+ }
150+
151+ double
152+ get_float8_nan (void )
153+ {
154+ #ifdef NAN
155+ /* C99 standard way */
156+ return (double )NAN ;
157+ #else
158+ /* Assume we can get a NAN via zero divide */
159+ return (double ) (0.0 /0.0 );
160+ #endif
161+ }
162+
163+ float
164+ get_float4_nan (void )
165+ {
166+ #ifdef NAN
167+ /* C99 standard way */
168+ return (float )NAN ;
169+ #else
170+ /* Assume we can get a NAN via zero divide */
171+ return (float ) (0.0 /0.0 );
172+ #endif
173+ }
174+
115175
116176/*
117177 * Returns -1 if 'val' represents negative infinity, 1 if 'val'
@@ -120,7 +180,7 @@ static intfloat8_cmp_internal(float8 a, float8 b);
120180 * does not specify that isinf() needs to distinguish between positive
121181 * and negative infinity.
122182 */
123- static int
183+ int
124184is_infinite (double val )
125185{
126186int inf = isinf (val );
@@ -134,6 +194,7 @@ is_infinite(double val)
134194return -1 ;
135195}
136196
197+
137198/*
138199 * check to see if a float4 val is outside of the FLOAT4_MIN,
139200 * FLOAT4_MAX bounds.
@@ -237,17 +298,17 @@ float4in(PG_FUNCTION_ARGS)
237298 */
238299if (strncasecmp (num ,"NaN" ,3 )== 0 )
239300{
240- val = NAN ;
301+ val = get_float4_nan () ;
241302endptr = num + 3 ;
242303}
243304else if (strncasecmp (num ,"Infinity" ,8 )== 0 )
244305{
245- val = HUGE_VAL ;
306+ val = get_float4_infinity () ;
246307endptr = num + 8 ;
247308}
248309else if (strncasecmp (num ,"-Infinity" ,9 )== 0 )
249310{
250- val = - HUGE_VAL ;
311+ val = - get_float4_infinity () ;
251312endptr = num + 9 ;
252313}
253314else
@@ -402,17 +463,17 @@ float8in(PG_FUNCTION_ARGS)
402463 */
403464if (strncasecmp (num ,"NaN" ,3 )== 0 )
404465{
405- val = NAN ;
466+ val = get_float8_nan () ;
406467endptr = num + 3 ;
407468}
408469else if (strncasecmp (num ,"Infinity" ,8 )== 0 )
409470{
410- val = HUGE_VAL ;
471+ val = get_float8_infinity () ;
411472endptr = num + 8 ;
412473}
413474else if (strncasecmp (num ,"-Infinity" ,9 )== 0 )
414475{
415- val = - HUGE_VAL ;
476+ val = - get_float8_infinity () ;
416477endptr = num + 9 ;
417478}
418479else