1 /*-------------------------------------------------------------------------
4 * Functions for the built-in floating-point types.
6 * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * $Header: /cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.61 2000/06/14 18:17:42 petere Exp $
13 *-------------------------------------------------------------------------
18 * float4in, float4out, float4abs, float4um
20 * float8in, float8inAd, float8out, float8outAd, float8abs, float8um
21 * Arithmetic operators:
22 * float4pl, float4mi, float4mul, float4div
23 * float8pl, float8mi, float8mul, float8div
24 * Comparison operators:
25 * float4eq, float4ne, float4lt, float4le, float4gt, float4ge
26 * float8eq, float8ne, float8lt, float8le, float8gt, float8ge
27 * Conversion routines:
28 * ftod, dtof, i4tod, dtoi4, i2tod, dtoi2, itof, ftoi, i2tof, ftoi2
31 * dround, dtrunc, dsqrt, dcbrt, dpow, dexp, dlog1
32 * Arithmetic operators:
33 * float48pl, float48mi, float48mul, float48div
34 * float84pl, float84mi, float84mul, float84div
35 * Comparison operators:
36 * float48eq, float48ne, float48lt, float48le, float48gt, float48ge
37 * float84eq, float84ne, float84lt, float84le, float84gt, float84ge
39 * (You can do the arithmetic and comparison stuff using conversion
40 * routines, but then you pay the overhead of converting...)
42 * XXX GLUESOME STUFF. FIX IT! -AY '94
44 * Added some additional conversion routines and cleaned up
45 * a bit of the existing code. Need to change the error checking
46 * for calls to pow(), exp() since on some machines (my Linux box
47 * included) these routines do not set errno. - tgl 97/05/10
51 #include <float.h> /* faked on sunos4 */
59 #define MAXINT INT_MAX
67 /* for finite() on Solaris */
73 #include "utils/builtins.h"
75 static void CheckFloat8Val(double val);
82 #define SHRT_MAX 32767
85 #define SHRT_MIN (-32768)
88 #define FORMAT 'g' /* use "g" output format as standard
90 /* not sure what the following should be, but better to make it over-sufficient */
91 #define MAXFLOATWIDTH 64
92 #define MAXDOUBLEWIDTH 128
94 #if !(NeXT && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_2)
95 /* NS3.3 has conflicting declarations of these in <math.h> */
98 extern double atof(const char *p);
104 static double cbrt(double x);
107 #if !defined(nextstep)
108 extern double cbrt(double x);
115 static double rint(double x);
118 extern double rint(double x);
124 /* ========== USER I/O ROUTINES ========== */
127 #define FLOAT4_MAX FLT_MAX
128 #define FLOAT4_MIN FLT_MIN
129 #define FLOAT8_MAX DBL_MAX
130 #define FLOAT8_MIN DBL_MIN
134 check to see if a float4 val is outside of
135 the FLOAT4_MIN, FLOAT4_MAX bounds.
137 raise an elog warning if it is
140 CheckFloat4Val(double val)
144 * defining unsafe floats's will make float4 and float8 ops faster at
145 * the cost of safety, of course!
150 if (fabs(val) > FLOAT4_MAX)
151 elog(ERROR, "Bad float4 input format -- overflow");
152 if (val != 0.0 && fabs(val) < FLOAT4_MIN)
153 elog(ERROR, "Bad float4 input format -- underflow");
155 #endif /* UNSAFE_FLOATS */
159 check to see if a float8 val is outside of
160 the FLOAT8_MIN, FLOAT8_MAX bounds.
162 raise an elog warning if it is
165 CheckFloat8Val(double val)
169 * defining unsafe floats's will make float4 and float8 ops faster at
170 * the cost of safety, of course!
175 if (fabs(val) > FLOAT8_MAX)
176 elog(ERROR, "Bad float8 input format -- overflow");
177 if (val != 0.0 && fabs(val) < FLOAT8_MIN)
178 elog(ERROR, "Bad float8 input format -- underflow");
180 #endif /* UNSAFE_FLOATS */
184 * float4in - converts "num" to float
186 * {<sp>} [+|-] {digit} [.{digit}] [<exp>]
187 * where <sp> is a space, digit is 0-9,
188 * <exp> is "e" or "E" followed by an integer.
193 float32 result = (float32) palloc(sizeof(float32data));
198 val = strtod(num, &endptr);
201 /* Should we accept "NaN" or "Infinity" for float4? */
202 elog(ERROR, "Bad float4 input format '%s'", num);
207 elog(ERROR, "Input '%s' is out of range for float4", num);
211 * if we get here, we have a legal double, still need to check to see
212 * if it's a legal float
222 * float4out - converts a float4 number to a string
223 * using a standard output format
226 float4out(float32 num)
228 char *ascii = (char *) palloc(MAXFLOATWIDTH + 1);
231 return strcpy(ascii, "(null)");
233 sprintf(ascii, "%.*g", FLT_DIG, *num);
239 * float8in - converts "num" to float8
241 * {<sp>} [+|-] {digit} [.{digit}] [<exp>]
242 * where <sp> is a space, digit is 0-9,
243 * <exp> is "e" or "E" followed by an integer.
248 float64 result = (float64) palloc(sizeof(float64data));
253 val = strtod(num, &endptr);
256 if (strcasecmp(num, "NaN") == 0)
258 else if (strcasecmp(num, "Infinity") == 0)
261 elog(ERROR, "Bad float8 input format '%s'", num);
266 elog(ERROR, "Input '%s' is out of range for float8", num);
277 * float8out - converts float8 number to a string
278 * using a standard output format
281 float8out(float64 num)
283 char *ascii = (char *) palloc(MAXDOUBLEWIDTH + 1);
286 return strcpy(ascii, "(null)");
289 return strcpy(ascii, "NaN");
291 return strcpy(ascii, "Infinity");
293 sprintf(ascii, "%.*g", DBL_DIG, *num);
297 /* ========== PUBLIC ROUTINES ========== */
301 * ======================
302 * FLOAT4 BASE OPERATIONS
303 * ======================
307 * float4abs - returns a pointer to |arg1| (absolute value)
310 float4abs(float32 arg1)
316 return (float32) NULL;
322 result = (float32) palloc(sizeof(float32data));
328 * float4um - returns a pointer to -arg1 (unary minus)
331 float4um(float32 arg1)
337 return (float32) NULL;
339 val = ((*arg1 != 0) ? -(*arg1) : *arg1);
342 result = (float32) palloc(sizeof(float32data));
348 float4larger(float32 arg1, float32 arg2)
353 return (float32) NULL;
355 result = (float32) palloc(sizeof(float32data));
357 *result = ((*arg1 > *arg2) ? *arg1 : *arg2);
362 float4smaller(float32 arg1, float32 arg2)
367 return (float32) NULL;
369 result = (float32) palloc(sizeof(float32data));
371 *result = ((*arg1 > *arg2) ? *arg2 : *arg1);
376 * ======================
377 * FLOAT8 BASE OPERATIONS
378 * ======================
382 * float8abs - returns a pointer to |arg1| (absolute value)
385 float8abs(float64 arg1)
391 return (float64) NULL;
393 result = (float64) palloc(sizeof(float64data));
403 * float8um - returns a pointer to -arg1 (unary minus)
406 float8um(float64 arg1)
412 return (float64) NULL;
414 val = ((*arg1 != 0) ? -(*arg1) : *arg1);
417 result = (float64) palloc(sizeof(float64data));
423 float8larger(float64 arg1, float64 arg2)
428 return (float64) NULL;
430 result = (float64) palloc(sizeof(float64data));
432 *result = ((*arg1 > *arg2) ? *arg1 : *arg2);
437 float8smaller(float64 arg1, float64 arg2)
442 return (float64) NULL;
444 result = (float64) palloc(sizeof(float64data));
446 *result = ((*arg1 > *arg2) ? *arg2 : *arg1);
452 * ====================
453 * ARITHMETIC OPERATORS
454 * ====================
458 * float4pl - returns a pointer to arg1 + arg2
459 * float4mi - returns a pointer to arg1 - arg2
460 * float4mul - returns a pointer to arg1 * arg2
461 * float4div - returns a pointer to arg1 / arg2
462 * float4inc - returns a poniter to arg1 + 1.0
465 float4pl(float32 arg1, float32 arg2)
471 return (float32) NULL;
476 result = (float32) palloc(sizeof(float32data));
483 float4mi(float32 arg1, float32 arg2)
489 return (float32) NULL;
494 result = (float32) palloc(sizeof(float32data));
500 float4mul(float32 arg1, float32 arg2)
506 return (float32) NULL;
511 result = (float32) palloc(sizeof(float32data));
517 float4div(float32 arg1, float32 arg2)
523 return (float32) NULL;
526 elog(ERROR, "float4div: divide by zero error");
531 result = (float32) palloc(sizeof(float32data));
537 float4inc(float32 arg1)
543 return (float32) NULL;
545 val = *arg1 + (float32data) 1.0;
548 result = (float32) palloc(sizeof(float32data));
554 * float8pl - returns a pointer to arg1 + arg2
555 * float8mi - returns a pointer to arg1 - arg2
556 * float8mul - returns a pointer to arg1 * arg2
557 * float8div - returns a pointer to arg1 / arg2
558 * float8inc - returns a pointer to arg1 + 1.0
561 float8pl(float64 arg1, float64 arg2)
567 return (float64) NULL;
569 result = (float64) palloc(sizeof(float64data));
578 float8mi(float64 arg1, float64 arg2)
584 return (float64) NULL;
586 result = (float64) palloc(sizeof(float64data));
595 float8mul(float64 arg1, float64 arg2)
601 return (float64) NULL;
603 result = (float64) palloc(sizeof(float64data));
612 float8div(float64 arg1, float64 arg2)
618 return (float64) NULL;
620 result = (float64) palloc(sizeof(float64data));
623 elog(ERROR, "float8div: divide by zero error");
632 float8inc(float64 arg1)
638 return (float64) NULL;
640 val = *arg1 + (float64data) 1.0;
642 result = (float64) palloc(sizeof(float64data));
649 * ====================
650 * COMPARISON OPERATORS
651 * ====================
655 * float4{eq,ne,lt,le,gt,ge} - float4/float4 comparison operations
658 float4eq(float32 arg1, float32 arg2)
663 return *arg1 == *arg2;
667 float4ne(float32 arg1, float32 arg2)
672 return *arg1 != *arg2;
676 float4lt(float32 arg1, float32 arg2)
681 return *arg1 < *arg2;
685 float4le(float32 arg1, float32 arg2)
690 return *arg1 <= *arg2;
694 float4gt(float32 arg1, float32 arg2)
699 return *arg1 > *arg2;
703 float4ge(float32 arg1, float32 arg2)
708 return *arg1 >= *arg2;
712 * float8{eq,ne,lt,le,gt,ge} - float8/float8 comparison operations
715 float8eq(float64 arg1, float64 arg2)
720 return *arg1 == *arg2;
724 float8ne(float64 arg1, float64 arg2)
729 return *arg1 != *arg2;
733 float8lt(float64 arg1, float64 arg2)
738 return *arg1 < *arg2;
742 float8le(float64 arg1, float64 arg2)
747 return *arg1 <= *arg2;
751 float8gt(float64 arg1, float64 arg2)
756 return *arg1 > *arg2;
760 float8ge(float64 arg1, float64 arg2)
765 return *arg1 >= *arg2;
770 * ===================
771 * CONVERSION ROUTINES
772 * ===================
776 * ftod - converts a float4 number to a float8 number
784 return (float64) NULL;
786 result = (float64) palloc(sizeof(float64data));
794 * dtof - converts a float8 number to a float4 number
802 return (float32) NULL;
804 CheckFloat4Val(*num);
806 result = (float32) palloc(sizeof(float32data));
814 * dtoi4 - converts a float8 number to an int4 number
822 return 0; /* fmgr will return NULL anyway */
824 if ((*num < INT_MIN) || (*num > INT_MAX))
825 elog(ERROR, "dtoi4: integer out of range");
833 * dtoi2 - converts a float8 number to an int2 number
836 dtoi2(PG_FUNCTION_ARGS)
838 float8 num = PG_GETARG_FLOAT8(0);
841 if ((num < SHRT_MIN) || (num > SHRT_MAX))
842 elog(ERROR, "dtoi2: integer out of range");
844 result = (int16) rint(num);
845 PG_RETURN_INT16(result);
850 * i4tod - converts an int4 number to a float8 number
853 i4tod(PG_FUNCTION_ARGS)
855 int32 num = PG_GETARG_INT32(0);
859 PG_RETURN_FLOAT8(result);
864 * i2tod - converts an int2 number to a float8 number
867 i2tod(PG_FUNCTION_ARGS)
869 int16 num = PG_GETARG_INT16(0);
873 PG_RETURN_FLOAT8(result);
878 * ftoi4 - converts a float8 number to an int4 number
886 return 0; /* fmgr will return NULL anyway */
888 if ((*num < INT_MIN) || (*num > INT_MAX))
889 elog(ERROR, "ftoi4: integer out of range");
897 * ftoi2 - converts a float4 number to an int2 number
900 ftoi2(PG_FUNCTION_ARGS)
902 float4 num = PG_GETARG_FLOAT4(0);
905 if ((num < SHRT_MIN) || (num > SHRT_MAX))
906 elog(ERROR, "ftoi2: integer out of range");
908 result = (int16) rint(num);
909 PG_RETURN_INT16(result);
914 * i4tof - converts an int4 number to a float8 number
917 i4tof(PG_FUNCTION_ARGS)
919 int32 num = PG_GETARG_INT32(0);
923 PG_RETURN_FLOAT4(result);
928 * i2tof - converts an int2 number to a float4 number
931 i2tof(PG_FUNCTION_ARGS)
933 int16 num = PG_GETARG_INT16(0);
937 PG_RETURN_FLOAT4(result);
942 * float8_text - converts a float8 number to a text string
945 float8_text(float64 num)
951 str = float8out(num);
952 len = (strlen(str) + VARHDRSZ);
954 result = palloc(len);
956 VARSIZE(result) = len;
957 memmove(VARDATA(result), str, (len - VARHDRSZ));
961 } /* float8_text() */
965 * text_float8 - converts a text string to a float8 number
968 text_float8(text *string)
974 len = (VARSIZE(string) - VARHDRSZ);
975 str = palloc(len + 1);
976 memmove(str, VARDATA(string), len);
979 result = float8in(str);
983 } /* text_float8() */
987 * float4_text - converts a float4 number to a text string
990 float4_text(float32 num)
996 str = float4out(num);
997 len = (strlen(str) + VARHDRSZ);
999 result = palloc(len);
1001 VARSIZE(result) = len;
1002 memmove(VARDATA(result), str, (len - VARHDRSZ));
1006 } /* float4_text() */
1010 * text_float4 - converts a text string to a float4 number
1013 text_float4(text *string)
1019 len = (VARSIZE(string) - VARHDRSZ);
1020 str = palloc(len + 1);
1021 memmove(str, VARDATA(string), len);
1022 *(str + len) = '\0';
1024 result = float4in(str);
1028 } /* text_float4() */
1032 * =======================
1033 * RANDOM FLOAT8 OPERATORS
1034 * =======================
1038 * dround - returns a pointer to ROUND(arg1)
1041 dround(float64 arg1)
1047 return (float64) NULL;
1049 result = (float64) palloc(sizeof(float64data));
1052 *result = (float64data) rint(tmp);
1058 * dtrunc - returns a pointer to truncation of arg1,
1059 * arg1 >= 0 ... the greatest integer as float8 less
1060 * than or equal to arg1
1061 * arg1 < 0 ... the greatest integer as float8 greater
1062 * than or equal to arg1
1065 dtrunc(float64 arg1)
1071 return (float64) NULL;
1073 result = (float64) palloc(sizeof(float64data));
1077 *result = (float64data) floor(tmp);
1079 *result = (float64data) -(floor(-tmp));
1085 * dsqrt - returns a pointer to square root of arg1
1094 return (float64) NULL;
1096 result = (float64) palloc(sizeof(float64data));
1099 *result = (float64data) sqrt(tmp);
1105 * dcbrt - returns a pointer to cube root of arg1
1114 return (float64) NULL;
1116 result = (float64) palloc(sizeof(float64data));
1119 *result = (float64data) cbrt(tmp);
1125 * dpow - returns a pointer to pow(arg1,arg2)
1128 dpow(float64 arg1, float64 arg2)
1135 return (float64) NULL;
1137 result = (float64) palloc(sizeof(float64data));
1143 * We must check both for errno getting set and for a NaN result, in
1144 * order to deal with the vagaries of different platforms...
1147 *result = (float64data) pow(tmp1, tmp2);
1153 elog(ERROR, "pow() result is out of range");
1155 CheckFloat8Val(*result);
1161 * dexp - returns a pointer to the exponential function of arg1
1170 return (float64) NULL;
1172 result = (float64) palloc(sizeof(float64data));
1177 * We must check both for errno getting set and for a NaN result, in
1178 * order to deal with the vagaries of different platforms. Also, a
1179 * zero result implies unreported underflow.
1182 *result = (float64data) exp(tmp);
1183 if (errno != 0 || *result == 0.0
1188 elog(ERROR, "exp() result is out of range");
1190 CheckFloat8Val(*result);
1196 * dlog1 - returns a pointer to the natural logarithm of arg1
1197 * ("dlog" is already a logging routine...)
1205 if (!PointerIsValid(arg1))
1206 return (float64) NULL;
1208 result = (float64) palloc(sizeof(float64data));
1212 elog(ERROR, "can't take log of zero");
1214 elog(ERROR, "can't take log of a negative number");
1215 *result = (float64data) log(tmp);
1217 CheckFloat8Val(*result);
1223 * dlog10 - returns a pointer to the base 10 logarithm of arg1
1226 dlog10(float64 arg1)
1231 if (!PointerIsValid(arg1))
1232 return (float64) NULL;
1234 result = (float64) palloc(sizeof(float64data));
1238 elog(ERROR, "can't take log of zero");
1240 elog(ERROR, "can't take log of a negative number");
1241 *result = (float64data) log10(tmp);
1243 CheckFloat8Val(*result);
1249 * dacos - returns a pointer to the arccos of arg1 (radians)
1257 if (!PointerIsValid(arg1))
1258 return (float64) NULL;
1260 result = (float64) palloc(sizeof(float64data));
1264 *result = (float64data) acos(tmp);
1270 elog(ERROR, "dacos(%f) input is out of range", *arg1);
1272 CheckFloat8Val(*result);
1278 * dasin - returns a pointer to the arcsin of arg1 (radians)
1286 if (!PointerIsValid(arg1))
1287 return (float64) NULL;
1289 result = (float64) palloc(sizeof(float64data));
1293 *result = (float64data) asin(tmp);
1299 elog(ERROR, "dasin(%f) input is out of range", *arg1);
1301 CheckFloat8Val(*result);
1307 * datan - returns a pointer to the arctan of arg1 (radians)
1315 if (!PointerIsValid(arg1))
1316 return (float64) NULL;
1318 result = (float64) palloc(sizeof(float64data));
1322 *result = (float64data) atan(tmp);
1328 elog(ERROR, "atan(%f) input is out of range", *arg1);
1330 CheckFloat8Val(*result);
1336 * atan2 - returns a pointer to the arctan2 of arg1 (radians)
1339 datan2(float64 arg1, float64 arg2)
1343 if (!PointerIsValid(arg1) || !PointerIsValid(arg1))
1344 return (float64) NULL;
1346 result = (float64) palloc(sizeof(float64data));
1349 *result = (float64data) atan2(*arg1, *arg2);
1355 elog(ERROR, "atan2(%f,%f) input is out of range", *arg1, *arg2);
1357 CheckFloat8Val(*result);
1363 * dcos - returns a pointer to the cosine of arg1 (radians)
1371 if (!PointerIsValid(arg1))
1372 return (float64) NULL;
1374 result = (float64) palloc(sizeof(float64data));
1378 *result = (float64data) cos(tmp);
1384 elog(ERROR, "dcos(%f) input is out of range", *arg1);
1386 CheckFloat8Val(*result);
1392 * dcot - returns a pointer to the cotangent of arg1 (radians)
1400 if (!PointerIsValid(arg1))
1401 return (float64) NULL;
1403 result = (float64) palloc(sizeof(float64data));
1407 *result = (float64data) tan(tmp);
1408 if ((errno != 0) || (*result == 0.0)
1413 elog(ERROR, "dcot(%f) input is out of range", *arg1);
1415 *result = 1.0 / (*result);
1416 CheckFloat8Val(*result);
1422 * dsin - returns a pointer to the sine of arg1 (radians)
1430 if (!PointerIsValid(arg1))
1431 return (float64) NULL;
1433 result = (float64) palloc(sizeof(float64data));
1437 *result = (float64data) sin(tmp);
1443 elog(ERROR, "dsin(%f) input is out of range", *arg1);
1445 CheckFloat8Val(*result);
1451 * dtan - returns a pointer to the tangent of arg1 (radians)
1459 if (!PointerIsValid(arg1))
1460 return (float64) NULL;
1462 result = (float64) palloc(sizeof(float64data));
1466 *result = (float64data) tan(tmp);
1472 elog(ERROR, "dtan(%f) input is out of range", *arg1);
1474 CheckFloat8Val(*result);
1480 /* from my RH5.2 gcc math.h file - thomas 2000-04-03 */
1481 #define M_PI 3.14159265358979323846
1486 * degrees - returns a pointer to degrees converted from radians
1489 degrees(float64 arg1)
1494 return (float64) NULL;
1496 result = (float64) palloc(sizeof(float64data));
1498 *result = ((*arg1) * (180.0 / M_PI));
1500 CheckFloat8Val(*result);
1506 * dpi - returns a pointer to degrees converted to radians
1513 result = (float64) palloc(sizeof(float64data));
1522 * radians - returns a pointer to radians converted from degrees
1525 radians(float64 arg1)
1530 return (float64) NULL;
1532 result = (float64) palloc(sizeof(float64data));
1534 *result = ((*arg1) * (M_PI / 180.0));
1536 CheckFloat8Val(*result);
1542 * drandom - returns a random number
1549 result = (float64) palloc(sizeof(float64data));
1551 /* result 0.0-1.0 */
1552 *result = (((double) random()) / RAND_MAX);
1554 CheckFloat8Val(*result);
1560 * setseed - set seed for the random number generator
1563 setseed(float64 seed)
1565 int iseed = ((*seed) * RAND_MAX);
1567 srandom((unsigned int) ((*seed) * RAND_MAX));
1574 * ====================
1575 * ARITHMETIC OPERATORS
1576 * ====================
1580 * float48pl - returns a pointer to arg1 + arg2
1581 * float48mi - returns a pointer to arg1 - arg2
1582 * float48mul - returns a pointer to arg1 * arg2
1583 * float48div - returns a pointer to arg1 / arg2
1586 float48pl(float32 arg1, float64 arg2)
1591 return (float64) NULL;
1593 result = (float64) palloc(sizeof(float64data));
1595 *result = *arg1 + *arg2;
1596 CheckFloat8Val(*result);
1601 float48mi(float32 arg1, float64 arg2)
1606 return (float64) NULL;
1608 result = (float64) palloc(sizeof(float64data));
1610 *result = *arg1 - *arg2;
1611 CheckFloat8Val(*result);
1616 float48mul(float32 arg1, float64 arg2)
1621 return (float64) NULL;
1623 result = (float64) palloc(sizeof(float64data));
1625 *result = *arg1 * *arg2;
1626 CheckFloat8Val(*result);
1631 float48div(float32 arg1, float64 arg2)
1636 return (float64) NULL;
1638 result = (float64) palloc(sizeof(float64data));
1641 elog(ERROR, "float48div: divide by zero");
1643 *result = *arg1 / *arg2;
1644 CheckFloat8Val(*result);
1649 * float84pl - returns a pointer to arg1 + arg2
1650 * float84mi - returns a pointer to arg1 - arg2
1651 * float84mul - returns a pointer to arg1 * arg2
1652 * float84div - returns a pointer to arg1 / arg2
1655 float84pl(float64 arg1, float32 arg2)
1660 return (float64) NULL;
1662 result = (float64) palloc(sizeof(float64data));
1664 *result = *arg1 + *arg2;
1665 CheckFloat8Val(*result);
1670 float84mi(float64 arg1, float32 arg2)
1675 return (float64) NULL;
1677 result = (float64) palloc(sizeof(float64data));
1679 *result = *arg1 - *arg2;
1680 CheckFloat8Val(*result);
1685 float84mul(float64 arg1, float32 arg2)
1691 return (float64) NULL;
1693 result = (float64) palloc(sizeof(float64data));
1695 *result = *arg1 * *arg2;
1696 CheckFloat8Val(*result);
1701 float84div(float64 arg1, float32 arg2)
1706 return (float64) NULL;
1708 result = (float64) palloc(sizeof(float64data));
1711 elog(ERROR, "float48div: divide by zero");
1713 *result = *arg1 / *arg2;
1714 CheckFloat8Val(*result);
1719 * ====================
1720 * COMPARISON OPERATORS
1721 * ====================
1725 * float48{eq,ne,lt,le,gt,ge} - float4/float8 comparison operations
1728 float48eq(float32 arg1, float64 arg2)
1733 return *arg1 == *arg2;
1737 float48ne(float32 arg1, float64 arg2)
1742 return *arg1 != *arg2;
1746 float48lt(float32 arg1, float64 arg2)
1751 return *arg1 < *arg2;
1755 float48le(float32 arg1, float64 arg2)
1760 return *arg1 <= *arg2;
1764 float48gt(float32 arg1, float64 arg2)
1769 return *arg1 > *arg2;
1773 float48ge(float32 arg1, float64 arg2)
1778 return *arg1 >= *arg2;
1782 * float84{eq,ne,lt,le,gt,ge} - float4/float8 comparison operations
1785 float84eq(float64 arg1, float32 arg2)
1790 return *arg1 == *arg2;
1794 float84ne(float64 arg1, float32 arg2)
1799 return *arg1 != *arg2;
1803 float84lt(float64 arg1, float32 arg2)
1808 return *arg1 < *arg2;
1812 float84le(float64 arg1, float32 arg2)
1817 return *arg1 <= *arg2;
1821 float84gt(float64 arg1, float32 arg2)
1826 return *arg1 > *arg2;
1830 float84ge(float64 arg1, float32 arg2)
1835 return *arg1 >= *arg2;
1838 /* ========== PRIVATE ROUTINES ========== */
1840 /* From "fdlibm" @ netlib.att.com */
1844 /* @(#)s_rint.c 5.1 93/09/24 */
1846 * ====================================================
1847 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
1849 * Developed at SunPro, a Sun Microsystems, Inc. business.
1850 * Permission to use, copy, modify, and distribute this
1851 * software is freely granted, provided that this notice
1853 * ====================================================
1858 * Return x rounded to integral value according to the prevailing
1861 * Using floating addition.
1863 * Inexact flag raised if x not equal to rint(x).
1873 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
1874 -4.50359962737049600000e+15,/* 0xC3300000, 0x00000000 */
1896 n0 = (*((int *) &one) >> 29) ^ 1;
1897 i0 = *(n0 + (int *) &x);
1898 sx = (i0 >> 31) & 1;
1899 i1 = *(1 - n0 + (int *) &x);
1900 j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;
1905 if (((i0 & 0x7fffffff) | i1) == 0)
1907 i1 |= (i0 & 0x0fffff);
1909 i0 |= ((i1 | -i1) >> 12) & 0x80000;
1910 *(n0 + (int *) &x) = i0;
1913 i0 = *(n0 + (int *) &t);
1914 *(n0 + (int *) &t) = (i0 & 0x7fffffff) | (sx << 31);
1919 i = (0x000fffff) >> j0;
1920 if (((i0 & i) | i1) == 0)
1921 return x; /* x is integral */
1923 if (((i0 & i) | i1) != 0)
1928 i0 = (i0 & (~i)) | ((0x20000) >> j0);
1935 return x + x; /* inf or NaN */
1937 return x; /* x is integral */
1941 i = ((unsigned) (0xffffffff)) >> (j0 - 20);
1943 return x; /* x is integral */
1946 i1 = (i1 & (~i)) | ((0x40000000) >> (j0 - 20));
1948 *(n0 + (int *) &x) = i0;
1949 *(1 - n0 + (int *) &x) = i1;
1951 return w - TWO52[sx];
1954 #endif /* !HAVE_RINT */
1963 int isneg = (x < 0.0);
1964 double tmpres = pow(fabs(x), (double) 1.0 / (double) 3.0);
1966 return isneg ? -tmpres : tmpres;
1969 #endif /* !HAVE_CBRT */