Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add from_ieee754_32 Presto function #7903

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions velox/docs/functions/presto/binary.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ Binary Functions

Decodes binary data from the hex encoded ``string``.

.. function:: from_ieee754_32(binary) -> real

Decodes the 32-bit big-endian ``binary`` in IEEE 754 single-precision floating-point format.
Yuhta marked this conversation as resolved.
Show resolved Hide resolved
Throws a VeloxUserError if input size is shorter / longer than 32 bits.

.. function:: from_ieee754_64(binary) -> double

Decodes the 64-bit big-endian ``binary`` in IEEE 754 double-precision floating-point format.
Throws a VeloxUserError if input size is shorter / longer than 64 bits.

.. function:: hmac_md5(binary, key) -> varbinary

Computes the HMAC with md5 of ``binary`` with the given ``key``.
Expand Down Expand Up @@ -98,10 +108,6 @@ Binary Functions

Encodes ``double`` in a 64-bit big-endian binary according to IEEE 754 double-precision floating-point format.

.. function:: from_ieee754_64(binary) -> double

Decodes the 64-bit big-endian ``binary`` in IEEE 754 double-precision floating-point format.

.. function:: xxhash64(binary) -> varbinary

Computes the xxhash64 hash of ``binary``.
17 changes: 17 additions & 0 deletions velox/functions/prestosql/BinaryFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -424,4 +424,21 @@ struct ToIEEE754Bits32 {
}
};

template <typename T>
struct FromIEEE754Bits32 {
VELOX_DEFINE_FUNCTION_TYPES(T);

FOLLY_ALWAYS_INLINE void call(
out_type<float>& result,
const arg_type<Varbinary>& input) {
static constexpr auto kTypeLength = sizeof(int32_t);
VELOX_USER_CHECK_EQ(
input.size(),
kTypeLength,
"Input floating-point value must be exactly 4 bytes long");
memcpy(&result, input.data(), kTypeLength);
result = folly::Endian::big(result);
}
};

} // namespace facebook::velox::functions
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ void registerSimpleFunctions(const std::string& prefix) {
{prefix + "from_ieee754_64"});
registerFunction<ToIEEE754Bits32, Varbinary, float>(
{prefix + "to_ieee754_32"});
registerFunction<FromIEEE754Bits32, float, Varbinary>(
{prefix + "from_ieee754_32"});
}
} // namespace

Expand Down
58 changes: 58 additions & 0 deletions velox/functions/prestosql/tests/BinaryFunctionsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <array>
#include <limits>
#include "velox/common/base/VeloxException.h"
#include "velox/common/base/tests/GTestUtils.h"
#include "velox/expression/Expr.h"
#include "velox/functions/prestosql/tests/utils/FunctionBaseTest.h"

Expand Down Expand Up @@ -697,4 +698,61 @@ TEST_F(BinaryFunctionsTest, toIEEE754Bits32) {
hexToDec("FF7FFFFF"),
toIEEE754Bits32(std::numeric_limits<float>::lowest()));
}

TEST_F(BinaryFunctionsTest, fromIEEE754Bits32) {
const auto fromIEEE754Bits32 = [&](const std::optional<std::string>& arg) {
return evaluateOnce<float, std::string>(
"from_ieee754_32(c0)", {arg}, {VARBINARY()});
};

const auto toIEEE754Bits32 = [&](std::optional<float> arg) {
return evaluateOnce<std::string, float>("to_ieee754_32(c0)", arg);
};

EXPECT_EQ(std::nullopt, fromIEEE754Bits32(std::nullopt));
aditi-pandit marked this conversation as resolved.
Show resolved Hide resolved
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<float>::infinity(),
fromIEEE754Bits32(hexToDec("7f800000")));
EXPECT_EQ(
-std::numeric_limits<float>::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(
aditi-pandit marked this conversation as resolved.
Show resolved Hide resolved
std::numeric_limits<float>::infinity(),
fromIEEE754Bits32(
toIEEE754Bits32(std::numeric_limits<float>::infinity())));
EXPECT_EQ(
-std::numeric_limits<float>::infinity(),
fromIEEE754Bits32(
toIEEE754Bits32(-std::numeric_limits<float>::infinity())));
EXPECT_EQ(
std::numeric_limits<float>::max(),
fromIEEE754Bits32(toIEEE754Bits32(std::numeric_limits<float>::max())));
EXPECT_EQ(
std::numeric_limits<float>::min(),
fromIEEE754Bits32(toIEEE754Bits32(std::numeric_limits<float>::min())));
EXPECT_TRUE(
std::isnan(fromIEEE754Bits32(
toIEEE754Bits32(std::numeric_limits<float>::quiet_NaN()))
.value()));
EXPECT_TRUE(std::isnan(
fromIEEE754Bits32(
toIEEE754Bits32(std::numeric_limits<float>::signaling_NaN()))
.value()));
EXPECT_TRUE(
std::isnan(fromIEEE754Bits32(toIEEE754Bits32(std::nan("nan"))).value()));
VELOX_ASSERT_THROW(
fromIEEE754Bits32(hexToDec("0000000000000001")),
"Input floating-point value must be exactly 4 bytes long");
}
} // namespace
Loading