head 1.25; access; symbols release_4_2:1.24 aix_ok:1.18 Version_2_1:1.8 C_Demo_1:1.7; locks; strict; comment @ * @; 1.25 date 94.09.28.14.03.15; author postdev; state Exp; branches; next 1.24; 1.24 date 94.06.16.03.23.06; author aoki; state Exp; branches; next 1.23; 1.23 date 94.02.12.12.06.27; author aoki; state Exp; branches; next 1.22; 1.22 date 94.02.09.00.12.24; author aoki; state Exp; branches; next 1.21; 1.21 date 94.02.07.14.02.25; author aoki; state Exp; branches; next 1.20; 1.20 date 94.01.30.04.17.52; author aoki; state Exp; branches; next 1.19; 1.19 date 94.01.29.02.11.33; author jolly; state Exp; branches; next 1.18; 1.18 date 93.08.16.04.20.18; author aoki; state Exp; branches; next 1.17; 1.17 date 93.01.16.03.14.59; author aoki; state Exp; branches; next 1.16; 1.16 date 92.12.18.21.11.18; author mao; state Exp; branches; next 1.15; 1.15 date 92.09.24.21.19.04; author mao; state Exp; branches; next 1.14; 1.14 date 92.08.16.03.41.41; author mer; state Exp; branches; next 1.13; 1.13 date 92.03.17.01.09.43; author olson; state Exp; branches; next 1.12; 1.12 date 92.03.16.22.42.11; author mer; state Exp; branches; next 1.11; 1.11 date 92.01.13.02.21.26; author mao; state Exp; branches; next 1.10; 1.10 date 91.11.09.01.49.10; author mer; state Exp; branches; next 1.9; 1.9 date 91.11.05.05.37.11; author mer; state Exp; branches; next 1.8; 1.8 date 90.09.25.16.49.15; author kemnitz; state Exp; branches; next 1.7; 1.7 date 89.09.05.17.26.08; author mao; state C_Demo_1; branches; next 1.6; 1.6 date 89.04.18.22.24.37; author dillon; state Exp; branches; next 1.5; 1.5 date 89.04.17.19.04.56; author dillon; state Exp; branches; next 1.4; 1.4 date 89.04.17.18.55.10; author dillon; state Exp; branches; next 1.3; 1.3 date 89.04.14.18.32.13; author dillon; state Exp; branches; next 1.2; 1.2 date 89.02.02.16.10.50; author aoki; state Stab; branches; next 1.1; 1.1 date 89.01.17.05.58.32; author cimarron; state Exp; branches; next ; desc @@ 1.25 log @added definition for isinf() @ text @/* * float.c -- * Functions for the built-in floating-point types. * * Basic float4 ops: * float4in, float4out, float4abs, float4um * Basic float8 ops: * float8in, float8inAd, float8out, float8outAd, float8abs, float8um * Arithmetic operators: * float4pl, float4mi, float4mul, float4div * float8pl, float8mi, float8mul, float8div * Comparison operators: * float4eq, float4ne, float4lt, float4le, float4gt, float4ge * float8eq, float8ne, float8lt, float8le, float8gt, float8ge * Conversion routines: * ftod, dtof * * Random float8 ops: * dround, dtrunc, dsqrt, dcbrt, dpow, dexp, dlog1 * Arithmetic operators: * float48pl, float48mi, float48mul, float48div * float84pl, float84mi, float84mul, float84div * Comparison operators: * float48eq, float48ne, float48lt, float48le, float48gt, float48ge * float84eq, float84ne, float84lt, float84le, float84gt, float84ge * * (You can do the arithmetic and comparison stuff using conversion * routines, but then you pay the overhead of converting...) */ #include #include #include #include #include /* faked on sunos4 */ #include #include "tmp/postgres.h" #include "fmgr.h" #include "utils/builtins.h" /* for ftod() prototype */ #include "utils/log.h" RcsId("$Header: /usr/people/postdev/src/backend/utils/adt/RCS/float.c,v 1.24 1994/06/16 03:23:06 aoki Exp postdev $"); #define FORMAT 'g' /* use "g" output format as standard format */ /* not sure what the following should be, but better to make it over-sufficient */ #define MAXFLOATWIDTH 64 #define MAXDOUBLEWIDTH 128 extern double atof ARGS((const char *p)); #ifdef NEED_CBRT #define cbrt my_cbrt static double cbrt ARGS((double x)); #else /* NEED_CBRT */ extern double cbrt ARGS((double x)); #endif /* NEED_CBRT */ #ifdef NEED_RINT #define rint my_rint static double rint ARGS((double x)); #else /* NEED_RINT */ extern double rint ARGS((double x)); #endif /* NEED_RINT */ #ifdef NEED_ISINF #define isinf my_isinf static int isinf ARGS((double x)); #else /* NEED_ISINF */ extern int isinf ARGS((double x)); #endif /* NEED_ISINF */ /* ========== USER I/O ROUTINES ========== */ /* * float4in - converts "num" to float * restricted syntax: * {} [+|-] {digit} [.{digit}] [] * where is a space, digit is 0-9, * is "e" or "E" followed by an integer. */ float32 float4in(num) char *num; { float32 result = (float32) palloc(sizeof(float32data)); double val; char* endptr; errno = 0; val = strtod(num,&endptr); if (*endptr != '\0' || errno == ERANGE) elog(WARN,"\tBad float4 input format\n"); /* if we get here, we have a legal double, still need to check to see if it's a legal float */ if (fabs(val) > FLT_MAX) elog(WARN,"\tBad float4 input format -- overflow\n"); if (val > 0.0 && fabs(val) < FLT_MIN) elog(WARN,"\tBad float4 input format -- underflow\n"); *result = val; return result; } /* * float4out - converts a float4 number to a string * using a standard output format */ char * float4out(num) float32 num; { char *ascii = (char *)palloc(MAXFLOATWIDTH+1); if (!num) return strcpy(ascii, "(null)"); sprintf(ascii, "%.*g", FLT_DIG, *num); return(ascii); } /* * float8in - converts "num" to float8 * restricted syntax: * {} [+|-] {digit} [.{digit}] [] * where is a space, digit is 0-9, * is "e" or "E" followed by an integer. */ float64 float8in(num) char *num; { float64 result = (float64) palloc(sizeof(float64data)); double val; char* endptr; errno = 0; val = strtod(num,&endptr); if (*endptr != '\0' || errno == ERANGE) elog(WARN,"\tBad float8 input format\n"); *result = val; return(result); } /* * float8out - converts float8 number to a string * using a standard output format */ char * float8out(num) float64 num; { char *ascii = (char *)palloc(MAXDOUBLEWIDTH+1); if (!num) return strcpy(ascii, "(null)"); if (isnan(*num)) return strcpy(ascii, "NaN"); if (isinf(*num)) return strcpy(ascii, "Infinity"); sprintf(ascii, "%.*g", DBL_DIG, *num); return(ascii); } /* ========== PUBLIC ROUTINES ========== */ /* * ====================== * FLOAT4 BASE OPERATIONS * ====================== */ /* * float4abs - returns a pointer to |arg1| (absolute value) */ float32 float4abs(arg1) float32 arg1; { float64 dblarg1; float32 result; double tmp; if (!arg1) return (float32)NULL; dblarg1 = ftod(arg1); result = (float32) palloc(sizeof(float32data)); tmp = *dblarg1; *result = (float32data) fabs(tmp); return(result); } /* * float4um - returns a pointer to -arg1 (unary minus) */ float32 float4um(arg1) float32 arg1; { float32 result; if (!arg1) return (float32)NULL; result = (float32) palloc(sizeof(float32data)); *result = -(*arg1); return(result); } float32 float4larger(arg1, arg2) float32 arg1; float32 arg2; { float32 result; if (!arg1 || !arg2) return (float32)NULL; result = (float32) palloc(sizeof(float32data)); *result = ((*arg1 > *arg2) ? *arg1 : *arg2); return result; } float32 float4smaller(arg1, arg2) float32 arg1; float32 arg2; { float32 result; if (!arg1 || !arg2) return (float32)NULL; result = (float32) palloc(sizeof(float32data)); *result = ((*arg1 > *arg2) ? *arg2 : *arg1); return result; } /* * ====================== * FLOAT8 BASE OPERATIONS * ====================== */ /* * float8abs - returns a pointer to |arg1| (absolute value) */ float64 float8abs(arg1) float64 arg1; { float64 result; double tmp; if (!arg1) return (float64)NULL; result = (float64) palloc(sizeof(float64data)); tmp = *arg1; *result = fabs(tmp); return(result); } /* * float8um - returns a pointer to -arg1 (unary minus) */ float64 float8um(arg1) float64 arg1; { float64 result; if (!arg1) return (float64)NULL; result = (float64) palloc(sizeof(float64data)); *result = -(*arg1); return(result); } float64 float8larger(arg1, arg2) float64 arg1; float64 arg2; { float64 result; if (!arg1 || !arg2) return (float64)NULL; result = (float64) palloc(sizeof(float64data)); *result = ((*arg1 > *arg2) ? *arg1 : *arg2); return result; } float64 float8smaller(arg1, arg2) float64 arg1; float64 arg2; { float64 result; if (!arg1 || !arg2) return (float64)NULL; result = (float64) palloc(sizeof(float64data)); *result = ((*arg1 > *arg2) ? *arg2 : *arg1); return result; } /* * ==================== * ARITHMETIC OPERATORS * ==================== */ /* * float4pl - returns a pointer to arg1 + arg2 * float4mi - returns a pointer to arg1 - arg2 * float4mul - returns a pointer to arg1 * arg2 * float4div - returns a pointer to arg1 / arg2 * float4inc - returns a poniter to arg1 + 1.0 */ float32 float4pl(arg1, arg2) float32 arg1, arg2; { float32 result; if (!arg1 || !arg2) return (float32)NULL; result = (float32) palloc(sizeof(float32data)); *result = *arg1 + *arg2; return(result); } float32 float4mi(arg1, arg2) float32 arg1, arg2; { float32 result; if (!arg1 || !arg2) return (float32)NULL; result = (float32) palloc(sizeof(float32data)); *result = *arg1 - *arg2; return(result); } float32 float4mul(arg1, arg2) float32 arg1, arg2; { float32 result; if (!arg1 || !arg2) return (float32)NULL; result = (float32) palloc(sizeof(float32data)); *result = *arg1 * *arg2; return(result); } float32 float4div(arg1, arg2) float32 arg1, arg2; { float32 result; if (!arg1 || !arg2) return (float32)NULL; result = (float32) palloc(sizeof(float32data)); *result = *arg1 / *arg2; return(result); } float32 float4inc(arg1) float32 arg1; { if (!arg1) return (float32)NULL; *arg1 = *arg1 + (float32data)1.0; return arg1; } /* * float8pl - returns a pointer to arg1 + arg2 * float8mi - returns a pointer to arg1 - arg2 * float8mul - returns a pointer to arg1 * arg2 * float8div - returns a pointer to arg1 / arg2 * float8inc - returns a pointer to arg1 + 1.0 */ float64 float8pl(arg1, arg2) float64 arg1, arg2; { float64 result; if (!arg1 || !arg2) return (float64)NULL; result = (float64) palloc(sizeof(float64data)); *result = *arg1 + *arg2; return(result); } float64 float8mi(arg1, arg2) float64 arg1, arg2; { float64 result; if (!arg1 || !arg2) return (float64)NULL; result = (float64) palloc(sizeof(float64data)); *result = *arg1 - *arg2; return(result); } float64 float8mul(arg1, arg2) float64 arg1, arg2; { float64 result; if (!arg1 || !arg2) return (float64)NULL; result = (float64) palloc(sizeof(float64data)); *result = *arg1 * *arg2; return(result); } float64 float8div(arg1, arg2) float64 arg1, arg2; { float64 result; if (!arg1 || !arg2) return (float64)NULL; result = (float64) palloc(sizeof(float64data)); *result = *arg1 / *arg2; return(result); } float64 float8inc(arg1) float64 arg1; { if (!arg1) return (float64)NULL; *arg1 = *arg1 + (float64data)1.0; return(arg1); } /* * ==================== * COMPARISON OPERATORS * ==================== */ /* * float4{eq,ne,lt,le,gt,ge} - float4/float4 comparison operations */ long float4eq(arg1, arg2) float32 arg1, arg2; { if (!arg1 || !arg2) return (long)NULL; return(*arg1 == *arg2); } long float4ne(arg1, arg2) float32 arg1, arg2; { if (!arg1 || !arg2) return (long)NULL; return(*arg1 != *arg2); } long float4lt(arg1, arg2) float32 arg1, arg2; { if (!arg1 || !arg2) return (long)NULL; return(*arg1 < *arg2); } long float4le(arg1, arg2) float32 arg1, arg2; { if (!arg1 || !arg2) return (long)NULL; return(*arg1 <= *arg2); } long float4gt(arg1, arg2) float32 arg1, arg2; { if (!arg1 || !arg2) return (long)NULL; return(*arg1 > *arg2); } long float4ge(arg1, arg2) float32 arg1, arg2; { if (!arg1 || !arg2) return (long)NULL; return(*arg1 >= *arg2); } /* * float8{eq,ne,lt,le,gt,ge} - float8/float8 comparison operations */ long float8eq(arg1, arg2) float64 arg1, arg2; { if (!arg1 || !arg2) return (long)NULL; return(*arg1 == *arg2); } long float8ne(arg1, arg2) float64 arg1, arg2; { if (!arg1 || !arg2) return (long)NULL; return(*arg1 != *arg2); } long float8lt(arg1, arg2) float64 arg1, arg2; { if (!arg1 || !arg2) return (long)NULL; return(*arg1 < *arg2); } long float8le(arg1, arg2) float64 arg1, arg2; { if (!arg1 || !arg2) return (long)NULL; return(*arg1 <= *arg2); } long float8gt(arg1, arg2) float64 arg1, arg2; { if (!arg1 || !arg2) return (long)NULL; return(*arg1 > *arg2); } long float8ge(arg1, arg2) float64 arg1, arg2; { if (!arg1 || !arg2) return (long)NULL; return(*arg1 >= *arg2); } /* * =================== * CONVERSION ROUTINES * =================== */ /* * ftod - converts a float4 number to a float8 number */ float64 ftod(num) float32 num; { float64 result; if (!num) return (float64)NULL; result = (float64) palloc(sizeof(float64data)); *result = *num; return(result); } /* * dtof - converts a float8 number to a float4 number */ float32 dtof(num) float64 num; { float32 result; if (!num) return (float32)NULL; result = (float32) palloc(sizeof(float32data)); *result = *num; return(result); } /* * ======================= * RANDOM FLOAT8 OPERATORS * ======================= */ /* * dround - returns a pointer to ROUND(arg1) */ float64 dround(arg1) float64 arg1; { float64 result; double tmp; if (!arg1) return (float64)NULL; result = (float64) palloc(sizeof(float64data)); tmp = *arg1; *result = (float64data) rint(tmp); return(result); } /* * dtrunc - returns a pointer to truncation of arg1, * arg1 >= 0 ... the greatest integer as float8 less * than or equal to arg1 * arg1 < 0 ... the greatest integer as float8 greater * than or equal to arg1 */ float64 dtrunc(arg1) float64 arg1; { float64 result; double tmp; if (!arg1) return (float64)NULL; result = (float64) palloc(sizeof(float64data)); tmp = *arg1; if (*arg1 > 0) *result = (float64data) floor(tmp); else *result = (float64data) -(floor(-tmp)); return(result); } /* * dsqrt - returns a pointer to square root of arg1 */ float64 dsqrt(arg1) float64 arg1; { float64 result; double tmp; if (!arg1) return (float64)NULL; result = (float64) palloc(sizeof(float64data)); tmp = *arg1; *result = (float64data) sqrt(tmp); return (result); } /* * dcbrt - returns a pointer to cube root of arg1 */ float64 dcbrt(arg1) float64 arg1; { float64 result; double tmp; if (!arg1) return (float64)NULL; result = (float64) palloc(sizeof(float64data)); tmp = *arg1; *result = (float64data) cbrt(tmp); return(result); } /* * dpow - returns a pointer to pow(arg1,arg2) */ float64 dpow(arg1, arg2) float64 arg1, arg2; { float64 result; double tmp1, tmp2; if (!arg1 || !arg2) return (float64)NULL; result = (float64) palloc(sizeof(float64data)); tmp1 = *arg1; tmp2 = *arg2; *result = (float64data) pow(tmp1, tmp2); return(result); } /* * dexp - returns a pointer to the exponential function of arg1 */ float64 dexp(arg1) float64 arg1; { float64 result; double tmp; if (!arg1) return (float64)NULL; result = (float64) palloc(sizeof(float64data)); tmp = *arg1; *result = (float64data) exp(tmp); return(result); } /* * dlog1 - returns a pointer to the natural logarithm of arg1 * ("dlog" is already a logging routine...) */ float64 dlog1(arg1) float64 arg1; { float64 result; double tmp; if (!arg1) return (float64)NULL; result = (float64) palloc(sizeof(float64data)); tmp = *arg1; *result = (float64data) log(tmp); return(result); } /* * ==================== * ARITHMETIC OPERATORS * ==================== */ /* * float48pl - returns a pointer to arg1 + arg2 * float48mi - returns a pointer to arg1 - arg2 * float48mul - returns a pointer to arg1 * arg2 * float48div - returns a pointer to arg1 / arg2 */ float64 float48pl(arg1, arg2) float32 arg1; float64 arg2; { float64 result; if (!arg1 || !arg2) return (float64)NULL; result = (float64) palloc(sizeof(float64data)); *result = *arg1 + *arg2; return(result); } float64 float48mi(arg1, arg2) float32 arg1; float64 arg2; { float64 result; if (!arg1 || !arg2) return (float64)NULL; result = (float64) palloc(sizeof(float64data)); *result = *arg1 - *arg2; return(result); } float64 float48mul(arg1, arg2) float32 arg1; float64 arg2; { float64 result; if (!arg1 || !arg2) return (float64)NULL; result = (float64) palloc(sizeof(float64data)); *result = *arg1 * *arg2; return(result); } float64 float48div(arg1, arg2) float32 arg1; float64 arg2; { float64 result; if (!arg1 || !arg2) return (float64)NULL; result = (float64) palloc(sizeof(float64data)); *result = *arg1 / *arg2; return(result); } /* * float84pl - returns a pointer to arg1 + arg2 * float84mi - returns a pointer to arg1 - arg2 * float84mul - returns a pointer to arg1 * arg2 * float84div - returns a pointer to arg1 / arg2 */ float64 float84pl(arg1, arg2) float64 arg1; float32 arg2; { float64 result; if (!arg1 || !arg2) return (float64)NULL; result = (float64) palloc(sizeof(float64data)); *result = *arg1 + *arg2; return(result); } float64 float84mi(arg1, arg2) float64 arg1; float32 arg2; { float64 result; if (!arg1 || !arg2) return (float64)NULL; result = (float64) palloc(sizeof(float64data)); *result = *arg1 - *arg2; return(result); } float64 float84mul(arg1, arg2) float64 arg1; float32 arg2; { float64 result; if (!arg1 || !arg2) return (float64)NULL; result = (float64) palloc(sizeof(float64data)); *result = *arg1 * *arg2; return(result); } float64 float84div(arg1, arg2) float64 arg1; float32 arg2; { float64 result; if (!arg1 || !arg2) return (float64)NULL; result = (float64) palloc(sizeof(float64data)); *result = *arg1 / *arg2; return(result); } /* * ==================== * COMPARISON OPERATORS * ==================== */ /* * float48{eq,ne,lt,le,gt,ge} - float4/float8 comparison operations */ long float48eq(arg1, arg2) float32 arg1; float64 arg2; { if (!arg1 || !arg2) return (long)NULL; return(*arg1 == *arg2); } long float48ne(arg1, arg2) float32 arg1; float64 arg2; { if (!arg1 || !arg2) return (long)NULL; return(*arg1 != *arg2); } long float48lt(arg1, arg2) float32 arg1; float64 arg2; { if (!arg1 || !arg2) return (long)NULL; return(*arg1 < *arg2); } long float48le(arg1, arg2) float32 arg1; float64 arg2; { if (!arg1 || !arg2) return (long)NULL; return(*arg1 <= *arg2); } long float48gt(arg1, arg2) float32 arg1; float64 arg2; { if (!arg1 || !arg2) return (long)NULL; return(*arg1 > *arg2); } long float48ge(arg1, arg2) float32 arg1; float64 arg2; { if (!arg1 || !arg2) return (long)NULL; return(*arg1 >= *arg2); } /* * float84{eq,ne,lt,le,gt,ge} - float4/float8 comparison operations */ long float84eq(arg1, arg2) float64 arg1; float32 arg2; { if (!arg1 || !arg2) return (long)NULL; return(*arg1 == *arg2); } long float84ne(arg1, arg2) float64 arg1; float32 arg2; { if (!arg1 || !arg2) return (long)NULL; return(*arg1 != *arg2); } long float84lt(arg1, arg2) float64 arg1; float32 arg2; { if (!arg1 || !arg2) return (long)NULL; return(*arg1 < *arg2); } long float84le(arg1, arg2) float64 arg1; float32 arg2; { if (!arg1 || !arg2) return (long)NULL; return(*arg1 <= *arg2); } long float84gt(arg1, arg2) float64 arg1; float32 arg2; { if (!arg1 || !arg2) return (long)NULL; return(*arg1 > *arg2); } long float84ge(arg1, arg2) float64 arg1; float32 arg2; { if (!arg1 || !arg2) return (long)NULL; return(*arg1 >= *arg2); } /* ========== PRIVATE ROUTINES ========== */ /* From "fdlibm" @@ netlib.att.com */ #ifdef NEED_RINT /* @@(#)s_rint.c 5.1 93/09/24 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunPro, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== */ /* * rint(x) * Return x rounded to integral value according to the prevailing * rounding mode. * Method: * Using floating addition. * Exception: * Inexact flag raised if x not equal to rint(x). */ #ifdef __STDC__ static const double #else static double #endif one = 1.0, TWO52[2]={ 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ }; #ifdef __STDC__ static double rint(double x) #else static double rint(x) double x; #endif { int i0,n0,j0,sx; unsigned i,i1; double w,t; n0 = (*((int *)&one)>>29)^1; i0 = *(n0+(int*)&x); sx = (i0>>31)&1; i1 = *(1-n0+(int*)&x); j0 = ((i0>>20)&0x7ff)-0x3ff; if(j0<20) { if(j0<0) { if(((i0&0x7fffffff)|i1)==0) return x; i1 |= (i0&0x0fffff); i0 &= 0xfffe0000; i0 |= ((i1|-i1)>>12)&0x80000; *(n0+(int*)&x)=i0; w = TWO52[sx]+x; t = w-TWO52[sx]; i0 = *(n0+(int*)&t); *(n0+(int*)&t) = (i0&0x7fffffff)|(sx<<31); return t; } else { i = (0x000fffff)>>j0; if(((i0&i)|i1)==0) return x; /* x is integral */ i>>=1; if(((i0&i)|i1)!=0) { if(j0==19) i1 = 0x40000000; else i0 = (i0&(~i))|((0x20000)>>j0); } } } else if (j0>51) { if(j0==0x400) return x+x; /* inf or NaN */ else return x; /* x is integral */ } else { i = ((unsigned)(0xffffffff))>>(j0-20); if((i1&i)==0) return x; /* x is integral */ i>>=1; if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20)); } *(n0+(int*)&x) = i0; *(1-n0+(int*)&x) = i1; w = TWO52[sx]+x; return w-TWO52[sx]; } #endif /* NEED_RINT */ #ifdef NEED_CBRT static double cbrt(x) double x; { int isneg = (x < 0.0); double tmpres = pow(fabs(x), (double) 1.0 / (double) 3.0); return(isneg ? -tmpres : tmpres); } #endif /* NEED_CBRT */ #ifdef NEED_ISINF #if defined(PORTNAME_aix) #ifdef CLASS_CONFLICT /* we want the math symbol */ #undef class #endif /* CLASS_CONFICT */ static int isinf(x) double x; { int fpclass = class(x); if (fpclass == FP_PLUS_INF) return(1); if (fpclass == FP_MINUS_INF) return(-1); return(0); } #endif /* PORTNAME_aix */ #if defined(PORTNAME_ultrix4) #include static int isinf(x) double x; { int fpclass = fp_class_d(x); if (fpclass == FP_POS_INF) return(1); if (fpclass == FP_NEG_INF) return(-1); return(0); } #endif /* PORTNAME_ultrix4 */ #if defined(PORTNAME_alpha) #include static int isinf(x) double x; { int fpclass = fp_class(x); if (fpclass == FP_POS_INF) return(1); if (fpclass == FP_NEG_INF) return(-1); return(0); } #endif /* PORTNAME_alpha */ #if defined(PORTNAME_sparc_solaris) #include static int isinf(d) double d; { fpclass_t type = fpclass(d); switch (type) { case FP_SNAN: case FP_QNAN: case FP_NINF: case FP_PINF: return (1); default: break; } return (0); } #endif /* PORTNAME_sparc_solaris */ #if defined(PORTNAME_irix5) #include static int isinf(x) double x; { int fpclass = fp_class_d(x); if (fpclass == FP_POS_INF) return(1); if (fpclass == FP_NEG_INF) return(-1); return(0); } #endif /* PORTNAME_irix5 */ #endif /* NEED_ISINF */ @ 1.24 log @isinf for solaris @ text @d45 1 a45 1 RcsId("$Header: /import/faerie/faerie/aoki/postgres/src/backend/utils/adt/RCS/float.c,v 1.23 1994/02/12 12:06:27 aoki Exp aoki $"); d1310 14 @ 1.23 log @aix fix @ text @d45 1 a45 1 RcsId("$Header: /usr/local/devel/postgres/src/backend/utils/adt/RCS/float.c,v 1.22 1994/02/09 00:12:24 aoki Exp aoki $"); d1289 21 @ 1.22 log @MINFLOAT and MAXFLOAT are not equivalent to ansi c FLT_MIN and FLT_MAX because the latter are normalized. hence to work around the sunos4 braindamage (no ansi float.h) i put a float.h in port/sparc with the constants we need (which come from the standard anyway). @ text @d45 1 a45 1 RcsId("$Header: /import/faerie/faerie/aoki/postgres/src/backend/utils/adt/RCS/float.c,v 1.21 1994/02/07 14:02:25 aoki Exp aoki $"); d1244 5 @ 1.21 log @the fdlibm cbrt doesn't work >-( use the cheesy pow(x,1/3) hack.. @ text @d36 1 a36 9 #ifdef sparc /* this is because SunOS doesn't have all the ANSI C library headers */ #include #define FLT_MIN MINFLOAT #define FLT_MAX MAXFLOAT #define FLT_DIG 6 #define DBL_DIG 15 #else #include #endif d45 1 a45 1 RcsId("$Header: float.c,v 1.20 94/01/30 04:17:52 aoki Exp $"); d69 7 d172 4 d1233 1 a1233 1 int tmpsign = (x < 0.0) ? -1 : 1; d1236 1 a1236 1 return(tmpsign * tmpres); d1240 45 @ 1.20 log @stole cbrt/rint from the sunpro fdlibm @ text @d53 1 a53 1 RcsId("$Header: /faerie/aoki/postgres/src/backend/utils/adt/RCS/float.c,v 1.19 1994/01/29 02:11:33 jolly Exp aoki $"); d1225 4 a1228 41 /* @@(#)s_cbrt.c 5.1 93/09/24 */ /* * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunPro, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. * ==================================================== * */ /* cbrt(x) * Return cube root of x */ #ifdef __STDC__ static const unsigned #else static unsigned #endif B1 = 715094163, /* B1 = (682-0.03306235651)*2**20 */ B2 = 696219795; /* B2 = (664-0.03306235651)*2**20 */ #ifdef __STDC__ static const double #else static double #endif C = 5.42857142857142815906e-01, /* 19/35 = 0x3FE15F15, 0xF15F15F1 */ D = -7.05306122448979611050e-01, /* -864/1225 = 0xBFE691DE, 0x2532C834 */ E = 1.41428571428571436819e+00, /* 99/70 = 0x3FF6A0EA, 0x0EA0EA0F */ F = 1.60714285714285720630e+00, /* 45/28 = 0x3FF9B6DB, 0x6DB6DB6E */ G = 3.57142857142857150787e-01; /* 5/14 = 0x3FD6DB6D, 0xB6DB6DB7 */ #ifdef __STDC__ double cbrt(double x) #else double cbrt(x) double x; #endif d1230 2 a1231 39 double one = 1.0; int n0,hx; double r,s,t=0.0,w; unsigned *pt = (unsigned *) &t, sign; n0 = ((*(int*)&one)>>29)^1; /* index of high word */ hx = *( n0 + (int*)&x); /* high word of x */ sign=hx&0x80000000; /* sign= sign(x) */ hx ^=sign; if(hx>=0x7ff00000) return(x+x); /* cbrt(NaN,INF) is itself */ if((hx|*(1-n0+(int*)&x))==0) return(x); /* cbrt(0) is itself */ *(n0+(int*)&x) = hx; /* x <- |x| */ /* rough cbrt to 5 bits */ if(hx<0x00100000) /* subnormal number */ {pt[n0]=0x43500000; /* set t= 2**54 */ t*=x; pt[n0]=pt[n0]/3+B2; } else pt[n0]=hx/3+B1; /* new cbrt to 23 bits, may be implemented in single precision */ r=t*t/x; s=C+r*t; t*=G+F/(s+E+D/s); /* chopped to 20 bits and make it larger than cbrt(x) */ pt[1-n0]=0; pt[n0]+=0x00000001; /* one step newton iteration to 53 bits with error less than 0.667 ulps */ s=t*t; /* t*t is exact */ r=x/s; w=t+t; r=(r-t)/(w+r); /* r-s is exact */ t=t+t*r; d1233 1 a1233 3 /* retore the sign bit */ pt[n0] |= sign; return(t); @ 1.19 log @changed float4in() and float8in() functions to use strtod removed obsolete float4inAd() and float8inAd() upped MAXFLOATWIDTH to 64 and MAXDOUBLEWIDTH to 128 (those are sizes for the output strings for float4out and float8out) @ text @d53 1 a53 1 RcsId("$Header: /private/postgres/src/backend/utils/adt/RCS/float.c,v 1.18 1993/08/16 04:20:18 aoki Exp jolly $"); d62 5 a66 1 #ifndef NEED_CBRT d69 5 a73 1 #ifndef NEED_RINT a699 6 #ifdef NEED_RINT if (tmp < 0.0) *result = (float64data) ((long) (tmp - 0.5)); else *result = (float64data) ((long) (tmp + 0.5)); #else /* NEED_RINT */ a700 1 #endif /* NEED_RINT */ a769 3 #ifdef NEED_CBRT *result = (float64data) pow(tmp, 1.0 / 3.0); #else /* NEED_CBRT */ a770 1 #endif /* NEED_CBRT */ d1131 167 d1300 11 a1310 1 /* ========== PRIVATE ROUTINES ========== */ d1312 1 a1312 1 /* (none) */ @ 1.18 log @some systems don't have rint/cbrt, and in fact have broken ones when they do. inserted roll-your-own code for those two routines (parameterized as NEED_RINT and NEED_CBRT). also, i'm not sure i trust hpux cc to get the double * deref right inside an expression, so i stuck in a gratuitous assignment into a temp double variable. the compiler may optimize it away, but.. @ text @d6 1 a6 1 * float4in, float4inAd, float4out, float4outAd, float4abs, float4um d33 10 a42 1 #ifndef sparc a43 3 #else #define FLT_DIG 6 #define DBL_DIG 15 d45 1 d53 1 a53 1 RcsId("$Header: /home2/aoki/postgres/src/backend/utils/adt/RCS/float.c,v 1.17 1993/01/16 03:14:59 aoki Exp aoki $"); d57 3 a59 2 #define MAXFLOATWIDTH 12 #define MAXDOUBLEWIDTH 24 a68 5 char *float8outAd ARGS((float64 num , int precision , char format )); float64 float8inAd ARGS((char *num )); char *float4outAd ARGS((float32 num , int precision , char format )); float32 float4inAd ARGS((char *num )); d83 2 d86 2 a87 4 *result = (float32data) atof(num); return(result); } d89 12 a101 27 /* * float4inAd - advanced float4in, converts "num" to float4, * extended syntax: * {}[+|-]{}{}[.{digit}]{}[] * where is "e" or "E" followed by an integer, * is a space character, is zero through * nine, [] is zero or one, and {} is zero or more. * * uses atof1, code of ingres; file atof1.c */ float32 float4inAd(num) char *num; { float64data val; float32 result = (float32) palloc(sizeof(float32data)); int status; status=atof1(num,&val); if (status==0) { *result = val; return(result); } if (status==-1) printf("\tSyntax error\n"); if (status==1) printf("\tOverflow\n"); d103 2 a104 1 return(result); a126 29 /* float4outAd - converts a float4 number to a string * allowing to specify the output format * * 'format' can be: * e or E: "E" format output * f or F: "F" format output * g or G: "F" format output if it will fit, otherwise * use "E" format. * n or N: same as G, but decimal points will not always * be aligned. * * 'precision' is the number of digits after decimal point. */ char * float4outAd(num, precision, format) float32 num; int precision; char format; { char *ascii = (char *)palloc(MAXFLOATWIDTH); if (!num) return strcpy(ascii, "(null)"); ftoa(*num, ascii, MAXFLOATWIDTH, precision, format); return(ascii); } d139 2 a140 5 *result = (float64data) atof(num); return(result); } d142 4 a145 16 /* * float8inAd - advanced float8in, converts "num" to float8, * extended syntax: * {}[+|-]{}{}[.{digit}]{}[] * where is "e" or "E" followed by an integer, * is a space character, is zero through * nine, [] is zero or one, and {} is zero or more. * */ float64 float8inAd(num) char *num; { float64data val; float64 result = (float64) palloc(sizeof(float64data)); int status; a146 9 status = atof1(num,&val); if (status==0) { *result = val; return(result); } if (status == -1) elog(WARN, "Bad float8 constant"); if (status == 1) elog(WARN, "float8 overflow"); d149 1 a168 31 /* * float8outAd - advanced float8out, converts float8 number to a * string allowing to specify the output format * * 'format' can be: * e or E: "E" format output * f or F: "F" format output * g or G: "F" format output if it will fit, otherwise * use "E" format. * n or N: same as G, but decimal points will not always * be aligned. * * 'precision' is the number of digits after decimal point. */ char * float8outAd(num, precision, format) float64 num; int precision; char format; { char *ascii = (char *)palloc(MAXDOUBLEWIDTH); if (!num) return strcpy(ascii, "(null)"); ftoa(*num, ascii, MAXDOUBLEWIDTH, precision, format); return(ascii); } @ 1.17 log @removed references to utils/fmgr.h and parser/parse.h @ text @d46 1 a46 1 RcsId("$Header: /home2/aoki/postgres/src/backend/utils/adt/RCS/float.c,v 1.16 1992/12/18 21:11:18 mao Exp aoki $"); d53 7 a59 2 extern double atof(); extern double cbrt(); a60 1 d282 1 d290 2 a291 1 *result = (float32data) fabs(*dblarg1); d359 1 d366 2 a367 1 *result = fabs(*arg1); d777 7 a783 2 float64 result = (float64) palloc(sizeof(float64data)); double rint(); d785 9 a793 1 *result = (float64data) rint((double) *arg1); d810 1 d817 1 d819 1 a819 1 *result = (float64data) floor((double) *arg1); d821 1 a821 1 *result = (float64data) -(floor((double) -(*arg1))); d834 1 d841 2 a842 1 *result = (float64data) sqrt((double) *arg1); d855 1 d862 6 a867 1 *result = (float64data) cbrt((double) *arg1); d880 1 d887 3 a889 1 *result = (float64data) pow((double) *arg1, (double) *arg2); d902 1 d909 2 a910 1 *result = (float64data) exp((double) *arg1); d924 1 d931 2 a932 1 *result = (float64data) log((double) *arg1); @ 1.16 log @on sparcs, need to know FLT_DIG and DBL_DIG @ text @d42 1 a42 1 #include "utils/fmgr.h" d46 1 a46 1 RcsId("$Header: /private/mao/postgres/src/utils/adt/RCS/float.c,v 1.15 1992/09/24 21:19:04 mao Exp $"); @ 1.15 log @change format of displayed floating point numbers -- don't always use n.nnnnnnesdd notation, as this is impossible to read @ text @d33 1 d35 4 d46 1 a46 1 RcsId("$Header: /private/mao/postgres/src/utils/adt/RCS/float.c,v 1.14 1992/08/16 03:41:41 mer Exp mao $"); @ 1.14 log @palloc more space for float output funcs (were overstepping bounds) also, rounding function is available on dec platforms as well @ text @d33 1 d41 1 a41 1 RcsId("$Header: /private/mer/pg/src/utils/adt/RCS/float.c,v 1.13 1992/03/17 01:09:43 olson Exp mer $"); d44 3 a46 7 #define FORMAT 'e' /* use "E" output format as standard format */ #define MAXFLOATWIDTH 12 /* "n.nnnnnE+nn\0" format */ #define FLOATPRECISION 5 /* number of significant digits */ /* after decimal point */ #define MAXDOUBLEWIDTH 24 /* "n.nnnnnnnnnnnnnnnnnE+nn\0" format */ #define DOUBLEPRECISION 17 /* number of significant digits */ /* after decimal point */ d124 1 a124 1 ftoa((double) *num, ascii, MAXFLOATWIDTH, FLOATPRECISION, FORMAT); d220 1 a220 1 ftoa(*num, ascii, MAXDOUBLEWIDTH, DOUBLEPRECISION, FORMAT); @ 1.13 log @fix for compilation on Suns @ text @d40 1 a40 1 RcsId("$Header: src/utils/adt/RCS/float.c,v 1.12 92/03/16 22:42:11 mer Exp Locker: olson $"); d122 1 a122 1 char *ascii = (char *)palloc(MAXFLOATWIDTH); d218 1 a218 1 char *ascii = (char *)palloc(MAXDOUBLEWIDTH); a766 1 #ifdef sun d768 1 a771 3 #else elog(WARN, "dround: not implemented yet for non-sun machines"); #endif @ 1.12 log @comparison functions won't dump core now, but operations just pass the buck @ text @a37 2 #ifndef sun a38 1 #endif d40 1 a40 1 RcsId("$Header: /users/mer/pg/src/utils/adt/RCS/float.c,v 1.11 1992/01/13 02:21:26 mao Exp mer $"); @ 1.11 log @flatten include file graph @ text @d43 1 a43 1 RcsId("$Header: RCS/float.c,v 1.10 91/11/09 01:49:10 mer Exp Locker: mer $"); d127 3 d155 4 a158 1 d205 1 a205 1 printf("\tSyntax error\n"); d207 1 a207 1 printf("\tOverflow\n"); d222 4 a225 1 d253 3 d277 2 a278 2 float64 dblarg1 = ftod(arg1); float32 result = (float32) palloc(sizeof(float32data)); d280 6 d297 1 a297 1 float32 result = (float32) palloc(sizeof(float32data)); d299 5 d313 6 a318 1 float32 result = (float32) palloc(sizeof(float32data)); d329 6 a334 1 float32 result = (float32) palloc(sizeof(float32data)); d353 1 a353 1 float64 result = (float64) palloc(sizeof(float64data)); d355 5 d372 1 a372 1 float64 result = (float64) palloc(sizeof(float64data)); d374 5 d388 6 a393 1 float64 result = (float64) palloc(sizeof(float64data)); d404 6 a409 1 float64 result = (float64) palloc(sizeof(float64data)); d433 7 a439 1 float32 result = (float32) palloc(sizeof(float32data)); d448 7 a454 1 float32 result = (float32) palloc(sizeof(float32data)); d464 7 a470 1 float32 result = (float32) palloc(sizeof(float32data)); d479 7 a485 1 float32 result = (float32) palloc(sizeof(float32data)); d494 3 d512 7 a518 1 float64 result = (float64) palloc(sizeof(float64data)); d527 7 a533 1 float64 result = (float64) palloc(sizeof(float64data)); d542 7 a548 2 float64 result = (float64) palloc(sizeof(float64data)); d557 7 a563 1 float64 result = (float64) palloc(sizeof(float64data)); d572 3 d592 6 a597 1 { return(*arg1 == *arg2); } d602 6 a607 1 { return(*arg1 != *arg2); } d612 6 a617 1 { return(*arg1 < *arg2); } d622 6 a627 1 { return(*arg1 <= *arg2); } d632 6 a637 1 { return(*arg1 > *arg2); } d642 6 a647 1 { return(*arg1 >= *arg2); } d655 6 a660 1 { return(*arg1 == *arg2); } d665 6 a670 1 { return(*arg1 != *arg2); } d675 6 a680 1 { return(*arg1 < *arg2); } d685 6 a690 1 { return(*arg1 <= *arg2); } d695 6 a700 1 { return(*arg1 > *arg2); } d705 3 a707 1 { return(*arg1 >= *arg2); } d709 3 d726 1 a726 1 float64 result = (float64) palloc(sizeof(float64data)); d728 5 d745 1 a745 1 float32 result = (float32) palloc(sizeof(float32data)); d747 5 d792 6 a797 1 float64 result = (float64) palloc(sizeof(float64data)); d814 6 a819 1 float64 result = (float64) palloc(sizeof(float64data)); d833 6 a838 1 float64 result = (float64) palloc(sizeof(float64data)); d852 6 a857 1 float64 result = (float64) palloc(sizeof(float64data)); d871 6 a876 1 float64 result = (float64) palloc(sizeof(float64data)); d891 6 a896 1 float64 result = (float64) palloc(sizeof(float64data)); d920 7 a926 1 float64 result = (float64) palloc(sizeof(float64data)); d936 7 a942 1 float64 result = (float64) palloc(sizeof(float64data)); d952 7 a958 2 float64 result = (float64) palloc(sizeof(float64data)); d968 7 a974 1 float64 result = (float64) palloc(sizeof(float64data)); d990 7 a996 1 float64 result = (float64) palloc(sizeof(float64data)); d1006 7 a1012 1 float64 result = (float64) palloc(sizeof(float64data)); d1023 7 a1029 1 float64 result = (float64) palloc(sizeof(float64data)); d1039 7 a1045 1 float64 result = (float64) palloc(sizeof(float64data)); d1063 6 a1068 1 { return(*arg1 == *arg2); } d1074 6 a1079 1 { return(*arg1 != *arg2); } d1085 6 a1090 1 { return(*arg1 < *arg2); } d1096 6 a1101 1 { return(*arg1 <= *arg2); } d1107 6 a1112 1 { return(*arg1 > *arg2); } d1118 6 a1123 1 { return(*arg1 >= *arg2); } d1132 6 a1137 1 { return(*arg1 == *arg2); } d1143 6 a1148 1 { return(*arg1 != *arg2); } d1154 6 a1159 1 { return(*arg1 < *arg2); } d1165 6 a1170 1 { return(*arg1 <= *arg2); } d1176 6 a1181 1 { return(*arg1 > *arg2); } d1187 6 a1192 1 { return(*arg1 >= *arg2); } @ 1.10 log @function prototype additions and error fixes @ text @a17 3 * Routines for (non-builtin) floating point operations. * (included if FMGR_MATH is defined in h/fmgr.h) * d37 1 d43 1 a43 1 RcsId("$Header: /users/mer/postgres/src/utils/adt/RCS/float.c,v 1.9 1991/11/05 05:37:11 mer Exp mer $"); a580 1 #ifdef FMGR_MATH a879 1 #endif FMGR_MATH @ 1.9 log @add functions for aggregate definitions @ text @d45 1 a45 1 RcsId("$Header: /users/mer/postgres/src/utils/adt/RCS/float.c,v 1.8 1990/09/25 16:49:15 kemnitz Exp mer $"); a58 2 float64 ftod(); float32 dtof(); d60 4 d127 1 a127 1 char *ascii = palloc(MAXFLOATWIDTH); d153 1 a153 1 char *ascii = palloc(MAXFLOATWIDTH); d217 1 a217 1 char *ascii = palloc(MAXDOUBLEWIDTH); d244 1 a244 1 char *ascii = palloc(MAXDOUBLEWIDTH); @ 1.8 log @Updating from revision 1.7 to revision 1.8 @ text @d45 1 a45 1 RcsId("$Header: RCS/float.c,v 1.8 90/08/15 08:19:42 cimarron Exp $"); d285 21 d340 22 d374 1 d413 8 d426 1 d463 8 @ 1.7 log @Working version of C-only demo @ text @a33 4 #include "c.h" #include "postgres.h" #include "fmgr.h" d38 3 d42 1 a42 1 #include "log.h" d45 1 a45 1 RcsId("$Header: /usr6/postgres/mao/postgres/src/utils/adt/RCS/float.c,v 1.6 89/04/18 22:24:37 dillon Exp $"); @ 1.6 log @removed cbrt() to dynix port @ text @d46 1 a46 1 RcsId("$Header: /usr6/postgres/dillon/ptree/src/utils/adt/RCS/float.c,v 1.5 89/04/17 19:04:56 dillon Exp $"); @ 1.5 log @*** empty log message *** @ text @d46 1 a46 1 RcsId("$Header: /usr6/postgres/dillon/ptree/src/utils/adt/RCS/float.c,v 1.4 89/04/17 18:55:10 dillon Exp $"); a822 9 #ifdef sequent double cbrt(x) double x; { return(pow(x, 1.0/3.0)); } #endif @ 1.4 log @added cvrt for sequent @ text @d46 1 a46 1 RcsId("$Header: float.c,v 1.3 89/04/14 18:32:13 dillon Locked $"); d58 1 @ 1.3 log @sequent hacks @ text @d46 1 a46 1 RcsId("$Header: /usr6/postgres/dillon/ptree/src/utils/adt/RCS/float.c,v 1.2 89/02/02 16:10:50 aoki Stab $"); d821 10 @ 1.2 log @MERGE WITH OLD TREE @ text @d42 3 a44 1 RcsId("$Header: float.c,v 1.4 88/06/26 23:10:47 aoki Locked $"); d46 3 d534 1 d539 3 @ 1.1 log @Initial revision @ text @a0 1 a1 26 * * POSTGRES Data Base Management System * * Copyright (c) 1988 Regents of the University of California * * Permission to use, copy, modify, and distribute this software and its * documentation for educational, research, and non-profit purposes and * without fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright notice and * this permission notice appear in supporting documentation, and that * the name of the University of California not be used in advertising * or publicity pertaining to distribution of the software without * specific, written prior permission. Permission to incorporate this * software into commercial products can be obtained from the Campus * Software Office, 295 Evans Hall, University of California, Berkeley, * Ca., 94720 provided only that the the requestor give the University * of California a free licence to any derived software for educational * and research purposes. The University of California makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * */ /* d42 1 a42 1 RcsId("$Header: float.c,v 1.1 88/11/11 16:35:43 postgres Exp $"); @