]> granicus.if.org Git - postgresql/commitdiff
Change float8-to-int8 conversion to round to nearest, rather than
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 26 Jan 2001 22:50:26 +0000 (22:50 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 26 Jan 2001 22:50:26 +0000 (22:50 +0000)
truncating to integer.  Remove regress test that checks whether
4567890123456789 can be converted to float without loss; since that's
52 bits, it's on the hairy edge of failing with IEEE float8s, and indeed
rint seems to give platform-dependent results for it.

src/backend/utils/adt/int8.c
src/test/regress/expected/int8-exp-three-digits.out
src/test/regress/expected/int8.out
src/test/regress/sql/int8.sql

index c02ada56ba4233ae3300a6fbaf3cc4169a135923..a7df878c65ba371c4a156e7779fe02422edec0f6 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/adt/int8.c,v 1.27 2001/01/24 19:43:14 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/adt/int8.c,v 1.28 2001/01/26 22:50:26 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -693,13 +693,6 @@ i8tod(PG_FUNCTION_ARGS)
 
 /* dtoi8()
  * Convert double float to 8-byte integer.
- * Do a range check before the conversion.
- * Note that the comparison probably isn't quite right
- *     since we only have ~52 bits of precision in a double float
- *     and so subtracting one from a large number gives the large
- *     number exactly. However, for some reason the comparison below
- *     does the right thing on my i686/linux-rh4.2 box.
- * - thomas 1998-06-16
  */
 Datum
 dtoi8(PG_FUNCTION_ARGS)
@@ -707,11 +700,18 @@ dtoi8(PG_FUNCTION_ARGS)
        float8          val = PG_GETARG_FLOAT8(0);
        int64           result;
 
-       if ((val < (-pow(2.0, 63.0) + 1)) || (val > (pow(2.0, 63.0) - 1)))
-               elog(ERROR, "Floating point conversion to int64 is out of range");
-
+       /* Round val to nearest integer (but it's still in float form) */
+       val = rint(val);
+       /*
+        * Does it fit in an int64?  Avoid assuming that we have handy constants
+        * defined for the range boundaries, instead test for overflow by
+        * reverse-conversion.
+        */
        result = (int64) val;
 
+       if ((float8) result != val)
+               elog(ERROR, "Floating point conversion to int8 is out of range");
+
        PG_RETURN_INT64(result);
 }
 
index 562655bf4402549cb9d61eaad764a8b9f58b74f8..e42d5dfaf2c898e3d3ba73d7ca4e96c4df6a21c8 100644 (file)
@@ -87,16 +87,6 @@ SELECT '' AS five, q2, float8(q2) FROM INT8_TBL;
       | -4567890123456789 | -4.56789012345679e+015
 (5 rows)
 
-SELECT '' AS five, q1, int8(float8(q1)) AS "two coercions" FROM INT8_TBL;
- five |        q1        |  two coercions   
-------+------------------+------------------
-      |              123 |              123
-      |              123 |              123
-      | 4567890123456789 | 4567890123456789
-      | 4567890123456789 | 4567890123456789
-      | 4567890123456789 | 4567890123456789
-(5 rows)
-
 SELECT '' AS five, 2 * q1 AS "twice int4" FROM INT8_TBL;
  five |    twice int4    
 ------+------------------
index 30424a3f27449b4a9d1eb2903a38c14b059672b9..269cd2c0b50b309177047dc1dd134511046bacda 100644 (file)
@@ -87,16 +87,6 @@ SELECT '' AS five, q2, float8(q2) FROM INT8_TBL;
       | -4567890123456789 | -4.56789012345679e+15
 (5 rows)
 
-SELECT '' AS five, q1, int8(float8(q1)) AS "two coercions" FROM INT8_TBL;
- five |        q1        |  two coercions   
-------+------------------+------------------
-      |              123 |              123
-      |              123 |              123
-      | 4567890123456789 | 4567890123456789
-      | 4567890123456789 | 4567890123456789
-      | 4567890123456789 | 4567890123456789
-(5 rows)
-
 SELECT '' AS five, 2 * q1 AS "twice int4" FROM INT8_TBL;
  five |    twice int4    
 ------+------------------
index 0014efa220d150c2b248f43e5eed90e964bff99d..b5cb13480be743bfeb686fc0abb5db4e0bd299b7 100644 (file)
@@ -22,7 +22,6 @@ SELECT '' AS five, q1, q2, q1 / q2 AS divide FROM INT8_TBL;
 
 SELECT '' AS five, q1, float8(q1) FROM INT8_TBL;
 SELECT '' AS five, q2, float8(q2) FROM INT8_TBL;
-SELECT '' AS five, q1, int8(float8(q1)) AS "two coercions" FROM INT8_TBL;
 
 SELECT '' AS five, 2 * q1 AS "twice int4" FROM INT8_TBL;
 SELECT '' AS five, q1 * 2 AS "twice int4" FROM INT8_TBL;