From b8a6db18ea98ab1c1fd338b7ebbe9288592c9595 Mon Sep 17 00:00:00 2001 From: Pratik Joseph Dabre Date: Fri, 5 Jan 2024 02:07:39 -0800 Subject: [PATCH] Add from_ieee754_32 Scalar function --- velox/docs/functions/presto/binary.rst | 4 +++ velox/functions/prestosql/BinaryFunctions.h | 14 ++++++++ .../BinaryFunctionsRegistration.cpp | 2 ++ .../prestosql/tests/BinaryFunctionsTest.cpp | 34 +++++++++++++++++++ 4 files changed, 54 insertions(+) diff --git a/velox/docs/functions/presto/binary.rst b/velox/docs/functions/presto/binary.rst index d5a9ad3a1dec3..a68bf6a21bd77 100644 --- a/velox/docs/functions/presto/binary.rst +++ b/velox/docs/functions/presto/binary.rst @@ -94,6 +94,10 @@ Binary Functions Encodes ``real`` in a 32-bit big-endian binary according to IEEE 754 single-precision floating-point format. +.. function:: from_ieee754_32(binary) -> real + + Decodes the 32-bit big-endian ``binary`` in IEEE 754 single-precision floating-point format. + .. function:: to_ieee754_64(double) -> varbinary Encodes ``double`` in a 64-bit big-endian binary according to IEEE 754 double-precision floating-point format. diff --git a/velox/functions/prestosql/BinaryFunctions.h b/velox/functions/prestosql/BinaryFunctions.h index d01e1e73a4b69..2347cc541e156 100644 --- a/velox/functions/prestosql/BinaryFunctions.h +++ b/velox/functions/prestosql/BinaryFunctions.h @@ -427,4 +427,18 @@ struct ToIEEE754Bits32 { } }; +template +struct FromIEEE754Bits32 { + VELOX_DEFINE_FUNCTION_TYPES(T); + + FOLLY_ALWAYS_INLINE void call( + out_type& result, + const arg_type& input) { + static constexpr auto kTypeLength = sizeof(int32_t); + VELOX_USER_CHECK_EQ(input.size(), kTypeLength, "Expected 4-byte input"); + memcpy(&result, input.data(), kTypeLength); + result = folly::Endian::big(result); + } +}; + } // namespace facebook::velox::functions diff --git a/velox/functions/prestosql/registration/BinaryFunctionsRegistration.cpp b/velox/functions/prestosql/registration/BinaryFunctionsRegistration.cpp index b9201cf22db15..3004e2c451594 100644 --- a/velox/functions/prestosql/registration/BinaryFunctionsRegistration.cpp +++ b/velox/functions/prestosql/registration/BinaryFunctionsRegistration.cpp @@ -66,6 +66,8 @@ void registerSimpleFunctions(const std::string& prefix) { {prefix + "from_ieee754_64"}); registerFunction( {prefix + "to_ieee754_32"}); + registerFunction( + {prefix + "from_ieee754_32"}); } } // namespace diff --git a/velox/functions/prestosql/tests/BinaryFunctionsTest.cpp b/velox/functions/prestosql/tests/BinaryFunctionsTest.cpp index 0a647d2ecf520..6b9c0fa1327fc 100644 --- a/velox/functions/prestosql/tests/BinaryFunctionsTest.cpp +++ b/velox/functions/prestosql/tests/BinaryFunctionsTest.cpp @@ -697,4 +697,38 @@ TEST_F(BinaryFunctionsTest, toIEEE754Bits32) { hexToDec("FF7FFFFF"), toIEEE754Bits32(std::numeric_limits::lowest())); } + +TEST_F(BinaryFunctionsTest, fromIEEE754Bits32) { + const auto fromIEEE754Bits32 = [&](const std::optional& arg) { + return evaluateOnce( + "from_ieee754_32(c0)", {arg}, {VARBINARY()}); + }; + + const auto toIEEE754Bits32 = [&](std::optional arg) { + return evaluateOnce("to_ieee754_32(c0)", arg); + }; + + EXPECT_EQ(std::nullopt, fromIEEE754Bits32(std::nullopt)); + EXPECT_EQ(1.0f, fromIEEE754Bits32(hexToDec("3F800000"))); + EXPECT_EQ(3.14f, fromIEEE754Bits32(hexToDec("4048F5C3"))); + EXPECT_EQ(3.4028235E38f, fromIEEE754Bits32(hexToDec("7f7fffff"))); + EXPECT_EQ(-3.4028235E38f, fromIEEE754Bits32(hexToDec("ff7fffff"))); + EXPECT_EQ(1.4E-45f, fromIEEE754Bits32(hexToDec("00000001"))); + EXPECT_EQ(-1.4E-45f, fromIEEE754Bits32(hexToDec("80000001"))); + EXPECT_EQ( + std::numeric_limits::infinity(), + fromIEEE754Bits32(hexToDec("7f800000"))); + EXPECT_EQ( + -std::numeric_limits::infinity(), + fromIEEE754Bits32(hexToDec("ff800000"))); + EXPECT_THROW(fromIEEE754Bits32("YQ"), VeloxUserError); + EXPECT_EQ(3.4028235E38f, fromIEEE754Bits32(toIEEE754Bits32(3.4028235E38f))); + EXPECT_EQ(-3.4028235E38f, fromIEEE754Bits32(toIEEE754Bits32(-3.4028235E38f))); + EXPECT_EQ(1.4E-45f, fromIEEE754Bits32(toIEEE754Bits32(1.4E-45f))); + EXPECT_EQ(-1.4E-45f, fromIEEE754Bits32(toIEEE754Bits32(-1.4E-45f))); + EXPECT_EQ( + std::numeric_limits::infinity(), + fromIEEE754Bits32( + toIEEE754Bits32(std::numeric_limits::infinity()))); +} } // namespace