float.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:27k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*-------------------------------------------------------------------------
  2.  *
  3.  * float.c
  4.  *   Functions for the built-in floating-point types.
  5.  *
  6.  * Copyright (c) 1994, Regents of the University of California
  7.  *
  8.  *
  9.  * IDENTIFICATION
  10.  *   $Header: /usr/local/cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.42.2.1 1999/08/02 05:24:52 scrappy Exp $
  11.  *
  12.  *-------------------------------------------------------------------------
  13.  */
  14. /*
  15.  * OLD COMMENTS
  16.  * Basic float4 ops:
  17.  *  float4in, float4out, float4abs, float4um
  18.  * Basic float8 ops:
  19.  *  float8in, float8inAd, float8out, float8outAd, float8abs, float8um
  20.  * Arithmetic operators:
  21.  *  float4pl, float4mi, float4mul, float4div
  22.  *  float8pl, float8mi, float8mul, float8div
  23.  * Comparison operators:
  24.  *  float4eq, float4ne, float4lt, float4le, float4gt, float4ge
  25.  *  float8eq, float8ne, float8lt, float8le, float8gt, float8ge
  26.  * Conversion routines:
  27.  *  ftod, dtof, i4tod, dtoi4, i2tod, dtoi2, itof, ftoi, i2tof, ftoi2
  28.  *
  29.  * Random float8 ops:
  30.  *  dround, dtrunc, dsqrt, dcbrt, dpow, dexp, dlog1
  31.  * Arithmetic operators:
  32.  *  float48pl, float48mi, float48mul, float48div
  33.  *  float84pl, float84mi, float84mul, float84div
  34.  * Comparison operators:
  35.  *  float48eq, float48ne, float48lt, float48le, float48gt, float48ge
  36.  *  float84eq, float84ne, float84lt, float84le, float84gt, float84ge
  37.  *
  38.  * (You can do the arithmetic and comparison stuff using conversion
  39.  *  routines, but then you pay the overhead of converting...)
  40.  *
  41.  * XXX GLUESOME STUFF. FIX IT! -AY '94
  42.  *
  43.  * Added some additional conversion routines and cleaned up
  44.  *  a bit of the existing code. Need to change the error checking
  45.  *  for calls to pow(), exp() since on some machines (my Linux box
  46.  *  included) these routines do not set errno. - tgl 97/05/10
  47.  */
  48. #include <ctype.h>
  49. #include <errno.h>
  50. #include <float.h> /* faked on sunos4 */
  51. #include <math.h>
  52. #include "postgres.h"
  53. #ifdef HAVE_LIMITS_H
  54. #include <limits.h>
  55. #endif
  56. #include "fmgr.h"
  57. #include "utils/builtins.h"
  58. #ifndef NAN
  59. #define NAN (0.0/0.0)
  60. #endif
  61. #ifndef SHRT_MAX
  62. #define SHRT_MAX 32767
  63. #endif
  64. #ifndef SHRT_MIN
  65. #define SHRT_MIN (-32768)
  66. #endif
  67. #define FORMAT 'g' /* use "g" output format as standard
  68.  * format */
  69. /* not sure what the following should be, but better to make it over-sufficient */
  70. #define MAXFLOATWIDTH 64
  71. #define MAXDOUBLEWIDTH 128
  72. #if !(NeXT && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_2)
  73.  /* NS3.3 has conflicting declarations of these in <math.h> */
  74. #ifndef atof
  75. extern double atof(const char *p);
  76. #endif
  77. #ifndef HAVE_CBRT
  78. #define cbrt my_cbrt
  79. static double cbrt(double x);
  80. #else
  81. #if !defined(nextstep)
  82. extern double cbrt(double x);
  83. #endif
  84. #endif
  85. #ifndef HAVE_RINT
  86. #define rint my_rint
  87. static double rint(double x);
  88. #else
  89. extern double rint(double x);
  90. #endif
  91. #endif
  92. /* ========== USER I/O ROUTINES ========== */
  93. #define FLOAT4_MAX  FLT_MAX
  94. #define FLOAT4_MIN  FLT_MIN
  95. #define FLOAT8_MAX  DBL_MAX
  96. #define FLOAT8_MIN  DBL_MIN
  97. /*
  98.  * if FLOAT8_MIN and FLOAT8_MAX are the limits of the range a
  99.  * double can store, then how are we ever going to wind up
  100.  * with something stored in a double that is outside those
  101.  * limits? (and similarly for FLOAT4_{MIN,MAX}/float.)
  102.  * doesn't make sense to me, and it causes a
  103.  * floating point exception on linuxalpha, so UNSAFE_FLOATS
  104.  * it is.
  105.  * (maybe someone wanted to allow for values other than DBL_MIN/
  106.  * DBL_MAX for FLOAT8_MIN/FLOAT8_MAX?)
  107.  * --djm 12/12/96
  108.  * according to Richard Henderson this is a known bug in gcc on
  109.  * the Alpha.  might as well leave the workaround in
  110.  * until the distributions are updated.
  111.  * --djm 12/16/96
  112.  */
  113. #if ( defined(linux) && defined(__alpha__) ) && !defined(UNSAFE_FLOATS)
  114. #define UNSAFE_FLOATS
  115. #endif
  116. /*
  117.    check to see if a float4 val is outside of
  118.    the FLOAT4_MIN, FLOAT4_MAX bounds.
  119.    raise an elog warning if it is
  120. */
  121. static void
  122. CheckFloat4Val(double val)
  123. {
  124. /*
  125.  * defining unsafe floats's will make float4 and float8 ops faster at
  126.  * the cost of safety, of course!
  127.  */
  128. #ifdef UNSAFE_FLOATS
  129. return;
  130. #else
  131. if (fabs(val) > FLOAT4_MAX)
  132. elog(ERROR, "Bad float4 input format -- overflow");
  133. if (val != 0.0 && fabs(val) < FLOAT4_MIN)
  134. elog(ERROR, "Bad float4 input format -- underflow");
  135. return;
  136. #endif  /* UNSAFE_FLOATS */
  137. }
  138. /*
  139.    check to see if a float8 val is outside of
  140.    the FLOAT8_MIN, FLOAT8_MAX bounds.
  141.    raise an elog warning if it is
  142. */
  143. void
  144. CheckFloat8Val(double val)
  145. {
  146. /*
  147.  * defining unsafe floats's will make float4 and float8 ops faster at
  148.  * the cost of safety, of course!
  149.  */
  150. #ifdef UNSAFE_FLOATS
  151. return;
  152. #else
  153. if (fabs(val) > FLOAT8_MAX)
  154. elog(ERROR, "Bad float8 input format -- overflow");
  155. if (val != 0.0 && fabs(val) < FLOAT8_MIN)
  156. elog(ERROR, "Bad float8 input format -- underflow");
  157. return;
  158. #endif  /* UNSAFE_FLOATS */
  159. }
  160. /*
  161.  * float4in - converts "num" to float
  162.  *   restricted syntax:
  163.  *   {<sp>} [+|-] {digit} [.{digit}] [<exp>]
  164.  *   where <sp> is a space, digit is 0-9,
  165.  *   <exp> is "e" or "E" followed by an integer.
  166.  */
  167. float32
  168. float4in(char *num)
  169. {
  170. float32 result = (float32) palloc(sizeof(float32data));
  171. double val;
  172. char    *endptr;
  173. errno = 0;
  174. val = strtod(num, &endptr);
  175. if (*endptr != '')
  176. {
  177. /* Should we accept "NaN" or "Infinity" for float4? */
  178. elog(ERROR, "Bad float4 input format '%s'", num);
  179. }
  180. else
  181. {
  182. if (errno == ERANGE)
  183. elog(ERROR, "Input '%s' is out of range for float4", num);
  184. }
  185. /*
  186.  * if we get here, we have a legal double, still need to check to see
  187.  * if it's a legal float
  188.  */
  189. CheckFloat4Val(val);
  190. *result = val;
  191. return result;
  192. }
  193. /*
  194.  * float4out - converts a float4 number to a string
  195.  *   using a standard output format
  196.  */
  197. char *
  198. float4out(float32 num)
  199. {
  200. char    *ascii = (char *) palloc(MAXFLOATWIDTH + 1);
  201. if (!num)
  202. return strcpy(ascii, "(null)");
  203. sprintf(ascii, "%.*g", FLT_DIG, *num);
  204. return ascii;
  205. }
  206. /*
  207.  * float8in - converts "num" to float8
  208.  *   restricted syntax:
  209.  *   {<sp>} [+|-] {digit} [.{digit}] [<exp>]
  210.  *   where <sp> is a space, digit is 0-9,
  211.  *   <exp> is "e" or "E" followed by an integer.
  212.  */
  213. float64
  214. float8in(char *num)
  215. {
  216. float64 result = (float64) palloc(sizeof(float64data));
  217. double val;
  218. char    *endptr;
  219. errno = 0;
  220. val = strtod(num, &endptr);
  221. if (*endptr != '')
  222. {
  223. if (strcasecmp(num, "NaN") == 0)
  224. val = NAN;
  225. else if (strcasecmp(num, "Infinity") == 0)
  226. val = HUGE_VAL;
  227. else
  228. elog(ERROR, "Bad float8 input format '%s'", num);
  229. }
  230. else
  231. {
  232. if (errno == ERANGE)
  233. elog(ERROR, "Input '%s' is out of range for float8", num);
  234. }
  235. CheckFloat8Val(val);
  236. *result = val;
  237. return result;
  238. }
  239. /*
  240.  * float8out - converts float8 number to a string
  241.  *   using a standard output format
  242.  */
  243. char *
  244. float8out(float64 num)
  245. {
  246. char    *ascii = (char *) palloc(MAXDOUBLEWIDTH + 1);
  247. if (!num)
  248. return strcpy(ascii, "(null)");
  249. if (isnan(*num))
  250. return strcpy(ascii, "NaN");
  251. if (isinf(*num))
  252. return strcpy(ascii, "Infinity");
  253. sprintf(ascii, "%.*g", DBL_DIG, *num);
  254. return ascii;
  255. }
  256. /* ========== PUBLIC ROUTINES ========== */
  257. /*
  258.  * ======================
  259.  * FLOAT4 BASE OPERATIONS
  260.  * ======================
  261.  */
  262. /*
  263.  * float4abs - returns a pointer to |arg1| (absolute value)
  264.  */
  265. float32
  266. float4abs(float32 arg1)
  267. {
  268. float32 result;
  269. double val;
  270. if (!arg1)
  271. return (float32) NULL;
  272. val = fabs(*arg1);
  273. CheckFloat4Val(val);
  274. result = (float32) palloc(sizeof(float32data));
  275. *result = val;
  276. return result;
  277. }
  278. /*
  279.  * float4um - returns a pointer to -arg1 (unary minus)
  280.  */
  281. float32
  282. float4um(float32 arg1)
  283. {
  284. float32 result;
  285. double val;
  286. if (!arg1)
  287. return (float32) NULL;
  288. val = ((*arg1 != 0) ? -(*arg1) : *arg1);
  289. CheckFloat4Val(val);
  290. result = (float32) palloc(sizeof(float32data));
  291. *result = val;
  292. return result;
  293. }
  294. float32
  295. float4larger(float32 arg1, float32 arg2)
  296. {
  297. float32 result;
  298. if (!arg1 || !arg2)
  299. return (float32) NULL;
  300. result = (float32) palloc(sizeof(float32data));
  301. *result = ((*arg1 > *arg2) ? *arg1 : *arg2);
  302. return result;
  303. }
  304. float32
  305. float4smaller(float32 arg1, float32 arg2)
  306. {
  307. float32 result;
  308. if (!arg1 || !arg2)
  309. return (float32) NULL;
  310. result = (float32) palloc(sizeof(float32data));
  311. *result = ((*arg1 > *arg2) ? *arg2 : *arg1);
  312. return result;
  313. }
  314. /*
  315.  * ======================
  316.  * FLOAT8 BASE OPERATIONS
  317.  * ======================
  318.  */
  319. /*
  320.  * float8abs - returns a pointer to |arg1| (absolute value)
  321.  */
  322. float64
  323. float8abs(float64 arg1)
  324. {
  325. float64 result;
  326. double val;
  327. if (!arg1)
  328. return (float64) NULL;
  329. result = (float64) palloc(sizeof(float64data));
  330. val = fabs(*arg1);
  331. CheckFloat8Val(val);
  332. *result = val;
  333. return result;
  334. }
  335. /*
  336.  * float8um - returns a pointer to -arg1 (unary minus)
  337.  */
  338. float64
  339. float8um(float64 arg1)
  340. {
  341. float64 result;
  342. double val;
  343. if (!arg1)
  344. return (float64) NULL;
  345. val = ((*arg1 != 0) ? -(*arg1) : *arg1);
  346. CheckFloat8Val(val);
  347. result = (float64) palloc(sizeof(float64data));
  348. *result = val;
  349. return result;
  350. }
  351. float64
  352. float8larger(float64 arg1, float64 arg2)
  353. {
  354. float64 result;
  355. if (!arg1 || !arg2)
  356. return (float64) NULL;
  357. result = (float64) palloc(sizeof(float64data));
  358. *result = ((*arg1 > *arg2) ? *arg1 : *arg2);
  359. return result;
  360. }
  361. float64
  362. float8smaller(float64 arg1, float64 arg2)
  363. {
  364. float64 result;
  365. if (!arg1 || !arg2)
  366. return (float64) NULL;
  367. result = (float64) palloc(sizeof(float64data));
  368. *result = ((*arg1 > *arg2) ? *arg2 : *arg1);
  369. return result;
  370. }
  371. /*
  372.  * ====================
  373.  * ARITHMETIC OPERATORS
  374.  * ====================
  375.  */
  376. /*
  377.  * float4pl - returns a pointer to arg1 + arg2
  378.  * float4mi - returns a pointer to arg1 - arg2
  379.  * float4mul - returns a pointer to arg1 * arg2
  380.  * float4div - returns a pointer to arg1 / arg2
  381.  * float4inc - returns a poniter to arg1 + 1.0
  382.  */
  383. float32
  384. float4pl(float32 arg1, float32 arg2)
  385. {
  386. float32 result;
  387. double val;
  388. if (!arg1 || !arg2)
  389. return (float32) NULL;
  390. val = *arg1 + *arg2;
  391. CheckFloat4Val(val);
  392. result = (float32) palloc(sizeof(float32data));
  393. *result = val;
  394. return result;
  395. }
  396. float32
  397. float4mi(float32 arg1, float32 arg2)
  398. {
  399. float32 result;
  400. double val;
  401. if (!arg1 || !arg2)
  402. return (float32) NULL;
  403. val = *arg1 - *arg2;
  404. CheckFloat4Val(val);
  405. result = (float32) palloc(sizeof(float32data));
  406. *result = val;
  407. return result;
  408. }
  409. float32
  410. float4mul(float32 arg1, float32 arg2)
  411. {
  412. float32 result;
  413. double val;
  414. if (!arg1 || !arg2)
  415. return (float32) NULL;
  416. val = *arg1 * *arg2;
  417. CheckFloat4Val(val);
  418. result = (float32) palloc(sizeof(float32data));
  419. *result = val;
  420. return result;
  421. }
  422. float32
  423. float4div(float32 arg1, float32 arg2)
  424. {
  425. float32 result;
  426. double val;
  427. if (!arg1 || !arg2)
  428. return (float32) NULL;
  429. if (*arg2 == 0.0)
  430. elog(ERROR, "float4div: divide by zero error");
  431. val = *arg1 / *arg2;
  432. CheckFloat4Val(val);
  433. result = (float32) palloc(sizeof(float32data));
  434. *result = *arg1 / *arg2;
  435. return result;
  436. }
  437. float32
  438. float4inc(float32 arg1)
  439. {
  440. double val;
  441. if (!arg1)
  442. return (float32) NULL;
  443. val = *arg1 + (float32data) 1.0;
  444. CheckFloat4Val(val);
  445. *arg1 = val;
  446. return arg1;
  447. }
  448. /*
  449.  * float8pl - returns a pointer to arg1 + arg2
  450.  * float8mi - returns a pointer to arg1 - arg2
  451.  * float8mul - returns a pointer to arg1 * arg2
  452.  * float8div - returns a pointer to arg1 / arg2
  453.  * float8inc - returns a pointer to arg1 + 1.0
  454.  */
  455. float64
  456. float8pl(float64 arg1, float64 arg2)
  457. {
  458. float64 result;
  459. double val;
  460. if (!arg1 || !arg2)
  461. return (float64) NULL;
  462. result = (float64) palloc(sizeof(float64data));
  463. val = *arg1 + *arg2;
  464. CheckFloat8Val(val);
  465. *result = val;
  466. return result;
  467. }
  468. float64
  469. float8mi(float64 arg1, float64 arg2)
  470. {
  471. float64 result;
  472. double val;
  473. if (!arg1 || !arg2)
  474. return (float64) NULL;
  475. result = (float64) palloc(sizeof(float64data));
  476. val = *arg1 - *arg2;
  477. CheckFloat8Val(val);
  478. *result = val;
  479. return result;
  480. }
  481. float64
  482. float8mul(float64 arg1, float64 arg2)
  483. {
  484. float64 result;
  485. double val;
  486. if (!arg1 || !arg2)
  487. return (float64) NULL;
  488. result = (float64) palloc(sizeof(float64data));
  489. val = *arg1 * *arg2;
  490. CheckFloat8Val(val);
  491. *result = val;
  492. return result;
  493. }
  494. float64
  495. float8div(float64 arg1, float64 arg2)
  496. {
  497. float64 result;
  498. double val;
  499. if (!arg1 || !arg2)
  500. return (float64) NULL;
  501. result = (float64) palloc(sizeof(float64data));
  502. if (*arg2 == 0.0)
  503. elog(ERROR, "float8div: divide by zero error");
  504. val = *arg1 / *arg2;
  505. CheckFloat8Val(val);
  506. *result = val;
  507. return result;
  508. }
  509. float64
  510. float8inc(float64 arg1)
  511. {
  512. double val;
  513. if (!arg1)
  514. return (float64) NULL;
  515. val = *arg1 + (float64data) 1.0;
  516. CheckFloat8Val(val);
  517. *arg1 = val;
  518. return arg1;
  519. }
  520. /*
  521.  * ====================
  522.  * COMPARISON OPERATORS
  523.  * ====================
  524.  */
  525. /*
  526.  * float4{eq,ne,lt,le,gt,ge} - float4/float4 comparison operations
  527.  */
  528. bool
  529. float4eq(float32 arg1, float32 arg2)
  530. {
  531. if (!arg1 || !arg2)
  532. return 0;
  533. return *arg1 == *arg2;
  534. }
  535. bool
  536. float4ne(float32 arg1, float32 arg2)
  537. {
  538. if (!arg1 || !arg2)
  539. return 0;
  540. return *arg1 != *arg2;
  541. }
  542. bool
  543. float4lt(float32 arg1, float32 arg2)
  544. {
  545. if (!arg1 || !arg2)
  546. return 0;
  547. return *arg1 < *arg2;
  548. }
  549. bool
  550. float4le(float32 arg1, float32 arg2)
  551. {
  552. if (!arg1 || !arg2)
  553. return 0;
  554. return *arg1 <= *arg2;
  555. }
  556. bool
  557. float4gt(float32 arg1, float32 arg2)
  558. {
  559. if (!arg1 || !arg2)
  560. return 0;
  561. return *arg1 > *arg2;
  562. }
  563. bool
  564. float4ge(float32 arg1, float32 arg2)
  565. {
  566. if (!arg1 || !arg2)
  567. return 0;
  568. return *arg1 >= *arg2;
  569. }
  570. /*
  571.  * float8{eq,ne,lt,le,gt,ge} - float8/float8 comparison operations
  572.  */
  573. bool
  574. float8eq(float64 arg1, float64 arg2)
  575. {
  576. if (!arg1 || !arg2)
  577. return 0;
  578. return *arg1 == *arg2;
  579. }
  580. bool
  581. float8ne(float64 arg1, float64 arg2)
  582. {
  583. if (!arg1 || !arg2)
  584. return 0;
  585. return *arg1 != *arg2;
  586. }
  587. bool
  588. float8lt(float64 arg1, float64 arg2)
  589. {
  590. if (!arg1 || !arg2)
  591. return 0;
  592. return *arg1 < *arg2;
  593. }
  594. bool
  595. float8le(float64 arg1, float64 arg2)
  596. {
  597. if (!arg1 || !arg2)
  598. return 0;
  599. return *arg1 <= *arg2;
  600. }
  601. bool
  602. float8gt(float64 arg1, float64 arg2)
  603. {
  604. if (!arg1 || !arg2)
  605. return 0;
  606. return *arg1 > *arg2;
  607. }
  608. bool
  609. float8ge(float64 arg1, float64 arg2)
  610. {
  611. if (!arg1 || !arg2)
  612. return 0;
  613. return *arg1 >= *arg2;
  614. }
  615. /*
  616.  * ===================
  617.  * CONVERSION ROUTINES
  618.  * ===================
  619.  */
  620. /*
  621.  * ftod - converts a float4 number to a float8 number
  622.  */
  623. float64
  624. ftod(float32 num)
  625. {
  626. float64 result;
  627. if (!num)
  628. return (float64) NULL;
  629. result = (float64) palloc(sizeof(float64data));
  630. *result = *num;
  631. return result;
  632. }
  633. /*
  634.  * dtof - converts a float8 number to a float4 number
  635.  */
  636. float32
  637. dtof(float64 num)
  638. {
  639. float32 result;
  640. if (!num)
  641. return (float32) NULL;
  642. CheckFloat4Val(*num);
  643. result = (float32) palloc(sizeof(float32data));
  644. *result = *num;
  645. return result;
  646. }
  647. /*
  648.  * dtoi4 - converts a float8 number to an int4 number
  649.  */
  650. int32
  651. dtoi4(float64 num)
  652. {
  653. int32 result;
  654. if (!PointerIsValid(num))
  655. elog(ERROR, "dtoi4: unable to convert null", NULL);
  656. if ((*num < INT_MIN) || (*num > INT_MAX))
  657. elog(ERROR, "dtoi4: integer out of range", NULL);
  658. result = rint(*num);
  659. return result;
  660. }
  661. /*
  662.  * dtoi2 - converts a float8 number to an int2 number
  663.  */
  664. int16
  665. dtoi2(float64 num)
  666. {
  667. int16 result;
  668. if (!PointerIsValid(num))
  669. elog(ERROR, "dtoi2: unable to convert null", NULL);
  670. if ((*num < SHRT_MIN) || (*num > SHRT_MAX))
  671. elog(ERROR, "dtoi2: integer out of range", NULL);
  672. result = rint(*num);
  673. return result;
  674. }
  675. /*
  676.  * i4tod - converts an int4 number to a float8 number
  677.  */
  678. float64
  679. i4tod(int32 num)
  680. {
  681. float64 result;
  682. result = (float64) palloc(sizeof(float64data));
  683. *result = num;
  684. return result;
  685. }
  686. /*
  687.  * i2tod - converts an int2 number to a float8 number
  688.  */
  689. float64
  690. i2tod(int16 num)
  691. {
  692. float64 result;
  693. result = (float64) palloc(sizeof(float64data));
  694. *result = num;
  695. return result;
  696. }
  697. /*
  698.  * ftoi4 - converts a float8 number to an int4 number
  699.  */
  700. int32
  701. ftoi4(float32 num)
  702. {
  703. int32 result;
  704. if (!PointerIsValid(num))
  705. elog(ERROR, "ftoi4: unable to convert null", NULL);
  706. if ((*num < INT_MIN) || (*num > INT_MAX))
  707. elog(ERROR, "ftoi4: integer out of range", NULL);
  708. result = rint(*num);
  709. return result;
  710. }
  711. /*
  712.  * ftoi2 - converts a float8 number to an int2 number
  713.  */
  714. int16
  715. ftoi2(float32 num)
  716. {
  717. int16 result;
  718. if (!PointerIsValid(num))
  719. elog(ERROR, "ftoi2: unable to convert null", NULL);
  720. if ((*num < SHRT_MIN) || (*num > SHRT_MAX))
  721. elog(ERROR, "ftoi2: integer out of range", NULL);
  722. result = rint(*num);
  723. return result;
  724. }
  725. /*
  726.  * i4tof - converts an int4 number to a float8 number
  727.  */
  728. float32
  729. i4tof(int32 num)
  730. {
  731. float32 result;
  732. result = (float32) palloc(sizeof(float32data));
  733. *result = num;
  734. return result;
  735. }
  736. /*
  737.  * i2tof - converts an int2 number to a float8 number
  738.  */
  739. float32
  740. i2tof(int16 num)
  741. {
  742. float32 result;
  743. result = (float32) palloc(sizeof(float32data));
  744. *result = num;
  745. return result;
  746. }
  747. /*
  748.  * float8_text - converts a float8 number to a text string
  749.  */
  750. text *
  751. float8_text(float64 num)
  752. {
  753. text    *result;
  754. int len;
  755. char    *str;
  756. str = float8out(num);
  757. len = (strlen(str) + VARHDRSZ);
  758. result = palloc(len);
  759. VARSIZE(result) = len;
  760. memmove(VARDATA(result), str, (len - VARHDRSZ));
  761. pfree(str);
  762. return result;
  763. } /* float8_text() */
  764. /*
  765.  * text_float8 - converts a text string to a float8 number
  766.  */
  767. float64
  768. text_float8(text *string)
  769. {
  770. float64 result;
  771. int len;
  772. char    *str;
  773. len = (VARSIZE(string) - VARHDRSZ);
  774. str = palloc(len + 1);
  775. memmove(str, VARDATA(string), len);
  776. *(str + len) = '';
  777. result = float8in(str);
  778. pfree(str);
  779. return result;
  780. } /* text_float8() */
  781. /*
  782.  * float4_text - converts a float4 number to a text string
  783.  */
  784. text *
  785. float4_text(float32 num)
  786. {
  787. text    *result;
  788. int len;
  789. char    *str;
  790. str = float4out(num);
  791. len = (strlen(str) + VARHDRSZ);
  792. result = palloc(len);
  793. VARSIZE(result) = len;
  794. memmove(VARDATA(result), str, (len - VARHDRSZ));
  795. pfree(str);
  796. return result;
  797. } /* float4_text() */
  798. /*
  799.  * text_float4 - converts a text string to a float4 number
  800.  */
  801. float32
  802. text_float4(text *string)
  803. {
  804. float32 result;
  805. int len;
  806. char    *str;
  807. len = (VARSIZE(string) - VARHDRSZ);
  808. str = palloc(len + 1);
  809. memmove(str, VARDATA(string), len);
  810. *(str + len) = '';
  811. result = float4in(str);
  812. pfree(str);
  813. return result;
  814. } /* text_float4() */
  815. /*
  816.  * =======================
  817.  * RANDOM FLOAT8 OPERATORS
  818.  * =======================
  819.  */
  820. /*
  821.  * dround - returns a pointer to ROUND(arg1)
  822.  */
  823. float64
  824. dround(float64 arg1)
  825. {
  826. float64 result;
  827. double tmp;
  828. if (!arg1)
  829. return (float64) NULL;
  830. result = (float64) palloc(sizeof(float64data));
  831. tmp = *arg1;
  832. *result = (float64data) rint(tmp);
  833. return result;
  834. }
  835. /*
  836.  * dtrunc - returns a pointer to truncation of arg1,
  837.  *   arg1 >= 0 ... the greatest integer as float8 less
  838.  * than or equal to arg1
  839.  *   arg1 < 0 ... the greatest integer as float8 greater
  840.  * than or equal to arg1
  841.  */
  842. float64
  843. dtrunc(float64 arg1)
  844. {
  845. float64 result;
  846. double tmp;
  847. if (!arg1)
  848. return (float64) NULL;
  849. result = (float64) palloc(sizeof(float64data));
  850. tmp = *arg1;
  851. if (*arg1 >= 0)
  852. *result = (float64data) floor(tmp);
  853. else
  854. *result = (float64data) -(floor(-tmp));
  855. return result;
  856. }
  857. /*
  858.  * dsqrt - returns a pointer to square root of arg1
  859.  */
  860. float64
  861. dsqrt(float64 arg1)
  862. {
  863. float64 result;
  864. double tmp;
  865. if (!arg1)
  866. return (float64) NULL;
  867. result = (float64) palloc(sizeof(float64data));
  868. tmp = *arg1;
  869. *result = (float64data) sqrt(tmp);
  870. return result;
  871. }
  872. /*
  873.  * dcbrt - returns a pointer to cube root of arg1
  874.  */
  875. float64
  876. dcbrt(float64 arg1)
  877. {
  878. float64 result;
  879. double tmp;
  880. if (!arg1)
  881. return (float64) NULL;
  882. result = (float64) palloc(sizeof(float64data));
  883. tmp = *arg1;
  884. *result = (float64data) cbrt(tmp);
  885. return result;
  886. }
  887. /*
  888.  * dpow - returns a pointer to pow(arg1,arg2)
  889.  */
  890. float64
  891. dpow(float64 arg1, float64 arg2)
  892. {
  893. float64 result;
  894. double tmp1,
  895. tmp2;
  896. if (!arg1 || !arg2)
  897. return (float64) NULL;
  898. result = (float64) palloc(sizeof(float64data));
  899. tmp1 = *arg1;
  900. tmp2 = *arg2;
  901. #ifndef finite
  902. errno = 0;
  903. #endif
  904. *result = (float64data) pow(tmp1, tmp2);
  905. #ifndef finite
  906. if (errno != 0) /* on some machines both EDOM & ERANGE can
  907.  * occur */
  908. #else
  909. if (!finite(*result))
  910. #endif
  911. elog(ERROR, "pow() result is out of range");
  912. CheckFloat8Val(*result);
  913. return result;
  914. }
  915. /*
  916.  * dexp - returns a pointer to the exponential function of arg1
  917.  */
  918. float64
  919. dexp(float64 arg1)
  920. {
  921. float64 result;
  922. double tmp;
  923. if (!arg1)
  924. return (float64) NULL;
  925. result = (float64) palloc(sizeof(float64data));
  926. tmp = *arg1;
  927. #ifndef finite
  928. errno = 0;
  929. #endif
  930. *result = (float64data) exp(tmp);
  931. #ifndef finite
  932. if (errno == ERANGE)
  933. #else
  934. /* infinity implies overflow, zero implies underflow */
  935. if (!finite(*result) || *result == 0.0)
  936. #endif
  937. elog(ERROR, "exp() result is out of range");
  938. CheckFloat8Val(*result);
  939. return result;
  940. }
  941. /*
  942.  * dlog1 - returns a pointer to the natural logarithm of arg1
  943.  *   ("dlog" is already a logging routine...)
  944.  */
  945. float64
  946. dlog1(float64 arg1)
  947. {
  948. float64 result;
  949. double tmp;
  950. if (!arg1)
  951. return (float64) NULL;
  952. result = (float64) palloc(sizeof(float64data));
  953. tmp = *arg1;
  954. if (tmp == 0.0)
  955. elog(ERROR, "can't take log of zero");
  956. if (tmp < 0)
  957. elog(ERROR, "can't take log of a negative number");
  958. *result = (float64data) log(tmp);
  959. CheckFloat8Val(*result);
  960. return result;
  961. }
  962. /*
  963.  * ====================
  964.  * ARITHMETIC OPERATORS
  965.  * ====================
  966.  */
  967. /*
  968.  * float48pl - returns a pointer to arg1 + arg2
  969.  * float48mi - returns a pointer to arg1 - arg2
  970.  * float48mul - returns a pointer to arg1 * arg2
  971.  * float48div - returns a pointer to arg1 / arg2
  972.  */
  973. float64
  974. float48pl(float32 arg1, float64 arg2)
  975. {
  976. float64 result;
  977. if (!arg1 || !arg2)
  978. return (float64) NULL;
  979. result = (float64) palloc(sizeof(float64data));
  980. *result = *arg1 + *arg2;
  981. CheckFloat8Val(*result);
  982. return result;
  983. }
  984. float64
  985. float48mi(float32 arg1, float64 arg2)
  986. {
  987. float64 result;
  988. if (!arg1 || !arg2)
  989. return (float64) NULL;
  990. result = (float64) palloc(sizeof(float64data));
  991. *result = *arg1 - *arg2;
  992. CheckFloat8Val(*result);
  993. return result;
  994. }
  995. float64
  996. float48mul(float32 arg1, float64 arg2)
  997. {
  998. float64 result;
  999. if (!arg1 || !arg2)
  1000. return (float64) NULL;
  1001. result = (float64) palloc(sizeof(float64data));
  1002. *result = *arg1 * *arg2;
  1003. CheckFloat8Val(*result);
  1004. return result;
  1005. }
  1006. float64
  1007. float48div(float32 arg1, float64 arg2)
  1008. {
  1009. float64 result;
  1010. if (!arg1 || !arg2)
  1011. return (float64) NULL;
  1012. result = (float64) palloc(sizeof(float64data));
  1013. if (*arg2 == 0.0)
  1014. elog(ERROR, "float48div: divide by zero");
  1015. *result = *arg1 / *arg2;
  1016. CheckFloat8Val(*result);
  1017. return result;
  1018. }
  1019. /*
  1020.  * float84pl - returns a pointer to arg1 + arg2
  1021.  * float84mi - returns a pointer to arg1 - arg2
  1022.  * float84mul - returns a pointer to arg1 * arg2
  1023.  * float84div - returns a pointer to arg1 / arg2
  1024.  */
  1025. float64
  1026. float84pl(float64 arg1, float32 arg2)
  1027. {
  1028. float64 result;
  1029. if (!arg1 || !arg2)
  1030. return (float64) NULL;
  1031. result = (float64) palloc(sizeof(float64data));
  1032. *result = *arg1 + *arg2;
  1033. CheckFloat8Val(*result);
  1034. return result;
  1035. }
  1036. float64
  1037. float84mi(float64 arg1, float32 arg2)
  1038. {
  1039. float64 result;
  1040. if (!arg1 || !arg2)
  1041. return (float64) NULL;
  1042. result = (float64) palloc(sizeof(float64data));
  1043. *result = *arg1 - *arg2;
  1044. CheckFloat8Val(*result);
  1045. return result;
  1046. }
  1047. float64
  1048. float84mul(float64 arg1, float32 arg2)
  1049. {
  1050. float64 result;
  1051. if (!arg1 || !arg2)
  1052. return (float64) NULL;
  1053. result = (float64) palloc(sizeof(float64data));
  1054. *result = *arg1 * *arg2;
  1055. CheckFloat8Val(*result);
  1056. return result;
  1057. }
  1058. float64
  1059. float84div(float64 arg1, float32 arg2)
  1060. {
  1061. float64 result;
  1062. if (!arg1 || !arg2)
  1063. return (float64) NULL;
  1064. result = (float64) palloc(sizeof(float64data));
  1065. if (*arg2 == 0.0)
  1066. elog(ERROR, "float48div: divide by zero");
  1067. *result = *arg1 / *arg2;
  1068. CheckFloat8Val(*result);
  1069. return result;
  1070. }
  1071. /*
  1072.  * ====================
  1073.  * COMPARISON OPERATORS
  1074.  * ====================
  1075.  */
  1076. /*
  1077.  * float48{eq,ne,lt,le,gt,ge} - float4/float8 comparison operations
  1078.  */
  1079. bool
  1080. float48eq(float32 arg1, float64 arg2)
  1081. {
  1082. if (!arg1 || !arg2)
  1083. return 0;
  1084. return *arg1 == (float) *arg2;
  1085. }
  1086. bool
  1087. float48ne(float32 arg1, float64 arg2)
  1088. {
  1089. if (!arg1 || !arg2)
  1090. return 0;
  1091. return *arg1 != (float) *arg2;
  1092. }
  1093. bool
  1094. float48lt(float32 arg1, float64 arg2)
  1095. {
  1096. if (!arg1 || !arg2)
  1097. return 0;
  1098. return *arg1 < (float) *arg2;
  1099. }
  1100. bool
  1101. float48le(float32 arg1, float64 arg2)
  1102. {
  1103. if (!arg1 || !arg2)
  1104. return 0;
  1105. return *arg1 <= (float) *arg2;
  1106. }
  1107. bool
  1108. float48gt(float32 arg1, float64 arg2)
  1109. {
  1110. if (!arg1 || !arg2)
  1111. return 0;
  1112. return *arg1 > (float) *arg2;
  1113. }
  1114. bool
  1115. float48ge(float32 arg1, float64 arg2)
  1116. {
  1117. if (!arg1 || !arg2)
  1118. return 0;
  1119. return *arg1 >= (float) *arg2;
  1120. }
  1121. /*
  1122.  * float84{eq,ne,lt,le,gt,ge} - float4/float8 comparison operations
  1123.  */
  1124. bool
  1125. float84eq(float64 arg1, float32 arg2)
  1126. {
  1127. if (!arg1 || !arg2)
  1128. return 0;
  1129. return (float) *arg1 == *arg2;
  1130. }
  1131. bool
  1132. float84ne(float64 arg1, float32 arg2)
  1133. {
  1134. if (!arg1 || !arg2)
  1135. return 0;
  1136. return (float) *arg1 != *arg2;
  1137. }
  1138. bool
  1139. float84lt(float64 arg1, float32 arg2)
  1140. {
  1141. if (!arg1 || !arg2)
  1142. return 0;
  1143. return (float) *arg1 < *arg2;
  1144. }
  1145. bool
  1146. float84le(float64 arg1, float32 arg2)
  1147. {
  1148. if (!arg1 || !arg2)
  1149. return 0;
  1150. return (float) *arg1 <= *arg2;
  1151. }
  1152. bool
  1153. float84gt(float64 arg1, float32 arg2)
  1154. {
  1155. if (!arg1 || !arg2)
  1156. return 0;
  1157. return (float) *arg1 > *arg2;
  1158. }
  1159. bool
  1160. float84ge(float64 arg1, float32 arg2)
  1161. {
  1162. if (!arg1 || !arg2)
  1163. return 0;
  1164. return (float) *arg1 >= *arg2;
  1165. }
  1166. /* ========== PRIVATE ROUTINES ========== */
  1167. /* From "fdlibm" @ netlib.att.com */
  1168. #ifndef HAVE_RINT
  1169. /* @(#)s_rint.c 5.1 93/09/24 */
  1170. /*
  1171.  * ====================================================
  1172.  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  1173.  *
  1174.  * Developed at SunPro, a Sun Microsystems, Inc. business.
  1175.  * Permission to use, copy, modify, and distribute this
  1176.  * software is freely granted, provided that this notice
  1177.  * is preserved.
  1178.  * ====================================================
  1179.  */
  1180. /*
  1181.  * rint(x)
  1182.  * Return x rounded to integral value according to the prevailing
  1183.  * rounding mode.
  1184.  * Method:
  1185.  * Using floating addition.
  1186.  * Exception:
  1187.  * Inexact flag raised if x not equal to rint(x).
  1188.  */
  1189. #ifdef __STDC__
  1190. static const double
  1191. #else
  1192. static double
  1193. #endif
  1194. one = 1.0,
  1195. TWO52[2] = {
  1196. 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
  1197. -4.50359962737049600000e+15,/* 0xC3300000, 0x00000000 */
  1198. };
  1199. #ifdef __STDC__
  1200. static double
  1201. rint(double x)
  1202. #else
  1203. static double
  1204. rint(x)
  1205. double x;
  1206. #endif
  1207. {
  1208. int i0,
  1209. n0,
  1210. j0,
  1211. sx;
  1212. unsigned i,
  1213. i1;
  1214. double w,
  1215. t;
  1216. n0 = (*((int *) &one) >> 29) ^ 1;
  1217. i0 = *(n0 + (int *) &x);
  1218. sx = (i0 >> 31) & 1;
  1219. i1 = *(1 - n0 + (int *) &x);
  1220. j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;
  1221. if (j0 < 20)
  1222. {
  1223. if (j0 < 0)
  1224. {
  1225. if (((i0 & 0x7fffffff) | i1) == 0)
  1226. return x;
  1227. i1 |= (i0 & 0x0fffff);
  1228. i0 &= 0xfffe0000;
  1229. i0 |= ((i1 | -i1) >> 12) & 0x80000;
  1230. *(n0 + (int *) &x) = i0;
  1231. w = TWO52[sx] + x;
  1232. t = w - TWO52[sx];
  1233. i0 = *(n0 + (int *) &t);
  1234. *(n0 + (int *) &t) = (i0 & 0x7fffffff) | (sx << 31);
  1235. return t;
  1236. }
  1237. else
  1238. {
  1239. i = (0x000fffff) >> j0;
  1240. if (((i0 & i) | i1) == 0)
  1241. return x; /* x is integral */
  1242. i >>= 1;
  1243. if (((i0 & i) | i1) != 0)
  1244. {
  1245. if (j0 == 19)
  1246. i1 = 0x40000000;
  1247. else
  1248. i0 = (i0 & (~i)) | ((0x20000) >> j0);
  1249. }
  1250. }
  1251. }
  1252. else if (j0 > 51)
  1253. {
  1254. if (j0 == 0x400)
  1255. return x + x; /* inf or NaN */
  1256. else
  1257. return x; /* x is integral */
  1258. }
  1259. else
  1260. {
  1261. i = ((unsigned) (0xffffffff)) >> (j0 - 20);
  1262. if ((i1 & i) == 0)
  1263. return x; /* x is integral */
  1264. i >>= 1;
  1265. if ((i1 & i) != 0)
  1266. i1 = (i1 & (~i)) | ((0x40000000) >> (j0 - 20));
  1267. }
  1268. *(n0 + (int *) &x) = i0;
  1269. *(1 - n0 + (int *) &x) = i1;
  1270. w = TWO52[sx] + x;
  1271. return w - TWO52[sx];
  1272. }
  1273. #endif  /* !HAVE_RINT */
  1274. #ifndef HAVE_CBRT
  1275. static
  1276. double
  1277. cbrt(x)
  1278. double x;
  1279. {
  1280. int isneg = (x < 0.0);
  1281. double tmpres = pow(fabs(x), (double) 1.0 / (double) 3.0);
  1282. return isneg ? -tmpres : tmpres;
  1283. }
  1284. #endif  /* !HAVE_CBRT */