mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
Change float8-to-int8 conversion to round to nearest, rather than
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.
This commit is contained in:
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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()
|
/* dtoi8()
|
||||||
* Convert double float to 8-byte integer.
|
* 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
|
Datum
|
||||||
dtoi8(PG_FUNCTION_ARGS)
|
dtoi8(PG_FUNCTION_ARGS)
|
||||||
@ -707,11 +700,18 @@ dtoi8(PG_FUNCTION_ARGS)
|
|||||||
float8 val = PG_GETARG_FLOAT8(0);
|
float8 val = PG_GETARG_FLOAT8(0);
|
||||||
int64 result;
|
int64 result;
|
||||||
|
|
||||||
if ((val < (-pow(2.0, 63.0) + 1)) || (val > (pow(2.0, 63.0) - 1)))
|
/* Round val to nearest integer (but it's still in float form) */
|
||||||
elog(ERROR, "Floating point conversion to int64 is out of range");
|
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;
|
result = (int64) val;
|
||||||
|
|
||||||
|
if ((float8) result != val)
|
||||||
|
elog(ERROR, "Floating point conversion to int8 is out of range");
|
||||||
|
|
||||||
PG_RETURN_INT64(result);
|
PG_RETURN_INT64(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,16 +87,6 @@ SELECT '' AS five, q2, float8(q2) FROM INT8_TBL;
|
|||||||
| -4567890123456789 | -4.56789012345679e+015
|
| -4567890123456789 | -4.56789012345679e+015
|
||||||
(5 rows)
|
(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;
|
SELECT '' AS five, 2 * q1 AS "twice int4" FROM INT8_TBL;
|
||||||
five | twice int4
|
five | twice int4
|
||||||
------+------------------
|
------+------------------
|
||||||
|
@ -87,16 +87,6 @@ SELECT '' AS five, q2, float8(q2) FROM INT8_TBL;
|
|||||||
| -4567890123456789 | -4.56789012345679e+15
|
| -4567890123456789 | -4.56789012345679e+15
|
||||||
(5 rows)
|
(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;
|
SELECT '' AS five, 2 * q1 AS "twice int4" FROM INT8_TBL;
|
||||||
five | twice int4
|
five | twice int4
|
||||||
------+------------------
|
------+------------------
|
||||||
|
@ -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, q1, float8(q1) FROM INT8_TBL;
|
||||||
SELECT '' AS five, q2, float8(q2) 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, 2 * q1 AS "twice int4" FROM INT8_TBL;
|
||||||
SELECT '' AS five, q1 * 2 AS "twice int4" FROM INT8_TBL;
|
SELECT '' AS five, q1 * 2 AS "twice int4" FROM INT8_TBL;
|
||||||
|
Reference in New Issue
Block a user