namespace
{
using namespace vulkan_cpu::util::soft_float;
-std::string hexValue(const ExtendedFloat &v)
+[[gnu::unused]] std::string hexValue(const ExtendedFloat &v)
{
if(v.isNaN())
{
{
return log10(ExtendedFloat(a));
};
+ auto fromHalf_1 = [](std::uint16_t a, long double b) -> ExtendedFloat
+ {
+ return ExtendedFloat::fromHalfPrecision(a);
+ };
+ auto fromHalf_2 = [](std::uint16_t a, long double b) -> ExtendedFloat
+ {
+ return ExtendedFloat(b);
+ };
const long double NaN = std::numeric_limits<long double>::quiet_NaN();
const long double Infinity = std::numeric_limits<long double>::infinity();
testCase("add", add1, add2, +0.0L, +0.0L);
testCase("log2", log2_1, log2_2, static_cast<long double>(ExtendedFloat::LogOf2()));
testCase("log10", log10_1, log10_2, 1e1001L);
testCase("log10", log10_1, log10_2, 1.5L);
+ testCase("fromHalf",
+ fromHalf_1,
+ fromHalf_2,
+ static_cast<std::uint64_t>(0x1U),
+ 5.9604644775390625e-8L);
+ testCase("fromHalf",
+ fromHalf_1,
+ fromHalf_2,
+ static_cast<std::uint64_t>(0x8001U),
+ -5.9604644775390625e-8L);
+ testCase("fromHalf", fromHalf_1, fromHalf_2, static_cast<std::uint64_t>(0x3C00U), 1.0L);
+ testCase("fromHalf", fromHalf_1, fromHalf_2, static_cast<std::uint64_t>(0xBC00U), -1.0L);
+ testCase("fromHalf", fromHalf_1, fromHalf_2, static_cast<std::uint64_t>(0x7C00U), Infinity);
+ testCase("fromHalf", fromHalf_1, fromHalf_2, static_cast<std::uint64_t>(0xFC00U), -Infinity);
+ testCase("fromHalf", fromHalf_1, fromHalf_2, static_cast<std::uint64_t>(0x7C01U), NaN);
}
struct Init
{
value = std::scalbn(value, 63 - static_cast<long>(exponent) + exponentBias());
mantissa = value;
}
+ static constexpr ExtendedFloat fromHalfPrecision(std::uint16_t value) noexcept
+ {
+ bool sign = (value & 0x8000U) != 0;
+ std::uint16_t exponentField = (value & 0x7C00U) >> 10;
+ std::uint16_t mantissaField = value & 0x3FFU;
+ if(exponentField == 0x1FU)
+ {
+ if(mantissaField != 0)
+ return NaN();
+ return Infinity(sign);
+ }
+ if(exponentField != 0)
+ mantissaField |= 0x400U; // add in implicit 1
+ else
+ exponentField = 1;
+ return ExtendedFloat(mantissaField, static_cast<int>(exponentField) - 15 - 10 + exponentBias() + 63, sign);
+ }
explicit operator long double() const noexcept
{
if(exponent == infinityNaNExponent())