Commit fac83dbd authored by Tom Lane's avatar Tom Lane

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
parent 9e38c2bb
...@@ -225,9 +225,9 @@ float4_div(const float4 val1, const float4 val2) ...@@ -225,9 +225,9 @@ float4_div(const float4 val1, const float4 val2)
if (unlikely(val2 == 0.0f) && !isnan(val1)) if (unlikely(val2 == 0.0f) && !isnan(val1))
float_zero_divide_error(); float_zero_divide_error();
result = val1 / val2; result = val1 / val2;
if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2)) if (unlikely(isinf(result)) && !isinf(val1))
float_overflow_error(); float_overflow_error();
if (unlikely(result == 0.0f) && val1 != 0.0f) if (unlikely(result == 0.0f) && val1 != 0.0f && !isinf(val2))
float_underflow_error(); float_underflow_error();
return result; return result;
...@@ -241,9 +241,9 @@ float8_div(const float8 val1, const float8 val2) ...@@ -241,9 +241,9 @@ float8_div(const float8 val1, const float8 val2)
if (unlikely(val2 == 0.0) && !isnan(val1)) if (unlikely(val2 == 0.0) && !isnan(val1))
float_zero_divide_error(); float_zero_divide_error();
result = val1 / val2; result = val1 / val2;
if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2)) if (unlikely(isinf(result)) && !isinf(val1))
float_overflow_error(); float_overflow_error();
if (unlikely(result == 0.0) && val1 != 0.0) if (unlikely(result == 0.0) && val1 != 0.0 && !isinf(val2))
float_underflow_error(); float_underflow_error();
return result; return result;
......
...@@ -137,6 +137,12 @@ SELECT 'Infinity'::float4 / 'Infinity'::float4; ...@@ -137,6 +137,12 @@ SELECT 'Infinity'::float4 / 'Infinity'::float4;
NaN NaN
(1 row) (1 row)
SELECT '42'::float4 / 'Infinity'::float4;
?column?
----------
0
(1 row)
SELECT 'nan'::float4 / 'nan'::float4; SELECT 'nan'::float4 / 'nan'::float4;
?column? ?column?
---------- ----------
......
...@@ -137,6 +137,12 @@ SELECT 'Infinity'::float4 / 'Infinity'::float4; ...@@ -137,6 +137,12 @@ SELECT 'Infinity'::float4 / 'Infinity'::float4;
NaN NaN
(1 row) (1 row)
SELECT '42'::float4 / 'Infinity'::float4;
?column?
----------
0
(1 row)
SELECT 'nan'::float4 / 'nan'::float4; SELECT 'nan'::float4 / 'nan'::float4;
?column? ?column?
---------- ----------
......
...@@ -120,6 +120,12 @@ SELECT 'Infinity'::float8 / 'Infinity'::float8; ...@@ -120,6 +120,12 @@ SELECT 'Infinity'::float8 / 'Infinity'::float8;
NaN NaN
(1 row) (1 row)
SELECT '42'::float8 / 'Infinity'::float8;
?column?
----------
0
(1 row)
SELECT 'nan'::float8 / 'nan'::float8; SELECT 'nan'::float8 / 'nan'::float8;
?column? ?column?
---------- ----------
......
...@@ -49,6 +49,7 @@ SELECT ' INFINITY x'::float4; ...@@ -49,6 +49,7 @@ SELECT ' INFINITY x'::float4;
SELECT 'Infinity'::float4 + 100.0; SELECT 'Infinity'::float4 + 100.0;
SELECT 'Infinity'::float4 / 'Infinity'::float4; SELECT 'Infinity'::float4 / 'Infinity'::float4;
SELECT '42'::float4 / 'Infinity'::float4;
SELECT 'nan'::float4 / 'nan'::float4; SELECT 'nan'::float4 / 'nan'::float4;
SELECT 'nan'::float4 / '0'::float4; SELECT 'nan'::float4 / '0'::float4;
SELECT 'nan'::numeric::float4; SELECT 'nan'::numeric::float4;
......
...@@ -42,6 +42,7 @@ SELECT ' INFINITY x'::float8; ...@@ -42,6 +42,7 @@ SELECT ' INFINITY x'::float8;
SELECT 'Infinity'::float8 + 100.0; SELECT 'Infinity'::float8 + 100.0;
SELECT 'Infinity'::float8 / 'Infinity'::float8; SELECT 'Infinity'::float8 / 'Infinity'::float8;
SELECT '42'::float8 / 'Infinity'::float8;
SELECT 'nan'::float8 / 'nan'::float8; SELECT 'nan'::float8 / 'nan'::float8;
SELECT 'nan'::float8 / '0'::float8; SELECT 'nan'::float8 / '0'::float8;
SELECT 'nan'::numeric::float8; SELECT 'nan'::numeric::float8;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment