postgres.git / summary / log / commit / refs
commit fac83dbd6fe1ac3d4125bfa39f287f95bffe6cda
Author: Tom Lane <tgl@sss.pgh.pa.us>
Date: Wed Nov 04 23:11:15 2020 +0000
First released in: 14.0
Remove underflow error in float division with infinite divisor.
float4_div and float8_div correctly produced zero for zero divided
by infinity, but threw an underflow error for nonzero finite values
divided by infinity. This seems wrong; at the very least it's
inconsistent with the behavior recently implemented for numeric
infinities. Remove the error and allow zero to be returned.
This patch also removes a useless isinf() test from the overflow
checks in these functions (non-Inf divided by Inf can't produce Inf).
Extracted from a larger patch; this seems significant outside the
context of geometric operators, so it deserves its own commit.
Kyotaro Horiguchi
Discussion: https://postgr.es/m/CAGf+fX70rWFOk5cd00uMfa__0yP+vtQg5ck7c2Onb-Yczp0URA@mail.gmail.com
src/include/utils/float.h | 8 ++++----
src/test/regress/expected/float4-misrounded-input.out | 6 ++++++
src/test/regress/expected/float4.out | 6 ++++++
src/test/regress/expected/float8.out | 6 ++++++
src/test/regress/sql/float4.sql | 1 +
src/test/regress/sql/float8.sql | 1 +
6 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/src/include/utils/float.h b/src/include/utils/float.h
index e2aae8ef177..79bf8daca80 100644
--- a/src/include/utils/float.h
+++ b/src/include/utils/float.h
@@ -225,9 +225,9 @@ float4_div(const float4 val1, const float4 val2)
if (unlikely(val2 == 0.0f) && !isnan(val1))
float_zero_divide_error();
result = val1 / val2;
- if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))
+ if (unlikely(isinf(result)) && !isinf(val1))
float_overflow_error();
- if (unlikely(result == 0.0f) && val1 != 0.0f)
+ if (unlikely(result == 0.0f) && val1 != 0.0f && !isinf(val2))
float_underflow_error();
return result;
@@ -241,9 +241,9 @@ float8_div(const float8 val1, const float8 val2)
if (unlikely(val2 == 0.0) && !isnan(val1))
float_zero_divide_error();
result = val1 / val2;
- if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2))
+ if (unlikely(isinf(result)) && !isinf(val1))
float_overflow_error();
- if (unlikely(result == 0.0) && val1 != 0.0)
+ if (unlikely(result == 0.0) && val1 != 0.0 && !isinf(val2))
float_underflow_error();
return result;
diff --git a/src/test/regress/expected/float4-misrounded-input.out b/src/test/regress/expected/float4-misrounded-input.out
index 38b847a1adb..7b4964e1799 100644
--- a/src/test/regress/expected/float4-misrounded-input.out
+++ b/src/test/regress/expected/float4-misrounded-input.out
@@ -137,6 +137,12 @@ SELECT 'Infinity'::float4 / 'Infinity'::float4;
NaN
(1 row)
+SELECT '42'::float4 / 'Infinity'::float4;
+ ?column?
+----------
+ 0
+(1 row)
+
SELECT 'nan'::float4 / 'nan'::float4;
?column?
----------
diff --git a/src/test/regress/expected/float4.out b/src/test/regress/expected/float4.out
index 310402b6ee2..dde8c343ce4 100644
--- a/src/test/regress/expected/float4.out
+++ b/src/test/regress/expected/float4.out
@@ -137,6 +137,12 @@ SELECT 'Infinity'::float4 / 'Infinity'::float4;
NaN
(1 row)
+SELECT '42'::float4 / 'Infinity'::float4;
+ ?column?
+----------
+ 0
+(1 row)
+
SELECT 'nan'::float4 / 'nan'::float4;
?column?
----------
diff --git a/src/test/regress/expected/float8.out b/src/test/regress/expected/float8.out
index 2304b579d2b..63da7338937 100644
--- a/src/test/regress/expected/float8.out
+++ b/src/test/regress/expected/float8.out
@@ -120,6 +120,12 @@ SELECT 'Infinity'::float8 / 'Infinity'::float8;
NaN
(1 row)
+SELECT '42'::float8 / 'Infinity'::float8;
+ ?column?
+----------
+ 0
+(1 row)
+
SELECT 'nan'::float8 / 'nan'::float8;
?column?
----------
diff --git a/src/test/regress/sql/float4.sql b/src/test/regress/sql/float4.sql
index 1fcf823c21b..14e54714826 100644
--- a/src/test/regress/sql/float4.sql
+++ b/src/test/regress/sql/float4.sql
@@ -49,6 +49,7 @@ SELECT ' INFINITY x'::float4;
SELECT 'Infinity'::float4 + 100.0;
SELECT 'Infinity'::float4 / 'Infinity'::float4;
+SELECT '42'::float4 / 'Infinity'::float4;
SELECT 'nan'::float4 / 'nan'::float4;
SELECT 'nan'::float4 / '0'::float4;
SELECT 'nan'::numeric::float4;
diff --git a/src/test/regress/sql/float8.sql b/src/test/regress/sql/float8.sql
index f103871cdb2..7e817198533 100644
--- a/src/test/regress/sql/float8.sql
+++ b/src/test/regress/sql/float8.sql
@@ -42,6 +42,7 @@ SELECT ' INFINITY x'::float8;
SELECT 'Infinity'::float8 + 100.0;
SELECT 'Infinity'::float8 / 'Infinity'::float8;
+SELECT '42'::float8 / 'Infinity'::float8;
SELECT 'nan'::float8 / 'nan'::float8;
SELECT 'nan'::float8 / '0'::float8;
SELECT 'nan'::numeric::float8;
[parent: 9e38c2bb5093]