From 82678ada78e8bed7eb720b031513baa7020040cc 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 13ea96859e51d..8b785040fd9be 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 35648c8921234..bebea83855d25 100644 --- a/velox/functions/prestosql/BinaryFunctions.h +++ b/velox/functions/prestosql/BinaryFunctions.h @@ -436,4 +436,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 78bcea6c12030..6cba321b7a9a5 100644 --- a/velox/functions/prestosql/registration/BinaryFunctionsRegistration.cpp +++ b/velox/functions/prestosql/registration/BinaryFunctionsRegistration.cpp @@ -64,6 +64,8 @@ void registerSimpleFunctions(const std::string& prefix) { {prefix + "to_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 47a1e67dfedb8..3883f85dd6fa7 100644 --- a/velox/functions/prestosql/tests/BinaryFunctionsTest.cpp +++ b/velox/functions/prestosql/tests/BinaryFunctionsTest.cpp @@ -662,4 +662,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