xref: /aosp_15_r20/external/skia/tests/FloatingPointTest.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2023 Google LLC
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "include/private/base/SkAssert.h"
9 #include "include/private/base/SkFloatingPoint.h"
10 #include "src/base/SkUtils.h"
11 #include "tests/Test.h"
12 
13 #include <array>
14 #include <cfloat>
15 #include <cmath>
16 #include <cstdint>
17 #include <cstring>
18 #include <limits>
19 
DEF_TEST(DoubleNearlyZero,reporter)20 DEF_TEST(DoubleNearlyZero, reporter) {
21     REPORTER_ASSERT(reporter, sk_double_nearly_zero(0.));
22     REPORTER_ASSERT(reporter, sk_double_nearly_zero(-0.));
23     REPORTER_ASSERT(reporter, sk_double_nearly_zero(DBL_EPSILON));
24     REPORTER_ASSERT(reporter, sk_double_nearly_zero(-DBL_EPSILON));
25 
26     double nearly = 1. / 20000000000LL;
27     REPORTER_ASSERT(reporter, nearly != 0);
28     REPORTER_ASSERT(reporter, sk_double_nearly_zero(nearly));
29     REPORTER_ASSERT(reporter, sk_double_nearly_zero(-nearly));
30 
31     REPORTER_ASSERT(reporter, !sk_double_nearly_zero(FLT_EPSILON));
32     REPORTER_ASSERT(reporter, !sk_double_nearly_zero(-FLT_EPSILON));
33     REPORTER_ASSERT(reporter, !sk_double_nearly_zero(1));
34     REPORTER_ASSERT(reporter, !sk_double_nearly_zero(-1));
35     REPORTER_ASSERT(reporter, !sk_double_nearly_zero(INFINITY));
36     REPORTER_ASSERT(reporter, !sk_double_nearly_zero(HUGE_VALF));
37     REPORTER_ASSERT(reporter, !sk_double_nearly_zero(HUGE_VAL));
38     REPORTER_ASSERT(reporter, !sk_double_nearly_zero(HUGE_VALL));
39     REPORTER_ASSERT(reporter, !sk_double_nearly_zero(-INFINITY));
40     REPORTER_ASSERT(reporter, !sk_double_nearly_zero(-HUGE_VALF));
41     REPORTER_ASSERT(reporter, !sk_double_nearly_zero(-HUGE_VAL));
42     REPORTER_ASSERT(reporter, !sk_double_nearly_zero(-HUGE_VALL));
43     REPORTER_ASSERT(reporter, !sk_double_nearly_zero(NAN));
44     REPORTER_ASSERT(reporter, !sk_double_nearly_zero(-NAN));
45 }
46 
DEF_TEST(DoubleNearlyEqualUlps,reporter)47 DEF_TEST(DoubleNearlyEqualUlps, reporter) {
48     // Our tolerance is looser than DBL_EPSILON
49     REPORTER_ASSERT(reporter, sk_doubles_nearly_equal_ulps(1., 1.));
50     REPORTER_ASSERT(reporter, sk_doubles_nearly_equal_ulps(1., 1. - DBL_EPSILON));
51     REPORTER_ASSERT(reporter, sk_doubles_nearly_equal_ulps(1., 1. + DBL_EPSILON));
52     REPORTER_ASSERT(reporter, sk_doubles_nearly_equal_ulps(100.5, 100.5));
53     REPORTER_ASSERT(reporter, sk_doubles_nearly_equal_ulps(100.5, 100.5 - DBL_EPSILON));
54     REPORTER_ASSERT(reporter, sk_doubles_nearly_equal_ulps(100.5, 100.5 + DBL_EPSILON));
55 
56     // Our tolerance is tighter than FLT_EPSILON
57     REPORTER_ASSERT(reporter, !sk_doubles_nearly_equal_ulps(1., 1. - FLT_EPSILON));
58     REPORTER_ASSERT(reporter, !sk_doubles_nearly_equal_ulps(1., 1. + FLT_EPSILON));
59     REPORTER_ASSERT(reporter, !sk_doubles_nearly_equal_ulps(100.5, 100.5 - FLT_EPSILON));
60     REPORTER_ASSERT(reporter, !sk_doubles_nearly_equal_ulps(100.5, 100.5 + FLT_EPSILON));
61     REPORTER_ASSERT(reporter, !sk_doubles_nearly_equal_ulps(0, 0.1));
62     REPORTER_ASSERT(reporter, !sk_doubles_nearly_equal_ulps(FLT_EPSILON, 0));
63 
64     REPORTER_ASSERT(reporter, sk_doubles_nearly_equal_ulps(INFINITY, INFINITY));
65     REPORTER_ASSERT(reporter, !sk_doubles_nearly_equal_ulps(INFINITY, 10));
66     REPORTER_ASSERT(reporter, !sk_doubles_nearly_equal_ulps(10, INFINITY));
67     REPORTER_ASSERT(reporter, !sk_doubles_nearly_equal_ulps(NAN, INFINITY));
68 
69     REPORTER_ASSERT(reporter, !sk_doubles_nearly_equal_ulps(INFINITY, -INFINITY));
70     REPORTER_ASSERT(reporter, !sk_doubles_nearly_equal_ulps(-INFINITY, INFINITY));
71     REPORTER_ASSERT(reporter, sk_doubles_nearly_equal_ulps(-INFINITY, -INFINITY));
72 
73     // Test values upto the edge of infinity.
74     const double biggest = std::numeric_limits<double>::max();
75     auto almostBiggest = [&](int n) {
76         double almostBiggest = biggest;
77         for (int i = 0; i < n; ++i) {
78             almostBiggest = std::nextafter(almostBiggest, -INFINITY);
79         }
80         return almostBiggest;
81     };
82     const double nextBiggest = almostBiggest(1);
83     REPORTER_ASSERT(reporter, sk_doubles_nearly_equal_ulps(biggest, nextBiggest));
84     REPORTER_ASSERT(reporter, sk_doubles_nearly_equal_ulps(biggest, almostBiggest(16)));
85     REPORTER_ASSERT(reporter, !sk_doubles_nearly_equal_ulps(biggest, almostBiggest(17)));
86 
87     // One ulp less would be infinity.
88     const uint64_t smallestNANPattern =
89             0b0'11111111111'0000000000000000000000000000000000000000000000000001;
90     double smallestNAN;
91     memcpy(&smallestNAN, &smallestNANPattern, sizeof(double));
92     SkASSERT(std::isnan(smallestNAN));
93     SkASSERT(biggest != nextBiggest);
94 
95     // Sanity check.
96     REPORTER_ASSERT(reporter, !sk_doubles_nearly_equal_ulps(smallestNAN, NAN));
97 
98     // Make sure to return false along the edge of infinity.
99     REPORTER_ASSERT(reporter, !sk_doubles_nearly_equal_ulps(INFINITY, biggest));
100     REPORTER_ASSERT(reporter, !sk_doubles_nearly_equal_ulps(smallestNAN, biggest));
101     REPORTER_ASSERT(reporter, !sk_doubles_nearly_equal_ulps(smallestNAN, INFINITY));
102 
103     const double smallest = std::numeric_limits<double>::denorm_min();
104     REPORTER_ASSERT(reporter, !sk_doubles_nearly_equal_ulps(NAN, NAN));
105     REPORTER_ASSERT(reporter, sk_doubles_nearly_equal_ulps(smallest, 0));
106     REPORTER_ASSERT(reporter, sk_doubles_nearly_equal_ulps(smallest, -smallest));
107     REPORTER_ASSERT(reporter, sk_doubles_nearly_equal_ulps(8*smallest, -8*smallest));
108     REPORTER_ASSERT(reporter, !sk_doubles_nearly_equal_ulps(8*smallest, -9*smallest));
109 }
110 
DEF_TEST(BitCastDoubleRoundTrip,reporter)111 DEF_TEST(BitCastDoubleRoundTrip, reporter) {
112     std::array<double, 5>  testCases = {0.0, 1.0, -13.0, 1.234567890123456, -543210.987654321};
113 
114     for (size_t i = 0; i < testCases.size(); i++) {
115         double input = testCases[i];
116         uint64_t bits = sk_bit_cast<uint64_t>(input);
117         double output = sk_bit_cast<double>(bits);
118         REPORTER_ASSERT(reporter, input == output, "%.16f is not exactly %.16f", input, output);
119     }
120 
121     {
122         uint64_t bits = sk_bit_cast<uint64_t>((double) NAN);
123         double output = sk_bit_cast<double>(bits);
124         REPORTER_ASSERT(reporter, std::isnan(output), "%.16f is not nan", output);
125     }
126     {
127         uint64_t bits = sk_bit_cast<uint64_t>((double) INFINITY);
128         double output = sk_bit_cast<double>(bits);
129         REPORTER_ASSERT(reporter, !SkIsFinite(output), "%.16f is not infinity", output);
130     }
131 }
132 
DEF_TEST(FMA,reporter)133 DEF_TEST(FMA, reporter) {
134     // 0b0'01111111111'00'0000000000'0000000000'0000000010'0000000000'0000000000
135     double over1 = 1+4.656612873e-10;
136 
137     // 0b0'01111111110'11'1111111111'1111111111'1111111100'0000000000'0000000000
138     double under1 = 1-4.656612873e-10;
139 
140     // Precision loss
141     //                         -------------- becomes 1; extra bits are rounded off.
142     double x = std::fma(1, -1, over1 * under1);
143 
144     // Precision maintained
145     //                  ------------- becomes 1 - 2^-62; extra bits are maintained
146     double y = std::fma(over1, under1, -1);
147 
148     REPORTER_ASSERT(reporter, x == 0);
149     REPORTER_ASSERT(reporter, y == -exp2(-62));
150 }
151 
DEF_TEST(Midpoint,reporter)152 DEF_TEST(Midpoint, reporter) {
153     const float smallest = std::numeric_limits<float>::denorm_min();
154     REPORTER_ASSERT(reporter, sk_float_midpoint(smallest, smallest) == smallest);
155     REPORTER_ASSERT(reporter, sk_float_midpoint(smallest, -smallest) == 0);
156 
157     const float biggest = std::numeric_limits<float>::max();
158     REPORTER_ASSERT(reporter, sk_float_midpoint(biggest, biggest) == biggest);
159     REPORTER_ASSERT(reporter, sk_float_midpoint(biggest, -biggest) == 0);
160 
161 }
162