4 #include <gtest/gtest.h>
8 TEST(FP16Test, Simple) {
9 EXPECT_EQ(0x0000, fp64_to_fp16(0.0));
10 EXPECT_DOUBLE_EQ(0.0, fp16_to_fp64(0x0000));
12 EXPECT_EQ(0x3c00, fp64_to_fp16(1.0));
13 EXPECT_DOUBLE_EQ(1.0, fp16_to_fp64(0x3c00));
15 EXPECT_EQ(0x3555, fp64_to_fp16(1.0 / 3.0));
16 EXPECT_DOUBLE_EQ(0.333251953125, fp16_to_fp64(0x3555));
19 TEST(FP16Test, RoundToNearestEven) {
20 ASSERT_DOUBLE_EQ(1.0, fp16_to_fp64(0x3c00));
22 double x0 = fp16_to_fp64(0x3c00);
23 double x1 = fp16_to_fp64(0x3c01);
24 double x2 = fp16_to_fp64(0x3c02);
25 double x3 = fp16_to_fp64(0x3c03);
26 double x4 = fp16_to_fp64(0x3c04);
28 EXPECT_EQ(0x3c00, fp64_to_fp16(0.5 * (x0 + x1)));
29 EXPECT_EQ(0x3c02, fp64_to_fp16(0.5 * (x1 + x2)));
30 EXPECT_EQ(0x3c02, fp64_to_fp16(0.5 * (x2 + x3)));
31 EXPECT_EQ(0x3c04, fp64_to_fp16(0.5 * (x3 + x4)));
36 unsigned long long ll;
44 EXPECT_EQ(0xfe00, fp64_to_fp16(0.0 / 0.0));
45 EXPECT_TRUE(isnan(fp16_to_fp64(0xfe00)));
48 borderline_inf.ll = 0x7ff0000000000000ull;
50 borderline_nan.ll = 0x7ff0000000000001ull;
52 ASSERT_FALSE(isfinite(borderline_inf.f));
53 ASSERT_FALSE(isnan(borderline_inf.f));
55 ASSERT_FALSE(isfinite(borderline_nan.f));
56 ASSERT_TRUE(isnan(borderline_nan.f));
58 double borderline_inf_roundtrip = fp16_to_fp64(fp64_to_fp16(borderline_inf.f));
59 double borderline_nan_roundtrip = fp16_to_fp64(fp64_to_fp16(borderline_nan.f));
61 EXPECT_FALSE(isfinite(borderline_inf_roundtrip));
62 EXPECT_FALSE(isnan(borderline_inf_roundtrip));
64 EXPECT_FALSE(isfinite(borderline_nan_roundtrip));
65 EXPECT_TRUE(isnan(borderline_nan_roundtrip));
68 TEST(FP16Test, Denormals) {
69 const double smallest_fp16_denormal = 5.9604644775390625e-08;
70 EXPECT_EQ(0x0001, fp64_to_fp16(smallest_fp16_denormal));
71 EXPECT_EQ(0x0000, fp64_to_fp16(0.5 * smallest_fp16_denormal)); // Round-to-even.
72 EXPECT_EQ(0x0001, fp64_to_fp16(0.51 * smallest_fp16_denormal));
73 EXPECT_EQ(0x0002, fp64_to_fp16(1.5 * smallest_fp16_denormal));
75 const double smallest_fp16_non_denormal = 6.103515625e-05;
76 EXPECT_EQ(0x0400, fp64_to_fp16(smallest_fp16_non_denormal));
77 EXPECT_EQ(0x0400, fp64_to_fp16(smallest_fp16_non_denormal - 0.5 * smallest_fp16_denormal)); // Round-to-even.
78 EXPECT_EQ(0x03ff, fp64_to_fp16(smallest_fp16_non_denormal - smallest_fp16_denormal));
81 // Randomly test a large number of fp64 -> fp32 conversions, comparing
83 TEST(FP16Test, FP32ReferenceDownconvert) {
86 for (int i = 0; i < 1000000; ++i) {
91 union fp32 reference, result;
93 src.ll = (((unsigned long long)r1) << 33) ^ ((unsigned long long)r2 << 16) ^ r3;
94 reference.f = float(src.f);
95 result.u = fp64_to_fp32(src.f);
97 EXPECT_EQ(isnan(result.f), isnan(reference.f));
98 if (!isnan(result.f)) {
99 EXPECT_EQ(result.u, reference.u)
100 << src.f << " got rounded to " << result.u << " (" << result.f << ")";
105 // Randomly test a large number of fp32 -> fp64 conversions, comparing
107 TEST(FP16Test, FP32ReferenceUpconvert) {
110 for (int i = 0; i < 1000000; ++i) {
111 unsigned r1 = rand();
112 unsigned r2 = rand();
114 union fp64 reference, result;
116 src.u = ((unsigned long long)r1 << 16) ^ r2;
117 reference.f = double(src.f);
118 result.f = fp32_to_fp64(src.u);
120 EXPECT_EQ(isnan(result.f), isnan(reference.f));
121 if (!isnan(result.f)) {
122 EXPECT_EQ(result.ll, reference.ll)
123 << src.f << " got converted to " << result.ll << " (" << result.f << ")";