diff --git a/velox/functions/prestosql/BinaryFunctions.h b/velox/functions/prestosql/BinaryFunctions.h index ce153ee349fc..c9495daff1bb 100644 --- a/velox/functions/prestosql/BinaryFunctions.h +++ b/velox/functions/prestosql/BinaryFunctions.h @@ -388,7 +388,11 @@ struct ToIEEE754Bits64 { out_type& result, const arg_type& input) { static constexpr auto kTypeLength = sizeof(int64_t); - auto value = folly::Endian::big(input); + // Since we consider NaNs with different binary representation as equal, we + // normalize them to a single value to ensure the output is equal too. + auto value = std::isnan(input) + ? folly::Endian::big(std::numeric_limits::quiet_NaN()) + : folly::Endian::big(input); result.setNoCopy( StringView(reinterpret_cast(&value), kTypeLength)); } @@ -416,7 +420,11 @@ struct ToIEEE754Bits32 { out_type& result, const arg_type& input) { static constexpr auto kTypeLength = sizeof(int32_t); - auto value = folly::Endian::big(input); + // Since we consider NaNs with different binary representation as equal, we + // normalize them to a single value to ensure the output is equal too. + auto value = std::isnan(input) + ? folly::Endian::big(std::numeric_limits::quiet_NaN()) + : folly::Endian::big(input); result.setNoCopy( StringView(reinterpret_cast(&value), kTypeLength)); } diff --git a/velox/functions/prestosql/tests/BinaryFunctionsTest.cpp b/velox/functions/prestosql/tests/BinaryFunctionsTest.cpp index 2ce20c3f58e2..18fb0b8b9a10 100644 --- a/velox/functions/prestosql/tests/BinaryFunctionsTest.cpp +++ b/velox/functions/prestosql/tests/BinaryFunctionsTest.cpp @@ -635,8 +635,10 @@ TEST_F(BinaryFunctionsTest, toIEEE754Bits64) { EXPECT_EQ( hexToDec("7FF8000000000000"), toIEEE754Bits64(std::numeric_limits::quiet_NaN())); + // NaNs are normalized when generating output to ensure they are equal as all + // NaNs are considered equal EXPECT_EQ( - hexToDec("7FF4000000000000"), + hexToDec("7FF8000000000000"), toIEEE754Bits64(std::numeric_limits::signaling_NaN())); EXPECT_EQ( hexToDec("FFF0000000000000"), @@ -698,6 +700,11 @@ TEST_F(BinaryFunctionsTest, toIEEE754Bits32) { EXPECT_EQ( hexToDec("7FC00000"), toIEEE754Bits32(std::numeric_limits::quiet_NaN())); + // NaNs are normalized when generating output to ensure they are equal as all + // NaNs are considered equal + EXPECT_EQ( + hexToDec("7FC00000"), + toIEEE754Bits32(std::numeric_limits::signaling_NaN())); EXPECT_EQ( hexToDec("7F800000"), toIEEE754Bits32(std::numeric_limits::infinity()));