提交 a0f2b85c 编写于 作者: A Alexey Milovidov

Make round function to behave consistently on non-x86_64

上级 cb4e119c
...@@ -547,6 +547,7 @@ ...@@ -547,6 +547,7 @@
M(577, INVALID_SHARD_ID) \ M(577, INVALID_SHARD_ID) \
M(578, INVALID_FORMAT_INSERT_QUERY_WITH_DATA) \ M(578, INVALID_FORMAT_INSERT_QUERY_WITH_DATA) \
M(579, INCORRECT_PART_TYPE) \ M(579, INCORRECT_PART_TYPE) \
M(580, CANNOT_SET_ROUNDING_MODE) \
\ \
M(998, POSTGRESQL_CONNECTION_FAILURE) \ M(998, POSTGRESQL_CONNECTION_FAILURE) \
M(999, KEEPER_EXCEPTION) \ M(999, KEEPER_EXCEPTION) \
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#ifdef __SSE4_1__ #ifdef __SSE4_1__
#include <smmintrin.h> #include <smmintrin.h>
#else
#include <fenv.h>
#endif #endif
...@@ -34,6 +36,7 @@ namespace ErrorCodes ...@@ -34,6 +36,7 @@ namespace ErrorCodes
extern const int ARGUMENT_OUT_OF_BOUND; extern const int ARGUMENT_OUT_OF_BOUND;
extern const int ILLEGAL_COLUMN; extern const int ILLEGAL_COLUMN;
extern const int BAD_ARGUMENTS; extern const int BAD_ARGUMENTS;
extern const int CANNOT_SET_ROUNDING_MODE;
} }
...@@ -231,7 +234,7 @@ inline float roundWithMode(float x, RoundingMode mode) ...@@ -231,7 +234,7 @@ inline float roundWithMode(float x, RoundingMode mode)
{ {
switch (mode) switch (mode)
{ {
case RoundingMode::Round: return roundf(x); case RoundingMode::Round: return nearbyintf(x);
case RoundingMode::Floor: return floorf(x); case RoundingMode::Floor: return floorf(x);
case RoundingMode::Ceil: return ceilf(x); case RoundingMode::Ceil: return ceilf(x);
case RoundingMode::Trunc: return truncf(x); case RoundingMode::Trunc: return truncf(x);
...@@ -244,7 +247,7 @@ inline double roundWithMode(double x, RoundingMode mode) ...@@ -244,7 +247,7 @@ inline double roundWithMode(double x, RoundingMode mode)
{ {
switch (mode) switch (mode)
{ {
case RoundingMode::Round: return round(x); case RoundingMode::Round: return nearbyint(x);
case RoundingMode::Floor: return floor(x); case RoundingMode::Floor: return floor(x);
case RoundingMode::Ceil: return ceil(x); case RoundingMode::Ceil: return ceil(x);
case RoundingMode::Trunc: return trunc(x); case RoundingMode::Trunc: return trunc(x);
...@@ -595,6 +598,15 @@ public: ...@@ -595,6 +598,15 @@ public:
return false; return false;
}; };
#if !defined(__SSE4_1__)
/// In case of "nearbyint" function is used, we should ensure the expected rounding mode for the Banker's rounding.
/// Actually it is by default. But we will set it just in case.
if constexpr (rounding_mode == RoundingMode::Round)
if (0 != fesetround(FE_TONEAREST))
throw Exception("Cannot set floating point rounding mode", ErrorCodes::CANNOT_SET_ROUNDING_MODE);
#endif
if (!callOnIndexAndDataType<void>(column.type->getTypeId(), call)) if (!callOnIndexAndDataType<void>(column.type->getTypeId(), call))
{ {
throw Exception("Illegal column " + column.name + " of argument of function " + getName(), throw Exception("Illegal column " + column.name + " of argument of function " + getName(),
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册