-// Randomly test a large number of fp64 -> fp32 conversions, comparing
-// against the FPU.
-TEST(FP16Test, FP32ReferenceDownconvert) {
- srand(12345);
-
- for (int i = 0; i < 1000000; ++i) {
- unsigned r1 = rand();
- unsigned r2 = rand();
- unsigned r3 = rand();
- union fp64 src;
- union fp32 reference, result;
-
- src.ll = (((unsigned long long)r1) << 33) ^ ((unsigned long long)r2 << 16) ^ r3;
- reference.f = float(src.f);
- result.u = fp64_to_fp32(src.f);
-
- EXPECT_EQ(isnan(result.f), isnan(reference.f));
- if (!isnan(result.f)) {
- EXPECT_EQ(result.u, reference.u)
- << src.f << " got rounded to " << result.u << " (" << result.f << ")";
- }
- }
+TEST(FP16Test, NaN) {
+ // Ignore the sign bit.
+ EXPECT_EQ(0x7e00, fp32_to_fp16(0.0 / 0.0).val & 0x7fff);
+ EXPECT_TRUE(isnan(fp16_to_fp32(make_fp16(0xfe00))));
+
+ fp32 borderline_inf;
+ borderline_inf.u = 0x7f800000ull;
+ fp32 borderline_nan;
+ borderline_nan.u = 0x7f800001ull;
+
+ ASSERT_FALSE(isfinite(borderline_inf.f));
+ ASSERT_FALSE(isnan(borderline_inf.f));
+
+ ASSERT_FALSE(isfinite(borderline_nan.f));
+ ASSERT_TRUE(isnan(borderline_nan.f));
+
+ double borderline_inf_roundtrip = fp16_to_fp32(fp32_to_fp16(borderline_inf.f));
+ double borderline_nan_roundtrip = fp16_to_fp32(fp32_to_fp16(borderline_nan.f));
+
+ EXPECT_FALSE(isfinite(borderline_inf_roundtrip));
+ EXPECT_FALSE(isnan(borderline_inf_roundtrip));
+
+ EXPECT_FALSE(isfinite(borderline_nan_roundtrip));
+ EXPECT_TRUE(isnan(borderline_nan_roundtrip));