Skip to content

Commit

Permalink
Add from_ieee754_32 scalar function
Browse files Browse the repository at this point in the history
  • Loading branch information
pdabre12 authored and Pratik Joseph Dabre committed Feb 5, 2024
1 parent 3c5d864 commit 4df9d68
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 0 deletions.
4 changes: 4 additions & 0 deletions velox/docs/functions/presto/binary.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
14 changes: 14 additions & 0 deletions velox/functions/prestosql/BinaryFunctions.h
Original file line number Diff line number Diff line change
Expand Up @@ -424,4 +424,18 @@ 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, "Expected 4-byte input");
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
54 changes: 54 additions & 0 deletions velox/functions/prestosql/tests/BinaryFunctionsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -697,4 +697,58 @@ 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));
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(
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()));
}
} // namespace

0 comments on commit 4df9d68

Please sign in to comment.