Merge pull request #22582 from ClickHouse/round-arm-bankers

Make round function to behave consistently on non-x86_64
This commit is contained in:
alexey-milovidov 2021-04-04 12:25:22 +03:00 committed by GitHub
commit 7512227431
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 15 additions and 2 deletions

View File

@ -547,6 +547,7 @@
M(577, INVALID_SHARD_ID) \
M(578, INVALID_FORMAT_INSERT_QUERY_WITH_DATA) \
M(579, INCORRECT_PART_TYPE) \
M(580, CANNOT_SET_ROUNDING_MODE) \
\
M(998, POSTGRESQL_CONNECTION_FAILURE) \
M(999, KEEPER_EXCEPTION) \

View File

@ -21,6 +21,8 @@
#ifdef __SSE4_1__
#include <smmintrin.h>
#else
#include <fenv.h>
#endif
@ -34,6 +36,7 @@ namespace ErrorCodes
extern const int ARGUMENT_OUT_OF_BOUND;
extern const int ILLEGAL_COLUMN;
extern const int BAD_ARGUMENTS;
extern const int CANNOT_SET_ROUNDING_MODE;
}
@ -231,7 +234,7 @@ inline float roundWithMode(float x, RoundingMode mode)
{
switch (mode)
{
case RoundingMode::Round: return roundf(x);
case RoundingMode::Round: return nearbyintf(x);
case RoundingMode::Floor: return floorf(x);
case RoundingMode::Ceil: return ceilf(x);
case RoundingMode::Trunc: return truncf(x);
@ -244,7 +247,7 @@ inline double roundWithMode(double x, RoundingMode mode)
{
switch (mode)
{
case RoundingMode::Round: return round(x);
case RoundingMode::Round: return nearbyint(x);
case RoundingMode::Floor: return floor(x);
case RoundingMode::Ceil: return ceil(x);
case RoundingMode::Trunc: return trunc(x);
@ -595,6 +598,15 @@ public:
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))
{
throw Exception("Illegal column " + column.name + " of argument of function " + getName(),