xref: /aosp_15_r20/external/openscreen/util/saturate_cast_unittest.cc (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
1*3f982cf4SFabien Sanglard // Copyright 2019 The Chromium Authors. All rights reserved.
2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be
3*3f982cf4SFabien Sanglard // found in the LICENSE file.
4*3f982cf4SFabien Sanglard 
5*3f982cf4SFabien Sanglard #include "util/saturate_cast.h"
6*3f982cf4SFabien Sanglard 
7*3f982cf4SFabien Sanglard #include "gtest/gtest.h"
8*3f982cf4SFabien Sanglard 
9*3f982cf4SFabien Sanglard namespace openscreen {
10*3f982cf4SFabien Sanglard namespace {
11*3f982cf4SFabien Sanglard 
TEST(SaturateCastTest,LargerToSmallerSignedInteger)12*3f982cf4SFabien Sanglard TEST(SaturateCastTest, LargerToSmallerSignedInteger) {
13*3f982cf4SFabien Sanglard   struct ValuePair {
14*3f982cf4SFabien Sanglard     int64_t from;
15*3f982cf4SFabien Sanglard     int32_t to;
16*3f982cf4SFabien Sanglard   };
17*3f982cf4SFabien Sanglard   constexpr ValuePair kValuePairs[] = {
18*3f982cf4SFabien Sanglard       {std::numeric_limits<int64_t>::max(),
19*3f982cf4SFabien Sanglard        std::numeric_limits<int32_t>::max()},
20*3f982cf4SFabien Sanglard       {std::numeric_limits<int64_t>::max() / 2 + 42,
21*3f982cf4SFabien Sanglard        std::numeric_limits<int32_t>::max()},
22*3f982cf4SFabien Sanglard       {std::numeric_limits<int32_t>::max(),
23*3f982cf4SFabien Sanglard        std::numeric_limits<int32_t>::max()},
24*3f982cf4SFabien Sanglard       {42, 42},
25*3f982cf4SFabien Sanglard       {0, 0},
26*3f982cf4SFabien Sanglard       {-42, -42},
27*3f982cf4SFabien Sanglard       {std::numeric_limits<int32_t>::min(),
28*3f982cf4SFabien Sanglard        std::numeric_limits<int32_t>::min()},
29*3f982cf4SFabien Sanglard       {std::numeric_limits<int64_t>::min() / 2 - 42,
30*3f982cf4SFabien Sanglard        std::numeric_limits<int32_t>::min()},
31*3f982cf4SFabien Sanglard       {std::numeric_limits<int64_t>::min(),
32*3f982cf4SFabien Sanglard        std::numeric_limits<int32_t>::min()},
33*3f982cf4SFabien Sanglard   };
34*3f982cf4SFabien Sanglard   for (const ValuePair& value_pair : kValuePairs) {
35*3f982cf4SFabien Sanglard     EXPECT_EQ(value_pair.to, saturate_cast<int32_t>(value_pair.from));
36*3f982cf4SFabien Sanglard   }
37*3f982cf4SFabien Sanglard }
38*3f982cf4SFabien Sanglard 
TEST(SaturateCastTest,LargerToSmallerUnsignedInteger)39*3f982cf4SFabien Sanglard TEST(SaturateCastTest, LargerToSmallerUnsignedInteger) {
40*3f982cf4SFabien Sanglard   struct ValuePair {
41*3f982cf4SFabien Sanglard     uint64_t from;
42*3f982cf4SFabien Sanglard     uint32_t to;
43*3f982cf4SFabien Sanglard   };
44*3f982cf4SFabien Sanglard   constexpr ValuePair kValuePairs[] = {
45*3f982cf4SFabien Sanglard       {std::numeric_limits<uint64_t>::max(),
46*3f982cf4SFabien Sanglard        std::numeric_limits<uint32_t>::max()},
47*3f982cf4SFabien Sanglard       {std::numeric_limits<uint64_t>::max() / 2 + 42,
48*3f982cf4SFabien Sanglard        std::numeric_limits<uint32_t>::max()},
49*3f982cf4SFabien Sanglard       {std::numeric_limits<uint32_t>::max(),
50*3f982cf4SFabien Sanglard        std::numeric_limits<uint32_t>::max()},
51*3f982cf4SFabien Sanglard       {42, 42},
52*3f982cf4SFabien Sanglard       {0, 0},
53*3f982cf4SFabien Sanglard   };
54*3f982cf4SFabien Sanglard   for (const ValuePair& value_pair : kValuePairs) {
55*3f982cf4SFabien Sanglard     EXPECT_EQ(value_pair.to, saturate_cast<uint32_t>(value_pair.from));
56*3f982cf4SFabien Sanglard   }
57*3f982cf4SFabien Sanglard }
58*3f982cf4SFabien Sanglard 
TEST(SaturateCastTest,LargerSignedToSmallerUnsignedInteger)59*3f982cf4SFabien Sanglard TEST(SaturateCastTest, LargerSignedToSmallerUnsignedInteger) {
60*3f982cf4SFabien Sanglard   struct ValuePair {
61*3f982cf4SFabien Sanglard     int64_t from;
62*3f982cf4SFabien Sanglard     uint32_t to;
63*3f982cf4SFabien Sanglard   };
64*3f982cf4SFabien Sanglard   constexpr ValuePair kValuePairs[] = {
65*3f982cf4SFabien Sanglard       {std::numeric_limits<int64_t>::max(),
66*3f982cf4SFabien Sanglard        std::numeric_limits<uint32_t>::max()},
67*3f982cf4SFabien Sanglard       {std::numeric_limits<int64_t>::max() / 2 + 42,
68*3f982cf4SFabien Sanglard        std::numeric_limits<uint32_t>::max()},
69*3f982cf4SFabien Sanglard       {std::numeric_limits<uint32_t>::max(),
70*3f982cf4SFabien Sanglard        std::numeric_limits<uint32_t>::max()},
71*3f982cf4SFabien Sanglard       {42, 42},
72*3f982cf4SFabien Sanglard       {0, 0},
73*3f982cf4SFabien Sanglard       {-42, 0},
74*3f982cf4SFabien Sanglard       {std::numeric_limits<int64_t>::min() / 2 - 42, 0},
75*3f982cf4SFabien Sanglard       {std::numeric_limits<int64_t>::min(), 0},
76*3f982cf4SFabien Sanglard   };
77*3f982cf4SFabien Sanglard   for (const ValuePair& value_pair : kValuePairs) {
78*3f982cf4SFabien Sanglard     EXPECT_EQ(value_pair.to, saturate_cast<uint32_t>(value_pair.from));
79*3f982cf4SFabien Sanglard   }
80*3f982cf4SFabien Sanglard }
81*3f982cf4SFabien Sanglard 
TEST(SaturateCastTest,LargerUnsignedToSmallerSignedInteger)82*3f982cf4SFabien Sanglard TEST(SaturateCastTest, LargerUnsignedToSmallerSignedInteger) {
83*3f982cf4SFabien Sanglard   struct ValuePair {
84*3f982cf4SFabien Sanglard     uint64_t from;
85*3f982cf4SFabien Sanglard     int32_t to;
86*3f982cf4SFabien Sanglard   };
87*3f982cf4SFabien Sanglard   constexpr ValuePair kValuePairs[] = {
88*3f982cf4SFabien Sanglard       {std::numeric_limits<uint64_t>::max(),
89*3f982cf4SFabien Sanglard        std::numeric_limits<int32_t>::max()},
90*3f982cf4SFabien Sanglard       {std::numeric_limits<uint64_t>::max() / 2 + 42,
91*3f982cf4SFabien Sanglard        std::numeric_limits<int32_t>::max()},
92*3f982cf4SFabien Sanglard       {std::numeric_limits<int32_t>::max(),
93*3f982cf4SFabien Sanglard        std::numeric_limits<int32_t>::max()},
94*3f982cf4SFabien Sanglard       {42, 42},
95*3f982cf4SFabien Sanglard       {0, 0},
96*3f982cf4SFabien Sanglard   };
97*3f982cf4SFabien Sanglard   for (const ValuePair& value_pair : kValuePairs) {
98*3f982cf4SFabien Sanglard     EXPECT_EQ(value_pair.to, saturate_cast<int32_t>(value_pair.from));
99*3f982cf4SFabien Sanglard   }
100*3f982cf4SFabien Sanglard }
101*3f982cf4SFabien Sanglard 
TEST(SaturateCastTest,SignedToUnsigned32BitInteger)102*3f982cf4SFabien Sanglard TEST(SaturateCastTest, SignedToUnsigned32BitInteger) {
103*3f982cf4SFabien Sanglard   struct ValuePair {
104*3f982cf4SFabien Sanglard     int32_t from;
105*3f982cf4SFabien Sanglard     uint32_t to;
106*3f982cf4SFabien Sanglard   };
107*3f982cf4SFabien Sanglard   constexpr ValuePair kValuePairs[] = {
108*3f982cf4SFabien Sanglard       {std::numeric_limits<int32_t>::max(),
109*3f982cf4SFabien Sanglard        std::numeric_limits<int32_t>::max()},
110*3f982cf4SFabien Sanglard       {42, 42},
111*3f982cf4SFabien Sanglard       {0, 0},
112*3f982cf4SFabien Sanglard       {-42, 0},
113*3f982cf4SFabien Sanglard       {std::numeric_limits<int32_t>::min(), 0},
114*3f982cf4SFabien Sanglard   };
115*3f982cf4SFabien Sanglard   for (const ValuePair& value_pair : kValuePairs) {
116*3f982cf4SFabien Sanglard     EXPECT_EQ(value_pair.to, saturate_cast<uint32_t>(value_pair.from));
117*3f982cf4SFabien Sanglard   }
118*3f982cf4SFabien Sanglard }
119*3f982cf4SFabien Sanglard 
TEST(SaturateCastTest,UnsignedToSigned32BitInteger)120*3f982cf4SFabien Sanglard TEST(SaturateCastTest, UnsignedToSigned32BitInteger) {
121*3f982cf4SFabien Sanglard   struct ValuePair {
122*3f982cf4SFabien Sanglard     uint32_t from;
123*3f982cf4SFabien Sanglard     int32_t to;
124*3f982cf4SFabien Sanglard   };
125*3f982cf4SFabien Sanglard   constexpr ValuePair kValuePairs[] = {
126*3f982cf4SFabien Sanglard       {std::numeric_limits<uint32_t>::max(),
127*3f982cf4SFabien Sanglard        std::numeric_limits<int32_t>::max()},
128*3f982cf4SFabien Sanglard       {std::numeric_limits<uint32_t>::max() / 2 + 42,
129*3f982cf4SFabien Sanglard        std::numeric_limits<int32_t>::max()},
130*3f982cf4SFabien Sanglard       {std::numeric_limits<int32_t>::max(),
131*3f982cf4SFabien Sanglard        std::numeric_limits<int32_t>::max()},
132*3f982cf4SFabien Sanglard       {42, 42},
133*3f982cf4SFabien Sanglard       {0, 0},
134*3f982cf4SFabien Sanglard   };
135*3f982cf4SFabien Sanglard   for (const ValuePair& value_pair : kValuePairs) {
136*3f982cf4SFabien Sanglard     EXPECT_EQ(value_pair.to, saturate_cast<int32_t>(value_pair.from));
137*3f982cf4SFabien Sanglard   }
138*3f982cf4SFabien Sanglard }
139*3f982cf4SFabien Sanglard 
TEST(SaturateCastTest,SignedToUnsigned64BitInteger)140*3f982cf4SFabien Sanglard TEST(SaturateCastTest, SignedToUnsigned64BitInteger) {
141*3f982cf4SFabien Sanglard   struct ValuePair {
142*3f982cf4SFabien Sanglard     int64_t from;
143*3f982cf4SFabien Sanglard     uint64_t to;
144*3f982cf4SFabien Sanglard   };
145*3f982cf4SFabien Sanglard   constexpr ValuePair kValuePairs[] = {
146*3f982cf4SFabien Sanglard       {std::numeric_limits<int64_t>::max(),
147*3f982cf4SFabien Sanglard        std::numeric_limits<int64_t>::max()},
148*3f982cf4SFabien Sanglard       {42, 42},
149*3f982cf4SFabien Sanglard       {0, 0},
150*3f982cf4SFabien Sanglard       {-42, 0},
151*3f982cf4SFabien Sanglard       {std::numeric_limits<int64_t>::min(), 0},
152*3f982cf4SFabien Sanglard   };
153*3f982cf4SFabien Sanglard   for (const ValuePair& value_pair : kValuePairs) {
154*3f982cf4SFabien Sanglard     EXPECT_EQ(value_pair.to, saturate_cast<uint64_t>(value_pair.from));
155*3f982cf4SFabien Sanglard   }
156*3f982cf4SFabien Sanglard }
157*3f982cf4SFabien Sanglard 
TEST(SaturateCastTest,UnsignedToSigned64BitInteger)158*3f982cf4SFabien Sanglard TEST(SaturateCastTest, UnsignedToSigned64BitInteger) {
159*3f982cf4SFabien Sanglard   struct ValuePair {
160*3f982cf4SFabien Sanglard     uint64_t from;
161*3f982cf4SFabien Sanglard     int64_t to;
162*3f982cf4SFabien Sanglard   };
163*3f982cf4SFabien Sanglard   constexpr ValuePair kValuePairs[] = {
164*3f982cf4SFabien Sanglard       {std::numeric_limits<uint64_t>::max(),
165*3f982cf4SFabien Sanglard        std::numeric_limits<int64_t>::max()},
166*3f982cf4SFabien Sanglard       {std::numeric_limits<uint64_t>::max() / 2 + 42,
167*3f982cf4SFabien Sanglard        std::numeric_limits<int64_t>::max()},
168*3f982cf4SFabien Sanglard       {std::numeric_limits<int64_t>::max(),
169*3f982cf4SFabien Sanglard        std::numeric_limits<int64_t>::max()},
170*3f982cf4SFabien Sanglard       {42, 42},
171*3f982cf4SFabien Sanglard       {0, 0},
172*3f982cf4SFabien Sanglard   };
173*3f982cf4SFabien Sanglard   for (const ValuePair& value_pair : kValuePairs) {
174*3f982cf4SFabien Sanglard     EXPECT_EQ(value_pair.to, saturate_cast<int64_t>(value_pair.from));
175*3f982cf4SFabien Sanglard   }
176*3f982cf4SFabien Sanglard }
177*3f982cf4SFabien Sanglard 
TEST(SaturateCastTest,Float32ToSigned32)178*3f982cf4SFabien Sanglard TEST(SaturateCastTest, Float32ToSigned32) {
179*3f982cf4SFabien Sanglard   struct ValuePair {
180*3f982cf4SFabien Sanglard     float from;
181*3f982cf4SFabien Sanglard     int32_t to;
182*3f982cf4SFabien Sanglard   };
183*3f982cf4SFabien Sanglard   constexpr float kFloatMax = std::numeric_limits<float>::max();
184*3f982cf4SFabien Sanglard   // Note: kIntMax is one larger because float cannot represent the exact value.
185*3f982cf4SFabien Sanglard   constexpr float kIntMax =
186*3f982cf4SFabien Sanglard       static_cast<float>(std::numeric_limits<int32_t>::max());
187*3f982cf4SFabien Sanglard   constexpr float kIntMin = std::numeric_limits<int32_t>::min();
188*3f982cf4SFabien Sanglard   const ValuePair kValuePairs[] = {
189*3f982cf4SFabien Sanglard       {kFloatMax, std::numeric_limits<int32_t>::max()},
190*3f982cf4SFabien Sanglard       {std::nextafter(kIntMax, kFloatMax), std::numeric_limits<int32_t>::max()},
191*3f982cf4SFabien Sanglard       {kIntMax, std::numeric_limits<int32_t>::max()},
192*3f982cf4SFabien Sanglard       {std::nextafter(kIntMax, 0.f), 2147483520},
193*3f982cf4SFabien Sanglard       {42, 42},
194*3f982cf4SFabien Sanglard       {0, 0},
195*3f982cf4SFabien Sanglard       {-42, -42},
196*3f982cf4SFabien Sanglard       {std::nextafter(kIntMin, 0.f), -2147483520},
197*3f982cf4SFabien Sanglard       {kIntMin, std::numeric_limits<int32_t>::min()},
198*3f982cf4SFabien Sanglard       {std::nextafter(kIntMin, -kFloatMax),
199*3f982cf4SFabien Sanglard        std::numeric_limits<int32_t>::min()},
200*3f982cf4SFabien Sanglard       {-kFloatMax, std::numeric_limits<int32_t>::min()},
201*3f982cf4SFabien Sanglard   };
202*3f982cf4SFabien Sanglard   for (const ValuePair& value_pair : kValuePairs) {
203*3f982cf4SFabien Sanglard     EXPECT_EQ(value_pair.to, saturate_cast<int32_t>(value_pair.from));
204*3f982cf4SFabien Sanglard   }
205*3f982cf4SFabien Sanglard }
206*3f982cf4SFabien Sanglard 
TEST(SaturateCastTest,Float32ToSigned64)207*3f982cf4SFabien Sanglard TEST(SaturateCastTest, Float32ToSigned64) {
208*3f982cf4SFabien Sanglard   struct ValuePair {
209*3f982cf4SFabien Sanglard     float from;
210*3f982cf4SFabien Sanglard     int64_t to;
211*3f982cf4SFabien Sanglard   };
212*3f982cf4SFabien Sanglard   constexpr float kFloatMax = std::numeric_limits<float>::max();
213*3f982cf4SFabien Sanglard   // Note: kIntMax is one larger because float cannot represent the exact value.
214*3f982cf4SFabien Sanglard   constexpr float kIntMax =
215*3f982cf4SFabien Sanglard       static_cast<float>(std::numeric_limits<int64_t>::max());
216*3f982cf4SFabien Sanglard   constexpr float kIntMin = std::numeric_limits<int64_t>::min();
217*3f982cf4SFabien Sanglard   const ValuePair kValuePairs[] = {
218*3f982cf4SFabien Sanglard       {kFloatMax, std::numeric_limits<int64_t>::max()},
219*3f982cf4SFabien Sanglard       {std::nextafter(kIntMax, kFloatMax), std::numeric_limits<int64_t>::max()},
220*3f982cf4SFabien Sanglard       {kIntMax, std::numeric_limits<int64_t>::max()},
221*3f982cf4SFabien Sanglard       {std::nextafter(kIntMax, 0.f), INT64_C(9223371487098961920)},
222*3f982cf4SFabien Sanglard       {42, 42},
223*3f982cf4SFabien Sanglard       {0, 0},
224*3f982cf4SFabien Sanglard       {-42, -42},
225*3f982cf4SFabien Sanglard       {std::nextafter(kIntMin, 0.f), INT64_C(-9223371487098961920)},
226*3f982cf4SFabien Sanglard       {kIntMin, std::numeric_limits<int64_t>::min()},
227*3f982cf4SFabien Sanglard       {std::nextafter(kIntMin, -kFloatMax),
228*3f982cf4SFabien Sanglard        std::numeric_limits<int64_t>::min()},
229*3f982cf4SFabien Sanglard       {-kFloatMax, std::numeric_limits<int64_t>::min()},
230*3f982cf4SFabien Sanglard   };
231*3f982cf4SFabien Sanglard   for (const ValuePair& value_pair : kValuePairs) {
232*3f982cf4SFabien Sanglard     EXPECT_EQ(value_pair.to, saturate_cast<int64_t>(value_pair.from));
233*3f982cf4SFabien Sanglard   }
234*3f982cf4SFabien Sanglard }
235*3f982cf4SFabien Sanglard 
TEST(SaturateCastTest,Float64ToSigned32)236*3f982cf4SFabien Sanglard TEST(SaturateCastTest, Float64ToSigned32) {
237*3f982cf4SFabien Sanglard   struct ValuePair {
238*3f982cf4SFabien Sanglard     double from;
239*3f982cf4SFabien Sanglard     int32_t to;
240*3f982cf4SFabien Sanglard   };
241*3f982cf4SFabien Sanglard   constexpr double kDoubleMax = std::numeric_limits<double>::max();
242*3f982cf4SFabien Sanglard   constexpr double kIntMax = std::numeric_limits<int32_t>::max();
243*3f982cf4SFabien Sanglard   constexpr double kIntMin = std::numeric_limits<int32_t>::min();
244*3f982cf4SFabien Sanglard   const ValuePair kValuePairs[] = {
245*3f982cf4SFabien Sanglard       {kDoubleMax, std::numeric_limits<int32_t>::max()},
246*3f982cf4SFabien Sanglard       {std::nextafter(kIntMax, kDoubleMax),
247*3f982cf4SFabien Sanglard        std::numeric_limits<int32_t>::max()},
248*3f982cf4SFabien Sanglard       {kIntMax, std::numeric_limits<int32_t>::max()},
249*3f982cf4SFabien Sanglard       {std::nextafter(kIntMax, 0.0), std::numeric_limits<int32_t>::max() - 1},
250*3f982cf4SFabien Sanglard       {42, 42},
251*3f982cf4SFabien Sanglard       {0, 0},
252*3f982cf4SFabien Sanglard       {-42, -42},
253*3f982cf4SFabien Sanglard       {std::nextafter(kIntMin, 0.0), std::numeric_limits<int32_t>::min() + 1},
254*3f982cf4SFabien Sanglard       {kIntMin, std::numeric_limits<int32_t>::min()},
255*3f982cf4SFabien Sanglard       {std::nextafter(kIntMin, -kDoubleMax),
256*3f982cf4SFabien Sanglard        std::numeric_limits<int32_t>::min()},
257*3f982cf4SFabien Sanglard       {-kDoubleMax, std::numeric_limits<int32_t>::min()},
258*3f982cf4SFabien Sanglard   };
259*3f982cf4SFabien Sanglard   for (const ValuePair& value_pair : kValuePairs) {
260*3f982cf4SFabien Sanglard     EXPECT_EQ(value_pair.to, saturate_cast<int32_t>(value_pair.from));
261*3f982cf4SFabien Sanglard   }
262*3f982cf4SFabien Sanglard }
263*3f982cf4SFabien Sanglard 
TEST(SaturateCastTest,Float64ToSigned64)264*3f982cf4SFabien Sanglard TEST(SaturateCastTest, Float64ToSigned64) {
265*3f982cf4SFabien Sanglard   struct ValuePair {
266*3f982cf4SFabien Sanglard     double from;
267*3f982cf4SFabien Sanglard     int64_t to;
268*3f982cf4SFabien Sanglard   };
269*3f982cf4SFabien Sanglard   constexpr double kDoubleMax = std::numeric_limits<double>::max();
270*3f982cf4SFabien Sanglard   // Note: kIntMax is one larger because double cannot represent the exact
271*3f982cf4SFabien Sanglard   // value.
272*3f982cf4SFabien Sanglard   constexpr double kIntMax =
273*3f982cf4SFabien Sanglard       static_cast<double>(std::numeric_limits<int64_t>::max());
274*3f982cf4SFabien Sanglard   constexpr double kIntMin = std::numeric_limits<int64_t>::min();
275*3f982cf4SFabien Sanglard   const ValuePair kValuePairs[] = {
276*3f982cf4SFabien Sanglard       {kDoubleMax, std::numeric_limits<int64_t>::max()},
277*3f982cf4SFabien Sanglard       {std::nextafter(kIntMax, kDoubleMax),
278*3f982cf4SFabien Sanglard        std::numeric_limits<int64_t>::max()},
279*3f982cf4SFabien Sanglard       {kIntMax, std::numeric_limits<int64_t>::max()},
280*3f982cf4SFabien Sanglard       {std::nextafter(kIntMax, 0.0), INT64_C(9223372036854774784)},
281*3f982cf4SFabien Sanglard       {42, 42},
282*3f982cf4SFabien Sanglard       {0, 0},
283*3f982cf4SFabien Sanglard       {-42, -42},
284*3f982cf4SFabien Sanglard       {std::nextafter(kIntMin, 0.0), INT64_C(-9223372036854774784)},
285*3f982cf4SFabien Sanglard       {kIntMin, std::numeric_limits<int64_t>::min()},
286*3f982cf4SFabien Sanglard       {std::nextafter(kIntMin, -kDoubleMax),
287*3f982cf4SFabien Sanglard        std::numeric_limits<int64_t>::min()},
288*3f982cf4SFabien Sanglard       {-kDoubleMax, std::numeric_limits<int64_t>::min()},
289*3f982cf4SFabien Sanglard   };
290*3f982cf4SFabien Sanglard   for (const ValuePair& value_pair : kValuePairs) {
291*3f982cf4SFabien Sanglard     EXPECT_EQ(value_pair.to, saturate_cast<int64_t>(value_pair.from));
292*3f982cf4SFabien Sanglard   }
293*3f982cf4SFabien Sanglard }
294*3f982cf4SFabien Sanglard 
TEST(SaturateCastTest,Float32ToUnsigned64)295*3f982cf4SFabien Sanglard TEST(SaturateCastTest, Float32ToUnsigned64) {
296*3f982cf4SFabien Sanglard   struct ValuePair {
297*3f982cf4SFabien Sanglard     float from;
298*3f982cf4SFabien Sanglard     uint64_t to;
299*3f982cf4SFabien Sanglard   };
300*3f982cf4SFabien Sanglard   constexpr float kFloatMax = std::numeric_limits<float>::max();
301*3f982cf4SFabien Sanglard   // Note: kIntMax is one larger because float cannot represent the exact value.
302*3f982cf4SFabien Sanglard   constexpr float kIntMax =
303*3f982cf4SFabien Sanglard       static_cast<float>(std::numeric_limits<uint64_t>::max());
304*3f982cf4SFabien Sanglard   const ValuePair kValuePairs[] = {
305*3f982cf4SFabien Sanglard       {kFloatMax, std::numeric_limits<uint64_t>::max()},
306*3f982cf4SFabien Sanglard       {std::nextafter(kIntMax, kFloatMax),
307*3f982cf4SFabien Sanglard        std::numeric_limits<uint64_t>::max()},
308*3f982cf4SFabien Sanglard       {kIntMax, std::numeric_limits<uint64_t>::max()},
309*3f982cf4SFabien Sanglard       {std::nextafter(kIntMax, 0.f), UINT64_C(18446742974197923840)},
310*3f982cf4SFabien Sanglard       {42, 42},
311*3f982cf4SFabien Sanglard       {0, 0},
312*3f982cf4SFabien Sanglard       {-42, 0},
313*3f982cf4SFabien Sanglard       {-kFloatMax, 0},
314*3f982cf4SFabien Sanglard   };
315*3f982cf4SFabien Sanglard   for (const ValuePair& value_pair : kValuePairs) {
316*3f982cf4SFabien Sanglard     EXPECT_EQ(value_pair.to, saturate_cast<uint64_t>(value_pair.from));
317*3f982cf4SFabien Sanglard   }
318*3f982cf4SFabien Sanglard }
319*3f982cf4SFabien Sanglard 
TEST(SaturateCastTest,RoundingFloat32ToSigned64)320*3f982cf4SFabien Sanglard TEST(SaturateCastTest, RoundingFloat32ToSigned64) {
321*3f982cf4SFabien Sanglard   struct ValuePair {
322*3f982cf4SFabien Sanglard     float from;
323*3f982cf4SFabien Sanglard     int64_t to;
324*3f982cf4SFabien Sanglard   };
325*3f982cf4SFabien Sanglard   constexpr float kFloatMax = std::numeric_limits<float>::max();
326*3f982cf4SFabien Sanglard   // Note: kIntMax is one larger because float cannot represent the exact value.
327*3f982cf4SFabien Sanglard   constexpr float kIntMax =
328*3f982cf4SFabien Sanglard       static_cast<float>(std::numeric_limits<int64_t>::max());
329*3f982cf4SFabien Sanglard   constexpr float kIntMin = std::numeric_limits<int64_t>::min();
330*3f982cf4SFabien Sanglard   const ValuePair kValuePairs[] = {
331*3f982cf4SFabien Sanglard       {kFloatMax, std::numeric_limits<int64_t>::max()},
332*3f982cf4SFabien Sanglard       {std::nextafter(kIntMax, kFloatMax), std::numeric_limits<int64_t>::max()},
333*3f982cf4SFabien Sanglard       {kIntMax, std::numeric_limits<int64_t>::max()},
334*3f982cf4SFabien Sanglard       {std::nextafter(kIntMax, 0.f), INT64_C(9223371487098961920)},
335*3f982cf4SFabien Sanglard       {41.9, 42},
336*3f982cf4SFabien Sanglard       {42, 42},
337*3f982cf4SFabien Sanglard       {42.6, 43},
338*3f982cf4SFabien Sanglard       {42.5, 43},
339*3f982cf4SFabien Sanglard       {42.4, 42},
340*3f982cf4SFabien Sanglard       {0.5, 1},
341*3f982cf4SFabien Sanglard       {0.1, 0},
342*3f982cf4SFabien Sanglard       {0, 0},
343*3f982cf4SFabien Sanglard       {-0.1, 0},
344*3f982cf4SFabien Sanglard       {-0.5, -1},
345*3f982cf4SFabien Sanglard       {-41.9, -42},
346*3f982cf4SFabien Sanglard       {-42, -42},
347*3f982cf4SFabien Sanglard       {-42.4, -42},
348*3f982cf4SFabien Sanglard       {-42.5, -43},
349*3f982cf4SFabien Sanglard       {-42.6, -43},
350*3f982cf4SFabien Sanglard       {std::nextafter(kIntMin, 0.f), INT64_C(-9223371487098961920)},
351*3f982cf4SFabien Sanglard       {kIntMin, std::numeric_limits<int64_t>::min()},
352*3f982cf4SFabien Sanglard       {std::nextafter(kIntMin, -kFloatMax),
353*3f982cf4SFabien Sanglard        std::numeric_limits<int64_t>::min()},
354*3f982cf4SFabien Sanglard       {-kFloatMax, std::numeric_limits<int64_t>::min()},
355*3f982cf4SFabien Sanglard   };
356*3f982cf4SFabien Sanglard   for (const ValuePair& value_pair : kValuePairs) {
357*3f982cf4SFabien Sanglard     EXPECT_EQ(value_pair.to, rounded_saturate_cast<int64_t>(value_pair.from));
358*3f982cf4SFabien Sanglard   }
359*3f982cf4SFabien Sanglard }
360*3f982cf4SFabien Sanglard 
361*3f982cf4SFabien Sanglard }  // namespace
362*3f982cf4SFabien Sanglard }  // namespace openscreen
363