0005-float-zero-v06.patch
application/octet-stream
Filename: 0005-float-zero-v06.patch
Type: application/octet-stream
Part: 4
Message:
Re: [PATCH] Improve geometric types
Patch
Format: format-patch
Series: patch v6-0005
Subject: float-zero-v06
| File | + | − |
|---|---|---|
| src/include/utils/float.h | 20 | 6 |
From 7a02dad9c234e824a2a8916cf043d3ac22908f79 Mon Sep 17 00:00:00 2001
From: Emre Hasegeli <emre@hasegeli.com>
Date: Thu, 2 Nov 2017 12:21:19 +0100
Subject: [PATCH 5/6] float-zero-v06
Check for float -0 after multiplications and divisions
Discussion: https://www.postgresql.org/message-id/CAE2gYzxF7-5djV6-cEvqQu-fNsnt%3DEqbOURx7ZDg%2BVv6ZMTWbg%40mail.gmail.com
---
src/include/utils/float.h | 26 ++++++++++++++++++++------
1 file changed, 20 insertions(+), 6 deletions(-)
diff --git a/src/include/utils/float.h b/src/include/utils/float.h
index 48a16f491c..0ce37f4a17 100644
--- a/src/include/utils/float.h
+++ b/src/include/utils/float.h
@@ -210,69 +210,83 @@ float8_mi(const float8 val1, const float8 val2)
result = val1 - val2;
check_float8_val(result, isinf(val1) || isinf(val2), true);
return result;
}
static inline float4
float4_mul(const float4 val1, const float4 val2)
{
+ const bool zero_is_valid = val1 == 0.0f || val2 == 0.0f;
float4 result;
result = val1 * val2;
- check_float4_val(result, isinf(val1) || isinf(val2),
- val1 == 0.0f || val2 == 0.0f);
+ check_float4_val(result, isinf(val1) || isinf(val2), zero_is_valid);
+
+ if (zero_is_valid && unlikely(result == -0.0f))
+ result = 0.0f;
return result;
}
static inline float8
float8_mul(const float8 val1, const float8 val2)
{
+ const bool zero_is_valid = val1 == 0.0 || val2 == 0.0;
float8 result;
result = val1 * val2;
- check_float8_val(result, isinf(val1) || isinf(val2),
- val1 == 0.0 || val2 == 0.0);
+ check_float8_val(result, isinf(val1) || isinf(val2), zero_is_valid);
+
+ if (zero_is_valid && unlikely(result == -0.0))
+ result = 0.0;
return result;
}
static inline float4
float4_div(const float4 val1, const float4 val2)
{
+ const bool zero_is_valid = val1 == 0.0f;
float4 result;
if (val2 == 0.0f)
ereport(ERROR,
(errcode(ERRCODE_DIVISION_BY_ZERO),
errmsg("division by zero")));
result = val1 / val2;
- check_float4_val(result, isinf(val1) || isinf(val2), val1 == 0.0f);
+ check_float4_val(result, isinf(val1) || isinf(val2), zero_is_valid);
+
+ if (zero_is_valid && unlikely(result == -0.0f))
+ result = 0.0f;
return result;
}
static inline float8
float8_div(const float8 val1, const float8 val2)
{
+ const bool zero_is_valid = val1 == 0.0;
float8 result;
if (val2 == 0.0)
ereport(ERROR,
(errcode(ERRCODE_DIVISION_BY_ZERO),
errmsg("division by zero")));
result = val1 / val2;
- check_float8_val(result, isinf(val1) || isinf(val2), val1 == 0.0);
+ check_float8_val(result, isinf(val1) || isinf(val2), zero_is_valid);
+
+ if (zero_is_valid && unlikely(result == -0.0))
+ result = 0.0;
return result;
}
/*
* Routines for NaN-aware comparisons
*
* We consider all NaNs to be equal and larger than any non-NaN. This is
* somewhat arbitrary; the important thing is to have a consistent sort
* order.
--
2.14.3 (Apple Git-98)