Serenity Operating System
1/*
2 * Copyright (c) 2022, Jelle Raaijmakers <jelle@gmta.nl>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <AK/FloatingPoint.h>
8#include <LibTest/TestCase.h>
9#include <math.h>
10
11TEST_CASE(f16_1_5_10_to_native_float)
12{
13 auto within_approximate = [](u16 lhs, float rhs) -> bool {
14 auto f32_lhs = convert_to_native_float(FloatingPointBits<1, 5, 10>(lhs));
15 return fabsf(f32_lhs - rhs) <= 0.00001f;
16 };
17
18 EXPECT(within_approximate(0x0000, 0.f));
19 EXPECT(within_approximate(0x03FF, 0.000061f));
20 EXPECT(within_approximate(0x3CEF, 1.23339f));
21 EXPECT(within_approximate(0xBC00, -1.f));
22 EXPECT(within_approximate(0xA266, -0.0125f));
23
24 float result;
25 result = convert_to_native_float(FloatingPointBits<1, 5, 10>(0xFC01u));
26 EXPECT(isnan(result));
27
28 result = convert_to_native_float(FloatingPointBits<1, 5, 10>(0x7C00u));
29 EXPECT(isinf(result));
30}
31
32TEST_CASE(float_to_double_roundtrips)
33{
34 auto roundtrip = [](float floatvalue1) {
35 auto doublevalue = convert_from_native_float<DoubleFloatingPointBits>(floatvalue1).as_double();
36 auto floatbits = convert_from_native_double<SingleFloatingPointBits>(doublevalue);
37 auto floatvalue2 = convert_to_native_float(floatbits);
38
39 EXPECT_APPROXIMATE(floatvalue1, floatvalue2);
40 };
41
42 roundtrip(-1.0f);
43 roundtrip(-0.1f);
44 roundtrip(0.0f);
45 roundtrip(0.000001f);
46 roundtrip(0.1f);
47 roundtrip(1.0f);
48 roundtrip(3.141592f);
49 roundtrip(16777216.0f);
50 roundtrip(33554432.0f);
51
52 roundtrip(1 / 0.0f);
53 roundtrip(1 / -0.0f);
54 roundtrip(0 / 0.0f);
55}
56
57TEST_CASE(normalize_denormalize)
58{
59 // Go from denormalized float to normalized double
60 auto denormalized_float = 6.709679e-39f;
61 auto denormalized_float_bits = SingleFloatingPointBits(denormalized_float);
62 auto normalized_double = convert_to_native_double(denormalized_float_bits);
63 EXPECT_APPROXIMATE(denormalized_float, normalized_double);
64
65 // Go back from normalized double to denormalized float
66 auto normalized_double_bits = DoubleFloatingPointBits(normalized_double);
67 auto reconstructed_denormalized_float = convert_to_native_float(normalized_double_bits);
68 EXPECT_APPROXIMATE(denormalized_float, reconstructed_denormalized_float);
69}
70
71TEST_CASE(large_exponent)
72{
73 // Make sure we support at least 62 bits of exponent
74 auto large_exponent_float = convert_from_native_double<FloatingPointBits<1, 62, 1>>(1.0);
75 auto converted_double = convert_to_native_double(large_exponent_float);
76 EXPECT_APPROXIMATE(converted_double, 1.0);
77}
78
79TEST_CASE(large_mantissa)
80{
81 // Make sure we support at least 62 bits of mantissa
82 auto large_exponent_float = convert_from_native_double<FloatingPointBits<1, 1, 62>>(1.0);
83 auto converted_double = convert_to_native_double(large_exponent_float);
84 EXPECT_APPROXIMATE(converted_double, 1.0);
85}