Serenity Operating System
at master 171 lines 6.5 kB view raw
1/* 2 * Copyright (c) 2021, the SerenityOS developers. 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <LibTest/TestCase.h> 8 9#include <AK/FixedPoint.h> 10#include <AK/NumericLimits.h> 11 12using Type = FixedPoint<4>; 13 14TEST_CASE(arithmetic) 15{ 16 EXPECT_EQ( 17 Type(0.5) + Type(0.5), 18 Type(1)); 19 EXPECT_EQ( 20 Type(1) + Type(0.5), 21 Type(1.5)); 22 EXPECT_EQ( 23 (float)(Type(1) + Type(0.5)), 24 1.5f); 25 // FIXME: Test for rounded multiply 26 EXPECT_EQ( 27 Type((int)1) * Type(0.5), 28 Type(0.5)); 29 EXPECT_EQ( 30 Type((int)1) / Type(0.5), 31 Type(2)); 32} 33 34TEST_CASE(rounding) 35{ 36 EXPECT_EQ(Type(0.5).round(), Type(0)); 37 EXPECT_EQ(Type(0.5).floor(), Type(0)); 38 EXPECT_EQ(Type(0.5).ceil(), Type(1)); 39 EXPECT_EQ(Type(0.75).trunk(), Type(0)); 40 41 EXPECT_EQ(Type(1.5).round(), Type(2)); 42 EXPECT_EQ(Type(1.5).floor(), Type(1)); 43 EXPECT_EQ(Type(1.5).ceil(), Type(2)); 44 EXPECT_EQ(Type(1.25).trunk(), Type(1)); 45 46 EXPECT_EQ(Type(-0.5).round(), Type(0)); 47 EXPECT_EQ(Type(-0.5).floor(), Type(-1)); 48 EXPECT_EQ(Type(-0.5).ceil(), Type(0)); 49 EXPECT_EQ(Type(-0.75).trunk(), Type(0)); 50 51 EXPECT_EQ(Type(-1.5).round(), Type(-2)); 52 EXPECT_EQ(Type(-1.5).floor(), Type(-2)); 53 EXPECT_EQ(Type(-1.5).ceil(), Type(-1)); 54 EXPECT_EQ(Type(-1.25).trunk(), Type(-1)); 55 56 EXPECT_EQ(Type(0.5).lround(), 0); 57 EXPECT_EQ(Type(0.5).lfloor(), 0); 58 EXPECT_EQ(Type(0.5).lceil(), 1); 59 EXPECT_EQ(Type(0.5).ltrunk(), 0); 60 61 EXPECT_EQ(Type(1.5).lround(), 2); 62 EXPECT_EQ(Type(1.5).lfloor(), 1); 63 EXPECT_EQ(Type(1.5).lceil(), 2); 64 EXPECT_EQ(Type(1.5).ltrunk(), 1); 65 66 EXPECT_EQ(Type(-0.5).lround(), 0); 67 EXPECT_EQ(Type(-0.5).lfloor(), -1); 68 EXPECT_EQ(Type(-0.5).lceil(), 0); 69 EXPECT_EQ(Type(-0.5).ltrunk(), 0); 70 71 EXPECT_EQ(Type(-1.5).lround(), -2); 72 EXPECT_EQ(Type(-1.5).lfloor(), -2); 73 EXPECT_EQ(Type(-1.5).lceil(), -1); 74 EXPECT_EQ(Type(-1.5).ltrunk(), -1); 75 76 // Check that sRGB TRC curve parameters match the s15fixed16 values stored in Gimp's built-in profile. 77 // (This only requires that the FixedPoint<> constructor rounds before truncating to the fixed-point value, 78 // as it should anyways.) 79 using S15Fixed16 = FixedPoint<16, i32>; 80 EXPECT_EQ(S15Fixed16(2.4).raw(), 0x26666); 81 EXPECT_EQ(S15Fixed16(1 / 1.055).raw(), 0xf2a7); 82 EXPECT_EQ(S15Fixed16(0.055 / 1.055).raw(), 0xd59); 83 EXPECT_EQ(S15Fixed16(1 / 12.92).raw(), 0x13d0); 84 EXPECT_EQ(S15Fixed16(0.04045).raw(), 0xa5b); 85} 86 87TEST_CASE(logarithm) 88{ 89 EXPECT_EQ(Type(0).log2().raw(), NumericLimits<int>::min()); 90 EXPECT_EQ(Type(1).log2(), Type(0)); 91 EXPECT_EQ(Type(2).log2(), Type(1)); 92 EXPECT_EQ(Type(8).log2(), Type(3)); 93 EXPECT_EQ(Type(0.5).log2(), Type(-1)); 94 95 EXPECT_EQ(Type(22.627416997969520780827019587355).log2(), Type(4.4375)); 96 EXPECT_EQ(Type(3088).log2(), Type(11.592457037268080419637304576833)); 97} 98 99TEST_CASE(comparison) 100{ 101 EXPECT(Type(0) < 1); 102 EXPECT(Type(0) <= 1); 103 EXPECT(Type(0) <= 0); 104 EXPECT(Type(-10) <= -10); 105 106 EXPECT(Type(4.25) > 4); 107 EXPECT(Type(4.25) >= 4); 108 EXPECT(Type(4.25) <= 5); 109 EXPECT(Type(4.25) < 5); 110 EXPECT(Type(1.5) > 1); 111 112 EXPECT(!(FixedPoint<4, u8>(2) > 128)); 113 EXPECT(!(FixedPoint<4, u8>(2) >= 128)); 114 115 EXPECT(Type(-6.25) < -6); 116 EXPECT(Type(-6.25) <= -6); 117 EXPECT(Type(-6.75) > -7); 118 EXPECT(Type(-6.75) >= -7); 119 120 EXPECT(Type(17) == 17); 121 EXPECT(Type(-8) != -9); 122} 123 124TEST_CASE(cast) 125{ 126 FixedPoint<16, u32> downcast_value1(FixedPoint<32, u64>(123.4567)); 127 EXPECT((double)downcast_value1 >= 123.4566 && (double)downcast_value1 <= 123.4568); 128 static FixedPoint<32, u64> const value1(321.7654); 129 downcast_value1 = value1; 130 EXPECT((double)downcast_value1 >= 321.7653 && (double)downcast_value1 <= 321.7655); 131 FixedPoint<6, u32> downcast_value2(FixedPoint<32, u64>(4567.123456)); 132 EXPECT((double)downcast_value2 >= 4567.1 && (double)downcast_value2 <= 4567.2); 133 downcast_value2 = FixedPoint<32, u64>(7654.654321); 134 EXPECT((double)downcast_value2 >= 7654.64 && (double)downcast_value2 <= 7654.66); 135 136 EXPECT((double)downcast_value2 >= 7654.64 && (double)downcast_value2 <= 7654.66); 137 FixedPoint<6, u32> downcast_value3(FixedPoint<32, u64>(4567.987654)); 138 EXPECT((double)downcast_value3 >= 4567.9 && (double)downcast_value3 <= 4567.99); 139 downcast_value3 = FixedPoint<32, u64>(7654.456789); 140 EXPECT((double)downcast_value3 >= 7654.45 && (double)downcast_value3 <= 7654.46); 141 142 FixedPoint<32, u64> upcast_value1(FixedPoint<16, u32>(123.4567)); 143 EXPECT((double)upcast_value1 >= 123.4566 && (double)upcast_value1 <= 123.4568); 144 upcast_value1 = FixedPoint<16, u32>(321.7654); 145 EXPECT((double)upcast_value1 >= 321.7653 && (double)upcast_value1 <= 321.7655); 146 FixedPoint<32, u64> upcast_value2(FixedPoint<6, u32>(4567.123456)); 147 EXPECT((double)upcast_value2 >= 4567.1 && (double)upcast_value2 <= 4567.2); 148 upcast_value2 = FixedPoint<6, u32>(7654.654321); 149 EXPECT((double)upcast_value2 >= 7654.64 && (double)upcast_value2 <= 7654.66); 150 FixedPoint<32, u64> upcast_value3(FixedPoint<6, u32>(4567.987654)); 151 EXPECT((double)upcast_value3 >= 4567.9 && (double)upcast_value3 <= 4567.99); 152 upcast_value3 = FixedPoint<6, u32>(7654.456789); 153 EXPECT((double)upcast_value3 >= 7654.45 && (double)upcast_value3 <= 7654.46); 154} 155 156TEST_CASE(formatter) 157{ 158 EXPECT_EQ(DeprecatedString::formatted("{}", FixedPoint<16>(123.456)), "123.455993"sv); 159 EXPECT_EQ(DeprecatedString::formatted("{}", FixedPoint<16>(-123.456)), "-123.455994"sv); 160 EXPECT_EQ(DeprecatedString::formatted("{}", FixedPoint<4>(123.456)), "123.4375"sv); 161 EXPECT_EQ(DeprecatedString::formatted("{}", FixedPoint<4>(-123.456)), "-123.4375"sv); 162 EXPECT_EQ(DeprecatedString::formatted("{}", FixedPoint<16> {}), "0"sv); 163 EXPECT_EQ(DeprecatedString::formatted("{}", FixedPoint<16>(0.1)), "0.100006"sv); 164 EXPECT_EQ(DeprecatedString::formatted("{}", FixedPoint<16>(0.02)), "0.020004"sv); 165 EXPECT_EQ(DeprecatedString::formatted("{}", FixedPoint<16>(0.003)), "0.003005"sv); 166 EXPECT_EQ(DeprecatedString::formatted("{}", FixedPoint<16>(0.0004)), "0.000396"sv); 167 EXPECT_EQ(DeprecatedString::formatted("{}", FixedPoint<16>(0.0000000005)), "0"sv); 168 EXPECT_EQ(DeprecatedString::formatted("{}", FixedPoint<16>(-0.1)), "-0.100007"sv); 169 EXPECT_EQ(DeprecatedString::formatted("{}", FixedPoint<16>(-0.02)), "-0.020005"sv); 170 EXPECT_EQ(DeprecatedString::formatted("{}", FixedPoint<16>(-0.0000000005)), "0"sv); 171}