diff --git a/src/Common/ErrorCodes.cpp b/src/Common/ErrorCodes.cpp index 918bc30175444c8ae80051ce51ae5a51f0e90cc5..0f85ad5c792fd56d2b42732929d4a57a06a4648f 100644 --- a/src/Common/ErrorCodes.cpp +++ b/src/Common/ErrorCodes.cpp @@ -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) \ diff --git a/src/Functions/FunctionsRound.h b/src/Functions/FunctionsRound.h index b510f62662e711dfcd856e856d8a842241681d13..b190bc5bd8bbc7592c14b1ac22cebc2d384835cf 100644 --- a/src/Functions/FunctionsRound.h +++ b/src/Functions/FunctionsRound.h @@ -21,6 +21,8 @@ #ifdef __SSE4_1__ #include +#else + #include #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(column.type->getTypeId(), call)) { throw Exception("Illegal column " + column.name + " of argument of function " + getName(),