xref: /aosp_15_r20/external/skia/modules/bentleyottmann/tests/Int96Test.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 // Copyright 2023 Google LLC
2 // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
3 
4 #include "modules/bentleyottmann/include/Int96.h"
5 #include "tests/Test.h"
6 
7 #include <cstdint>
8 #include <limits>
9 
10 using namespace bentleyottmann;
11 
DEF_TEST(BO_Int96Basic,reporter)12 DEF_TEST(BO_Int96Basic, reporter) {
13     {
14         int32_t t = 0;
15         Int96 z = Int96::Make(t);
16         REPORTER_ASSERT(reporter, z.hi == 0 && z.lo == 0);
17     }
18     {
19         int64_t t = 0;
20         Int96 z = Int96::Make(t);
21         REPORTER_ASSERT(reporter, z.hi == 0 && z.lo == 0);
22     }
23     {
24         int32_t t = -1;
25         Int96 z = Int96::Make(t);
26         REPORTER_ASSERT(reporter, z.hi == -1 && z.lo == 0xFFFFFFFF);
27     }
28     {
29         int64_t t = -1;
30         Int96 z = Int96::Make(t);
31         REPORTER_ASSERT(reporter, z.hi == -1 && z.lo == 0xFFFFFFFF);
32     }
33     {
34         int32_t t = 3;
35         Int96 z = Int96::Make(t);
36         REPORTER_ASSERT(reporter, z.hi == 0 && z.lo == 3);
37     }
38     {
39         int64_t t = 3;
40         Int96 z = Int96::Make(t);
41         REPORTER_ASSERT(reporter, z.hi == 0 && z.lo == 3);
42     }
43     {
44         int32_t t = -3;
45         Int96 z = Int96::Make(t);
46         REPORTER_ASSERT(reporter, z.hi == -1 && z.lo == (uint32_t)-3);
47     }
48     {
49         int64_t t = -3;
50         Int96 z = Int96::Make(t);
51         REPORTER_ASSERT(reporter, z.hi == -1 && z.lo == (uint32_t)-3);
52     }
53 
54     {
55         int64_t t = 1ll << 32;
56         Int96 z = Int96::Make(t);
57         REPORTER_ASSERT(reporter, z.hi == 1 && z.lo == 0);
58     }
59     {
60         // -2 << 32 -- without the warnings.
61         int64_t t = -(2ll << 32);
62         Int96 z = Int96::Make(t);
63         REPORTER_ASSERT(reporter, z.hi == -2 && z.lo == 0);
64     }
65 }
66 
67 [[maybe_unused]]
68 static int64_t interesting64[] = {-std::numeric_limits<int64_t>::max(),
69                                   -std::numeric_limits<int64_t>::max() + 1,
70                                   (int64_t) -std::numeric_limits<int32_t>::max() - 1,
71                                   (int64_t) -std::numeric_limits<int32_t>::max(),
72                                   (int64_t) -std::numeric_limits<int32_t>::max() + 1,
73                                   -2,
74                                   -1,
75                                   0,
76                                   1,
77                                   2,
78                                   (int64_t) std::numeric_limits<int32_t>::max() - 1,
79                                   (int64_t) std::numeric_limits<int32_t>::max(),
80                                   (int64_t) std::numeric_limits<int32_t>::max() + 1,
81                                   std::numeric_limits<int64_t>::max() - 1,
82                                   std::numeric_limits<int64_t>::max()};
83 
DEF_TEST(BO_Int96Less,reporter)84 DEF_TEST(BO_Int96Less, reporter) {
85 #if (defined(__clang__) || defined(__GNUC__)) && defined(__SIZEOF_INT128__)
86     for (auto a : interesting64) {
87         for (auto b : interesting64) {
88             __int128 a128 = a,
89                     b128 = b;
90             bool l128 = a128 < b128,
91                  g128 = b128 < a128;
92 
93             Int96 a96 = Int96::Make(a),
94                   b96 = Int96::Make(b);
95             bool l96 = a96 < b96,
96                  g96 = b96 < a96;
97 
98             REPORTER_ASSERT(reporter, l128 == l96);
99             REPORTER_ASSERT(reporter, g128 == g96);
100 
101         }
102     }
103 #endif
104 }
105 
DEF_TEST(BO_Int96Add,reporter)106 DEF_TEST(BO_Int96Add, reporter) {
107 #if (defined(__clang__) || defined(__GNUC__)) && defined(__SIZEOF_INT128__)
108     for (auto a : interesting64) {
109         for (auto b : interesting64) {
110             __int128 a128 = a,
111                      b128 = b,
112                      r128 = a128 + b128;
113 
114             Int96 a96 = Int96::Make(a),
115                   b96 = Int96::Make(b),
116                   r96 = a96 + b96;
117 
118             // Explicitly check the low bits.
119             REPORTER_ASSERT(reporter, r96.lo == (r128 & 0xFFFFFFFF));
120 
121             // Build a __int128 from an Int96.
122             __int128 hi128 = r96.hi,
123                      lo128 = r96.lo,
124                      all128 = hi128 * 0x1'0000'0000 + lo128;
125             REPORTER_ASSERT(reporter, r128 == all128);
126         }
127     }
128 #endif
129 }
130 
DEF_TEST(BO_Int96Mult,reporter)131 DEF_TEST(BO_Int96Mult, reporter) {
132 #if (defined(__clang__) || defined(__GNUC__)) && defined(__SIZEOF_INT128__)
133     int32_t interesting32[] = {-std::numeric_limits<int32_t>::max(),
134                                -std::numeric_limits<int32_t>::max() + 1,
135                                -2,
136                                -1,
137                                0,
138                                1,
139                                2,
140                                std::numeric_limits<int32_t>::max() - 1,
141                                std::numeric_limits<int32_t>::max()};
142 
143     for (auto i64 : interesting64) {
144         for (auto i32 : interesting32) {
145             __int128 a128 = i64,
146                      b128 = i32,
147                      r128 = a128 * b128;
148 
149             Int96 r96 = multiply(i64, i32);
150 
151             // Explicitly check the low bits.
152             REPORTER_ASSERT(reporter, r96.lo == (r128 & 0xFFFFFFFF));
153 
154             // Build a __int128 from an Int96.
155             __int128 hi128 = r96.hi,
156                      lo128 = r96.lo,
157                      all128 = hi128 * 0x1'0000'0000 + lo128;
158             REPORTER_ASSERT(reporter, r128 == all128);
159         }
160     }
161 #endif
162 }
163