1 | //===- llvm/unittest/ADT/APFloat.cpp - APFloat unit tests ---------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "llvm/ADT/APFloat.h" |
10 | #include "llvm/ADT/APSInt.h" |
11 | #include "llvm/ADT/Hashing.h" |
12 | #include "llvm/ADT/SmallString.h" |
13 | #include "llvm/ADT/SmallVector.h" |
14 | #include "llvm/ADT/StringExtras.h" |
15 | #include "llvm/Support/Error.h" |
16 | #include "llvm/Support/FormatVariadic.h" |
17 | #include "gtest/gtest.h" |
18 | #include <cmath> |
19 | #include <ostream> |
20 | #include <string> |
21 | #include <tuple> |
22 | |
23 | using namespace llvm; |
24 | |
25 | static std::string convertToErrorFromString(StringRef Str) { |
26 | llvm::APFloat F(0.0); |
27 | auto StatusOrErr = |
28 | F.convertFromString(Str, llvm::APFloat::rmNearestTiesToEven); |
29 | EXPECT_TRUE(!StatusOrErr); |
30 | return toString(E: StatusOrErr.takeError()); |
31 | } |
32 | |
33 | static double convertToDoubleFromString(StringRef Str) { |
34 | llvm::APFloat F(0.0); |
35 | auto StatusOrErr = |
36 | F.convertFromString(Str, llvm::APFloat::rmNearestTiesToEven); |
37 | EXPECT_FALSE(!StatusOrErr); |
38 | consumeError(Err: StatusOrErr.takeError()); |
39 | return F.convertToDouble(); |
40 | } |
41 | |
42 | static std::string convertToString(double d, unsigned Prec, unsigned Pad, |
43 | bool Tr = true) { |
44 | llvm::SmallVector<char, 100> Buffer; |
45 | llvm::APFloat F(d); |
46 | F.toString(Str&: Buffer, FormatPrecision: Prec, FormatMaxPadding: Pad, TruncateZero: Tr); |
47 | return std::string(Buffer.data(), Buffer.size()); |
48 | } |
49 | |
50 | namespace { |
51 | |
52 | TEST(APFloatTest, isSignaling) { |
53 | // We test qNaN, -qNaN, +sNaN, -sNaN with and without payloads. *NOTE* The |
54 | // positive/negative distinction is included only since the getQNaN/getSNaN |
55 | // API provides the option. |
56 | APInt payload = APInt::getOneBitSet(numBits: 4, BitNo: 2); |
57 | APFloat QNan = APFloat::getQNaN(Sem: APFloat::IEEEsingle(), Negative: false); |
58 | EXPECT_FALSE(QNan.isSignaling()); |
59 | EXPECT_EQ(fcQNan, QNan.classify()); |
60 | |
61 | EXPECT_FALSE(APFloat::getQNaN(APFloat::IEEEsingle(), true).isSignaling()); |
62 | EXPECT_FALSE(APFloat::getQNaN(APFloat::IEEEsingle(), false, &payload).isSignaling()); |
63 | EXPECT_FALSE(APFloat::getQNaN(APFloat::IEEEsingle(), true, &payload).isSignaling()); |
64 | |
65 | APFloat SNan = APFloat::getSNaN(Sem: APFloat::IEEEsingle(), Negative: false); |
66 | EXPECT_TRUE(SNan.isSignaling()); |
67 | EXPECT_EQ(fcSNan, SNan.classify()); |
68 | |
69 | EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle(), true).isSignaling()); |
70 | EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle(), false, &payload).isSignaling()); |
71 | EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle(), true, &payload).isSignaling()); |
72 | } |
73 | |
74 | TEST(APFloatTest, next) { |
75 | |
76 | APFloat test(APFloat::IEEEquad(), APFloat::uninitialized); |
77 | APFloat expected(APFloat::IEEEquad(), APFloat::uninitialized); |
78 | |
79 | // 1. Test Special Cases Values. |
80 | // |
81 | // Test all special values for nextUp and nextDown perscribed by IEEE-754R |
82 | // 2008. These are: |
83 | // 1. +inf |
84 | // 2. -inf |
85 | // 3. getLargest() |
86 | // 4. -getLargest() |
87 | // 5. getSmallest() |
88 | // 6. -getSmallest() |
89 | // 7. qNaN |
90 | // 8. sNaN |
91 | // 9. +0 |
92 | // 10. -0 |
93 | |
94 | // nextUp(+inf) = +inf. |
95 | test = APFloat::getInf(Sem: APFloat::IEEEquad(), Negative: false); |
96 | expected = APFloat::getInf(Sem: APFloat::IEEEquad(), Negative: false); |
97 | EXPECT_EQ(test.next(false), APFloat::opOK); |
98 | EXPECT_TRUE(test.isInfinity()); |
99 | EXPECT_TRUE(!test.isNegative()); |
100 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
101 | |
102 | // nextDown(+inf) = -nextUp(-inf) = -(-getLargest()) = getLargest() |
103 | test = APFloat::getInf(Sem: APFloat::IEEEquad(), Negative: false); |
104 | expected = APFloat::getLargest(Sem: APFloat::IEEEquad(), Negative: false); |
105 | EXPECT_EQ(test.next(true), APFloat::opOK); |
106 | EXPECT_TRUE(!test.isNegative()); |
107 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
108 | |
109 | // nextUp(-inf) = -getLargest() |
110 | test = APFloat::getInf(Sem: APFloat::IEEEquad(), Negative: true); |
111 | expected = APFloat::getLargest(Sem: APFloat::IEEEquad(), Negative: true); |
112 | EXPECT_EQ(test.next(false), APFloat::opOK); |
113 | EXPECT_TRUE(test.isNegative()); |
114 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
115 | |
116 | // nextDown(-inf) = -nextUp(+inf) = -(+inf) = -inf. |
117 | test = APFloat::getInf(Sem: APFloat::IEEEquad(), Negative: true); |
118 | expected = APFloat::getInf(Sem: APFloat::IEEEquad(), Negative: true); |
119 | EXPECT_EQ(test.next(true), APFloat::opOK); |
120 | EXPECT_TRUE(test.isInfinity() && test.isNegative()); |
121 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
122 | |
123 | // nextUp(getLargest()) = +inf |
124 | test = APFloat::getLargest(Sem: APFloat::IEEEquad(), Negative: false); |
125 | expected = APFloat::getInf(Sem: APFloat::IEEEquad(), Negative: false); |
126 | EXPECT_EQ(test.next(false), APFloat::opOK); |
127 | EXPECT_TRUE(test.isInfinity() && !test.isNegative()); |
128 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
129 | |
130 | // nextDown(getLargest()) = -nextUp(-getLargest()) |
131 | // = -(-getLargest() + inc) |
132 | // = getLargest() - inc. |
133 | test = APFloat::getLargest(Sem: APFloat::IEEEquad(), Negative: false); |
134 | expected = APFloat(APFloat::IEEEquad(), |
135 | "0x1.fffffffffffffffffffffffffffep+16383" ); |
136 | EXPECT_EQ(test.next(true), APFloat::opOK); |
137 | EXPECT_TRUE(!test.isInfinity() && !test.isNegative()); |
138 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
139 | |
140 | // nextUp(-getLargest()) = -getLargest() + inc. |
141 | test = APFloat::getLargest(Sem: APFloat::IEEEquad(), Negative: true); |
142 | expected = APFloat(APFloat::IEEEquad(), |
143 | "-0x1.fffffffffffffffffffffffffffep+16383" ); |
144 | EXPECT_EQ(test.next(false), APFloat::opOK); |
145 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
146 | |
147 | // nextDown(-getLargest()) = -nextUp(getLargest()) = -(inf) = -inf. |
148 | test = APFloat::getLargest(Sem: APFloat::IEEEquad(), Negative: true); |
149 | expected = APFloat::getInf(Sem: APFloat::IEEEquad(), Negative: true); |
150 | EXPECT_EQ(test.next(true), APFloat::opOK); |
151 | EXPECT_TRUE(test.isInfinity() && test.isNegative()); |
152 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
153 | |
154 | // nextUp(getSmallest()) = getSmallest() + inc. |
155 | test = APFloat(APFloat::IEEEquad(), "0x0.0000000000000000000000000001p-16382" ); |
156 | expected = APFloat(APFloat::IEEEquad(), |
157 | "0x0.0000000000000000000000000002p-16382" ); |
158 | EXPECT_EQ(test.next(false), APFloat::opOK); |
159 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
160 | |
161 | // nextDown(getSmallest()) = -nextUp(-getSmallest()) = -(-0) = +0. |
162 | test = APFloat(APFloat::IEEEquad(), "0x0.0000000000000000000000000001p-16382" ); |
163 | expected = APFloat::getZero(Sem: APFloat::IEEEquad(), Negative: false); |
164 | EXPECT_EQ(test.next(true), APFloat::opOK); |
165 | EXPECT_TRUE(test.isPosZero()); |
166 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
167 | |
168 | // nextUp(-getSmallest()) = -0. |
169 | test = APFloat(APFloat::IEEEquad(), "-0x0.0000000000000000000000000001p-16382" ); |
170 | expected = APFloat::getZero(Sem: APFloat::IEEEquad(), Negative: true); |
171 | EXPECT_EQ(test.next(false), APFloat::opOK); |
172 | EXPECT_TRUE(test.isNegZero()); |
173 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
174 | |
175 | // nextDown(-getSmallest()) = -nextUp(getSmallest()) = -getSmallest() - inc. |
176 | test = APFloat(APFloat::IEEEquad(), "-0x0.0000000000000000000000000001p-16382" ); |
177 | expected = APFloat(APFloat::IEEEquad(), |
178 | "-0x0.0000000000000000000000000002p-16382" ); |
179 | EXPECT_EQ(test.next(true), APFloat::opOK); |
180 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
181 | |
182 | // nextUp(qNaN) = qNaN |
183 | test = APFloat::getQNaN(Sem: APFloat::IEEEquad(), Negative: false); |
184 | expected = APFloat::getQNaN(Sem: APFloat::IEEEquad(), Negative: false); |
185 | EXPECT_EQ(test.next(false), APFloat::opOK); |
186 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
187 | |
188 | // nextDown(qNaN) = qNaN |
189 | test = APFloat::getQNaN(Sem: APFloat::IEEEquad(), Negative: false); |
190 | expected = APFloat::getQNaN(Sem: APFloat::IEEEquad(), Negative: false); |
191 | EXPECT_EQ(test.next(true), APFloat::opOK); |
192 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
193 | |
194 | // nextUp(sNaN) = qNaN |
195 | test = APFloat::getSNaN(Sem: APFloat::IEEEquad(), Negative: false); |
196 | expected = APFloat::getQNaN(Sem: APFloat::IEEEquad(), Negative: false); |
197 | EXPECT_EQ(test.next(false), APFloat::opInvalidOp); |
198 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
199 | |
200 | // nextDown(sNaN) = qNaN |
201 | test = APFloat::getSNaN(Sem: APFloat::IEEEquad(), Negative: false); |
202 | expected = APFloat::getQNaN(Sem: APFloat::IEEEquad(), Negative: false); |
203 | EXPECT_EQ(test.next(true), APFloat::opInvalidOp); |
204 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
205 | |
206 | // nextUp(+0) = +getSmallest() |
207 | test = APFloat::getZero(Sem: APFloat::IEEEquad(), Negative: false); |
208 | expected = APFloat::getSmallest(Sem: APFloat::IEEEquad(), Negative: false); |
209 | EXPECT_EQ(test.next(false), APFloat::opOK); |
210 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
211 | |
212 | // nextDown(+0) = -nextUp(-0) = -getSmallest() |
213 | test = APFloat::getZero(Sem: APFloat::IEEEquad(), Negative: false); |
214 | expected = APFloat::getSmallest(Sem: APFloat::IEEEquad(), Negative: true); |
215 | EXPECT_EQ(test.next(true), APFloat::opOK); |
216 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
217 | |
218 | // nextUp(-0) = +getSmallest() |
219 | test = APFloat::getZero(Sem: APFloat::IEEEquad(), Negative: true); |
220 | expected = APFloat::getSmallest(Sem: APFloat::IEEEquad(), Negative: false); |
221 | EXPECT_EQ(test.next(false), APFloat::opOK); |
222 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
223 | |
224 | // nextDown(-0) = -nextUp(0) = -getSmallest() |
225 | test = APFloat::getZero(Sem: APFloat::IEEEquad(), Negative: true); |
226 | expected = APFloat::getSmallest(Sem: APFloat::IEEEquad(), Negative: true); |
227 | EXPECT_EQ(test.next(true), APFloat::opOK); |
228 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
229 | |
230 | // 2. Binade Boundary Tests. |
231 | |
232 | // 2a. Test denormal <-> normal binade boundaries. |
233 | // * nextUp(+Largest Denormal) -> +Smallest Normal. |
234 | // * nextDown(-Largest Denormal) -> -Smallest Normal. |
235 | // * nextUp(-Smallest Normal) -> -Largest Denormal. |
236 | // * nextDown(+Smallest Normal) -> +Largest Denormal. |
237 | |
238 | // nextUp(+Largest Denormal) -> +Smallest Normal. |
239 | test = APFloat(APFloat::IEEEquad(), "0x0.ffffffffffffffffffffffffffffp-16382" ); |
240 | expected = APFloat(APFloat::IEEEquad(), |
241 | "0x1.0000000000000000000000000000p-16382" ); |
242 | EXPECT_EQ(test.next(false), APFloat::opOK); |
243 | EXPECT_FALSE(test.isDenormal()); |
244 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
245 | |
246 | // nextDown(-Largest Denormal) -> -Smallest Normal. |
247 | test = APFloat(APFloat::IEEEquad(), |
248 | "-0x0.ffffffffffffffffffffffffffffp-16382" ); |
249 | expected = APFloat(APFloat::IEEEquad(), |
250 | "-0x1.0000000000000000000000000000p-16382" ); |
251 | EXPECT_EQ(test.next(true), APFloat::opOK); |
252 | EXPECT_FALSE(test.isDenormal()); |
253 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
254 | |
255 | // nextUp(-Smallest Normal) -> -LargestDenormal. |
256 | test = APFloat(APFloat::IEEEquad(), |
257 | "-0x1.0000000000000000000000000000p-16382" ); |
258 | expected = APFloat(APFloat::IEEEquad(), |
259 | "-0x0.ffffffffffffffffffffffffffffp-16382" ); |
260 | EXPECT_EQ(test.next(false), APFloat::opOK); |
261 | EXPECT_TRUE(test.isDenormal()); |
262 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
263 | |
264 | // nextDown(+Smallest Normal) -> +Largest Denormal. |
265 | test = APFloat(APFloat::IEEEquad(), |
266 | "+0x1.0000000000000000000000000000p-16382" ); |
267 | expected = APFloat(APFloat::IEEEquad(), |
268 | "+0x0.ffffffffffffffffffffffffffffp-16382" ); |
269 | EXPECT_EQ(test.next(true), APFloat::opOK); |
270 | EXPECT_TRUE(test.isDenormal()); |
271 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
272 | |
273 | // 2b. Test normal <-> normal binade boundaries. |
274 | // * nextUp(-Normal Binade Boundary) -> -Normal Binade Boundary + 1. |
275 | // * nextDown(+Normal Binade Boundary) -> +Normal Binade Boundary - 1. |
276 | // * nextUp(+Normal Binade Boundary - 1) -> +Normal Binade Boundary. |
277 | // * nextDown(-Normal Binade Boundary + 1) -> -Normal Binade Boundary. |
278 | |
279 | // nextUp(-Normal Binade Boundary) -> -Normal Binade Boundary + 1. |
280 | test = APFloat(APFloat::IEEEquad(), "-0x1p+1" ); |
281 | expected = APFloat(APFloat::IEEEquad(), |
282 | "-0x1.ffffffffffffffffffffffffffffp+0" ); |
283 | EXPECT_EQ(test.next(false), APFloat::opOK); |
284 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
285 | |
286 | // nextDown(+Normal Binade Boundary) -> +Normal Binade Boundary - 1. |
287 | test = APFloat(APFloat::IEEEquad(), "0x1p+1" ); |
288 | expected = APFloat(APFloat::IEEEquad(), "0x1.ffffffffffffffffffffffffffffp+0" ); |
289 | EXPECT_EQ(test.next(true), APFloat::opOK); |
290 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
291 | |
292 | // nextUp(+Normal Binade Boundary - 1) -> +Normal Binade Boundary. |
293 | test = APFloat(APFloat::IEEEquad(), "0x1.ffffffffffffffffffffffffffffp+0" ); |
294 | expected = APFloat(APFloat::IEEEquad(), "0x1p+1" ); |
295 | EXPECT_EQ(test.next(false), APFloat::opOK); |
296 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
297 | |
298 | // nextDown(-Normal Binade Boundary + 1) -> -Normal Binade Boundary. |
299 | test = APFloat(APFloat::IEEEquad(), "-0x1.ffffffffffffffffffffffffffffp+0" ); |
300 | expected = APFloat(APFloat::IEEEquad(), "-0x1p+1" ); |
301 | EXPECT_EQ(test.next(true), APFloat::opOK); |
302 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
303 | |
304 | // 2c. Test using next at binade boundaries with a direction away from the |
305 | // binade boundary. Away from denormal <-> normal boundaries. |
306 | // |
307 | // This is to make sure that even though we are at a binade boundary, since |
308 | // we are rounding away, we do not trigger the binade boundary code. Thus we |
309 | // test: |
310 | // * nextUp(-Largest Denormal) -> -Largest Denormal + inc. |
311 | // * nextDown(+Largest Denormal) -> +Largest Denormal - inc. |
312 | // * nextUp(+Smallest Normal) -> +Smallest Normal + inc. |
313 | // * nextDown(-Smallest Normal) -> -Smallest Normal - inc. |
314 | |
315 | // nextUp(-Largest Denormal) -> -Largest Denormal + inc. |
316 | test = APFloat(APFloat::IEEEquad(), "-0x0.ffffffffffffffffffffffffffffp-16382" ); |
317 | expected = APFloat(APFloat::IEEEquad(), |
318 | "-0x0.fffffffffffffffffffffffffffep-16382" ); |
319 | EXPECT_EQ(test.next(false), APFloat::opOK); |
320 | EXPECT_TRUE(test.isDenormal()); |
321 | EXPECT_TRUE(test.isNegative()); |
322 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
323 | |
324 | // nextDown(+Largest Denormal) -> +Largest Denormal - inc. |
325 | test = APFloat(APFloat::IEEEquad(), "0x0.ffffffffffffffffffffffffffffp-16382" ); |
326 | expected = APFloat(APFloat::IEEEquad(), |
327 | "0x0.fffffffffffffffffffffffffffep-16382" ); |
328 | EXPECT_EQ(test.next(true), APFloat::opOK); |
329 | EXPECT_TRUE(test.isDenormal()); |
330 | EXPECT_TRUE(!test.isNegative()); |
331 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
332 | |
333 | // nextUp(+Smallest Normal) -> +Smallest Normal + inc. |
334 | test = APFloat(APFloat::IEEEquad(), "0x1.0000000000000000000000000000p-16382" ); |
335 | expected = APFloat(APFloat::IEEEquad(), |
336 | "0x1.0000000000000000000000000001p-16382" ); |
337 | EXPECT_EQ(test.next(false), APFloat::opOK); |
338 | EXPECT_TRUE(!test.isDenormal()); |
339 | EXPECT_TRUE(!test.isNegative()); |
340 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
341 | |
342 | // nextDown(-Smallest Normal) -> -Smallest Normal - inc. |
343 | test = APFloat(APFloat::IEEEquad(), "-0x1.0000000000000000000000000000p-16382" ); |
344 | expected = APFloat(APFloat::IEEEquad(), |
345 | "-0x1.0000000000000000000000000001p-16382" ); |
346 | EXPECT_EQ(test.next(true), APFloat::opOK); |
347 | EXPECT_TRUE(!test.isDenormal()); |
348 | EXPECT_TRUE(test.isNegative()); |
349 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
350 | |
351 | // 2d. Test values which cause our exponent to go to min exponent. This |
352 | // is to ensure that guards in the code to check for min exponent |
353 | // trigger properly. |
354 | // * nextUp(-0x1p-16381) -> -0x1.ffffffffffffffffffffffffffffp-16382 |
355 | // * nextDown(-0x1.ffffffffffffffffffffffffffffp-16382) -> |
356 | // -0x1p-16381 |
357 | // * nextUp(0x1.ffffffffffffffffffffffffffffp-16382) -> 0x1p-16382 |
358 | // * nextDown(0x1p-16382) -> 0x1.ffffffffffffffffffffffffffffp-16382 |
359 | |
360 | // nextUp(-0x1p-16381) -> -0x1.ffffffffffffffffffffffffffffp-16382 |
361 | test = APFloat(APFloat::IEEEquad(), "-0x1p-16381" ); |
362 | expected = APFloat(APFloat::IEEEquad(), |
363 | "-0x1.ffffffffffffffffffffffffffffp-16382" ); |
364 | EXPECT_EQ(test.next(false), APFloat::opOK); |
365 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
366 | |
367 | // nextDown(-0x1.ffffffffffffffffffffffffffffp-16382) -> |
368 | // -0x1p-16381 |
369 | test = APFloat(APFloat::IEEEquad(), "-0x1.ffffffffffffffffffffffffffffp-16382" ); |
370 | expected = APFloat(APFloat::IEEEquad(), "-0x1p-16381" ); |
371 | EXPECT_EQ(test.next(true), APFloat::opOK); |
372 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
373 | |
374 | // nextUp(0x1.ffffffffffffffffffffffffffffp-16382) -> 0x1p-16381 |
375 | test = APFloat(APFloat::IEEEquad(), "0x1.ffffffffffffffffffffffffffffp-16382" ); |
376 | expected = APFloat(APFloat::IEEEquad(), "0x1p-16381" ); |
377 | EXPECT_EQ(test.next(false), APFloat::opOK); |
378 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
379 | |
380 | // nextDown(0x1p-16381) -> 0x1.ffffffffffffffffffffffffffffp-16382 |
381 | test = APFloat(APFloat::IEEEquad(), "0x1p-16381" ); |
382 | expected = APFloat(APFloat::IEEEquad(), |
383 | "0x1.ffffffffffffffffffffffffffffp-16382" ); |
384 | EXPECT_EQ(test.next(true), APFloat::opOK); |
385 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
386 | |
387 | // 3. Now we test both denormal/normal computation which will not cause us |
388 | // to go across binade boundaries. Specifically we test: |
389 | // * nextUp(+Denormal) -> +Denormal. |
390 | // * nextDown(+Denormal) -> +Denormal. |
391 | // * nextUp(-Denormal) -> -Denormal. |
392 | // * nextDown(-Denormal) -> -Denormal. |
393 | // * nextUp(+Normal) -> +Normal. |
394 | // * nextDown(+Normal) -> +Normal. |
395 | // * nextUp(-Normal) -> -Normal. |
396 | // * nextDown(-Normal) -> -Normal. |
397 | |
398 | // nextUp(+Denormal) -> +Denormal. |
399 | test = APFloat(APFloat::IEEEquad(), |
400 | "0x0.ffffffffffffffffffffffff000cp-16382" ); |
401 | expected = APFloat(APFloat::IEEEquad(), |
402 | "0x0.ffffffffffffffffffffffff000dp-16382" ); |
403 | EXPECT_EQ(test.next(false), APFloat::opOK); |
404 | EXPECT_TRUE(test.isDenormal()); |
405 | EXPECT_TRUE(!test.isNegative()); |
406 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
407 | |
408 | // nextDown(+Denormal) -> +Denormal. |
409 | test = APFloat(APFloat::IEEEquad(), |
410 | "0x0.ffffffffffffffffffffffff000cp-16382" ); |
411 | expected = APFloat(APFloat::IEEEquad(), |
412 | "0x0.ffffffffffffffffffffffff000bp-16382" ); |
413 | EXPECT_EQ(test.next(true), APFloat::opOK); |
414 | EXPECT_TRUE(test.isDenormal()); |
415 | EXPECT_TRUE(!test.isNegative()); |
416 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
417 | |
418 | // nextUp(-Denormal) -> -Denormal. |
419 | test = APFloat(APFloat::IEEEquad(), |
420 | "-0x0.ffffffffffffffffffffffff000cp-16382" ); |
421 | expected = APFloat(APFloat::IEEEquad(), |
422 | "-0x0.ffffffffffffffffffffffff000bp-16382" ); |
423 | EXPECT_EQ(test.next(false), APFloat::opOK); |
424 | EXPECT_TRUE(test.isDenormal()); |
425 | EXPECT_TRUE(test.isNegative()); |
426 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
427 | |
428 | // nextDown(-Denormal) -> -Denormal |
429 | test = APFloat(APFloat::IEEEquad(), |
430 | "-0x0.ffffffffffffffffffffffff000cp-16382" ); |
431 | expected = APFloat(APFloat::IEEEquad(), |
432 | "-0x0.ffffffffffffffffffffffff000dp-16382" ); |
433 | EXPECT_EQ(test.next(true), APFloat::opOK); |
434 | EXPECT_TRUE(test.isDenormal()); |
435 | EXPECT_TRUE(test.isNegative()); |
436 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
437 | |
438 | // nextUp(+Normal) -> +Normal. |
439 | test = APFloat(APFloat::IEEEquad(), |
440 | "0x1.ffffffffffffffffffffffff000cp-16000" ); |
441 | expected = APFloat(APFloat::IEEEquad(), |
442 | "0x1.ffffffffffffffffffffffff000dp-16000" ); |
443 | EXPECT_EQ(test.next(false), APFloat::opOK); |
444 | EXPECT_TRUE(!test.isDenormal()); |
445 | EXPECT_TRUE(!test.isNegative()); |
446 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
447 | |
448 | // nextDown(+Normal) -> +Normal. |
449 | test = APFloat(APFloat::IEEEquad(), |
450 | "0x1.ffffffffffffffffffffffff000cp-16000" ); |
451 | expected = APFloat(APFloat::IEEEquad(), |
452 | "0x1.ffffffffffffffffffffffff000bp-16000" ); |
453 | EXPECT_EQ(test.next(true), APFloat::opOK); |
454 | EXPECT_TRUE(!test.isDenormal()); |
455 | EXPECT_TRUE(!test.isNegative()); |
456 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
457 | |
458 | // nextUp(-Normal) -> -Normal. |
459 | test = APFloat(APFloat::IEEEquad(), |
460 | "-0x1.ffffffffffffffffffffffff000cp-16000" ); |
461 | expected = APFloat(APFloat::IEEEquad(), |
462 | "-0x1.ffffffffffffffffffffffff000bp-16000" ); |
463 | EXPECT_EQ(test.next(false), APFloat::opOK); |
464 | EXPECT_TRUE(!test.isDenormal()); |
465 | EXPECT_TRUE(test.isNegative()); |
466 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
467 | |
468 | // nextDown(-Normal) -> -Normal. |
469 | test = APFloat(APFloat::IEEEquad(), |
470 | "-0x1.ffffffffffffffffffffffff000cp-16000" ); |
471 | expected = APFloat(APFloat::IEEEquad(), |
472 | "-0x1.ffffffffffffffffffffffff000dp-16000" ); |
473 | EXPECT_EQ(test.next(true), APFloat::opOK); |
474 | EXPECT_TRUE(!test.isDenormal()); |
475 | EXPECT_TRUE(test.isNegative()); |
476 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
477 | } |
478 | |
479 | TEST(APFloatTest, FMA) { |
480 | APFloat::roundingMode rdmd = APFloat::rmNearestTiesToEven; |
481 | |
482 | { |
483 | APFloat f1(14.5f); |
484 | APFloat f2(-14.5f); |
485 | APFloat f3(225.0f); |
486 | f1.fusedMultiplyAdd(Multiplicand: f2, Addend: f3, RM: APFloat::rmNearestTiesToEven); |
487 | EXPECT_EQ(14.75f, f1.convertToFloat()); |
488 | } |
489 | |
490 | { |
491 | APFloat Val2(2.0f); |
492 | APFloat f1((float)1.17549435e-38F); |
493 | APFloat f2((float)1.17549435e-38F); |
494 | f1.divide(RHS: Val2, RM: rdmd); |
495 | f2.divide(RHS: Val2, RM: rdmd); |
496 | APFloat f3(12.0f); |
497 | f1.fusedMultiplyAdd(Multiplicand: f2, Addend: f3, RM: APFloat::rmNearestTiesToEven); |
498 | EXPECT_EQ(12.0f, f1.convertToFloat()); |
499 | } |
500 | |
501 | // Test for correct zero sign when answer is exactly zero. |
502 | // fma(1.0, -1.0, 1.0) -> +ve 0. |
503 | { |
504 | APFloat f1(1.0); |
505 | APFloat f2(-1.0); |
506 | APFloat f3(1.0); |
507 | f1.fusedMultiplyAdd(Multiplicand: f2, Addend: f3, RM: APFloat::rmNearestTiesToEven); |
508 | EXPECT_TRUE(!f1.isNegative() && f1.isZero()); |
509 | } |
510 | |
511 | // Test for correct zero sign when answer is exactly zero and rounding towards |
512 | // negative. |
513 | // fma(1.0, -1.0, 1.0) -> +ve 0. |
514 | { |
515 | APFloat f1(1.0); |
516 | APFloat f2(-1.0); |
517 | APFloat f3(1.0); |
518 | f1.fusedMultiplyAdd(Multiplicand: f2, Addend: f3, RM: APFloat::rmTowardNegative); |
519 | EXPECT_TRUE(f1.isNegative() && f1.isZero()); |
520 | } |
521 | |
522 | // Test for correct (in this case -ve) sign when adding like signed zeros. |
523 | // Test fma(0.0, -0.0, -0.0) -> -ve 0. |
524 | { |
525 | APFloat f1(0.0); |
526 | APFloat f2(-0.0); |
527 | APFloat f3(-0.0); |
528 | f1.fusedMultiplyAdd(Multiplicand: f2, Addend: f3, RM: APFloat::rmNearestTiesToEven); |
529 | EXPECT_TRUE(f1.isNegative() && f1.isZero()); |
530 | } |
531 | |
532 | // Test -ve sign preservation when small negative results underflow. |
533 | { |
534 | APFloat f1(APFloat::IEEEdouble(), "-0x1p-1074" ); |
535 | APFloat f2(APFloat::IEEEdouble(), "+0x1p-1074" ); |
536 | APFloat f3(0.0); |
537 | f1.fusedMultiplyAdd(Multiplicand: f2, Addend: f3, RM: APFloat::rmNearestTiesToEven); |
538 | EXPECT_TRUE(f1.isNegative() && f1.isZero()); |
539 | } |
540 | |
541 | // Test x87 extended precision case from http://llvm.org/PR20728. |
542 | { |
543 | APFloat M1(APFloat::x87DoubleExtended(), 1); |
544 | APFloat M2(APFloat::x87DoubleExtended(), 1); |
545 | APFloat A(APFloat::x87DoubleExtended(), 3); |
546 | |
547 | bool losesInfo = false; |
548 | M1.fusedMultiplyAdd(Multiplicand: M1, Addend: A, RM: APFloat::rmNearestTiesToEven); |
549 | M1.convert(ToSemantics: APFloat::IEEEsingle(), RM: APFloat::rmNearestTiesToEven, losesInfo: &losesInfo); |
550 | EXPECT_FALSE(losesInfo); |
551 | EXPECT_EQ(4.0f, M1.convertToFloat()); |
552 | } |
553 | |
554 | // Regression test that failed an assertion. |
555 | { |
556 | APFloat f1(-8.85242279E-41f); |
557 | APFloat f2(2.0f); |
558 | APFloat f3(8.85242279E-41f); |
559 | f1.fusedMultiplyAdd(Multiplicand: f2, Addend: f3, RM: APFloat::rmNearestTiesToEven); |
560 | EXPECT_EQ(-8.85242279E-41f, f1.convertToFloat()); |
561 | } |
562 | |
563 | // Test using only a single instance of APFloat. |
564 | { |
565 | APFloat F(1.5); |
566 | |
567 | F.fusedMultiplyAdd(Multiplicand: F, Addend: F, RM: APFloat::rmNearestTiesToEven); |
568 | EXPECT_EQ(3.75, F.convertToDouble()); |
569 | } |
570 | } |
571 | |
572 | TEST(APFloatTest, MinNum) { |
573 | APFloat f1(1.0); |
574 | APFloat f2(2.0); |
575 | APFloat nan = APFloat::getNaN(Sem: APFloat::IEEEdouble()); |
576 | |
577 | EXPECT_EQ(1.0, minnum(f1, f2).convertToDouble()); |
578 | EXPECT_EQ(1.0, minnum(f2, f1).convertToDouble()); |
579 | EXPECT_EQ(1.0, minnum(f1, nan).convertToDouble()); |
580 | EXPECT_EQ(1.0, minnum(nan, f1).convertToDouble()); |
581 | |
582 | APFloat zp(0.0); |
583 | APFloat zn(-0.0); |
584 | EXPECT_EQ(-0.0, minnum(zp, zn).convertToDouble()); |
585 | EXPECT_EQ(-0.0, minnum(zn, zp).convertToDouble()); |
586 | } |
587 | |
588 | TEST(APFloatTest, MaxNum) { |
589 | APFloat f1(1.0); |
590 | APFloat f2(2.0); |
591 | APFloat nan = APFloat::getNaN(Sem: APFloat::IEEEdouble()); |
592 | |
593 | EXPECT_EQ(2.0, maxnum(f1, f2).convertToDouble()); |
594 | EXPECT_EQ(2.0, maxnum(f2, f1).convertToDouble()); |
595 | EXPECT_EQ(1.0, maxnum(f1, nan).convertToDouble()); |
596 | EXPECT_EQ(1.0, maxnum(nan, f1).convertToDouble()); |
597 | |
598 | APFloat zp(0.0); |
599 | APFloat zn(-0.0); |
600 | EXPECT_EQ(0.0, maxnum(zp, zn).convertToDouble()); |
601 | EXPECT_EQ(0.0, maxnum(zn, zp).convertToDouble()); |
602 | } |
603 | |
604 | TEST(APFloatTest, Minimum) { |
605 | APFloat f1(1.0); |
606 | APFloat f2(2.0); |
607 | APFloat zp(0.0); |
608 | APFloat zn(-0.0); |
609 | APFloat nan = APFloat::getNaN(Sem: APFloat::IEEEdouble()); |
610 | |
611 | EXPECT_EQ(1.0, minimum(f1, f2).convertToDouble()); |
612 | EXPECT_EQ(1.0, minimum(f2, f1).convertToDouble()); |
613 | EXPECT_EQ(-0.0, minimum(zp, zn).convertToDouble()); |
614 | EXPECT_EQ(-0.0, minimum(zn, zp).convertToDouble()); |
615 | EXPECT_TRUE(std::isnan(minimum(f1, nan).convertToDouble())); |
616 | EXPECT_TRUE(std::isnan(minimum(nan, f1).convertToDouble())); |
617 | } |
618 | |
619 | TEST(APFloatTest, Maximum) { |
620 | APFloat f1(1.0); |
621 | APFloat f2(2.0); |
622 | APFloat zp(0.0); |
623 | APFloat zn(-0.0); |
624 | APFloat nan = APFloat::getNaN(Sem: APFloat::IEEEdouble()); |
625 | |
626 | EXPECT_EQ(2.0, maximum(f1, f2).convertToDouble()); |
627 | EXPECT_EQ(2.0, maximum(f2, f1).convertToDouble()); |
628 | EXPECT_EQ(0.0, maximum(zp, zn).convertToDouble()); |
629 | EXPECT_EQ(0.0, maximum(zn, zp).convertToDouble()); |
630 | EXPECT_TRUE(std::isnan(maximum(f1, nan).convertToDouble())); |
631 | EXPECT_TRUE(std::isnan(maximum(nan, f1).convertToDouble())); |
632 | } |
633 | |
634 | TEST(APFloatTest, Denormal) { |
635 | APFloat::roundingMode rdmd = APFloat::rmNearestTiesToEven; |
636 | |
637 | // Test single precision |
638 | { |
639 | const char *MinNormalStr = "1.17549435082228750797e-38" ; |
640 | EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), MinNormalStr).isDenormal()); |
641 | EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), 0).isDenormal()); |
642 | |
643 | APFloat Val2(APFloat::IEEEsingle(), 2); |
644 | APFloat T(APFloat::IEEEsingle(), MinNormalStr); |
645 | T.divide(RHS: Val2, RM: rdmd); |
646 | EXPECT_TRUE(T.isDenormal()); |
647 | EXPECT_EQ(fcPosSubnormal, T.classify()); |
648 | |
649 | |
650 | const char *NegMinNormalStr = "-1.17549435082228750797e-38" ; |
651 | EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), NegMinNormalStr).isDenormal()); |
652 | APFloat NegT(APFloat::IEEEsingle(), NegMinNormalStr); |
653 | NegT.divide(RHS: Val2, RM: rdmd); |
654 | EXPECT_TRUE(NegT.isDenormal()); |
655 | EXPECT_EQ(fcNegSubnormal, NegT.classify()); |
656 | } |
657 | |
658 | // Test double precision |
659 | { |
660 | const char *MinNormalStr = "2.22507385850720138309e-308" ; |
661 | EXPECT_FALSE(APFloat(APFloat::IEEEdouble(), MinNormalStr).isDenormal()); |
662 | EXPECT_FALSE(APFloat(APFloat::IEEEdouble(), 0).isDenormal()); |
663 | |
664 | APFloat Val2(APFloat::IEEEdouble(), 2); |
665 | APFloat T(APFloat::IEEEdouble(), MinNormalStr); |
666 | T.divide(RHS: Val2, RM: rdmd); |
667 | EXPECT_TRUE(T.isDenormal()); |
668 | EXPECT_EQ(fcPosSubnormal, T.classify()); |
669 | } |
670 | |
671 | // Test Intel double-ext |
672 | { |
673 | const char *MinNormalStr = "3.36210314311209350626e-4932" ; |
674 | EXPECT_FALSE(APFloat(APFloat::x87DoubleExtended(), MinNormalStr).isDenormal()); |
675 | EXPECT_FALSE(APFloat(APFloat::x87DoubleExtended(), 0).isDenormal()); |
676 | |
677 | APFloat Val2(APFloat::x87DoubleExtended(), 2); |
678 | APFloat T(APFloat::x87DoubleExtended(), MinNormalStr); |
679 | T.divide(RHS: Val2, RM: rdmd); |
680 | EXPECT_TRUE(T.isDenormal()); |
681 | EXPECT_EQ(fcPosSubnormal, T.classify()); |
682 | } |
683 | |
684 | // Test quadruple precision |
685 | { |
686 | const char *MinNormalStr = "3.36210314311209350626267781732175260e-4932" ; |
687 | EXPECT_FALSE(APFloat(APFloat::IEEEquad(), MinNormalStr).isDenormal()); |
688 | EXPECT_FALSE(APFloat(APFloat::IEEEquad(), 0).isDenormal()); |
689 | |
690 | APFloat Val2(APFloat::IEEEquad(), 2); |
691 | APFloat T(APFloat::IEEEquad(), MinNormalStr); |
692 | T.divide(RHS: Val2, RM: rdmd); |
693 | EXPECT_TRUE(T.isDenormal()); |
694 | EXPECT_EQ(fcPosSubnormal, T.classify()); |
695 | } |
696 | |
697 | // Test TF32 |
698 | { |
699 | const char *MinNormalStr = "1.17549435082228750797e-38" ; |
700 | EXPECT_FALSE(APFloat(APFloat::FloatTF32(), MinNormalStr).isDenormal()); |
701 | EXPECT_FALSE(APFloat(APFloat::FloatTF32(), 0).isDenormal()); |
702 | |
703 | APFloat Val2(APFloat::FloatTF32(), 2); |
704 | APFloat T(APFloat::FloatTF32(), MinNormalStr); |
705 | T.divide(RHS: Val2, RM: rdmd); |
706 | EXPECT_TRUE(T.isDenormal()); |
707 | EXPECT_EQ(fcPosSubnormal, T.classify()); |
708 | |
709 | const char *NegMinNormalStr = "-1.17549435082228750797e-38" ; |
710 | EXPECT_FALSE(APFloat(APFloat::FloatTF32(), NegMinNormalStr).isDenormal()); |
711 | APFloat NegT(APFloat::FloatTF32(), NegMinNormalStr); |
712 | NegT.divide(RHS: Val2, RM: rdmd); |
713 | EXPECT_TRUE(NegT.isDenormal()); |
714 | EXPECT_EQ(fcNegSubnormal, NegT.classify()); |
715 | } |
716 | } |
717 | |
718 | TEST(APFloatTest, IsSmallestNormalized) { |
719 | for (unsigned I = 0; I != APFloat::S_MaxSemantics + 1; ++I) { |
720 | const fltSemantics &Semantics = |
721 | APFloat::EnumToSemantics(S: static_cast<APFloat::Semantics>(I)); |
722 | |
723 | EXPECT_FALSE(APFloat::getZero(Semantics, false).isSmallestNormalized()); |
724 | EXPECT_FALSE(APFloat::getZero(Semantics, true).isSmallestNormalized()); |
725 | |
726 | EXPECT_FALSE(APFloat::getInf(Semantics, false).isSmallestNormalized()); |
727 | EXPECT_FALSE(APFloat::getInf(Semantics, true).isSmallestNormalized()); |
728 | |
729 | EXPECT_FALSE(APFloat::getQNaN(Semantics).isSmallestNormalized()); |
730 | EXPECT_FALSE(APFloat::getSNaN(Semantics).isSmallestNormalized()); |
731 | |
732 | EXPECT_FALSE(APFloat::getLargest(Semantics).isSmallestNormalized()); |
733 | EXPECT_FALSE(APFloat::getLargest(Semantics, true).isSmallestNormalized()); |
734 | |
735 | EXPECT_FALSE(APFloat::getSmallest(Semantics).isSmallestNormalized()); |
736 | EXPECT_FALSE(APFloat::getSmallest(Semantics, true).isSmallestNormalized()); |
737 | |
738 | EXPECT_FALSE(APFloat::getAllOnesValue(Semantics).isSmallestNormalized()); |
739 | |
740 | APFloat PosSmallestNormalized = |
741 | APFloat::getSmallestNormalized(Sem: Semantics, Negative: false); |
742 | APFloat NegSmallestNormalized = |
743 | APFloat::getSmallestNormalized(Sem: Semantics, Negative: true); |
744 | EXPECT_TRUE(PosSmallestNormalized.isSmallestNormalized()); |
745 | EXPECT_TRUE(NegSmallestNormalized.isSmallestNormalized()); |
746 | EXPECT_EQ(fcPosNormal, PosSmallestNormalized.classify()); |
747 | EXPECT_EQ(fcNegNormal, NegSmallestNormalized.classify()); |
748 | |
749 | for (APFloat *Val : {&PosSmallestNormalized, &NegSmallestNormalized}) { |
750 | bool OldSign = Val->isNegative(); |
751 | |
752 | // Step down, make sure it's still not smallest normalized. |
753 | EXPECT_EQ(APFloat::opOK, Val->next(false)); |
754 | EXPECT_EQ(OldSign, Val->isNegative()); |
755 | EXPECT_FALSE(Val->isSmallestNormalized()); |
756 | EXPECT_EQ(OldSign, Val->isNegative()); |
757 | |
758 | // Step back up should restore it to being smallest normalized. |
759 | EXPECT_EQ(APFloat::opOK, Val->next(true)); |
760 | EXPECT_TRUE(Val->isSmallestNormalized()); |
761 | EXPECT_EQ(OldSign, Val->isNegative()); |
762 | |
763 | // Step beyond should no longer smallest normalized. |
764 | EXPECT_EQ(APFloat::opOK, Val->next(true)); |
765 | EXPECT_FALSE(Val->isSmallestNormalized()); |
766 | EXPECT_EQ(OldSign, Val->isNegative()); |
767 | } |
768 | } |
769 | } |
770 | |
771 | TEST(APFloatTest, Zero) { |
772 | EXPECT_EQ(0.0f, APFloat(0.0f).convertToFloat()); |
773 | EXPECT_EQ(-0.0f, APFloat(-0.0f).convertToFloat()); |
774 | EXPECT_TRUE(APFloat(-0.0f).isNegative()); |
775 | |
776 | EXPECT_EQ(0.0, APFloat(0.0).convertToDouble()); |
777 | EXPECT_EQ(-0.0, APFloat(-0.0).convertToDouble()); |
778 | EXPECT_TRUE(APFloat(-0.0).isNegative()); |
779 | |
780 | EXPECT_EQ(fcPosZero, APFloat(0.0).classify()); |
781 | EXPECT_EQ(fcNegZero, APFloat(-0.0).classify()); |
782 | } |
783 | |
784 | TEST(APFloatTest, DecimalStringsWithoutNullTerminators) { |
785 | // Make sure that we can parse strings without null terminators. |
786 | // rdar://14323230. |
787 | EXPECT_EQ(convertToDoubleFromString(StringRef("0.00" , 3)), 0.0); |
788 | EXPECT_EQ(convertToDoubleFromString(StringRef("0.01" , 3)), 0.0); |
789 | EXPECT_EQ(convertToDoubleFromString(StringRef("0.09" , 3)), 0.0); |
790 | EXPECT_EQ(convertToDoubleFromString(StringRef("0.095" , 4)), 0.09); |
791 | EXPECT_EQ(convertToDoubleFromString(StringRef("0.00e+3" , 7)), 0.00); |
792 | EXPECT_EQ(convertToDoubleFromString(StringRef("0e+3" , 4)), 0.00); |
793 | } |
794 | |
795 | TEST(APFloatTest, fromZeroDecimalString) { |
796 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0" ).convertToDouble()); |
797 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0" ).convertToDouble()); |
798 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0" ).convertToDouble()); |
799 | |
800 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0." ).convertToDouble()); |
801 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0." ).convertToDouble()); |
802 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0." ).convertToDouble()); |
803 | |
804 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), ".0" ).convertToDouble()); |
805 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+.0" ).convertToDouble()); |
806 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-.0" ).convertToDouble()); |
807 | |
808 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.0" ).convertToDouble()); |
809 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.0" ).convertToDouble()); |
810 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.0" ).convertToDouble()); |
811 | |
812 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "00000." ).convertToDouble()); |
813 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+00000." ).convertToDouble()); |
814 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-00000." ).convertToDouble()); |
815 | |
816 | EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble(), ".00000" ).convertToDouble()); |
817 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+.00000" ).convertToDouble()); |
818 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-.00000" ).convertToDouble()); |
819 | |
820 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0000.00000" ).convertToDouble()); |
821 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0000.00000" ).convertToDouble()); |
822 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0000.00000" ).convertToDouble()); |
823 | } |
824 | |
825 | TEST(APFloatTest, fromZeroDecimalSingleExponentString) { |
826 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e1" ).convertToDouble()); |
827 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e1" ).convertToDouble()); |
828 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e1" ).convertToDouble()); |
829 | |
830 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e+1" ).convertToDouble()); |
831 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e+1" ).convertToDouble()); |
832 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e+1" ).convertToDouble()); |
833 | |
834 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e-1" ).convertToDouble()); |
835 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e-1" ).convertToDouble()); |
836 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e-1" ).convertToDouble()); |
837 | |
838 | |
839 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.e1" ).convertToDouble()); |
840 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.e1" ).convertToDouble()); |
841 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.e1" ).convertToDouble()); |
842 | |
843 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.e+1" ).convertToDouble()); |
844 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.e+1" ).convertToDouble()); |
845 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.e+1" ).convertToDouble()); |
846 | |
847 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.e-1" ).convertToDouble()); |
848 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.e-1" ).convertToDouble()); |
849 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.e-1" ).convertToDouble()); |
850 | |
851 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), ".0e1" ).convertToDouble()); |
852 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+.0e1" ).convertToDouble()); |
853 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-.0e1" ).convertToDouble()); |
854 | |
855 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), ".0e+1" ).convertToDouble()); |
856 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+.0e+1" ).convertToDouble()); |
857 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-.0e+1" ).convertToDouble()); |
858 | |
859 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), ".0e-1" ).convertToDouble()); |
860 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+.0e-1" ).convertToDouble()); |
861 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-.0e-1" ).convertToDouble()); |
862 | |
863 | |
864 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.0e1" ).convertToDouble()); |
865 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.0e1" ).convertToDouble()); |
866 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.0e1" ).convertToDouble()); |
867 | |
868 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.0e+1" ).convertToDouble()); |
869 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.0e+1" ).convertToDouble()); |
870 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.0e+1" ).convertToDouble()); |
871 | |
872 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.0e-1" ).convertToDouble()); |
873 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.0e-1" ).convertToDouble()); |
874 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.0e-1" ).convertToDouble()); |
875 | |
876 | |
877 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "000.0000e1" ).convertToDouble()); |
878 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+000.0000e+1" ).convertToDouble()); |
879 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-000.0000e+1" ).convertToDouble()); |
880 | } |
881 | |
882 | TEST(APFloatTest, fromZeroDecimalLargeExponentString) { |
883 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e1234" ).convertToDouble()); |
884 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e1234" ).convertToDouble()); |
885 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e1234" ).convertToDouble()); |
886 | |
887 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e+1234" ).convertToDouble()); |
888 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e+1234" ).convertToDouble()); |
889 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e+1234" ).convertToDouble()); |
890 | |
891 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e-1234" ).convertToDouble()); |
892 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e-1234" ).convertToDouble()); |
893 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e-1234" ).convertToDouble()); |
894 | |
895 | EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble(), "000.0000e1234" ).convertToDouble()); |
896 | EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble(), "000.0000e-1234" ).convertToDouble()); |
897 | |
898 | EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble(), StringRef("0e1234" "\0" "2" , 6)).convertToDouble()); |
899 | } |
900 | |
901 | TEST(APFloatTest, fromZeroHexadecimalString) { |
902 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0p1" ).convertToDouble()); |
903 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0p1" ).convertToDouble()); |
904 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0p1" ).convertToDouble()); |
905 | |
906 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0p+1" ).convertToDouble()); |
907 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0p+1" ).convertToDouble()); |
908 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0p+1" ).convertToDouble()); |
909 | |
910 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0p-1" ).convertToDouble()); |
911 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0p-1" ).convertToDouble()); |
912 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0p-1" ).convertToDouble()); |
913 | |
914 | |
915 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.p1" ).convertToDouble()); |
916 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.p1" ).convertToDouble()); |
917 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.p1" ).convertToDouble()); |
918 | |
919 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.p+1" ).convertToDouble()); |
920 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.p+1" ).convertToDouble()); |
921 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.p+1" ).convertToDouble()); |
922 | |
923 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.p-1" ).convertToDouble()); |
924 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.p-1" ).convertToDouble()); |
925 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.p-1" ).convertToDouble()); |
926 | |
927 | |
928 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x.0p1" ).convertToDouble()); |
929 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x.0p1" ).convertToDouble()); |
930 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x.0p1" ).convertToDouble()); |
931 | |
932 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x.0p+1" ).convertToDouble()); |
933 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x.0p+1" ).convertToDouble()); |
934 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x.0p+1" ).convertToDouble()); |
935 | |
936 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x.0p-1" ).convertToDouble()); |
937 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x.0p-1" ).convertToDouble()); |
938 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x.0p-1" ).convertToDouble()); |
939 | |
940 | |
941 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.0p1" ).convertToDouble()); |
942 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.0p1" ).convertToDouble()); |
943 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.0p1" ).convertToDouble()); |
944 | |
945 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.0p+1" ).convertToDouble()); |
946 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.0p+1" ).convertToDouble()); |
947 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.0p+1" ).convertToDouble()); |
948 | |
949 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.0p-1" ).convertToDouble()); |
950 | EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.0p-1" ).convertToDouble()); |
951 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.0p-1" ).convertToDouble()); |
952 | |
953 | |
954 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x00000.p1" ).convertToDouble()); |
955 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0000.00000p1" ).convertToDouble()); |
956 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x.00000p1" ).convertToDouble()); |
957 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.p1" ).convertToDouble()); |
958 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0p1234" ).convertToDouble()); |
959 | EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0p1234" ).convertToDouble()); |
960 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x00000.p1234" ).convertToDouble()); |
961 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0000.00000p1234" ).convertToDouble()); |
962 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x.00000p1234" ).convertToDouble()); |
963 | EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.p1234" ).convertToDouble()); |
964 | } |
965 | |
966 | TEST(APFloatTest, fromDecimalString) { |
967 | EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1" ).convertToDouble()); |
968 | EXPECT_EQ(2.0, APFloat(APFloat::IEEEdouble(), "2." ).convertToDouble()); |
969 | EXPECT_EQ(0.5, APFloat(APFloat::IEEEdouble(), ".5" ).convertToDouble()); |
970 | EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1.0" ).convertToDouble()); |
971 | EXPECT_EQ(-2.0, APFloat(APFloat::IEEEdouble(), "-2" ).convertToDouble()); |
972 | EXPECT_EQ(-4.0, APFloat(APFloat::IEEEdouble(), "-4." ).convertToDouble()); |
973 | EXPECT_EQ(-0.5, APFloat(APFloat::IEEEdouble(), "-.5" ).convertToDouble()); |
974 | EXPECT_EQ(-1.5, APFloat(APFloat::IEEEdouble(), "-1.5" ).convertToDouble()); |
975 | EXPECT_EQ(1.25e12, APFloat(APFloat::IEEEdouble(), "1.25e12" ).convertToDouble()); |
976 | EXPECT_EQ(1.25e+12, APFloat(APFloat::IEEEdouble(), "1.25e+12" ).convertToDouble()); |
977 | EXPECT_EQ(1.25e-12, APFloat(APFloat::IEEEdouble(), "1.25e-12" ).convertToDouble()); |
978 | EXPECT_EQ(1024.0, APFloat(APFloat::IEEEdouble(), "1024." ).convertToDouble()); |
979 | EXPECT_EQ(1024.05, APFloat(APFloat::IEEEdouble(), "1024.05000" ).convertToDouble()); |
980 | EXPECT_EQ(0.05, APFloat(APFloat::IEEEdouble(), ".05000" ).convertToDouble()); |
981 | EXPECT_EQ(2.0, APFloat(APFloat::IEEEdouble(), "2." ).convertToDouble()); |
982 | EXPECT_EQ(2.0e2, APFloat(APFloat::IEEEdouble(), "2.e2" ).convertToDouble()); |
983 | EXPECT_EQ(2.0e+2, APFloat(APFloat::IEEEdouble(), "2.e+2" ).convertToDouble()); |
984 | EXPECT_EQ(2.0e-2, APFloat(APFloat::IEEEdouble(), "2.e-2" ).convertToDouble()); |
985 | EXPECT_EQ(2.05e2, APFloat(APFloat::IEEEdouble(), "002.05000e2" ).convertToDouble()); |
986 | EXPECT_EQ(2.05e+2, APFloat(APFloat::IEEEdouble(), "002.05000e+2" ).convertToDouble()); |
987 | EXPECT_EQ(2.05e-2, APFloat(APFloat::IEEEdouble(), "002.05000e-2" ).convertToDouble()); |
988 | EXPECT_EQ(2.05e12, APFloat(APFloat::IEEEdouble(), "002.05000e12" ).convertToDouble()); |
989 | EXPECT_EQ(2.05e+12, APFloat(APFloat::IEEEdouble(), "002.05000e+12" ).convertToDouble()); |
990 | EXPECT_EQ(2.05e-12, APFloat(APFloat::IEEEdouble(), "002.05000e-12" ).convertToDouble()); |
991 | |
992 | EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1e" ).convertToDouble()); |
993 | EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "+1e" ).convertToDouble()); |
994 | EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble(), "-1e" ).convertToDouble()); |
995 | |
996 | EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1.e" ).convertToDouble()); |
997 | EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "+1.e" ).convertToDouble()); |
998 | EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble(), "-1.e" ).convertToDouble()); |
999 | |
1000 | EXPECT_EQ(0.1, APFloat(APFloat::IEEEdouble(), ".1e" ).convertToDouble()); |
1001 | EXPECT_EQ(0.1, APFloat(APFloat::IEEEdouble(), "+.1e" ).convertToDouble()); |
1002 | EXPECT_EQ(-0.1, APFloat(APFloat::IEEEdouble(), "-.1e" ).convertToDouble()); |
1003 | |
1004 | EXPECT_EQ(1.1, APFloat(APFloat::IEEEdouble(), "1.1e" ).convertToDouble()); |
1005 | EXPECT_EQ(1.1, APFloat(APFloat::IEEEdouble(), "+1.1e" ).convertToDouble()); |
1006 | EXPECT_EQ(-1.1, APFloat(APFloat::IEEEdouble(), "-1.1e" ).convertToDouble()); |
1007 | |
1008 | EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1e+" ).convertToDouble()); |
1009 | EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1e-" ).convertToDouble()); |
1010 | |
1011 | EXPECT_EQ(0.1, APFloat(APFloat::IEEEdouble(), ".1e" ).convertToDouble()); |
1012 | EXPECT_EQ(0.1, APFloat(APFloat::IEEEdouble(), ".1e+" ).convertToDouble()); |
1013 | EXPECT_EQ(0.1, APFloat(APFloat::IEEEdouble(), ".1e-" ).convertToDouble()); |
1014 | |
1015 | EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1.0e" ).convertToDouble()); |
1016 | EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1.0e+" ).convertToDouble()); |
1017 | EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1.0e-" ).convertToDouble()); |
1018 | |
1019 | // These are "carefully selected" to overflow the fast log-base |
1020 | // calculations in APFloat.cpp |
1021 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "99e99999" ).isInfinity()); |
1022 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-99e99999" ).isInfinity()); |
1023 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "1e-99999" ).isPosZero()); |
1024 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-1e-99999" ).isNegZero()); |
1025 | |
1026 | EXPECT_EQ(2.71828, convertToDoubleFromString("2.71828" )); |
1027 | } |
1028 | |
1029 | TEST(APFloatTest, fromStringSpecials) { |
1030 | const fltSemantics &Sem = APFloat::IEEEdouble(); |
1031 | const unsigned Precision = 53; |
1032 | const unsigned PayloadBits = Precision - 2; |
1033 | uint64_t PayloadMask = (uint64_t(1) << PayloadBits) - uint64_t(1); |
1034 | |
1035 | uint64_t NaNPayloads[] = { |
1036 | 0, |
1037 | 1, |
1038 | 123, |
1039 | 0xDEADBEEF, |
1040 | uint64_t(-2), |
1041 | uint64_t(1) << PayloadBits, // overflow bit |
1042 | uint64_t(1) << (PayloadBits - 1), // signaling bit |
1043 | uint64_t(1) << (PayloadBits - 2) // highest possible bit |
1044 | }; |
1045 | |
1046 | // Convert payload integer to decimal string representation. |
1047 | std::string NaNPayloadDecStrings[std::size(NaNPayloads)]; |
1048 | for (size_t I = 0; I < std::size(NaNPayloads); ++I) |
1049 | NaNPayloadDecStrings[I] = utostr(X: NaNPayloads[I]); |
1050 | |
1051 | // Convert payload integer to hexadecimal string representation. |
1052 | std::string NaNPayloadHexStrings[std::size(NaNPayloads)]; |
1053 | for (size_t I = 0; I < std::size(NaNPayloads); ++I) |
1054 | NaNPayloadHexStrings[I] = "0x" + utohexstr(X: NaNPayloads[I]); |
1055 | |
1056 | // Fix payloads to expected result. |
1057 | for (uint64_t &Payload : NaNPayloads) |
1058 | Payload &= PayloadMask; |
1059 | |
1060 | // Signaling NaN must have a non-zero payload. In case a zero payload is |
1061 | // requested, a default arbitrary payload is set instead. Save this payload |
1062 | // for testing. |
1063 | const uint64_t SNaNDefaultPayload = |
1064 | APFloat::getSNaN(Sem).bitcastToAPInt().getZExtValue() & PayloadMask; |
1065 | |
1066 | // Negative sign prefix (or none - for positive). |
1067 | const char Signs[] = {0, '-'}; |
1068 | |
1069 | // "Signaling" prefix (or none - for "Quiet"). |
1070 | const char NaNTypes[] = {0, 's', 'S'}; |
1071 | |
1072 | const StringRef NaNStrings[] = {"nan" , "NaN" }; |
1073 | for (StringRef NaNStr : NaNStrings) |
1074 | for (char TypeChar : NaNTypes) { |
1075 | bool Signaling = (TypeChar == 's' || TypeChar == 'S'); |
1076 | |
1077 | for (size_t J = 0; J < std::size(NaNPayloads); ++J) { |
1078 | uint64_t Payload = (Signaling && !NaNPayloads[J]) ? SNaNDefaultPayload |
1079 | : NaNPayloads[J]; |
1080 | std::string &PayloadDec = NaNPayloadDecStrings[J]; |
1081 | std::string &PayloadHex = NaNPayloadHexStrings[J]; |
1082 | |
1083 | for (char SignChar : Signs) { |
1084 | bool Negative = (SignChar == '-'); |
1085 | |
1086 | std::string TestStrings[5]; |
1087 | size_t NumTestStrings = 0; |
1088 | |
1089 | std::string Prefix; |
1090 | if (SignChar) |
1091 | Prefix += SignChar; |
1092 | if (TypeChar) |
1093 | Prefix += TypeChar; |
1094 | Prefix += NaNStr; |
1095 | |
1096 | // Test without any paylod. |
1097 | if (!Payload) |
1098 | TestStrings[NumTestStrings++] = Prefix; |
1099 | |
1100 | // Test with the payload as a suffix. |
1101 | TestStrings[NumTestStrings++] = Prefix + PayloadDec; |
1102 | TestStrings[NumTestStrings++] = Prefix + PayloadHex; |
1103 | |
1104 | // Test with the payload inside parentheses. |
1105 | TestStrings[NumTestStrings++] = Prefix + '(' + PayloadDec + ')'; |
1106 | TestStrings[NumTestStrings++] = Prefix + '(' + PayloadHex + ')'; |
1107 | |
1108 | for (size_t K = 0; K < NumTestStrings; ++K) { |
1109 | StringRef TestStr = TestStrings[K]; |
1110 | |
1111 | APFloat F(Sem); |
1112 | bool HasError = !F.convertFromString( |
1113 | TestStr, llvm::APFloat::rmNearestTiesToEven); |
1114 | EXPECT_FALSE(HasError); |
1115 | EXPECT_TRUE(F.isNaN()); |
1116 | EXPECT_EQ(Signaling, F.isSignaling()); |
1117 | EXPECT_EQ(Negative, F.isNegative()); |
1118 | uint64_t PayloadResult = |
1119 | F.bitcastToAPInt().getZExtValue() & PayloadMask; |
1120 | EXPECT_EQ(Payload, PayloadResult); |
1121 | } |
1122 | } |
1123 | } |
1124 | } |
1125 | |
1126 | const StringRef InfStrings[] = {"inf" , "INFINITY" , "+Inf" , |
1127 | "-inf" , "-INFINITY" , "-Inf" }; |
1128 | for (StringRef InfStr : InfStrings) { |
1129 | bool Negative = InfStr.front() == '-'; |
1130 | |
1131 | APFloat F(Sem); |
1132 | bool HasError = |
1133 | !F.convertFromString(InfStr, llvm::APFloat::rmNearestTiesToEven); |
1134 | EXPECT_FALSE(HasError); |
1135 | EXPECT_TRUE(F.isInfinity()); |
1136 | EXPECT_EQ(Negative, F.isNegative()); |
1137 | uint64_t PayloadResult = F.bitcastToAPInt().getZExtValue() & PayloadMask; |
1138 | EXPECT_EQ(UINT64_C(0), PayloadResult); |
1139 | } |
1140 | } |
1141 | |
1142 | TEST(APFloatTest, fromToStringSpecials) { |
1143 | auto expects = [] (const char *first, const char *second) { |
1144 | std::string roundtrip = convertToString(d: convertToDoubleFromString(Str: second), Prec: 0, Pad: 3); |
1145 | EXPECT_STREQ(first, roundtrip.c_str()); |
1146 | }; |
1147 | expects("+Inf" , "+Inf" ); |
1148 | expects("+Inf" , "INFINITY" ); |
1149 | expects("+Inf" , "inf" ); |
1150 | expects("-Inf" , "-Inf" ); |
1151 | expects("-Inf" , "-INFINITY" ); |
1152 | expects("-Inf" , "-inf" ); |
1153 | expects("NaN" , "NaN" ); |
1154 | expects("NaN" , "nan" ); |
1155 | expects("NaN" , "-NaN" ); |
1156 | expects("NaN" , "-nan" ); |
1157 | } |
1158 | |
1159 | TEST(APFloatTest, fromHexadecimalString) { |
1160 | EXPECT_EQ( 1.0, APFloat(APFloat::IEEEdouble(), "0x1p0" ).convertToDouble()); |
1161 | EXPECT_EQ(+1.0, APFloat(APFloat::IEEEdouble(), "+0x1p0" ).convertToDouble()); |
1162 | EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble(), "-0x1p0" ).convertToDouble()); |
1163 | |
1164 | EXPECT_EQ( 1.0, APFloat(APFloat::IEEEdouble(), "0x1p+0" ).convertToDouble()); |
1165 | EXPECT_EQ(+1.0, APFloat(APFloat::IEEEdouble(), "+0x1p+0" ).convertToDouble()); |
1166 | EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble(), "-0x1p+0" ).convertToDouble()); |
1167 | |
1168 | EXPECT_EQ( 1.0, APFloat(APFloat::IEEEdouble(), "0x1p-0" ).convertToDouble()); |
1169 | EXPECT_EQ(+1.0, APFloat(APFloat::IEEEdouble(), "+0x1p-0" ).convertToDouble()); |
1170 | EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble(), "-0x1p-0" ).convertToDouble()); |
1171 | |
1172 | |
1173 | EXPECT_EQ( 2.0, APFloat(APFloat::IEEEdouble(), "0x1p1" ).convertToDouble()); |
1174 | EXPECT_EQ(+2.0, APFloat(APFloat::IEEEdouble(), "+0x1p1" ).convertToDouble()); |
1175 | EXPECT_EQ(-2.0, APFloat(APFloat::IEEEdouble(), "-0x1p1" ).convertToDouble()); |
1176 | |
1177 | EXPECT_EQ( 2.0, APFloat(APFloat::IEEEdouble(), "0x1p+1" ).convertToDouble()); |
1178 | EXPECT_EQ(+2.0, APFloat(APFloat::IEEEdouble(), "+0x1p+1" ).convertToDouble()); |
1179 | EXPECT_EQ(-2.0, APFloat(APFloat::IEEEdouble(), "-0x1p+1" ).convertToDouble()); |
1180 | |
1181 | EXPECT_EQ( 0.5, APFloat(APFloat::IEEEdouble(), "0x1p-1" ).convertToDouble()); |
1182 | EXPECT_EQ(+0.5, APFloat(APFloat::IEEEdouble(), "+0x1p-1" ).convertToDouble()); |
1183 | EXPECT_EQ(-0.5, APFloat(APFloat::IEEEdouble(), "-0x1p-1" ).convertToDouble()); |
1184 | |
1185 | |
1186 | EXPECT_EQ( 3.0, APFloat(APFloat::IEEEdouble(), "0x1.8p1" ).convertToDouble()); |
1187 | EXPECT_EQ(+3.0, APFloat(APFloat::IEEEdouble(), "+0x1.8p1" ).convertToDouble()); |
1188 | EXPECT_EQ(-3.0, APFloat(APFloat::IEEEdouble(), "-0x1.8p1" ).convertToDouble()); |
1189 | |
1190 | EXPECT_EQ( 3.0, APFloat(APFloat::IEEEdouble(), "0x1.8p+1" ).convertToDouble()); |
1191 | EXPECT_EQ(+3.0, APFloat(APFloat::IEEEdouble(), "+0x1.8p+1" ).convertToDouble()); |
1192 | EXPECT_EQ(-3.0, APFloat(APFloat::IEEEdouble(), "-0x1.8p+1" ).convertToDouble()); |
1193 | |
1194 | EXPECT_EQ( 0.75, APFloat(APFloat::IEEEdouble(), "0x1.8p-1" ).convertToDouble()); |
1195 | EXPECT_EQ(+0.75, APFloat(APFloat::IEEEdouble(), "+0x1.8p-1" ).convertToDouble()); |
1196 | EXPECT_EQ(-0.75, APFloat(APFloat::IEEEdouble(), "-0x1.8p-1" ).convertToDouble()); |
1197 | |
1198 | |
1199 | EXPECT_EQ( 8192.0, APFloat(APFloat::IEEEdouble(), "0x1000.000p1" ).convertToDouble()); |
1200 | EXPECT_EQ(+8192.0, APFloat(APFloat::IEEEdouble(), "+0x1000.000p1" ).convertToDouble()); |
1201 | EXPECT_EQ(-8192.0, APFloat(APFloat::IEEEdouble(), "-0x1000.000p1" ).convertToDouble()); |
1202 | |
1203 | EXPECT_EQ( 8192.0, APFloat(APFloat::IEEEdouble(), "0x1000.000p+1" ).convertToDouble()); |
1204 | EXPECT_EQ(+8192.0, APFloat(APFloat::IEEEdouble(), "+0x1000.000p+1" ).convertToDouble()); |
1205 | EXPECT_EQ(-8192.0, APFloat(APFloat::IEEEdouble(), "-0x1000.000p+1" ).convertToDouble()); |
1206 | |
1207 | EXPECT_EQ( 2048.0, APFloat(APFloat::IEEEdouble(), "0x1000.000p-1" ).convertToDouble()); |
1208 | EXPECT_EQ(+2048.0, APFloat(APFloat::IEEEdouble(), "+0x1000.000p-1" ).convertToDouble()); |
1209 | EXPECT_EQ(-2048.0, APFloat(APFloat::IEEEdouble(), "-0x1000.000p-1" ).convertToDouble()); |
1210 | |
1211 | |
1212 | EXPECT_EQ( 8192.0, APFloat(APFloat::IEEEdouble(), "0x1000p1" ).convertToDouble()); |
1213 | EXPECT_EQ(+8192.0, APFloat(APFloat::IEEEdouble(), "+0x1000p1" ).convertToDouble()); |
1214 | EXPECT_EQ(-8192.0, APFloat(APFloat::IEEEdouble(), "-0x1000p1" ).convertToDouble()); |
1215 | |
1216 | EXPECT_EQ( 8192.0, APFloat(APFloat::IEEEdouble(), "0x1000p+1" ).convertToDouble()); |
1217 | EXPECT_EQ(+8192.0, APFloat(APFloat::IEEEdouble(), "+0x1000p+1" ).convertToDouble()); |
1218 | EXPECT_EQ(-8192.0, APFloat(APFloat::IEEEdouble(), "-0x1000p+1" ).convertToDouble()); |
1219 | |
1220 | EXPECT_EQ( 2048.0, APFloat(APFloat::IEEEdouble(), "0x1000p-1" ).convertToDouble()); |
1221 | EXPECT_EQ(+2048.0, APFloat(APFloat::IEEEdouble(), "+0x1000p-1" ).convertToDouble()); |
1222 | EXPECT_EQ(-2048.0, APFloat(APFloat::IEEEdouble(), "-0x1000p-1" ).convertToDouble()); |
1223 | |
1224 | |
1225 | EXPECT_EQ( 16384.0, APFloat(APFloat::IEEEdouble(), "0x10p10" ).convertToDouble()); |
1226 | EXPECT_EQ(+16384.0, APFloat(APFloat::IEEEdouble(), "+0x10p10" ).convertToDouble()); |
1227 | EXPECT_EQ(-16384.0, APFloat(APFloat::IEEEdouble(), "-0x10p10" ).convertToDouble()); |
1228 | |
1229 | EXPECT_EQ( 16384.0, APFloat(APFloat::IEEEdouble(), "0x10p+10" ).convertToDouble()); |
1230 | EXPECT_EQ(+16384.0, APFloat(APFloat::IEEEdouble(), "+0x10p+10" ).convertToDouble()); |
1231 | EXPECT_EQ(-16384.0, APFloat(APFloat::IEEEdouble(), "-0x10p+10" ).convertToDouble()); |
1232 | |
1233 | EXPECT_EQ( 0.015625, APFloat(APFloat::IEEEdouble(), "0x10p-10" ).convertToDouble()); |
1234 | EXPECT_EQ(+0.015625, APFloat(APFloat::IEEEdouble(), "+0x10p-10" ).convertToDouble()); |
1235 | EXPECT_EQ(-0.015625, APFloat(APFloat::IEEEdouble(), "-0x10p-10" ).convertToDouble()); |
1236 | |
1237 | EXPECT_EQ(1.0625, APFloat(APFloat::IEEEdouble(), "0x1.1p0" ).convertToDouble()); |
1238 | EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "0x1p0" ).convertToDouble()); |
1239 | |
1240 | EXPECT_EQ(convertToDoubleFromString("0x1p-150" ), |
1241 | convertToDoubleFromString("+0x800000000000000001.p-221" )); |
1242 | EXPECT_EQ(2251799813685248.5, |
1243 | convertToDoubleFromString("0x80000000000004000000.010p-28" )); |
1244 | } |
1245 | |
1246 | TEST(APFloatTest, toString) { |
1247 | ASSERT_EQ("10" , convertToString(10.0, 6, 3)); |
1248 | ASSERT_EQ("1.0E+1" , convertToString(10.0, 6, 0)); |
1249 | ASSERT_EQ("10100" , convertToString(1.01E+4, 5, 2)); |
1250 | ASSERT_EQ("1.01E+4" , convertToString(1.01E+4, 4, 2)); |
1251 | ASSERT_EQ("1.01E+4" , convertToString(1.01E+4, 5, 1)); |
1252 | ASSERT_EQ("0.0101" , convertToString(1.01E-2, 5, 2)); |
1253 | ASSERT_EQ("0.0101" , convertToString(1.01E-2, 4, 2)); |
1254 | ASSERT_EQ("1.01E-2" , convertToString(1.01E-2, 5, 1)); |
1255 | ASSERT_EQ("0.78539816339744828" , convertToString(0.78539816339744830961, 0, 3)); |
1256 | ASSERT_EQ("4.9406564584124654E-324" , convertToString(4.9406564584124654e-324, 0, 3)); |
1257 | ASSERT_EQ("873.18340000000001" , convertToString(873.1834, 0, 1)); |
1258 | ASSERT_EQ("8.7318340000000001E+2" , convertToString(873.1834, 0, 0)); |
1259 | ASSERT_EQ("1.7976931348623157E+308" , convertToString(1.7976931348623157E+308, 0, 0)); |
1260 | ASSERT_EQ("10" , convertToString(10.0, 6, 3, false)); |
1261 | ASSERT_EQ("1.000000e+01" , convertToString(10.0, 6, 0, false)); |
1262 | ASSERT_EQ("10100" , convertToString(1.01E+4, 5, 2, false)); |
1263 | ASSERT_EQ("1.0100e+04" , convertToString(1.01E+4, 4, 2, false)); |
1264 | ASSERT_EQ("1.01000e+04" , convertToString(1.01E+4, 5, 1, false)); |
1265 | ASSERT_EQ("0.0101" , convertToString(1.01E-2, 5, 2, false)); |
1266 | ASSERT_EQ("0.0101" , convertToString(1.01E-2, 4, 2, false)); |
1267 | ASSERT_EQ("1.01000e-02" , convertToString(1.01E-2, 5, 1, false)); |
1268 | ASSERT_EQ("0.78539816339744828" , |
1269 | convertToString(0.78539816339744830961, 0, 3, false)); |
1270 | ASSERT_EQ("4.94065645841246540e-324" , |
1271 | convertToString(4.9406564584124654e-324, 0, 3, false)); |
1272 | ASSERT_EQ("873.18340000000001" , convertToString(873.1834, 0, 1, false)); |
1273 | ASSERT_EQ("8.73183400000000010e+02" , convertToString(873.1834, 0, 0, false)); |
1274 | ASSERT_EQ("1.79769313486231570e+308" , |
1275 | convertToString(1.7976931348623157E+308, 0, 0, false)); |
1276 | |
1277 | { |
1278 | SmallString<64> Str; |
1279 | APFloat UnnormalZero(APFloat::x87DoubleExtended(), APInt(80, {0, 1})); |
1280 | UnnormalZero.toString(Str); |
1281 | ASSERT_EQ("NaN" , Str); |
1282 | } |
1283 | } |
1284 | |
1285 | TEST(APFloatTest, toInteger) { |
1286 | bool isExact = false; |
1287 | APSInt result(5, /*isUnsigned=*/true); |
1288 | |
1289 | EXPECT_EQ(APFloat::opOK, |
1290 | APFloat(APFloat::IEEEdouble(), "10" ) |
1291 | .convertToInteger(result, APFloat::rmTowardZero, &isExact)); |
1292 | EXPECT_TRUE(isExact); |
1293 | EXPECT_EQ(APSInt(APInt(5, 10), true), result); |
1294 | |
1295 | EXPECT_EQ(APFloat::opInvalidOp, |
1296 | APFloat(APFloat::IEEEdouble(), "-10" ) |
1297 | .convertToInteger(result, APFloat::rmTowardZero, &isExact)); |
1298 | EXPECT_FALSE(isExact); |
1299 | EXPECT_EQ(APSInt::getMinValue(5, true), result); |
1300 | |
1301 | EXPECT_EQ(APFloat::opInvalidOp, |
1302 | APFloat(APFloat::IEEEdouble(), "32" ) |
1303 | .convertToInteger(result, APFloat::rmTowardZero, &isExact)); |
1304 | EXPECT_FALSE(isExact); |
1305 | EXPECT_EQ(APSInt::getMaxValue(5, true), result); |
1306 | |
1307 | EXPECT_EQ(APFloat::opInexact, |
1308 | APFloat(APFloat::IEEEdouble(), "7.9" ) |
1309 | .convertToInteger(result, APFloat::rmTowardZero, &isExact)); |
1310 | EXPECT_FALSE(isExact); |
1311 | EXPECT_EQ(APSInt(APInt(5, 7), true), result); |
1312 | |
1313 | result.setIsUnsigned(false); |
1314 | EXPECT_EQ(APFloat::opOK, |
1315 | APFloat(APFloat::IEEEdouble(), "-10" ) |
1316 | .convertToInteger(result, APFloat::rmTowardZero, &isExact)); |
1317 | EXPECT_TRUE(isExact); |
1318 | EXPECT_EQ(APSInt(APInt(5, -10, true), false), result); |
1319 | |
1320 | EXPECT_EQ(APFloat::opInvalidOp, |
1321 | APFloat(APFloat::IEEEdouble(), "-17" ) |
1322 | .convertToInteger(result, APFloat::rmTowardZero, &isExact)); |
1323 | EXPECT_FALSE(isExact); |
1324 | EXPECT_EQ(APSInt::getMinValue(5, false), result); |
1325 | |
1326 | EXPECT_EQ(APFloat::opInvalidOp, |
1327 | APFloat(APFloat::IEEEdouble(), "16" ) |
1328 | .convertToInteger(result, APFloat::rmTowardZero, &isExact)); |
1329 | EXPECT_FALSE(isExact); |
1330 | EXPECT_EQ(APSInt::getMaxValue(5, false), result); |
1331 | } |
1332 | |
1333 | static APInt nanbitsFromAPInt(const fltSemantics &Sem, bool SNaN, bool Negative, |
1334 | uint64_t payload) { |
1335 | APInt appayload(64, payload); |
1336 | if (SNaN) |
1337 | return APFloat::getSNaN(Sem, Negative, payload: &appayload).bitcastToAPInt(); |
1338 | else |
1339 | return APFloat::getQNaN(Sem, Negative, payload: &appayload).bitcastToAPInt(); |
1340 | } |
1341 | |
1342 | TEST(APFloatTest, makeNaN) { |
1343 | const struct { |
1344 | uint64_t expected; |
1345 | const fltSemantics &semantics; |
1346 | bool SNaN; |
1347 | bool Negative; |
1348 | uint64_t payload; |
1349 | } tests[] = { |
1350 | // clang-format off |
1351 | /* expected semantics SNaN Neg payload */ |
1352 | { .expected: 0x7fc00000ULL, .semantics: APFloat::IEEEsingle(), .SNaN: false, .Negative: false, .payload: 0x00000000ULL }, |
1353 | { .expected: 0xffc00000ULL, .semantics: APFloat::IEEEsingle(), .SNaN: false, .Negative: true, .payload: 0x00000000ULL }, |
1354 | { .expected: 0x7fc0ae72ULL, .semantics: APFloat::IEEEsingle(), .SNaN: false, .Negative: false, .payload: 0x0000ae72ULL }, |
1355 | { .expected: 0x7fffae72ULL, .semantics: APFloat::IEEEsingle(), .SNaN: false, .Negative: false, .payload: 0xffffae72ULL }, |
1356 | { .expected: 0x7fdaae72ULL, .semantics: APFloat::IEEEsingle(), .SNaN: false, .Negative: false, .payload: 0x00daae72ULL }, |
1357 | { .expected: 0x7fa00000ULL, .semantics: APFloat::IEEEsingle(), .SNaN: true, .Negative: false, .payload: 0x00000000ULL }, |
1358 | { .expected: 0xffa00000ULL, .semantics: APFloat::IEEEsingle(), .SNaN: true, .Negative: true, .payload: 0x00000000ULL }, |
1359 | { .expected: 0x7f80ae72ULL, .semantics: APFloat::IEEEsingle(), .SNaN: true, .Negative: false, .payload: 0x0000ae72ULL }, |
1360 | { .expected: 0x7fbfae72ULL, .semantics: APFloat::IEEEsingle(), .SNaN: true, .Negative: false, .payload: 0xffffae72ULL }, |
1361 | { .expected: 0x7f9aae72ULL, .semantics: APFloat::IEEEsingle(), .SNaN: true, .Negative: false, .payload: 0x001aae72ULL }, |
1362 | { .expected: 0x7ff8000000000000ULL, .semantics: APFloat::IEEEdouble(), .SNaN: false, .Negative: false, .payload: 0x0000000000000000ULL }, |
1363 | { .expected: 0xfff8000000000000ULL, .semantics: APFloat::IEEEdouble(), .SNaN: false, .Negative: true, .payload: 0x0000000000000000ULL }, |
1364 | { .expected: 0x7ff800000000ae72ULL, .semantics: APFloat::IEEEdouble(), .SNaN: false, .Negative: false, .payload: 0x000000000000ae72ULL }, |
1365 | { .expected: 0x7fffffffffffae72ULL, .semantics: APFloat::IEEEdouble(), .SNaN: false, .Negative: false, .payload: 0xffffffffffffae72ULL }, |
1366 | { .expected: 0x7ffdaaaaaaaaae72ULL, .semantics: APFloat::IEEEdouble(), .SNaN: false, .Negative: false, .payload: 0x000daaaaaaaaae72ULL }, |
1367 | { .expected: 0x7ff4000000000000ULL, .semantics: APFloat::IEEEdouble(), .SNaN: true, .Negative: false, .payload: 0x0000000000000000ULL }, |
1368 | { .expected: 0xfff4000000000000ULL, .semantics: APFloat::IEEEdouble(), .SNaN: true, .Negative: true, .payload: 0x0000000000000000ULL }, |
1369 | { .expected: 0x7ff000000000ae72ULL, .semantics: APFloat::IEEEdouble(), .SNaN: true, .Negative: false, .payload: 0x000000000000ae72ULL }, |
1370 | { .expected: 0x7ff7ffffffffae72ULL, .semantics: APFloat::IEEEdouble(), .SNaN: true, .Negative: false, .payload: 0xffffffffffffae72ULL }, |
1371 | { .expected: 0x7ff1aaaaaaaaae72ULL, .semantics: APFloat::IEEEdouble(), .SNaN: true, .Negative: false, .payload: 0x0001aaaaaaaaae72ULL }, |
1372 | { .expected: 0x80ULL, .semantics: APFloat::Float8E5M2FNUZ(), .SNaN: false, .Negative: false, .payload: 0xaaULL }, |
1373 | { .expected: 0x80ULL, .semantics: APFloat::Float8E5M2FNUZ(), .SNaN: false, .Negative: true, .payload: 0xaaULL }, |
1374 | { .expected: 0x80ULL, .semantics: APFloat::Float8E5M2FNUZ(), .SNaN: true, .Negative: false, .payload: 0xaaULL }, |
1375 | { .expected: 0x80ULL, .semantics: APFloat::Float8E5M2FNUZ(), .SNaN: true, .Negative: true, .payload: 0xaaULL }, |
1376 | { .expected: 0x80ULL, .semantics: APFloat::Float8E4M3FNUZ(), .SNaN: false, .Negative: false, .payload: 0xaaULL }, |
1377 | { .expected: 0x80ULL, .semantics: APFloat::Float8E4M3FNUZ(), .SNaN: false, .Negative: true, .payload: 0xaaULL }, |
1378 | { .expected: 0x80ULL, .semantics: APFloat::Float8E4M3FNUZ(), .SNaN: true, .Negative: false, .payload: 0xaaULL }, |
1379 | { .expected: 0x80ULL, .semantics: APFloat::Float8E4M3FNUZ(), .SNaN: true, .Negative: true, .payload: 0xaaULL }, |
1380 | { .expected: 0x80ULL, .semantics: APFloat::Float8E4M3B11FNUZ(), .SNaN: false, .Negative: false, .payload: 0xaaULL }, |
1381 | { .expected: 0x80ULL, .semantics: APFloat::Float8E4M3B11FNUZ(), .SNaN: false, .Negative: true, .payload: 0xaaULL }, |
1382 | { .expected: 0x80ULL, .semantics: APFloat::Float8E4M3B11FNUZ(), .SNaN: true, .Negative: false, .payload: 0xaaULL }, |
1383 | { .expected: 0x80ULL, .semantics: APFloat::Float8E4M3B11FNUZ(), .SNaN: true, .Negative: true, .payload: 0xaaULL }, |
1384 | { .expected: 0x3fe00ULL, .semantics: APFloat::FloatTF32(), .SNaN: false, .Negative: false, .payload: 0x00000000ULL }, |
1385 | { .expected: 0x7fe00ULL, .semantics: APFloat::FloatTF32(), .SNaN: false, .Negative: true, .payload: 0x00000000ULL }, |
1386 | { .expected: 0x3feaaULL, .semantics: APFloat::FloatTF32(), .SNaN: false, .Negative: false, .payload: 0xaaULL }, |
1387 | { .expected: 0x3ffaaULL, .semantics: APFloat::FloatTF32(), .SNaN: false, .Negative: false, .payload: 0xdaaULL }, |
1388 | { .expected: 0x3ffaaULL, .semantics: APFloat::FloatTF32(), .SNaN: false, .Negative: false, .payload: 0xfdaaULL }, |
1389 | { .expected: 0x3fd00ULL, .semantics: APFloat::FloatTF32(), .SNaN: true, .Negative: false, .payload: 0x00000000ULL }, |
1390 | { .expected: 0x7fd00ULL, .semantics: APFloat::FloatTF32(), .SNaN: true, .Negative: true, .payload: 0x00000000ULL }, |
1391 | { .expected: 0x3fcaaULL, .semantics: APFloat::FloatTF32(), .SNaN: true, .Negative: false, .payload: 0xaaULL }, |
1392 | { .expected: 0x3fdaaULL, .semantics: APFloat::FloatTF32(), .SNaN: true, .Negative: false, .payload: 0xfaaULL }, |
1393 | { .expected: 0x3fdaaULL, .semantics: APFloat::FloatTF32(), .SNaN: true, .Negative: false, .payload: 0x1aaULL }, |
1394 | // clang-format on |
1395 | }; |
1396 | |
1397 | for (const auto &t : tests) { |
1398 | ASSERT_EQ(t.expected, nanbitsFromAPInt(t.semantics, t.SNaN, t.Negative, t.payload)); |
1399 | } |
1400 | } |
1401 | |
1402 | #ifdef GTEST_HAS_DEATH_TEST |
1403 | #ifndef NDEBUG |
1404 | TEST(APFloatTest, SemanticsDeath) { |
1405 | EXPECT_DEATH(APFloat(APFloat::IEEEquad(), 0).convertToDouble(), |
1406 | "Float semantics is not representable by IEEEdouble" ); |
1407 | EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), 0).convertToFloat(), |
1408 | "Float semantics is not representable by IEEEsingle" ); |
1409 | } |
1410 | #endif |
1411 | #endif |
1412 | |
1413 | TEST(APFloatTest, StringDecimalError) { |
1414 | EXPECT_EQ("Invalid string length" , convertToErrorFromString("" )); |
1415 | EXPECT_EQ("String has no digits" , convertToErrorFromString("+" )); |
1416 | EXPECT_EQ("String has no digits" , convertToErrorFromString("-" )); |
1417 | |
1418 | EXPECT_EQ("Invalid character in significand" , convertToErrorFromString(StringRef("\0" , 1))); |
1419 | EXPECT_EQ("Invalid character in significand" , convertToErrorFromString(StringRef("1\0" , 2))); |
1420 | EXPECT_EQ("Invalid character in significand" , convertToErrorFromString(StringRef("1" "\0" "2" , 3))); |
1421 | EXPECT_EQ("Invalid character in significand" , convertToErrorFromString(StringRef("1" "\0" "2e1" , 5))); |
1422 | EXPECT_EQ("Invalid character in exponent" , convertToErrorFromString(StringRef("1e\0" , 3))); |
1423 | EXPECT_EQ("Invalid character in exponent" , convertToErrorFromString(StringRef("1e1\0" , 4))); |
1424 | EXPECT_EQ("Invalid character in exponent" , convertToErrorFromString(StringRef("1e1" "\0" "2" , 5))); |
1425 | |
1426 | EXPECT_EQ("Invalid character in significand" , convertToErrorFromString("1.0f" )); |
1427 | |
1428 | EXPECT_EQ("String contains multiple dots" , convertToErrorFromString(".." )); |
1429 | EXPECT_EQ("String contains multiple dots" , convertToErrorFromString("..0" )); |
1430 | EXPECT_EQ("String contains multiple dots" , convertToErrorFromString("1.0.0" )); |
1431 | } |
1432 | |
1433 | TEST(APFloatTest, StringDecimalSignificandError) { |
1434 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString( "." )); |
1435 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString("+." )); |
1436 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString("-." )); |
1437 | |
1438 | |
1439 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString( "e" )); |
1440 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString("+e" )); |
1441 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString("-e" )); |
1442 | |
1443 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString( "e1" )); |
1444 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString("+e1" )); |
1445 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString("-e1" )); |
1446 | |
1447 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString( ".e1" )); |
1448 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString("+.e1" )); |
1449 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString("-.e1" )); |
1450 | |
1451 | |
1452 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString( ".e" )); |
1453 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString("+.e" )); |
1454 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString("-.e" )); |
1455 | } |
1456 | |
1457 | TEST(APFloatTest, StringHexadecimalError) { |
1458 | EXPECT_EQ("Invalid string" , convertToErrorFromString( "0x" )); |
1459 | EXPECT_EQ("Invalid string" , convertToErrorFromString("+0x" )); |
1460 | EXPECT_EQ("Invalid string" , convertToErrorFromString("-0x" )); |
1461 | |
1462 | EXPECT_EQ("Hex strings require an exponent" , convertToErrorFromString( "0x0" )); |
1463 | EXPECT_EQ("Hex strings require an exponent" , convertToErrorFromString("+0x0" )); |
1464 | EXPECT_EQ("Hex strings require an exponent" , convertToErrorFromString("-0x0" )); |
1465 | |
1466 | EXPECT_EQ("Hex strings require an exponent" , convertToErrorFromString( "0x0." )); |
1467 | EXPECT_EQ("Hex strings require an exponent" , convertToErrorFromString("+0x0." )); |
1468 | EXPECT_EQ("Hex strings require an exponent" , convertToErrorFromString("-0x0." )); |
1469 | |
1470 | EXPECT_EQ("Hex strings require an exponent" , convertToErrorFromString( "0x.0" )); |
1471 | EXPECT_EQ("Hex strings require an exponent" , convertToErrorFromString("+0x.0" )); |
1472 | EXPECT_EQ("Hex strings require an exponent" , convertToErrorFromString("-0x.0" )); |
1473 | |
1474 | EXPECT_EQ("Hex strings require an exponent" , convertToErrorFromString( "0x0.0" )); |
1475 | EXPECT_EQ("Hex strings require an exponent" , convertToErrorFromString("+0x0.0" )); |
1476 | EXPECT_EQ("Hex strings require an exponent" , convertToErrorFromString("-0x0.0" )); |
1477 | |
1478 | EXPECT_EQ("Invalid character in significand" , convertToErrorFromString(StringRef("0x\0" , 3))); |
1479 | EXPECT_EQ("Invalid character in significand" , convertToErrorFromString(StringRef("0x1\0" , 4))); |
1480 | EXPECT_EQ("Invalid character in significand" , convertToErrorFromString(StringRef("0x1" "\0" "2" , 5))); |
1481 | EXPECT_EQ("Invalid character in significand" , convertToErrorFromString(StringRef("0x1" "\0" "2p1" , 7))); |
1482 | EXPECT_EQ("Invalid character in exponent" , convertToErrorFromString(StringRef("0x1p\0" , 5))); |
1483 | EXPECT_EQ("Invalid character in exponent" , convertToErrorFromString(StringRef("0x1p1\0" , 6))); |
1484 | EXPECT_EQ("Invalid character in exponent" , convertToErrorFromString(StringRef("0x1p1" "\0" "2" , 7))); |
1485 | |
1486 | EXPECT_EQ("Invalid character in exponent" , convertToErrorFromString("0x1p0f" )); |
1487 | |
1488 | EXPECT_EQ("String contains multiple dots" , convertToErrorFromString("0x..p1" )); |
1489 | EXPECT_EQ("String contains multiple dots" , convertToErrorFromString("0x..0p1" )); |
1490 | EXPECT_EQ("String contains multiple dots" , convertToErrorFromString("0x1.0.0p1" )); |
1491 | } |
1492 | |
1493 | TEST(APFloatTest, StringHexadecimalSignificandError) { |
1494 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString( "0x." )); |
1495 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString("+0x." )); |
1496 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString("-0x." )); |
1497 | |
1498 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString( "0xp" )); |
1499 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString("+0xp" )); |
1500 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString("-0xp" )); |
1501 | |
1502 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString( "0xp+" )); |
1503 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString("+0xp+" )); |
1504 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString("-0xp+" )); |
1505 | |
1506 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString( "0xp-" )); |
1507 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString("+0xp-" )); |
1508 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString("-0xp-" )); |
1509 | |
1510 | |
1511 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString( "0x.p" )); |
1512 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString("+0x.p" )); |
1513 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString("-0x.p" )); |
1514 | |
1515 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString( "0x.p+" )); |
1516 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString("+0x.p+" )); |
1517 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString("-0x.p+" )); |
1518 | |
1519 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString( "0x.p-" )); |
1520 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString("+0x.p-" )); |
1521 | EXPECT_EQ("Significand has no digits" , convertToErrorFromString("-0x.p-" )); |
1522 | } |
1523 | |
1524 | TEST(APFloatTest, StringHexadecimalExponentError) { |
1525 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString( "0x1p" )); |
1526 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString("+0x1p" )); |
1527 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString("-0x1p" )); |
1528 | |
1529 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString( "0x1p+" )); |
1530 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString("+0x1p+" )); |
1531 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString("-0x1p+" )); |
1532 | |
1533 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString( "0x1p-" )); |
1534 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString("+0x1p-" )); |
1535 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString("-0x1p-" )); |
1536 | |
1537 | |
1538 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString( "0x1.p" )); |
1539 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString("+0x1.p" )); |
1540 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString("-0x1.p" )); |
1541 | |
1542 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString( "0x1.p+" )); |
1543 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString("+0x1.p+" )); |
1544 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString("-0x1.p+" )); |
1545 | |
1546 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString( "0x1.p-" )); |
1547 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString("+0x1.p-" )); |
1548 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString("-0x1.p-" )); |
1549 | |
1550 | |
1551 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString( "0x.1p" )); |
1552 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString("+0x.1p" )); |
1553 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString("-0x.1p" )); |
1554 | |
1555 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString( "0x.1p+" )); |
1556 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString("+0x.1p+" )); |
1557 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString("-0x.1p+" )); |
1558 | |
1559 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString( "0x.1p-" )); |
1560 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString("+0x.1p-" )); |
1561 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString("-0x.1p-" )); |
1562 | |
1563 | |
1564 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString( "0x1.1p" )); |
1565 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString("+0x1.1p" )); |
1566 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString("-0x1.1p" )); |
1567 | |
1568 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString( "0x1.1p+" )); |
1569 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString("+0x1.1p+" )); |
1570 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString("-0x1.1p+" )); |
1571 | |
1572 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString( "0x1.1p-" )); |
1573 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString("+0x1.1p-" )); |
1574 | EXPECT_EQ("Exponent has no digits" , convertToErrorFromString("-0x1.1p-" )); |
1575 | } |
1576 | |
1577 | TEST(APFloatTest, exactInverse) { |
1578 | APFloat inv(0.0f); |
1579 | |
1580 | // Trivial operation. |
1581 | EXPECT_TRUE(APFloat(2.0).getExactInverse(&inv)); |
1582 | EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(0.5))); |
1583 | EXPECT_TRUE(APFloat(2.0f).getExactInverse(&inv)); |
1584 | EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(0.5f))); |
1585 | EXPECT_TRUE(APFloat(APFloat::IEEEquad(), "2.0" ).getExactInverse(&inv)); |
1586 | EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(APFloat::IEEEquad(), "0.5" ))); |
1587 | EXPECT_TRUE(APFloat(APFloat::PPCDoubleDouble(), "2.0" ).getExactInverse(&inv)); |
1588 | EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(APFloat::PPCDoubleDouble(), "0.5" ))); |
1589 | EXPECT_TRUE(APFloat(APFloat::x87DoubleExtended(), "2.0" ).getExactInverse(&inv)); |
1590 | EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(APFloat::x87DoubleExtended(), "0.5" ))); |
1591 | |
1592 | // FLT_MIN |
1593 | EXPECT_TRUE(APFloat(1.17549435e-38f).getExactInverse(&inv)); |
1594 | EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(8.5070592e+37f))); |
1595 | |
1596 | // Large float, inverse is a denormal. |
1597 | EXPECT_FALSE(APFloat(1.7014118e38f).getExactInverse(nullptr)); |
1598 | // Zero |
1599 | EXPECT_FALSE(APFloat(0.0).getExactInverse(nullptr)); |
1600 | // Denormalized float |
1601 | EXPECT_FALSE(APFloat(1.40129846e-45f).getExactInverse(nullptr)); |
1602 | } |
1603 | |
1604 | TEST(APFloatTest, roundToIntegral) { |
1605 | APFloat T(-0.5), S(3.14), R(APFloat::getLargest(Sem: APFloat::IEEEdouble())), P(0.0); |
1606 | |
1607 | P = T; |
1608 | P.roundToIntegral(RM: APFloat::rmTowardZero); |
1609 | EXPECT_EQ(-0.0, P.convertToDouble()); |
1610 | P = T; |
1611 | P.roundToIntegral(RM: APFloat::rmTowardNegative); |
1612 | EXPECT_EQ(-1.0, P.convertToDouble()); |
1613 | P = T; |
1614 | P.roundToIntegral(RM: APFloat::rmTowardPositive); |
1615 | EXPECT_EQ(-0.0, P.convertToDouble()); |
1616 | P = T; |
1617 | P.roundToIntegral(RM: APFloat::rmNearestTiesToEven); |
1618 | EXPECT_EQ(-0.0, P.convertToDouble()); |
1619 | |
1620 | P = S; |
1621 | P.roundToIntegral(RM: APFloat::rmTowardZero); |
1622 | EXPECT_EQ(3.0, P.convertToDouble()); |
1623 | P = S; |
1624 | P.roundToIntegral(RM: APFloat::rmTowardNegative); |
1625 | EXPECT_EQ(3.0, P.convertToDouble()); |
1626 | P = S; |
1627 | P.roundToIntegral(RM: APFloat::rmTowardPositive); |
1628 | EXPECT_EQ(4.0, P.convertToDouble()); |
1629 | P = S; |
1630 | P.roundToIntegral(RM: APFloat::rmNearestTiesToEven); |
1631 | EXPECT_EQ(3.0, P.convertToDouble()); |
1632 | |
1633 | P = R; |
1634 | P.roundToIntegral(RM: APFloat::rmTowardZero); |
1635 | EXPECT_EQ(R.convertToDouble(), P.convertToDouble()); |
1636 | P = R; |
1637 | P.roundToIntegral(RM: APFloat::rmTowardNegative); |
1638 | EXPECT_EQ(R.convertToDouble(), P.convertToDouble()); |
1639 | P = R; |
1640 | P.roundToIntegral(RM: APFloat::rmTowardPositive); |
1641 | EXPECT_EQ(R.convertToDouble(), P.convertToDouble()); |
1642 | P = R; |
1643 | P.roundToIntegral(RM: APFloat::rmNearestTiesToEven); |
1644 | EXPECT_EQ(R.convertToDouble(), P.convertToDouble()); |
1645 | |
1646 | P = APFloat::getZero(Sem: APFloat::IEEEdouble()); |
1647 | P.roundToIntegral(RM: APFloat::rmTowardZero); |
1648 | EXPECT_EQ(0.0, P.convertToDouble()); |
1649 | P = APFloat::getZero(Sem: APFloat::IEEEdouble(), Negative: true); |
1650 | P.roundToIntegral(RM: APFloat::rmTowardZero); |
1651 | EXPECT_EQ(-0.0, P.convertToDouble()); |
1652 | P = APFloat::getNaN(Sem: APFloat::IEEEdouble()); |
1653 | P.roundToIntegral(RM: APFloat::rmTowardZero); |
1654 | EXPECT_TRUE(std::isnan(P.convertToDouble())); |
1655 | P = APFloat::getInf(Sem: APFloat::IEEEdouble()); |
1656 | P.roundToIntegral(RM: APFloat::rmTowardZero); |
1657 | EXPECT_TRUE(std::isinf(P.convertToDouble()) && P.convertToDouble() > 0.0); |
1658 | P = APFloat::getInf(Sem: APFloat::IEEEdouble(), Negative: true); |
1659 | P.roundToIntegral(RM: APFloat::rmTowardZero); |
1660 | EXPECT_TRUE(std::isinf(P.convertToDouble()) && P.convertToDouble() < 0.0); |
1661 | |
1662 | APFloat::opStatus St; |
1663 | |
1664 | P = APFloat::getNaN(Sem: APFloat::IEEEdouble()); |
1665 | St = P.roundToIntegral(RM: APFloat::rmTowardZero); |
1666 | EXPECT_TRUE(P.isNaN()); |
1667 | EXPECT_FALSE(P.isNegative()); |
1668 | EXPECT_EQ(APFloat::opOK, St); |
1669 | |
1670 | P = APFloat::getNaN(Sem: APFloat::IEEEdouble(), Negative: true); |
1671 | St = P.roundToIntegral(RM: APFloat::rmTowardZero); |
1672 | EXPECT_TRUE(P.isNaN()); |
1673 | EXPECT_TRUE(P.isNegative()); |
1674 | EXPECT_EQ(APFloat::opOK, St); |
1675 | |
1676 | P = APFloat::getSNaN(Sem: APFloat::IEEEdouble()); |
1677 | St = P.roundToIntegral(RM: APFloat::rmTowardZero); |
1678 | EXPECT_TRUE(P.isNaN()); |
1679 | EXPECT_FALSE(P.isSignaling()); |
1680 | EXPECT_FALSE(P.isNegative()); |
1681 | EXPECT_EQ(APFloat::opInvalidOp, St); |
1682 | |
1683 | P = APFloat::getSNaN(Sem: APFloat::IEEEdouble(), Negative: true); |
1684 | St = P.roundToIntegral(RM: APFloat::rmTowardZero); |
1685 | EXPECT_TRUE(P.isNaN()); |
1686 | EXPECT_FALSE(P.isSignaling()); |
1687 | EXPECT_TRUE(P.isNegative()); |
1688 | EXPECT_EQ(APFloat::opInvalidOp, St); |
1689 | |
1690 | P = APFloat::getInf(Sem: APFloat::IEEEdouble()); |
1691 | St = P.roundToIntegral(RM: APFloat::rmTowardZero); |
1692 | EXPECT_TRUE(P.isInfinity()); |
1693 | EXPECT_FALSE(P.isNegative()); |
1694 | EXPECT_EQ(APFloat::opOK, St); |
1695 | |
1696 | P = APFloat::getInf(Sem: APFloat::IEEEdouble(), Negative: true); |
1697 | St = P.roundToIntegral(RM: APFloat::rmTowardZero); |
1698 | EXPECT_TRUE(P.isInfinity()); |
1699 | EXPECT_TRUE(P.isNegative()); |
1700 | EXPECT_EQ(APFloat::opOK, St); |
1701 | |
1702 | P = APFloat::getZero(Sem: APFloat::IEEEdouble(), Negative: false); |
1703 | St = P.roundToIntegral(RM: APFloat::rmTowardZero); |
1704 | EXPECT_TRUE(P.isZero()); |
1705 | EXPECT_FALSE(P.isNegative()); |
1706 | EXPECT_EQ(APFloat::opOK, St); |
1707 | |
1708 | P = APFloat::getZero(Sem: APFloat::IEEEdouble(), Negative: false); |
1709 | St = P.roundToIntegral(RM: APFloat::rmTowardNegative); |
1710 | EXPECT_TRUE(P.isZero()); |
1711 | EXPECT_FALSE(P.isNegative()); |
1712 | EXPECT_EQ(APFloat::opOK, St); |
1713 | |
1714 | P = APFloat::getZero(Sem: APFloat::IEEEdouble(), Negative: true); |
1715 | St = P.roundToIntegral(RM: APFloat::rmTowardZero); |
1716 | EXPECT_TRUE(P.isZero()); |
1717 | EXPECT_TRUE(P.isNegative()); |
1718 | EXPECT_EQ(APFloat::opOK, St); |
1719 | |
1720 | P = APFloat::getZero(Sem: APFloat::IEEEdouble(), Negative: true); |
1721 | St = P.roundToIntegral(RM: APFloat::rmTowardNegative); |
1722 | EXPECT_TRUE(P.isZero()); |
1723 | EXPECT_TRUE(P.isNegative()); |
1724 | EXPECT_EQ(APFloat::opOK, St); |
1725 | |
1726 | P = APFloat(1E-100); |
1727 | St = P.roundToIntegral(RM: APFloat::rmTowardNegative); |
1728 | EXPECT_TRUE(P.isZero()); |
1729 | EXPECT_FALSE(P.isNegative()); |
1730 | EXPECT_EQ(APFloat::opInexact, St); |
1731 | |
1732 | P = APFloat(1E-100); |
1733 | St = P.roundToIntegral(RM: APFloat::rmTowardPositive); |
1734 | EXPECT_EQ(1.0, P.convertToDouble()); |
1735 | EXPECT_FALSE(P.isNegative()); |
1736 | EXPECT_EQ(APFloat::opInexact, St); |
1737 | |
1738 | P = APFloat(-1E-100); |
1739 | St = P.roundToIntegral(RM: APFloat::rmTowardNegative); |
1740 | EXPECT_TRUE(P.isNegative()); |
1741 | EXPECT_EQ(-1.0, P.convertToDouble()); |
1742 | EXPECT_EQ(APFloat::opInexact, St); |
1743 | |
1744 | P = APFloat(-1E-100); |
1745 | St = P.roundToIntegral(RM: APFloat::rmTowardPositive); |
1746 | EXPECT_TRUE(P.isZero()); |
1747 | EXPECT_TRUE(P.isNegative()); |
1748 | EXPECT_EQ(APFloat::opInexact, St); |
1749 | |
1750 | P = APFloat(10.0); |
1751 | St = P.roundToIntegral(RM: APFloat::rmTowardZero); |
1752 | EXPECT_EQ(10.0, P.convertToDouble()); |
1753 | EXPECT_EQ(APFloat::opOK, St); |
1754 | |
1755 | P = APFloat(10.5); |
1756 | St = P.roundToIntegral(RM: APFloat::rmTowardZero); |
1757 | EXPECT_EQ(10.0, P.convertToDouble()); |
1758 | EXPECT_EQ(APFloat::opInexact, St); |
1759 | |
1760 | P = APFloat(10.5); |
1761 | St = P.roundToIntegral(RM: APFloat::rmTowardPositive); |
1762 | EXPECT_EQ(11.0, P.convertToDouble()); |
1763 | EXPECT_EQ(APFloat::opInexact, St); |
1764 | |
1765 | P = APFloat(10.5); |
1766 | St = P.roundToIntegral(RM: APFloat::rmTowardNegative); |
1767 | EXPECT_EQ(10.0, P.convertToDouble()); |
1768 | EXPECT_EQ(APFloat::opInexact, St); |
1769 | |
1770 | P = APFloat(10.5); |
1771 | St = P.roundToIntegral(RM: APFloat::rmNearestTiesToAway); |
1772 | EXPECT_EQ(11.0, P.convertToDouble()); |
1773 | EXPECT_EQ(APFloat::opInexact, St); |
1774 | |
1775 | P = APFloat(10.5); |
1776 | St = P.roundToIntegral(RM: APFloat::rmNearestTiesToEven); |
1777 | EXPECT_EQ(10.0, P.convertToDouble()); |
1778 | EXPECT_EQ(APFloat::opInexact, St); |
1779 | } |
1780 | |
1781 | TEST(APFloatTest, isInteger) { |
1782 | APFloat T(-0.0); |
1783 | EXPECT_TRUE(T.isInteger()); |
1784 | T = APFloat(3.14159); |
1785 | EXPECT_FALSE(T.isInteger()); |
1786 | T = APFloat::getNaN(Sem: APFloat::IEEEdouble()); |
1787 | EXPECT_FALSE(T.isInteger()); |
1788 | T = APFloat::getInf(Sem: APFloat::IEEEdouble()); |
1789 | EXPECT_FALSE(T.isInteger()); |
1790 | T = APFloat::getInf(Sem: APFloat::IEEEdouble(), Negative: true); |
1791 | EXPECT_FALSE(T.isInteger()); |
1792 | T = APFloat::getLargest(Sem: APFloat::IEEEdouble()); |
1793 | EXPECT_TRUE(T.isInteger()); |
1794 | } |
1795 | |
1796 | TEST(DoubleAPFloatTest, isInteger) { |
1797 | APFloat F1(-0.0); |
1798 | APFloat F2(-0.0); |
1799 | llvm::detail::DoubleAPFloat T(APFloat::PPCDoubleDouble(), std::move(F1), |
1800 | std::move(F2)); |
1801 | EXPECT_TRUE(T.isInteger()); |
1802 | APFloat F3(3.14159); |
1803 | APFloat F4(-0.0); |
1804 | llvm::detail::DoubleAPFloat T2(APFloat::PPCDoubleDouble(), std::move(F3), |
1805 | std::move(F4)); |
1806 | EXPECT_FALSE(T2.isInteger()); |
1807 | APFloat F5(-0.0); |
1808 | APFloat F6(3.14159); |
1809 | llvm::detail::DoubleAPFloat T3(APFloat::PPCDoubleDouble(), std::move(F5), |
1810 | std::move(F6)); |
1811 | EXPECT_FALSE(T3.isInteger()); |
1812 | } |
1813 | |
1814 | TEST(APFloatTest, getLargest) { |
1815 | EXPECT_EQ(3.402823466e+38f, APFloat::getLargest(APFloat::IEEEsingle()).convertToFloat()); |
1816 | EXPECT_EQ(1.7976931348623158e+308, APFloat::getLargest(APFloat::IEEEdouble()).convertToDouble()); |
1817 | EXPECT_EQ(448, APFloat::getLargest(APFloat::Float8E4M3FN()).convertToDouble()); |
1818 | EXPECT_EQ(240, |
1819 | APFloat::getLargest(APFloat::Float8E4M3FNUZ()).convertToDouble()); |
1820 | EXPECT_EQ(57344, |
1821 | APFloat::getLargest(APFloat::Float8E5M2FNUZ()).convertToDouble()); |
1822 | EXPECT_EQ( |
1823 | 30, APFloat::getLargest(APFloat::Float8E4M3B11FNUZ()).convertToDouble()); |
1824 | EXPECT_EQ(3.40116213421e+38f, |
1825 | APFloat::getLargest(APFloat::FloatTF32()).convertToFloat()); |
1826 | } |
1827 | |
1828 | TEST(APFloatTest, getSmallest) { |
1829 | APFloat test = APFloat::getSmallest(Sem: APFloat::IEEEsingle(), Negative: false); |
1830 | APFloat expected = APFloat(APFloat::IEEEsingle(), "0x0.000002p-126" ); |
1831 | EXPECT_FALSE(test.isNegative()); |
1832 | EXPECT_TRUE(test.isFiniteNonZero()); |
1833 | EXPECT_TRUE(test.isDenormal()); |
1834 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
1835 | |
1836 | test = APFloat::getSmallest(Sem: APFloat::IEEEsingle(), Negative: true); |
1837 | expected = APFloat(APFloat::IEEEsingle(), "-0x0.000002p-126" ); |
1838 | EXPECT_TRUE(test.isNegative()); |
1839 | EXPECT_TRUE(test.isFiniteNonZero()); |
1840 | EXPECT_TRUE(test.isDenormal()); |
1841 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
1842 | |
1843 | test = APFloat::getSmallest(Sem: APFloat::IEEEquad(), Negative: false); |
1844 | expected = APFloat(APFloat::IEEEquad(), "0x0.0000000000000000000000000001p-16382" ); |
1845 | EXPECT_FALSE(test.isNegative()); |
1846 | EXPECT_TRUE(test.isFiniteNonZero()); |
1847 | EXPECT_TRUE(test.isDenormal()); |
1848 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
1849 | |
1850 | test = APFloat::getSmallest(Sem: APFloat::IEEEquad(), Negative: true); |
1851 | expected = APFloat(APFloat::IEEEquad(), "-0x0.0000000000000000000000000001p-16382" ); |
1852 | EXPECT_TRUE(test.isNegative()); |
1853 | EXPECT_TRUE(test.isFiniteNonZero()); |
1854 | EXPECT_TRUE(test.isDenormal()); |
1855 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
1856 | |
1857 | test = APFloat::getSmallest(Sem: APFloat::Float8E5M2FNUZ(), Negative: false); |
1858 | expected = APFloat(APFloat::Float8E5M2FNUZ(), "0x0.4p-15" ); |
1859 | EXPECT_FALSE(test.isNegative()); |
1860 | EXPECT_TRUE(test.isFiniteNonZero()); |
1861 | EXPECT_TRUE(test.isDenormal()); |
1862 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
1863 | |
1864 | test = APFloat::getSmallest(Sem: APFloat::Float8E4M3FNUZ(), Negative: false); |
1865 | expected = APFloat(APFloat::Float8E4M3FNUZ(), "0x0.2p-7" ); |
1866 | EXPECT_FALSE(test.isNegative()); |
1867 | EXPECT_TRUE(test.isFiniteNonZero()); |
1868 | EXPECT_TRUE(test.isDenormal()); |
1869 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
1870 | |
1871 | test = APFloat::getSmallest(Sem: APFloat::Float8E4M3B11FNUZ(), Negative: false); |
1872 | expected = APFloat(APFloat::Float8E4M3B11FNUZ(), "0x0.2p-10" ); |
1873 | EXPECT_FALSE(test.isNegative()); |
1874 | EXPECT_TRUE(test.isFiniteNonZero()); |
1875 | EXPECT_TRUE(test.isDenormal()); |
1876 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
1877 | |
1878 | test = APFloat::getSmallest(Sem: APFloat::FloatTF32(), Negative: true); |
1879 | expected = APFloat(APFloat::FloatTF32(), "-0x0.004p-126" ); |
1880 | EXPECT_TRUE(test.isNegative()); |
1881 | EXPECT_TRUE(test.isFiniteNonZero()); |
1882 | EXPECT_TRUE(test.isDenormal()); |
1883 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
1884 | } |
1885 | |
1886 | TEST(APFloatTest, getSmallestNormalized) { |
1887 | APFloat test = APFloat::getSmallestNormalized(Sem: APFloat::IEEEsingle(), Negative: false); |
1888 | APFloat expected = APFloat(APFloat::IEEEsingle(), "0x1p-126" ); |
1889 | EXPECT_FALSE(test.isNegative()); |
1890 | EXPECT_TRUE(test.isFiniteNonZero()); |
1891 | EXPECT_FALSE(test.isDenormal()); |
1892 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
1893 | EXPECT_TRUE(test.isSmallestNormalized()); |
1894 | |
1895 | test = APFloat::getSmallestNormalized(Sem: APFloat::IEEEsingle(), Negative: true); |
1896 | expected = APFloat(APFloat::IEEEsingle(), "-0x1p-126" ); |
1897 | EXPECT_TRUE(test.isNegative()); |
1898 | EXPECT_TRUE(test.isFiniteNonZero()); |
1899 | EXPECT_FALSE(test.isDenormal()); |
1900 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
1901 | EXPECT_TRUE(test.isSmallestNormalized()); |
1902 | |
1903 | test = APFloat::getSmallestNormalized(Sem: APFloat::IEEEdouble(), Negative: false); |
1904 | expected = APFloat(APFloat::IEEEdouble(), "0x1p-1022" ); |
1905 | EXPECT_FALSE(test.isNegative()); |
1906 | EXPECT_TRUE(test.isFiniteNonZero()); |
1907 | EXPECT_FALSE(test.isDenormal()); |
1908 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
1909 | EXPECT_TRUE(test.isSmallestNormalized()); |
1910 | |
1911 | test = APFloat::getSmallestNormalized(Sem: APFloat::IEEEdouble(), Negative: true); |
1912 | expected = APFloat(APFloat::IEEEdouble(), "-0x1p-1022" ); |
1913 | EXPECT_TRUE(test.isNegative()); |
1914 | EXPECT_TRUE(test.isFiniteNonZero()); |
1915 | EXPECT_FALSE(test.isDenormal()); |
1916 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
1917 | EXPECT_TRUE(test.isSmallestNormalized()); |
1918 | |
1919 | test = APFloat::getSmallestNormalized(Sem: APFloat::IEEEquad(), Negative: false); |
1920 | expected = APFloat(APFloat::IEEEquad(), "0x1p-16382" ); |
1921 | EXPECT_FALSE(test.isNegative()); |
1922 | EXPECT_TRUE(test.isFiniteNonZero()); |
1923 | EXPECT_FALSE(test.isDenormal()); |
1924 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
1925 | EXPECT_TRUE(test.isSmallestNormalized()); |
1926 | |
1927 | test = APFloat::getSmallestNormalized(Sem: APFloat::IEEEquad(), Negative: true); |
1928 | expected = APFloat(APFloat::IEEEquad(), "-0x1p-16382" ); |
1929 | EXPECT_TRUE(test.isNegative()); |
1930 | EXPECT_TRUE(test.isFiniteNonZero()); |
1931 | EXPECT_FALSE(test.isDenormal()); |
1932 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
1933 | EXPECT_TRUE(test.isSmallestNormalized()); |
1934 | |
1935 | test = APFloat::getSmallestNormalized(Sem: APFloat::Float8E5M2FNUZ(), Negative: false); |
1936 | expected = APFloat(APFloat::Float8E5M2FNUZ(), "0x1.0p-15" ); |
1937 | EXPECT_FALSE(test.isNegative()); |
1938 | EXPECT_TRUE(test.isFiniteNonZero()); |
1939 | EXPECT_FALSE(test.isDenormal()); |
1940 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
1941 | EXPECT_TRUE(test.isSmallestNormalized()); |
1942 | |
1943 | test = APFloat::getSmallestNormalized(Sem: APFloat::Float8E4M3FNUZ(), Negative: false); |
1944 | expected = APFloat(APFloat::Float8E4M3FNUZ(), "0x1.0p-7" ); |
1945 | EXPECT_FALSE(test.isNegative()); |
1946 | EXPECT_TRUE(test.isFiniteNonZero()); |
1947 | EXPECT_FALSE(test.isDenormal()); |
1948 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
1949 | EXPECT_TRUE(test.isSmallestNormalized()); |
1950 | |
1951 | test = APFloat::getSmallestNormalized(Sem: APFloat::Float8E4M3B11FNUZ(), Negative: false); |
1952 | expected = APFloat(APFloat::Float8E4M3B11FNUZ(), "0x1.0p-10" ); |
1953 | EXPECT_FALSE(test.isNegative()); |
1954 | EXPECT_TRUE(test.isFiniteNonZero()); |
1955 | EXPECT_FALSE(test.isDenormal()); |
1956 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
1957 | EXPECT_TRUE(test.isSmallestNormalized()); |
1958 | |
1959 | test = APFloat::getSmallestNormalized(Sem: APFloat::FloatTF32(), Negative: false); |
1960 | expected = APFloat(APFloat::FloatTF32(), "0x1p-126" ); |
1961 | EXPECT_FALSE(test.isNegative()); |
1962 | EXPECT_TRUE(test.isFiniteNonZero()); |
1963 | EXPECT_FALSE(test.isDenormal()); |
1964 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
1965 | EXPECT_TRUE(test.isSmallestNormalized()); |
1966 | } |
1967 | |
1968 | TEST(APFloatTest, getZero) { |
1969 | struct { |
1970 | const fltSemantics *semantics; |
1971 | const bool sign; |
1972 | const bool signedZero; |
1973 | const unsigned long long bitPattern[2]; |
1974 | const unsigned bitPatternLength; |
1975 | } const GetZeroTest[] = { |
1976 | {.semantics: &APFloat::IEEEhalf(), .sign: false, .signedZero: true, .bitPattern: {0, 0}, .bitPatternLength: 1}, |
1977 | {.semantics: &APFloat::IEEEhalf(), .sign: true, .signedZero: true, .bitPattern: {0x8000ULL, 0}, .bitPatternLength: 1}, |
1978 | {.semantics: &APFloat::IEEEsingle(), .sign: false, .signedZero: true, .bitPattern: {0, 0}, .bitPatternLength: 1}, |
1979 | {.semantics: &APFloat::IEEEsingle(), .sign: true, .signedZero: true, .bitPattern: {0x80000000ULL, 0}, .bitPatternLength: 1}, |
1980 | {.semantics: &APFloat::IEEEdouble(), .sign: false, .signedZero: true, .bitPattern: {0, 0}, .bitPatternLength: 1}, |
1981 | {.semantics: &APFloat::IEEEdouble(), .sign: true, .signedZero: true, .bitPattern: {0x8000000000000000ULL, 0}, .bitPatternLength: 1}, |
1982 | {.semantics: &APFloat::IEEEquad(), .sign: false, .signedZero: true, .bitPattern: {0, 0}, .bitPatternLength: 2}, |
1983 | {.semantics: &APFloat::IEEEquad(), .sign: true, .signedZero: true, .bitPattern: {0, 0x8000000000000000ULL}, .bitPatternLength: 2}, |
1984 | {.semantics: &APFloat::PPCDoubleDouble(), .sign: false, .signedZero: true, .bitPattern: {0, 0}, .bitPatternLength: 2}, |
1985 | {.semantics: &APFloat::PPCDoubleDouble(), .sign: true, .signedZero: true, .bitPattern: {0x8000000000000000ULL, 0}, .bitPatternLength: 2}, |
1986 | {.semantics: &APFloat::x87DoubleExtended(), .sign: false, .signedZero: true, .bitPattern: {0, 0}, .bitPatternLength: 2}, |
1987 | {.semantics: &APFloat::x87DoubleExtended(), .sign: true, .signedZero: true, .bitPattern: {0, 0x8000ULL}, .bitPatternLength: 2}, |
1988 | {.semantics: &APFloat::Float8E5M2(), .sign: false, .signedZero: true, .bitPattern: {0, 0}, .bitPatternLength: 1}, |
1989 | {.semantics: &APFloat::Float8E5M2(), .sign: true, .signedZero: true, .bitPattern: {0x80ULL, 0}, .bitPatternLength: 1}, |
1990 | {.semantics: &APFloat::Float8E5M2FNUZ(), .sign: false, .signedZero: false, .bitPattern: {0, 0}, .bitPatternLength: 1}, |
1991 | {.semantics: &APFloat::Float8E5M2FNUZ(), .sign: true, .signedZero: false, .bitPattern: {0, 0}, .bitPatternLength: 1}, |
1992 | {.semantics: &APFloat::Float8E4M3FN(), .sign: false, .signedZero: true, .bitPattern: {0, 0}, .bitPatternLength: 1}, |
1993 | {.semantics: &APFloat::Float8E4M3FN(), .sign: true, .signedZero: true, .bitPattern: {0x80ULL, 0}, .bitPatternLength: 1}, |
1994 | {.semantics: &APFloat::Float8E4M3FNUZ(), .sign: false, .signedZero: false, .bitPattern: {0, 0}, .bitPatternLength: 1}, |
1995 | {.semantics: &APFloat::Float8E4M3FNUZ(), .sign: true, .signedZero: false, .bitPattern: {0, 0}, .bitPatternLength: 1}, |
1996 | {.semantics: &APFloat::Float8E4M3B11FNUZ(), .sign: false, .signedZero: false, .bitPattern: {0, 0}, .bitPatternLength: 1}, |
1997 | {.semantics: &APFloat::Float8E4M3B11FNUZ(), .sign: true, .signedZero: false, .bitPattern: {0, 0}, .bitPatternLength: 1}, |
1998 | {.semantics: &APFloat::FloatTF32(), .sign: false, .signedZero: true, .bitPattern: {0, 0}, .bitPatternLength: 1}, |
1999 | {.semantics: &APFloat::FloatTF32(), .sign: true, .signedZero: true, .bitPattern: {0x40000ULL, 0}, .bitPatternLength: 1}}; |
2000 | const unsigned NumGetZeroTests = std::size(GetZeroTest); |
2001 | for (unsigned i = 0; i < NumGetZeroTests; ++i) { |
2002 | APFloat test = APFloat::getZero(Sem: *GetZeroTest[i].semantics, |
2003 | Negative: GetZeroTest[i].sign); |
2004 | const char *pattern = GetZeroTest[i].sign? "-0x0p+0" : "0x0p+0" ; |
2005 | APFloat expected = APFloat(*GetZeroTest[i].semantics, |
2006 | pattern); |
2007 | EXPECT_TRUE(test.isZero()); |
2008 | if (GetZeroTest[i].signedZero) |
2009 | EXPECT_TRUE(GetZeroTest[i].sign ? test.isNegative() : !test.isNegative()); |
2010 | else |
2011 | EXPECT_TRUE(!test.isNegative()); |
2012 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
2013 | for (unsigned j = 0, je = GetZeroTest[i].bitPatternLength; j < je; ++j) { |
2014 | EXPECT_EQ(GetZeroTest[i].bitPattern[j], |
2015 | test.bitcastToAPInt().getRawData()[j]); |
2016 | } |
2017 | } |
2018 | } |
2019 | |
2020 | TEST(APFloatTest, copySign) { |
2021 | EXPECT_TRUE(APFloat(-42.0).bitwiseIsEqual( |
2022 | APFloat::copySign(APFloat(42.0), APFloat(-1.0)))); |
2023 | EXPECT_TRUE(APFloat(42.0).bitwiseIsEqual( |
2024 | APFloat::copySign(APFloat(-42.0), APFloat(1.0)))); |
2025 | EXPECT_TRUE(APFloat(-42.0).bitwiseIsEqual( |
2026 | APFloat::copySign(APFloat(-42.0), APFloat(-1.0)))); |
2027 | EXPECT_TRUE(APFloat(42.0).bitwiseIsEqual( |
2028 | APFloat::copySign(APFloat(42.0), APFloat(1.0)))); |
2029 | // For floating-point formats with unsigned 0, copySign() to a zero is a noop |
2030 | for (APFloat::Semantics S : |
2031 | {APFloat::S_Float8E4M3FNUZ, APFloat::S_Float8E4M3B11FNUZ}) { |
2032 | const llvm::fltSemantics &Sem = APFloat::EnumToSemantics(S); |
2033 | EXPECT_TRUE(APFloat::getZero(Sem).bitwiseIsEqual( |
2034 | APFloat::copySign(APFloat::getZero(Sem), APFloat(-1.0)))); |
2035 | EXPECT_TRUE(APFloat::getNaN(Sem, true).bitwiseIsEqual( |
2036 | APFloat::copySign(APFloat::getNaN(Sem, true), APFloat(1.0)))); |
2037 | } |
2038 | } |
2039 | |
2040 | TEST(APFloatTest, convert) { |
2041 | bool losesInfo; |
2042 | APFloat test(APFloat::IEEEdouble(), "1.0" ); |
2043 | test.convert(ToSemantics: APFloat::IEEEsingle(), RM: APFloat::rmNearestTiesToEven, losesInfo: &losesInfo); |
2044 | EXPECT_EQ(1.0f, test.convertToFloat()); |
2045 | EXPECT_FALSE(losesInfo); |
2046 | |
2047 | test = APFloat(APFloat::x87DoubleExtended(), "0x1p-53" ); |
2048 | test.add(RHS: APFloat(APFloat::x87DoubleExtended(), "1.0" ), RM: APFloat::rmNearestTiesToEven); |
2049 | test.convert(ToSemantics: APFloat::IEEEdouble(), RM: APFloat::rmNearestTiesToEven, losesInfo: &losesInfo); |
2050 | EXPECT_EQ(1.0, test.convertToDouble()); |
2051 | EXPECT_TRUE(losesInfo); |
2052 | |
2053 | test = APFloat(APFloat::IEEEquad(), "0x1p-53" ); |
2054 | test.add(RHS: APFloat(APFloat::IEEEquad(), "1.0" ), RM: APFloat::rmNearestTiesToEven); |
2055 | test.convert(ToSemantics: APFloat::IEEEdouble(), RM: APFloat::rmNearestTiesToEven, losesInfo: &losesInfo); |
2056 | EXPECT_EQ(1.0, test.convertToDouble()); |
2057 | EXPECT_TRUE(losesInfo); |
2058 | |
2059 | test = APFloat(APFloat::x87DoubleExtended(), "0xf.fffffffp+28" ); |
2060 | test.convert(ToSemantics: APFloat::IEEEdouble(), RM: APFloat::rmNearestTiesToEven, losesInfo: &losesInfo); |
2061 | EXPECT_EQ(4294967295.0, test.convertToDouble()); |
2062 | EXPECT_FALSE(losesInfo); |
2063 | |
2064 | test = APFloat::getSNaN(Sem: APFloat::IEEEsingle()); |
2065 | APFloat::opStatus status = test.convert(ToSemantics: APFloat::x87DoubleExtended(), RM: APFloat::rmNearestTiesToEven, losesInfo: &losesInfo); |
2066 | // Conversion quiets the SNAN, so now 2 bits of the 64-bit significand should be set. |
2067 | APInt topTwoBits(64, 0x6000000000000000); |
2068 | EXPECT_TRUE(test.bitwiseIsEqual(APFloat::getQNaN(APFloat::x87DoubleExtended(), false, &topTwoBits))); |
2069 | EXPECT_FALSE(losesInfo); |
2070 | EXPECT_EQ(status, APFloat::opInvalidOp); |
2071 | |
2072 | test = APFloat::getQNaN(Sem: APFloat::IEEEsingle()); |
2073 | APFloat X87QNaN = APFloat::getQNaN(Sem: APFloat::x87DoubleExtended()); |
2074 | test.convert(ToSemantics: APFloat::x87DoubleExtended(), RM: APFloat::rmNearestTiesToEven, |
2075 | losesInfo: &losesInfo); |
2076 | EXPECT_TRUE(test.bitwiseIsEqual(X87QNaN)); |
2077 | EXPECT_FALSE(losesInfo); |
2078 | |
2079 | test = APFloat::getSNaN(Sem: APFloat::x87DoubleExtended()); |
2080 | test.convert(ToSemantics: APFloat::x87DoubleExtended(), RM: APFloat::rmNearestTiesToEven, |
2081 | losesInfo: &losesInfo); |
2082 | APFloat X87SNaN = APFloat::getSNaN(Sem: APFloat::x87DoubleExtended()); |
2083 | EXPECT_TRUE(test.bitwiseIsEqual(X87SNaN)); |
2084 | EXPECT_FALSE(losesInfo); |
2085 | |
2086 | test = APFloat::getQNaN(Sem: APFloat::x87DoubleExtended()); |
2087 | test.convert(ToSemantics: APFloat::x87DoubleExtended(), RM: APFloat::rmNearestTiesToEven, |
2088 | losesInfo: &losesInfo); |
2089 | EXPECT_TRUE(test.bitwiseIsEqual(X87QNaN)); |
2090 | EXPECT_FALSE(losesInfo); |
2091 | |
2092 | // The payload is lost in truncation, but we retain NaN by setting the quiet bit. |
2093 | APInt payload(52, 1); |
2094 | test = APFloat::getSNaN(Sem: APFloat::IEEEdouble(), Negative: false, payload: &payload); |
2095 | status = test.convert(ToSemantics: APFloat::IEEEsingle(), RM: APFloat::rmNearestTiesToEven, losesInfo: &losesInfo); |
2096 | EXPECT_EQ(0x7fc00000, test.bitcastToAPInt()); |
2097 | EXPECT_TRUE(losesInfo); |
2098 | EXPECT_EQ(status, APFloat::opInvalidOp); |
2099 | |
2100 | // The payload is lost in truncation. QNaN remains QNaN. |
2101 | test = APFloat::getQNaN(Sem: APFloat::IEEEdouble(), Negative: false, payload: &payload); |
2102 | status = test.convert(ToSemantics: APFloat::IEEEsingle(), RM: APFloat::rmNearestTiesToEven, losesInfo: &losesInfo); |
2103 | EXPECT_EQ(0x7fc00000, test.bitcastToAPInt()); |
2104 | EXPECT_TRUE(losesInfo); |
2105 | EXPECT_EQ(status, APFloat::opOK); |
2106 | |
2107 | // Test that subnormals are handled correctly in double to float conversion |
2108 | test = APFloat(APFloat::IEEEdouble(), "0x0.0000010000000p-1022" ); |
2109 | test.convert(ToSemantics: APFloat::IEEEsingle(), RM: APFloat::rmNearestTiesToEven, losesInfo: &losesInfo); |
2110 | EXPECT_EQ(0.0f, test.convertToFloat()); |
2111 | EXPECT_TRUE(losesInfo); |
2112 | |
2113 | test = APFloat(APFloat::IEEEdouble(), "0x0.0000010000001p-1022" ); |
2114 | test.convert(ToSemantics: APFloat::IEEEsingle(), RM: APFloat::rmNearestTiesToEven, losesInfo: &losesInfo); |
2115 | EXPECT_EQ(0.0f, test.convertToFloat()); |
2116 | EXPECT_TRUE(losesInfo); |
2117 | |
2118 | test = APFloat(APFloat::IEEEdouble(), "-0x0.0000010000001p-1022" ); |
2119 | test.convert(ToSemantics: APFloat::IEEEsingle(), RM: APFloat::rmNearestTiesToEven, losesInfo: &losesInfo); |
2120 | EXPECT_EQ(0.0f, test.convertToFloat()); |
2121 | EXPECT_TRUE(losesInfo); |
2122 | |
2123 | test = APFloat(APFloat::IEEEdouble(), "0x0.0000020000000p-1022" ); |
2124 | test.convert(ToSemantics: APFloat::IEEEsingle(), RM: APFloat::rmNearestTiesToEven, losesInfo: &losesInfo); |
2125 | EXPECT_EQ(0.0f, test.convertToFloat()); |
2126 | EXPECT_TRUE(losesInfo); |
2127 | |
2128 | test = APFloat(APFloat::IEEEdouble(), "0x0.0000020000001p-1022" ); |
2129 | test.convert(ToSemantics: APFloat::IEEEsingle(), RM: APFloat::rmNearestTiesToEven, losesInfo: &losesInfo); |
2130 | EXPECT_EQ(0.0f, test.convertToFloat()); |
2131 | EXPECT_TRUE(losesInfo); |
2132 | |
2133 | // Test subnormal conversion to bfloat |
2134 | test = APFloat(APFloat::IEEEsingle(), "0x0.01p-126" ); |
2135 | test.convert(ToSemantics: APFloat::BFloat(), RM: APFloat::rmNearestTiesToEven, losesInfo: &losesInfo); |
2136 | EXPECT_EQ(0.0f, test.convertToFloat()); |
2137 | EXPECT_TRUE(losesInfo); |
2138 | |
2139 | test = APFloat(APFloat::IEEEsingle(), "0x0.02p-126" ); |
2140 | test.convert(ToSemantics: APFloat::BFloat(), RM: APFloat::rmNearestTiesToEven, losesInfo: &losesInfo); |
2141 | EXPECT_EQ(0x01, test.bitcastToAPInt()); |
2142 | EXPECT_FALSE(losesInfo); |
2143 | |
2144 | test = APFloat(APFloat::IEEEsingle(), "0x0.01p-126" ); |
2145 | test.convert(ToSemantics: APFloat::BFloat(), RM: APFloat::rmNearestTiesToAway, losesInfo: &losesInfo); |
2146 | EXPECT_EQ(0x01, test.bitcastToAPInt()); |
2147 | EXPECT_TRUE(losesInfo); |
2148 | } |
2149 | |
2150 | TEST(APFloatTest, Float8UZConvert) { |
2151 | bool losesInfo = false; |
2152 | std::pair<APFloat, APFloat::opStatus> toNaNTests[] = { |
2153 | {APFloat::getQNaN(Sem: APFloat::IEEEsingle(), Negative: false), APFloat::opOK}, |
2154 | {APFloat::getQNaN(Sem: APFloat::IEEEsingle(), Negative: true), APFloat::opOK}, |
2155 | {APFloat::getSNaN(Sem: APFloat::IEEEsingle(), Negative: false), APFloat::opInvalidOp}, |
2156 | {APFloat::getSNaN(Sem: APFloat::IEEEsingle(), Negative: true), APFloat::opInvalidOp}, |
2157 | {APFloat::getInf(Sem: APFloat::IEEEsingle(), Negative: false), APFloat::opInexact}, |
2158 | {APFloat::getInf(Sem: APFloat::IEEEsingle(), Negative: true), APFloat::opInexact}}; |
2159 | for (APFloat::Semantics S : |
2160 | {APFloat::S_Float8E5M2FNUZ, APFloat::S_Float8E4M3FNUZ, |
2161 | APFloat::S_Float8E4M3B11FNUZ}) { |
2162 | const llvm::fltSemantics &Sem = APFloat::EnumToSemantics(S); |
2163 | SCOPED_TRACE("Semantics = " + std::to_string(S)); |
2164 | for (auto [toTest, expectedRes] : toNaNTests) { |
2165 | llvm::SmallString<16> value; |
2166 | toTest.toString(Str&: value); |
2167 | SCOPED_TRACE("toTest = " + value); |
2168 | losesInfo = false; |
2169 | APFloat test = toTest; |
2170 | EXPECT_EQ(test.convert(Sem, APFloat::rmNearestTiesToAway, &losesInfo), |
2171 | expectedRes); |
2172 | EXPECT_TRUE(test.isNaN()); |
2173 | EXPECT_TRUE(test.isNegative()); |
2174 | EXPECT_FALSE(test.isSignaling()); |
2175 | EXPECT_FALSE(test.isInfinity()); |
2176 | EXPECT_EQ(0x80, test.bitcastToAPInt()); |
2177 | EXPECT_TRUE(losesInfo); |
2178 | } |
2179 | |
2180 | // Negative zero conversions are information losing. |
2181 | losesInfo = false; |
2182 | APFloat test = APFloat::getZero(Sem: APFloat::IEEEsingle(), Negative: true); |
2183 | EXPECT_EQ(test.convert(Sem, APFloat::rmNearestTiesToAway, &losesInfo), |
2184 | APFloat::opInexact); |
2185 | EXPECT_TRUE(test.isZero()); |
2186 | EXPECT_FALSE(test.isNegative()); |
2187 | EXPECT_TRUE(losesInfo); |
2188 | EXPECT_EQ(0x0, test.bitcastToAPInt()); |
2189 | |
2190 | losesInfo = true; |
2191 | test = APFloat::getZero(Sem: APFloat::IEEEsingle(), Negative: false); |
2192 | EXPECT_EQ(test.convert(Sem, APFloat::rmNearestTiesToAway, &losesInfo), |
2193 | APFloat::opOK); |
2194 | EXPECT_TRUE(test.isZero()); |
2195 | EXPECT_FALSE(test.isNegative()); |
2196 | EXPECT_FALSE(losesInfo); |
2197 | EXPECT_EQ(0x0, test.bitcastToAPInt()); |
2198 | |
2199 | // Except in casts between ourselves. |
2200 | losesInfo = true; |
2201 | test = APFloat::getZero(Sem); |
2202 | EXPECT_EQ(test.convert(Sem, APFloat::rmNearestTiesToAway, &losesInfo), |
2203 | APFloat::opOK); |
2204 | EXPECT_FALSE(losesInfo); |
2205 | EXPECT_EQ(0x0, test.bitcastToAPInt()); |
2206 | } |
2207 | } |
2208 | |
2209 | TEST(APFloatTest, PPCDoubleDouble) { |
2210 | APFloat test(APFloat::PPCDoubleDouble(), "1.0" ); |
2211 | EXPECT_EQ(0x3ff0000000000000ull, test.bitcastToAPInt().getRawData()[0]); |
2212 | EXPECT_EQ(0x0000000000000000ull, test.bitcastToAPInt().getRawData()[1]); |
2213 | |
2214 | // LDBL_MAX |
2215 | test = APFloat(APFloat::PPCDoubleDouble(), "1.79769313486231580793728971405301e+308" ); |
2216 | EXPECT_EQ(0x7fefffffffffffffull, test.bitcastToAPInt().getRawData()[0]); |
2217 | EXPECT_EQ(0x7c8ffffffffffffeull, test.bitcastToAPInt().getRawData()[1]); |
2218 | |
2219 | // LDBL_MIN |
2220 | test = APFloat(APFloat::PPCDoubleDouble(), "2.00416836000897277799610805135016e-292" ); |
2221 | EXPECT_EQ(0x0360000000000000ull, test.bitcastToAPInt().getRawData()[0]); |
2222 | EXPECT_EQ(0x0000000000000000ull, test.bitcastToAPInt().getRawData()[1]); |
2223 | |
2224 | // PR30869 |
2225 | { |
2226 | auto Result = APFloat(APFloat::PPCDoubleDouble(), "1.0" ) + |
2227 | APFloat(APFloat::PPCDoubleDouble(), "1.0" ); |
2228 | EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics()); |
2229 | |
2230 | Result = APFloat(APFloat::PPCDoubleDouble(), "1.0" ) - |
2231 | APFloat(APFloat::PPCDoubleDouble(), "1.0" ); |
2232 | EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics()); |
2233 | |
2234 | Result = APFloat(APFloat::PPCDoubleDouble(), "1.0" ) * |
2235 | APFloat(APFloat::PPCDoubleDouble(), "1.0" ); |
2236 | EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics()); |
2237 | |
2238 | Result = APFloat(APFloat::PPCDoubleDouble(), "1.0" ) / |
2239 | APFloat(APFloat::PPCDoubleDouble(), "1.0" ); |
2240 | EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics()); |
2241 | |
2242 | int Exp; |
2243 | Result = frexp(X: APFloat(APFloat::PPCDoubleDouble(), "1.0" ), Exp, |
2244 | RM: APFloat::rmNearestTiesToEven); |
2245 | EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics()); |
2246 | |
2247 | Result = scalbn(X: APFloat(APFloat::PPCDoubleDouble(), "1.0" ), Exp: 1, |
2248 | RM: APFloat::rmNearestTiesToEven); |
2249 | EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics()); |
2250 | } |
2251 | } |
2252 | |
2253 | TEST(APFloatTest, isNegative) { |
2254 | APFloat t(APFloat::IEEEsingle(), "0x1p+0" ); |
2255 | EXPECT_FALSE(t.isNegative()); |
2256 | t = APFloat(APFloat::IEEEsingle(), "-0x1p+0" ); |
2257 | EXPECT_TRUE(t.isNegative()); |
2258 | |
2259 | EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), false).isNegative()); |
2260 | EXPECT_TRUE(APFloat::getInf(APFloat::IEEEsingle(), true).isNegative()); |
2261 | |
2262 | EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), false).isNegative()); |
2263 | EXPECT_TRUE(APFloat::getZero(APFloat::IEEEsingle(), true).isNegative()); |
2264 | |
2265 | EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), false).isNegative()); |
2266 | EXPECT_TRUE(APFloat::getNaN(APFloat::IEEEsingle(), true).isNegative()); |
2267 | |
2268 | EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isNegative()); |
2269 | EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle(), true).isNegative()); |
2270 | } |
2271 | |
2272 | TEST(APFloatTest, isNormal) { |
2273 | APFloat t(APFloat::IEEEsingle(), "0x1p+0" ); |
2274 | EXPECT_TRUE(t.isNormal()); |
2275 | |
2276 | EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), false).isNormal()); |
2277 | EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), false).isNormal()); |
2278 | EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), false).isNormal()); |
2279 | EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isNormal()); |
2280 | EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), "0x1p-149" ).isNormal()); |
2281 | } |
2282 | |
2283 | TEST(APFloatTest, isFinite) { |
2284 | APFloat t(APFloat::IEEEsingle(), "0x1p+0" ); |
2285 | EXPECT_TRUE(t.isFinite()); |
2286 | EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), false).isFinite()); |
2287 | EXPECT_TRUE(APFloat::getZero(APFloat::IEEEsingle(), false).isFinite()); |
2288 | EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), false).isFinite()); |
2289 | EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isFinite()); |
2290 | EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "0x1p-149" ).isFinite()); |
2291 | } |
2292 | |
2293 | TEST(APFloatTest, isInfinity) { |
2294 | APFloat t(APFloat::IEEEsingle(), "0x1p+0" ); |
2295 | EXPECT_FALSE(t.isInfinity()); |
2296 | |
2297 | APFloat PosInf = APFloat::getInf(Sem: APFloat::IEEEsingle(), Negative: false); |
2298 | APFloat NegInf = APFloat::getInf(Sem: APFloat::IEEEsingle(), Negative: true); |
2299 | |
2300 | EXPECT_TRUE(PosInf.isInfinity()); |
2301 | EXPECT_TRUE(PosInf.isPosInfinity()); |
2302 | EXPECT_FALSE(PosInf.isNegInfinity()); |
2303 | EXPECT_EQ(fcPosInf, PosInf.classify()); |
2304 | |
2305 | EXPECT_TRUE(NegInf.isInfinity()); |
2306 | EXPECT_FALSE(NegInf.isPosInfinity()); |
2307 | EXPECT_TRUE(NegInf.isNegInfinity()); |
2308 | EXPECT_EQ(fcNegInf, NegInf.classify()); |
2309 | |
2310 | EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), false).isInfinity()); |
2311 | EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), false).isInfinity()); |
2312 | EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isInfinity()); |
2313 | EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), "0x1p-149" ).isInfinity()); |
2314 | } |
2315 | |
2316 | TEST(APFloatTest, isNaN) { |
2317 | APFloat t(APFloat::IEEEsingle(), "0x1p+0" ); |
2318 | EXPECT_FALSE(t.isNaN()); |
2319 | EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), false).isNaN()); |
2320 | EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), false).isNaN()); |
2321 | EXPECT_TRUE(APFloat::getNaN(APFloat::IEEEsingle(), false).isNaN()); |
2322 | EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isNaN()); |
2323 | EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), "0x1p-149" ).isNaN()); |
2324 | } |
2325 | |
2326 | TEST(APFloatTest, isFiniteNonZero) { |
2327 | // Test positive/negative normal value. |
2328 | EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "0x1p+0" ).isFiniteNonZero()); |
2329 | EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "-0x1p+0" ).isFiniteNonZero()); |
2330 | |
2331 | // Test positive/negative denormal value. |
2332 | EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "0x1p-149" ).isFiniteNonZero()); |
2333 | EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "-0x1p-149" ).isFiniteNonZero()); |
2334 | |
2335 | // Test +/- Infinity. |
2336 | EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), false).isFiniteNonZero()); |
2337 | EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), true).isFiniteNonZero()); |
2338 | |
2339 | // Test +/- Zero. |
2340 | EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), false).isFiniteNonZero()); |
2341 | EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), true).isFiniteNonZero()); |
2342 | |
2343 | // Test +/- qNaN. +/- dont mean anything with qNaN but paranoia can't hurt in |
2344 | // this instance. |
2345 | EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), false).isFiniteNonZero()); |
2346 | EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), true).isFiniteNonZero()); |
2347 | |
2348 | // Test +/- sNaN. +/- dont mean anything with sNaN but paranoia can't hurt in |
2349 | // this instance. |
2350 | EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isFiniteNonZero()); |
2351 | EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), true).isFiniteNonZero()); |
2352 | } |
2353 | |
2354 | TEST(APFloatTest, add) { |
2355 | // Test Special Cases against each other and normal values. |
2356 | |
2357 | APFloat PInf = APFloat::getInf(Sem: APFloat::IEEEsingle(), Negative: false); |
2358 | APFloat MInf = APFloat::getInf(Sem: APFloat::IEEEsingle(), Negative: true); |
2359 | APFloat PZero = APFloat::getZero(Sem: APFloat::IEEEsingle(), Negative: false); |
2360 | APFloat MZero = APFloat::getZero(Sem: APFloat::IEEEsingle(), Negative: true); |
2361 | APFloat QNaN = APFloat::getNaN(Sem: APFloat::IEEEsingle(), Negative: false); |
2362 | APFloat SNaN = APFloat(APFloat::IEEEsingle(), "snan123" ); |
2363 | APFloat PNormalValue = APFloat(APFloat::IEEEsingle(), "0x1p+0" ); |
2364 | APFloat MNormalValue = APFloat(APFloat::IEEEsingle(), "-0x1p+0" ); |
2365 | APFloat PLargestValue = APFloat::getLargest(Sem: APFloat::IEEEsingle(), Negative: false); |
2366 | APFloat MLargestValue = APFloat::getLargest(Sem: APFloat::IEEEsingle(), Negative: true); |
2367 | APFloat PSmallestValue = APFloat::getSmallest(Sem: APFloat::IEEEsingle(), Negative: false); |
2368 | APFloat MSmallestValue = APFloat::getSmallest(Sem: APFloat::IEEEsingle(), Negative: true); |
2369 | APFloat PSmallestNormalized = |
2370 | APFloat::getSmallestNormalized(Sem: APFloat::IEEEsingle(), Negative: false); |
2371 | APFloat MSmallestNormalized = |
2372 | APFloat::getSmallestNormalized(Sem: APFloat::IEEEsingle(), Negative: true); |
2373 | |
2374 | const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact; |
2375 | |
2376 | struct { |
2377 | APFloat x; |
2378 | APFloat y; |
2379 | const char *result; |
2380 | int status; |
2381 | int category; |
2382 | } SpecialCaseTests[] = { |
2383 | { .x: PInf, .y: PInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2384 | { .x: PInf, .y: MInf, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2385 | { .x: PInf, .y: PZero, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2386 | { .x: PInf, .y: MZero, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2387 | { .x: PInf, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2388 | { .x: PInf, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2389 | { .x: PInf, .y: PNormalValue, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2390 | { .x: PInf, .y: MNormalValue, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2391 | { .x: PInf, .y: PLargestValue, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2392 | { .x: PInf, .y: MLargestValue, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2393 | { .x: PInf, .y: PSmallestValue, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2394 | { .x: PInf, .y: MSmallestValue, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2395 | { .x: PInf, .y: PSmallestNormalized, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2396 | { .x: PInf, .y: MSmallestNormalized, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2397 | { .x: MInf, .y: PInf, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2398 | { .x: MInf, .y: MInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2399 | { .x: MInf, .y: PZero, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2400 | { .x: MInf, .y: MZero, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2401 | { .x: MInf, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2402 | { .x: MInf, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2403 | { .x: MInf, .y: PNormalValue, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2404 | { .x: MInf, .y: MNormalValue, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2405 | { .x: MInf, .y: PLargestValue, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2406 | { .x: MInf, .y: MLargestValue, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2407 | { .x: MInf, .y: PSmallestValue, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2408 | { .x: MInf, .y: MSmallestValue, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2409 | { .x: MInf, .y: PSmallestNormalized, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2410 | { .x: MInf, .y: MSmallestNormalized, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2411 | { .x: PZero, .y: PInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2412 | { .x: PZero, .y: MInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2413 | { .x: PZero, .y: PZero, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2414 | { .x: PZero, .y: MZero, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2415 | { .x: PZero, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2416 | { .x: PZero, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2417 | { .x: PZero, .y: PNormalValue, .result: "0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2418 | { .x: PZero, .y: MNormalValue, .result: "-0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2419 | { .x: PZero, .y: PLargestValue, .result: "0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2420 | { .x: PZero, .y: MLargestValue, .result: "-0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2421 | { .x: PZero, .y: PSmallestValue, .result: "0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2422 | { .x: PZero, .y: MSmallestValue, .result: "-0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2423 | { .x: PZero, .y: PSmallestNormalized, .result: "0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2424 | { .x: PZero, .y: MSmallestNormalized, .result: "-0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2425 | { .x: MZero, .y: PInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2426 | { .x: MZero, .y: MInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2427 | { .x: MZero, .y: PZero, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2428 | { .x: MZero, .y: MZero, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2429 | { .x: MZero, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2430 | { .x: MZero, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2431 | { .x: MZero, .y: PNormalValue, .result: "0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2432 | { .x: MZero, .y: MNormalValue, .result: "-0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2433 | { .x: MZero, .y: PLargestValue, .result: "0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2434 | { .x: MZero, .y: MLargestValue, .result: "-0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2435 | { .x: MZero, .y: PSmallestValue, .result: "0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2436 | { .x: MZero, .y: MSmallestValue, .result: "-0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2437 | { .x: MZero, .y: PSmallestNormalized, .result: "0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2438 | { .x: MZero, .y: MSmallestNormalized, .result: "-0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2439 | { .x: QNaN, .y: PInf, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2440 | { .x: QNaN, .y: MInf, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2441 | { .x: QNaN, .y: PZero, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2442 | { .x: QNaN, .y: MZero, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2443 | { .x: QNaN, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2444 | { .x: QNaN, .y: SNaN, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2445 | { .x: QNaN, .y: PNormalValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2446 | { .x: QNaN, .y: MNormalValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2447 | { .x: QNaN, .y: PLargestValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2448 | { .x: QNaN, .y: MLargestValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2449 | { .x: QNaN, .y: PSmallestValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2450 | { .x: QNaN, .y: MSmallestValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2451 | { .x: QNaN, .y: PSmallestNormalized, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2452 | { .x: QNaN, .y: MSmallestNormalized, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2453 | { .x: SNaN, .y: PInf, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2454 | { .x: SNaN, .y: MInf, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2455 | { .x: SNaN, .y: PZero, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2456 | { .x: SNaN, .y: MZero, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2457 | { .x: SNaN, .y: QNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2458 | { .x: SNaN, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2459 | { .x: SNaN, .y: PNormalValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2460 | { .x: SNaN, .y: MNormalValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2461 | { .x: SNaN, .y: PLargestValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2462 | { .x: SNaN, .y: MLargestValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2463 | { .x: SNaN, .y: PSmallestValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2464 | { .x: SNaN, .y: MSmallestValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2465 | { .x: SNaN, .y: PSmallestNormalized, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2466 | { .x: SNaN, .y: MSmallestNormalized, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2467 | { .x: PNormalValue, .y: PInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2468 | { .x: PNormalValue, .y: MInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2469 | { .x: PNormalValue, .y: PZero, .result: "0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2470 | { .x: PNormalValue, .y: MZero, .result: "0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2471 | { .x: PNormalValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2472 | { .x: PNormalValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2473 | { .x: PNormalValue, .y: PNormalValue, .result: "0x1p+1" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2474 | { .x: PNormalValue, .y: MNormalValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2475 | { .x: PNormalValue, .y: PLargestValue, .result: "0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2476 | { .x: PNormalValue, .y: MLargestValue, .result: "-0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2477 | { .x: PNormalValue, .y: PSmallestValue, .result: "0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2478 | { .x: PNormalValue, .y: MSmallestValue, .result: "0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2479 | { .x: PNormalValue, .y: PSmallestNormalized, .result: "0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2480 | { .x: PNormalValue, .y: MSmallestNormalized, .result: "0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2481 | { .x: MNormalValue, .y: PInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2482 | { .x: MNormalValue, .y: MInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2483 | { .x: MNormalValue, .y: PZero, .result: "-0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2484 | { .x: MNormalValue, .y: MZero, .result: "-0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2485 | { .x: MNormalValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2486 | { .x: MNormalValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2487 | { .x: MNormalValue, .y: PNormalValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2488 | { .x: MNormalValue, .y: MNormalValue, .result: "-0x1p+1" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2489 | { .x: MNormalValue, .y: PLargestValue, .result: "0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2490 | { .x: MNormalValue, .y: MLargestValue, .result: "-0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2491 | { .x: MNormalValue, .y: PSmallestValue, .result: "-0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2492 | { .x: MNormalValue, .y: MSmallestValue, .result: "-0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2493 | { .x: MNormalValue, .y: PSmallestNormalized, .result: "-0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2494 | { .x: MNormalValue, .y: MSmallestNormalized, .result: "-0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2495 | { .x: PLargestValue, .y: PInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2496 | { .x: PLargestValue, .y: MInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2497 | { .x: PLargestValue, .y: PZero, .result: "0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2498 | { .x: PLargestValue, .y: MZero, .result: "0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2499 | { .x: PLargestValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2500 | { .x: PLargestValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2501 | { .x: PLargestValue, .y: PNormalValue, .result: "0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2502 | { .x: PLargestValue, .y: MNormalValue, .result: "0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2503 | { .x: PLargestValue, .y: PLargestValue, .result: "inf" , .status: OverflowStatus, .category: APFloat::fcInfinity }, |
2504 | { .x: PLargestValue, .y: MLargestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2505 | { .x: PLargestValue, .y: PSmallestValue, .result: "0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2506 | { .x: PLargestValue, .y: MSmallestValue, .result: "0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2507 | { .x: PLargestValue, .y: PSmallestNormalized, .result: "0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2508 | { .x: PLargestValue, .y: MSmallestNormalized, .result: "0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2509 | { .x: MLargestValue, .y: PInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2510 | { .x: MLargestValue, .y: MInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2511 | { .x: MLargestValue, .y: PZero, .result: "-0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2512 | { .x: MLargestValue, .y: MZero, .result: "-0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2513 | { .x: MLargestValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2514 | { .x: MLargestValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2515 | { .x: MLargestValue, .y: PNormalValue, .result: "-0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2516 | { .x: MLargestValue, .y: MNormalValue, .result: "-0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2517 | { .x: MLargestValue, .y: PLargestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2518 | { .x: MLargestValue, .y: MLargestValue, .result: "-inf" , .status: OverflowStatus, .category: APFloat::fcInfinity }, |
2519 | { .x: MLargestValue, .y: PSmallestValue, .result: "-0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2520 | { .x: MLargestValue, .y: MSmallestValue, .result: "-0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2521 | { .x: MLargestValue, .y: PSmallestNormalized, .result: "-0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2522 | { .x: MLargestValue, .y: MSmallestNormalized, .result: "-0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2523 | { .x: PSmallestValue, .y: PInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2524 | { .x: PSmallestValue, .y: MInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2525 | { .x: PSmallestValue, .y: PZero, .result: "0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2526 | { .x: PSmallestValue, .y: MZero, .result: "0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2527 | { .x: PSmallestValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2528 | { .x: PSmallestValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2529 | { .x: PSmallestValue, .y: PNormalValue, .result: "0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2530 | { .x: PSmallestValue, .y: MNormalValue, .result: "-0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2531 | { .x: PSmallestValue, .y: PLargestValue, .result: "0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2532 | { .x: PSmallestValue, .y: MLargestValue, .result: "-0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2533 | { .x: PSmallestValue, .y: PSmallestValue, .result: "0x1p-148" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2534 | { .x: PSmallestValue, .y: MSmallestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2535 | { .x: PSmallestValue, .y: PSmallestNormalized, .result: "0x1.000002p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2536 | { .x: PSmallestValue, .y: MSmallestNormalized, .result: "-0x1.fffffcp-127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2537 | { .x: MSmallestValue, .y: PInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2538 | { .x: MSmallestValue, .y: MInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2539 | { .x: MSmallestValue, .y: PZero, .result: "-0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2540 | { .x: MSmallestValue, .y: MZero, .result: "-0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2541 | { .x: MSmallestValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2542 | { .x: MSmallestValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2543 | { .x: MSmallestValue, .y: PNormalValue, .result: "0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2544 | { .x: MSmallestValue, .y: MNormalValue, .result: "-0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2545 | { .x: MSmallestValue, .y: PLargestValue, .result: "0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2546 | { .x: MSmallestValue, .y: MLargestValue, .result: "-0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2547 | { .x: MSmallestValue, .y: PSmallestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2548 | { .x: MSmallestValue, .y: MSmallestValue, .result: "-0x1p-148" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2549 | { .x: MSmallestValue, .y: PSmallestNormalized, .result: "0x1.fffffcp-127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2550 | { .x: MSmallestValue, .y: MSmallestNormalized, .result: "-0x1.000002p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2551 | { .x: PSmallestNormalized, .y: PInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2552 | { .x: PSmallestNormalized, .y: MInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2553 | { .x: PSmallestNormalized, .y: PZero, .result: "0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2554 | { .x: PSmallestNormalized, .y: MZero, .result: "0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2555 | { .x: PSmallestNormalized, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2556 | { .x: PSmallestNormalized, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2557 | { .x: PSmallestNormalized, .y: PNormalValue, .result: "0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2558 | { .x: PSmallestNormalized, .y: MNormalValue, .result: "-0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2559 | { .x: PSmallestNormalized, .y: PLargestValue, .result: "0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2560 | { .x: PSmallestNormalized, .y: MLargestValue, .result: "-0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2561 | { .x: PSmallestNormalized, .y: PSmallestValue, .result: "0x1.000002p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2562 | { .x: PSmallestNormalized, .y: MSmallestValue, .result: "0x1.fffffcp-127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2563 | { .x: PSmallestNormalized, .y: PSmallestNormalized, .result: "0x1p-125" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2564 | { .x: PSmallestNormalized, .y: MSmallestNormalized, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2565 | { .x: MSmallestNormalized, .y: PInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2566 | { .x: MSmallestNormalized, .y: MInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2567 | { .x: MSmallestNormalized, .y: PZero, .result: "-0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2568 | { .x: MSmallestNormalized, .y: MZero, .result: "-0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2569 | { .x: MSmallestNormalized, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2570 | { .x: MSmallestNormalized, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2571 | { .x: MSmallestNormalized, .y: PNormalValue, .result: "0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2572 | { .x: MSmallestNormalized, .y: MNormalValue, .result: "-0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2573 | { .x: MSmallestNormalized, .y: PLargestValue, .result: "0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2574 | { .x: MSmallestNormalized, .y: MLargestValue, .result: "-0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2575 | { .x: MSmallestNormalized, .y: PSmallestValue, .result: "-0x1.fffffcp-127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2576 | { .x: MSmallestNormalized, .y: MSmallestValue, .result: "-0x1.000002p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2577 | { .x: MSmallestNormalized, .y: PSmallestNormalized, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2578 | { .x: MSmallestNormalized, .y: MSmallestNormalized, .result: "-0x1p-125" , .status: APFloat::opOK, .category: APFloat::fcNormal } |
2579 | }; |
2580 | |
2581 | for (size_t i = 0; i < std::size(SpecialCaseTests); ++i) { |
2582 | APFloat x(SpecialCaseTests[i].x); |
2583 | APFloat y(SpecialCaseTests[i].y); |
2584 | APFloat::opStatus status = x.add(RHS: y, RM: APFloat::rmNearestTiesToEven); |
2585 | |
2586 | APFloat result(APFloat::IEEEsingle(), SpecialCaseTests[i].result); |
2587 | |
2588 | EXPECT_TRUE(result.bitwiseIsEqual(x)); |
2589 | EXPECT_EQ(SpecialCaseTests[i].status, (int)status); |
2590 | EXPECT_EQ(SpecialCaseTests[i].category, (int)x.getCategory()); |
2591 | } |
2592 | } |
2593 | |
2594 | TEST(APFloatTest, subtract) { |
2595 | // Test Special Cases against each other and normal values. |
2596 | |
2597 | APFloat PInf = APFloat::getInf(Sem: APFloat::IEEEsingle(), Negative: false); |
2598 | APFloat MInf = APFloat::getInf(Sem: APFloat::IEEEsingle(), Negative: true); |
2599 | APFloat PZero = APFloat::getZero(Sem: APFloat::IEEEsingle(), Negative: false); |
2600 | APFloat MZero = APFloat::getZero(Sem: APFloat::IEEEsingle(), Negative: true); |
2601 | APFloat QNaN = APFloat::getNaN(Sem: APFloat::IEEEsingle(), Negative: false); |
2602 | APFloat SNaN = APFloat(APFloat::IEEEsingle(), "snan123" ); |
2603 | APFloat PNormalValue = APFloat(APFloat::IEEEsingle(), "0x1p+0" ); |
2604 | APFloat MNormalValue = APFloat(APFloat::IEEEsingle(), "-0x1p+0" ); |
2605 | APFloat PLargestValue = APFloat::getLargest(Sem: APFloat::IEEEsingle(), Negative: false); |
2606 | APFloat MLargestValue = APFloat::getLargest(Sem: APFloat::IEEEsingle(), Negative: true); |
2607 | APFloat PSmallestValue = APFloat::getSmallest(Sem: APFloat::IEEEsingle(), Negative: false); |
2608 | APFloat MSmallestValue = APFloat::getSmallest(Sem: APFloat::IEEEsingle(), Negative: true); |
2609 | APFloat PSmallestNormalized = |
2610 | APFloat::getSmallestNormalized(Sem: APFloat::IEEEsingle(), Negative: false); |
2611 | APFloat MSmallestNormalized = |
2612 | APFloat::getSmallestNormalized(Sem: APFloat::IEEEsingle(), Negative: true); |
2613 | |
2614 | const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact; |
2615 | |
2616 | struct { |
2617 | APFloat x; |
2618 | APFloat y; |
2619 | const char *result; |
2620 | int status; |
2621 | int category; |
2622 | } SpecialCaseTests[] = { |
2623 | { .x: PInf, .y: PInf, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2624 | { .x: PInf, .y: MInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2625 | { .x: PInf, .y: PZero, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2626 | { .x: PInf, .y: MZero, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2627 | { .x: PInf, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2628 | { .x: PInf, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2629 | { .x: PInf, .y: PNormalValue, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2630 | { .x: PInf, .y: MNormalValue, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2631 | { .x: PInf, .y: PLargestValue, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2632 | { .x: PInf, .y: MLargestValue, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2633 | { .x: PInf, .y: PSmallestValue, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2634 | { .x: PInf, .y: MSmallestValue, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2635 | { .x: PInf, .y: PSmallestNormalized, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2636 | { .x: PInf, .y: MSmallestNormalized, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2637 | { .x: MInf, .y: PInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2638 | { .x: MInf, .y: MInf, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2639 | { .x: MInf, .y: PZero, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2640 | { .x: MInf, .y: MZero, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2641 | { .x: MInf, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2642 | { .x: MInf, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2643 | { .x: MInf, .y: PNormalValue, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2644 | { .x: MInf, .y: MNormalValue, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2645 | { .x: MInf, .y: PLargestValue, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2646 | { .x: MInf, .y: MLargestValue, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2647 | { .x: MInf, .y: PSmallestValue, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2648 | { .x: MInf, .y: MSmallestValue, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2649 | { .x: MInf, .y: PSmallestNormalized, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2650 | { .x: MInf, .y: MSmallestNormalized, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2651 | { .x: PZero, .y: PInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2652 | { .x: PZero, .y: MInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2653 | { .x: PZero, .y: PZero, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2654 | { .x: PZero, .y: MZero, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2655 | { .x: PZero, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2656 | { .x: PZero, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2657 | { .x: PZero, .y: PNormalValue, .result: "-0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2658 | { .x: PZero, .y: MNormalValue, .result: "0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2659 | { .x: PZero, .y: PLargestValue, .result: "-0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2660 | { .x: PZero, .y: MLargestValue, .result: "0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2661 | { .x: PZero, .y: PSmallestValue, .result: "-0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2662 | { .x: PZero, .y: MSmallestValue, .result: "0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2663 | { .x: PZero, .y: PSmallestNormalized, .result: "-0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2664 | { .x: PZero, .y: MSmallestNormalized, .result: "0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2665 | { .x: MZero, .y: PInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2666 | { .x: MZero, .y: MInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2667 | { .x: MZero, .y: PZero, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2668 | { .x: MZero, .y: MZero, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2669 | { .x: MZero, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2670 | { .x: MZero, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2671 | { .x: MZero, .y: PNormalValue, .result: "-0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2672 | { .x: MZero, .y: MNormalValue, .result: "0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2673 | { .x: MZero, .y: PLargestValue, .result: "-0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2674 | { .x: MZero, .y: MLargestValue, .result: "0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2675 | { .x: MZero, .y: PSmallestValue, .result: "-0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2676 | { .x: MZero, .y: MSmallestValue, .result: "0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2677 | { .x: MZero, .y: PSmallestNormalized, .result: "-0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2678 | { .x: MZero, .y: MSmallestNormalized, .result: "0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2679 | { .x: QNaN, .y: PInf, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2680 | { .x: QNaN, .y: MInf, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2681 | { .x: QNaN, .y: PZero, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2682 | { .x: QNaN, .y: MZero, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2683 | { .x: QNaN, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2684 | { .x: QNaN, .y: SNaN, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2685 | { .x: QNaN, .y: PNormalValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2686 | { .x: QNaN, .y: MNormalValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2687 | { .x: QNaN, .y: PLargestValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2688 | { .x: QNaN, .y: MLargestValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2689 | { .x: QNaN, .y: PSmallestValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2690 | { .x: QNaN, .y: MSmallestValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2691 | { .x: QNaN, .y: PSmallestNormalized, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2692 | { .x: QNaN, .y: MSmallestNormalized, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2693 | { .x: SNaN, .y: PInf, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2694 | { .x: SNaN, .y: MInf, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2695 | { .x: SNaN, .y: PZero, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2696 | { .x: SNaN, .y: MZero, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2697 | { .x: SNaN, .y: QNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2698 | { .x: SNaN, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2699 | { .x: SNaN, .y: PNormalValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2700 | { .x: SNaN, .y: MNormalValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2701 | { .x: SNaN, .y: PLargestValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2702 | { .x: SNaN, .y: MLargestValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2703 | { .x: SNaN, .y: PSmallestValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2704 | { .x: SNaN, .y: MSmallestValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2705 | { .x: SNaN, .y: PSmallestNormalized, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2706 | { .x: SNaN, .y: MSmallestNormalized, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2707 | { .x: PNormalValue, .y: PInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2708 | { .x: PNormalValue, .y: MInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2709 | { .x: PNormalValue, .y: PZero, .result: "0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2710 | { .x: PNormalValue, .y: MZero, .result: "0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2711 | { .x: PNormalValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2712 | { .x: PNormalValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2713 | { .x: PNormalValue, .y: PNormalValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2714 | { .x: PNormalValue, .y: MNormalValue, .result: "0x1p+1" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2715 | { .x: PNormalValue, .y: PLargestValue, .result: "-0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2716 | { .x: PNormalValue, .y: MLargestValue, .result: "0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2717 | { .x: PNormalValue, .y: PSmallestValue, .result: "0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2718 | { .x: PNormalValue, .y: MSmallestValue, .result: "0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2719 | { .x: PNormalValue, .y: PSmallestNormalized, .result: "0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2720 | { .x: PNormalValue, .y: MSmallestNormalized, .result: "0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2721 | { .x: MNormalValue, .y: PInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2722 | { .x: MNormalValue, .y: MInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2723 | { .x: MNormalValue, .y: PZero, .result: "-0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2724 | { .x: MNormalValue, .y: MZero, .result: "-0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2725 | { .x: MNormalValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2726 | { .x: MNormalValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2727 | { .x: MNormalValue, .y: PNormalValue, .result: "-0x1p+1" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2728 | { .x: MNormalValue, .y: MNormalValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2729 | { .x: MNormalValue, .y: PLargestValue, .result: "-0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2730 | { .x: MNormalValue, .y: MLargestValue, .result: "0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2731 | { .x: MNormalValue, .y: PSmallestValue, .result: "-0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2732 | { .x: MNormalValue, .y: MSmallestValue, .result: "-0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2733 | { .x: MNormalValue, .y: PSmallestNormalized, .result: "-0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2734 | { .x: MNormalValue, .y: MSmallestNormalized, .result: "-0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2735 | { .x: PLargestValue, .y: PInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2736 | { .x: PLargestValue, .y: MInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2737 | { .x: PLargestValue, .y: PZero, .result: "0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2738 | { .x: PLargestValue, .y: MZero, .result: "0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2739 | { .x: PLargestValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2740 | { .x: PLargestValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2741 | { .x: PLargestValue, .y: PNormalValue, .result: "0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2742 | { .x: PLargestValue, .y: MNormalValue, .result: "0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2743 | { .x: PLargestValue, .y: PLargestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2744 | { .x: PLargestValue, .y: MLargestValue, .result: "inf" , .status: OverflowStatus, .category: APFloat::fcInfinity }, |
2745 | { .x: PLargestValue, .y: PSmallestValue, .result: "0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2746 | { .x: PLargestValue, .y: MSmallestValue, .result: "0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2747 | { .x: PLargestValue, .y: PSmallestNormalized, .result: "0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2748 | { .x: PLargestValue, .y: MSmallestNormalized, .result: "0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2749 | { .x: MLargestValue, .y: PInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2750 | { .x: MLargestValue, .y: MInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2751 | { .x: MLargestValue, .y: PZero, .result: "-0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2752 | { .x: MLargestValue, .y: MZero, .result: "-0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2753 | { .x: MLargestValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2754 | { .x: MLargestValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2755 | { .x: MLargestValue, .y: PNormalValue, .result: "-0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2756 | { .x: MLargestValue, .y: MNormalValue, .result: "-0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2757 | { .x: MLargestValue, .y: PLargestValue, .result: "-inf" , .status: OverflowStatus, .category: APFloat::fcInfinity }, |
2758 | { .x: MLargestValue, .y: MLargestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2759 | { .x: MLargestValue, .y: PSmallestValue, .result: "-0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2760 | { .x: MLargestValue, .y: MSmallestValue, .result: "-0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2761 | { .x: MLargestValue, .y: PSmallestNormalized, .result: "-0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2762 | { .x: MLargestValue, .y: MSmallestNormalized, .result: "-0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2763 | { .x: PSmallestValue, .y: PInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2764 | { .x: PSmallestValue, .y: MInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2765 | { .x: PSmallestValue, .y: PZero, .result: "0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2766 | { .x: PSmallestValue, .y: MZero, .result: "0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2767 | { .x: PSmallestValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2768 | { .x: PSmallestValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2769 | { .x: PSmallestValue, .y: PNormalValue, .result: "-0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2770 | { .x: PSmallestValue, .y: MNormalValue, .result: "0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2771 | { .x: PSmallestValue, .y: PLargestValue, .result: "-0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2772 | { .x: PSmallestValue, .y: MLargestValue, .result: "0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2773 | { .x: PSmallestValue, .y: PSmallestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2774 | { .x: PSmallestValue, .y: MSmallestValue, .result: "0x1p-148" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2775 | { .x: PSmallestValue, .y: PSmallestNormalized, .result: "-0x1.fffffcp-127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2776 | { .x: PSmallestValue, .y: MSmallestNormalized, .result: "0x1.000002p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2777 | { .x: MSmallestValue, .y: PInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2778 | { .x: MSmallestValue, .y: MInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2779 | { .x: MSmallestValue, .y: PZero, .result: "-0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2780 | { .x: MSmallestValue, .y: MZero, .result: "-0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2781 | { .x: MSmallestValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2782 | { .x: MSmallestValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2783 | { .x: MSmallestValue, .y: PNormalValue, .result: "-0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2784 | { .x: MSmallestValue, .y: MNormalValue, .result: "0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2785 | { .x: MSmallestValue, .y: PLargestValue, .result: "-0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2786 | { .x: MSmallestValue, .y: MLargestValue, .result: "0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2787 | { .x: MSmallestValue, .y: PSmallestValue, .result: "-0x1p-148" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2788 | { .x: MSmallestValue, .y: MSmallestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2789 | { .x: MSmallestValue, .y: PSmallestNormalized, .result: "-0x1.000002p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2790 | { .x: MSmallestValue, .y: MSmallestNormalized, .result: "0x1.fffffcp-127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2791 | { .x: PSmallestNormalized, .y: PInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2792 | { .x: PSmallestNormalized, .y: MInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2793 | { .x: PSmallestNormalized, .y: PZero, .result: "0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2794 | { .x: PSmallestNormalized, .y: MZero, .result: "0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2795 | { .x: PSmallestNormalized, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2796 | { .x: PSmallestNormalized, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2797 | { .x: PSmallestNormalized, .y: PNormalValue, .result: "-0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2798 | { .x: PSmallestNormalized, .y: MNormalValue, .result: "0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2799 | { .x: PSmallestNormalized, .y: PLargestValue, .result: "-0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2800 | { .x: PSmallestNormalized, .y: MLargestValue, .result: "0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2801 | { .x: PSmallestNormalized, .y: PSmallestValue, .result: "0x1.fffffcp-127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2802 | { .x: PSmallestNormalized, .y: MSmallestValue, .result: "0x1.000002p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2803 | { .x: PSmallestNormalized, .y: PSmallestNormalized, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2804 | { .x: PSmallestNormalized, .y: MSmallestNormalized, .result: "0x1p-125" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2805 | { .x: MSmallestNormalized, .y: PInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2806 | { .x: MSmallestNormalized, .y: MInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2807 | { .x: MSmallestNormalized, .y: PZero, .result: "-0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2808 | { .x: MSmallestNormalized, .y: MZero, .result: "-0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2809 | { .x: MSmallestNormalized, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2810 | { .x: MSmallestNormalized, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2811 | { .x: MSmallestNormalized, .y: PNormalValue, .result: "-0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2812 | { .x: MSmallestNormalized, .y: MNormalValue, .result: "0x1p+0" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2813 | { .x: MSmallestNormalized, .y: PLargestValue, .result: "-0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2814 | { .x: MSmallestNormalized, .y: MLargestValue, .result: "0x1.fffffep+127" , .status: APFloat::opInexact, .category: APFloat::fcNormal }, |
2815 | { .x: MSmallestNormalized, .y: PSmallestValue, .result: "-0x1.000002p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2816 | { .x: MSmallestNormalized, .y: MSmallestValue, .result: "-0x1.fffffcp-127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2817 | { .x: MSmallestNormalized, .y: PSmallestNormalized, .result: "-0x1p-125" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2818 | { .x: MSmallestNormalized, .y: MSmallestNormalized, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero } |
2819 | }; |
2820 | |
2821 | for (size_t i = 0; i < std::size(SpecialCaseTests); ++i) { |
2822 | APFloat x(SpecialCaseTests[i].x); |
2823 | APFloat y(SpecialCaseTests[i].y); |
2824 | APFloat::opStatus status = x.subtract(RHS: y, RM: APFloat::rmNearestTiesToEven); |
2825 | |
2826 | APFloat result(APFloat::IEEEsingle(), SpecialCaseTests[i].result); |
2827 | |
2828 | EXPECT_TRUE(result.bitwiseIsEqual(x)); |
2829 | EXPECT_EQ(SpecialCaseTests[i].status, (int)status); |
2830 | EXPECT_EQ(SpecialCaseTests[i].category, (int)x.getCategory()); |
2831 | } |
2832 | } |
2833 | |
2834 | TEST(APFloatTest, multiply) { |
2835 | // Test Special Cases against each other and normal values. |
2836 | |
2837 | APFloat PInf = APFloat::getInf(Sem: APFloat::IEEEsingle(), Negative: false); |
2838 | APFloat MInf = APFloat::getInf(Sem: APFloat::IEEEsingle(), Negative: true); |
2839 | APFloat PZero = APFloat::getZero(Sem: APFloat::IEEEsingle(), Negative: false); |
2840 | APFloat MZero = APFloat::getZero(Sem: APFloat::IEEEsingle(), Negative: true); |
2841 | APFloat QNaN = APFloat::getNaN(Sem: APFloat::IEEEsingle(), Negative: false); |
2842 | APFloat SNaN = APFloat(APFloat::IEEEsingle(), "snan123" ); |
2843 | APFloat PNormalValue = APFloat(APFloat::IEEEsingle(), "0x1p+0" ); |
2844 | APFloat MNormalValue = APFloat(APFloat::IEEEsingle(), "-0x1p+0" ); |
2845 | APFloat PLargestValue = APFloat::getLargest(Sem: APFloat::IEEEsingle(), Negative: false); |
2846 | APFloat MLargestValue = APFloat::getLargest(Sem: APFloat::IEEEsingle(), Negative: true); |
2847 | APFloat PSmallestValue = APFloat::getSmallest(Sem: APFloat::IEEEsingle(), Negative: false); |
2848 | APFloat MSmallestValue = APFloat::getSmallest(Sem: APFloat::IEEEsingle(), Negative: true); |
2849 | APFloat PSmallestNormalized = |
2850 | APFloat::getSmallestNormalized(Sem: APFloat::IEEEsingle(), Negative: false); |
2851 | APFloat MSmallestNormalized = |
2852 | APFloat::getSmallestNormalized(Sem: APFloat::IEEEsingle(), Negative: true); |
2853 | |
2854 | APFloat MaxQuad(APFloat::IEEEquad(), |
2855 | "0x1.ffffffffffffffffffffffffffffp+16383" ); |
2856 | APFloat MinQuad(APFloat::IEEEquad(), |
2857 | "0x0.0000000000000000000000000001p-16382" ); |
2858 | APFloat NMinQuad(APFloat::IEEEquad(), |
2859 | "-0x0.0000000000000000000000000001p-16382" ); |
2860 | |
2861 | const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact; |
2862 | const int UnderflowStatus = APFloat::opUnderflow | APFloat::opInexact; |
2863 | |
2864 | struct { |
2865 | APFloat x; |
2866 | APFloat y; |
2867 | const char *result; |
2868 | int status; |
2869 | int category; |
2870 | APFloat::roundingMode roundingMode = APFloat::rmNearestTiesToEven; |
2871 | } SpecialCaseTests[] = { |
2872 | { .x: PInf, .y: PInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2873 | { .x: PInf, .y: MInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2874 | { .x: PInf, .y: PZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2875 | { .x: PInf, .y: MZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2876 | { .x: PInf, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2877 | { .x: PInf, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2878 | { .x: PInf, .y: PNormalValue, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2879 | { .x: PInf, .y: MNormalValue, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2880 | { .x: PInf, .y: PLargestValue, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2881 | { .x: PInf, .y: MLargestValue, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2882 | { .x: PInf, .y: PSmallestValue, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2883 | { .x: PInf, .y: MSmallestValue, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2884 | { .x: PInf, .y: PSmallestNormalized, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2885 | { .x: PInf, .y: MSmallestNormalized, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2886 | { .x: MInf, .y: PInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2887 | { .x: MInf, .y: MInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2888 | { .x: MInf, .y: PZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2889 | { .x: MInf, .y: MZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2890 | { .x: MInf, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2891 | { .x: MInf, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2892 | { .x: MInf, .y: PNormalValue, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2893 | { .x: MInf, .y: MNormalValue, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2894 | { .x: MInf, .y: PLargestValue, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2895 | { .x: MInf, .y: MLargestValue, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2896 | { .x: MInf, .y: PSmallestValue, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2897 | { .x: MInf, .y: MSmallestValue, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2898 | { .x: MInf, .y: PSmallestNormalized, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2899 | { .x: MInf, .y: MSmallestNormalized, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2900 | { .x: PZero, .y: PInf, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2901 | { .x: PZero, .y: MInf, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2902 | { .x: PZero, .y: PZero, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2903 | { .x: PZero, .y: MZero, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2904 | { .x: PZero, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2905 | { .x: PZero, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2906 | { .x: PZero, .y: PNormalValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2907 | { .x: PZero, .y: MNormalValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2908 | { .x: PZero, .y: PLargestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2909 | { .x: PZero, .y: MLargestValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2910 | { .x: PZero, .y: PSmallestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2911 | { .x: PZero, .y: MSmallestValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2912 | { .x: PZero, .y: PSmallestNormalized, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2913 | { .x: PZero, .y: MSmallestNormalized, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2914 | { .x: MZero, .y: PInf, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2915 | { .x: MZero, .y: MInf, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2916 | { .x: MZero, .y: PZero, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2917 | { .x: MZero, .y: MZero, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2918 | { .x: MZero, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2919 | { .x: MZero, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2920 | { .x: MZero, .y: PNormalValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2921 | { .x: MZero, .y: MNormalValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2922 | { .x: MZero, .y: PLargestValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2923 | { .x: MZero, .y: MLargestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2924 | { .x: MZero, .y: PSmallestValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2925 | { .x: MZero, .y: MSmallestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2926 | { .x: MZero, .y: PSmallestNormalized, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2927 | { .x: MZero, .y: MSmallestNormalized, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2928 | { .x: QNaN, .y: PInf, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2929 | { .x: QNaN, .y: MInf, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2930 | { .x: QNaN, .y: PZero, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2931 | { .x: QNaN, .y: MZero, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2932 | { .x: QNaN, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2933 | { .x: QNaN, .y: SNaN, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2934 | { .x: QNaN, .y: PNormalValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2935 | { .x: QNaN, .y: MNormalValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2936 | { .x: QNaN, .y: PLargestValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2937 | { .x: QNaN, .y: MLargestValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2938 | { .x: QNaN, .y: PSmallestValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2939 | { .x: QNaN, .y: MSmallestValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2940 | { .x: QNaN, .y: PSmallestNormalized, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2941 | { .x: QNaN, .y: MSmallestNormalized, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2942 | { .x: SNaN, .y: PInf, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2943 | { .x: SNaN, .y: MInf, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2944 | { .x: SNaN, .y: PZero, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2945 | { .x: SNaN, .y: MZero, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2946 | { .x: SNaN, .y: QNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2947 | { .x: SNaN, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2948 | { .x: SNaN, .y: PNormalValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2949 | { .x: SNaN, .y: MNormalValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2950 | { .x: SNaN, .y: PLargestValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2951 | { .x: SNaN, .y: MLargestValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2952 | { .x: SNaN, .y: PSmallestValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2953 | { .x: SNaN, .y: MSmallestValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2954 | { .x: SNaN, .y: PSmallestNormalized, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2955 | { .x: SNaN, .y: MSmallestNormalized, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2956 | { .x: PNormalValue, .y: PInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2957 | { .x: PNormalValue, .y: MInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2958 | { .x: PNormalValue, .y: PZero, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2959 | { .x: PNormalValue, .y: MZero, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2960 | { .x: PNormalValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2961 | { .x: PNormalValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2962 | { .x: PNormalValue, .y: PNormalValue, .result: "0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2963 | { .x: PNormalValue, .y: MNormalValue, .result: "-0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2964 | { .x: PNormalValue, .y: PLargestValue, .result: "0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2965 | { .x: PNormalValue, .y: MLargestValue, .result: "-0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2966 | { .x: PNormalValue, .y: PSmallestValue, .result: "0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2967 | { .x: PNormalValue, .y: MSmallestValue, .result: "-0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2968 | { .x: PNormalValue, .y: PSmallestNormalized, .result: "0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2969 | { .x: PNormalValue, .y: MSmallestNormalized, .result: "-0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2970 | { .x: MNormalValue, .y: PInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2971 | { .x: MNormalValue, .y: MInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2972 | { .x: MNormalValue, .y: PZero, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2973 | { .x: MNormalValue, .y: MZero, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2974 | { .x: MNormalValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2975 | { .x: MNormalValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2976 | { .x: MNormalValue, .y: PNormalValue, .result: "-0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2977 | { .x: MNormalValue, .y: MNormalValue, .result: "0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2978 | { .x: MNormalValue, .y: PLargestValue, .result: "-0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2979 | { .x: MNormalValue, .y: MLargestValue, .result: "0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2980 | { .x: MNormalValue, .y: PSmallestValue, .result: "-0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2981 | { .x: MNormalValue, .y: MSmallestValue, .result: "0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2982 | { .x: MNormalValue, .y: PSmallestNormalized, .result: "-0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2983 | { .x: MNormalValue, .y: MSmallestNormalized, .result: "0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2984 | { .x: PLargestValue, .y: PInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2985 | { .x: PLargestValue, .y: MInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2986 | { .x: PLargestValue, .y: PZero, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2987 | { .x: PLargestValue, .y: MZero, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
2988 | { .x: PLargestValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
2989 | { .x: PLargestValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
2990 | { .x: PLargestValue, .y: PNormalValue, .result: "0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2991 | { .x: PLargestValue, .y: MNormalValue, .result: "-0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2992 | { .x: PLargestValue, .y: PLargestValue, .result: "inf" , .status: OverflowStatus, .category: APFloat::fcInfinity }, |
2993 | { .x: PLargestValue, .y: MLargestValue, .result: "-inf" , .status: OverflowStatus, .category: APFloat::fcInfinity }, |
2994 | { .x: PLargestValue, .y: PSmallestValue, .result: "0x1.fffffep-22" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2995 | { .x: PLargestValue, .y: MSmallestValue, .result: "-0x1.fffffep-22" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2996 | { .x: PLargestValue, .y: PSmallestNormalized, .result: "0x1.fffffep+1" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2997 | { .x: PLargestValue, .y: MSmallestNormalized, .result: "-0x1.fffffep+1" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
2998 | { .x: MLargestValue, .y: PInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
2999 | { .x: MLargestValue, .y: MInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3000 | { .x: MLargestValue, .y: PZero, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3001 | { .x: MLargestValue, .y: MZero, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3002 | { .x: MLargestValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3003 | { .x: MLargestValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3004 | { .x: MLargestValue, .y: PNormalValue, .result: "-0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3005 | { .x: MLargestValue, .y: MNormalValue, .result: "0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3006 | { .x: MLargestValue, .y: PLargestValue, .result: "-inf" , .status: OverflowStatus, .category: APFloat::fcInfinity }, |
3007 | { .x: MLargestValue, .y: MLargestValue, .result: "inf" , .status: OverflowStatus, .category: APFloat::fcInfinity }, |
3008 | { .x: MLargestValue, .y: PSmallestValue, .result: "-0x1.fffffep-22" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3009 | { .x: MLargestValue, .y: MSmallestValue, .result: "0x1.fffffep-22" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3010 | { .x: MLargestValue, .y: PSmallestNormalized, .result: "-0x1.fffffep+1" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3011 | { .x: MLargestValue, .y: MSmallestNormalized, .result: "0x1.fffffep+1" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3012 | { .x: PSmallestValue, .y: PInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3013 | { .x: PSmallestValue, .y: MInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3014 | { .x: PSmallestValue, .y: PZero, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3015 | { .x: PSmallestValue, .y: MZero, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3016 | { .x: PSmallestValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3017 | { .x: PSmallestValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3018 | { .x: PSmallestValue, .y: PNormalValue, .result: "0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3019 | { .x: PSmallestValue, .y: MNormalValue, .result: "-0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3020 | { .x: PSmallestValue, .y: PLargestValue, .result: "0x1.fffffep-22" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3021 | { .x: PSmallestValue, .y: MLargestValue, .result: "-0x1.fffffep-22" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3022 | { .x: PSmallestValue, .y: PSmallestValue, .result: "0x0p+0" , .status: UnderflowStatus, .category: APFloat::fcZero }, |
3023 | { .x: PSmallestValue, .y: MSmallestValue, .result: "-0x0p+0" , .status: UnderflowStatus, .category: APFloat::fcZero }, |
3024 | { .x: PSmallestValue, .y: PSmallestNormalized, .result: "0x0p+0" , .status: UnderflowStatus, .category: APFloat::fcZero }, |
3025 | { .x: PSmallestValue, .y: MSmallestNormalized, .result: "-0x0p+0" , .status: UnderflowStatus, .category: APFloat::fcZero }, |
3026 | { .x: MSmallestValue, .y: PInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3027 | { .x: MSmallestValue, .y: MInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3028 | { .x: MSmallestValue, .y: PZero, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3029 | { .x: MSmallestValue, .y: MZero, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3030 | { .x: MSmallestValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3031 | { .x: MSmallestValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3032 | { .x: MSmallestValue, .y: PNormalValue, .result: "-0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3033 | { .x: MSmallestValue, .y: MNormalValue, .result: "0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3034 | { .x: MSmallestValue, .y: PLargestValue, .result: "-0x1.fffffep-22" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3035 | { .x: MSmallestValue, .y: MLargestValue, .result: "0x1.fffffep-22" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3036 | { .x: MSmallestValue, .y: PSmallestValue, .result: "-0x0p+0" , .status: UnderflowStatus, .category: APFloat::fcZero }, |
3037 | { .x: MSmallestValue, .y: MSmallestValue, .result: "0x0p+0" , .status: UnderflowStatus, .category: APFloat::fcZero }, |
3038 | { .x: MSmallestValue, .y: PSmallestNormalized, .result: "-0x0p+0" , .status: UnderflowStatus, .category: APFloat::fcZero }, |
3039 | { .x: MSmallestValue, .y: MSmallestNormalized, .result: "0x0p+0" , .status: UnderflowStatus, .category: APFloat::fcZero }, |
3040 | { .x: PSmallestNormalized, .y: PInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3041 | { .x: PSmallestNormalized, .y: MInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3042 | { .x: PSmallestNormalized, .y: PZero, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3043 | { .x: PSmallestNormalized, .y: MZero, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3044 | { .x: PSmallestNormalized, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3045 | { .x: PSmallestNormalized, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3046 | { .x: PSmallestNormalized, .y: PNormalValue, .result: "0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3047 | { .x: PSmallestNormalized, .y: MNormalValue, .result: "-0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3048 | { .x: PSmallestNormalized, .y: PLargestValue, .result: "0x1.fffffep+1" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3049 | { .x: PSmallestNormalized, .y: MLargestValue, .result: "-0x1.fffffep+1" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3050 | { .x: PSmallestNormalized, .y: PSmallestValue, .result: "0x0p+0" , .status: UnderflowStatus, .category: APFloat::fcZero }, |
3051 | { .x: PSmallestNormalized, .y: MSmallestValue, .result: "-0x0p+0" , .status: UnderflowStatus, .category: APFloat::fcZero }, |
3052 | { .x: PSmallestNormalized, .y: PSmallestNormalized, .result: "0x0p+0" , .status: UnderflowStatus, .category: APFloat::fcZero }, |
3053 | { .x: PSmallestNormalized, .y: MSmallestNormalized, .result: "-0x0p+0" , .status: UnderflowStatus, .category: APFloat::fcZero }, |
3054 | { .x: MSmallestNormalized, .y: PInf, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3055 | { .x: MSmallestNormalized, .y: MInf, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3056 | { .x: MSmallestNormalized, .y: PZero, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3057 | { .x: MSmallestNormalized, .y: MZero, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3058 | { .x: MSmallestNormalized, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3059 | { .x: MSmallestNormalized, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3060 | { .x: MSmallestNormalized, .y: PNormalValue, .result: "-0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3061 | { .x: MSmallestNormalized, .y: MNormalValue, .result: "0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3062 | { .x: MSmallestNormalized, .y: PLargestValue, .result: "-0x1.fffffep+1" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3063 | { .x: MSmallestNormalized, .y: MLargestValue, .result: "0x1.fffffep+1" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3064 | { .x: MSmallestNormalized, .y: PSmallestValue, .result: "-0x0p+0" , .status: UnderflowStatus, .category: APFloat::fcZero }, |
3065 | { .x: MSmallestNormalized, .y: MSmallestValue, .result: "0x0p+0" , .status: UnderflowStatus, .category: APFloat::fcZero }, |
3066 | { .x: MSmallestNormalized, .y: PSmallestNormalized, .result: "-0x0p+0" , .status: UnderflowStatus, .category: APFloat::fcZero }, |
3067 | { .x: MSmallestNormalized, .y: MSmallestNormalized, .result: "0x0p+0" , .status: UnderflowStatus, .category: APFloat::fcZero }, |
3068 | |
3069 | {.x: MaxQuad, .y: MinQuad, .result: "0x1.ffffffffffffffffffffffffffffp-111" , .status: APFloat::opOK, |
3070 | .category: APFloat::fcNormal, .roundingMode: APFloat::rmNearestTiesToEven}, |
3071 | {.x: MaxQuad, .y: MinQuad, .result: "0x1.ffffffffffffffffffffffffffffp-111" , .status: APFloat::opOK, |
3072 | .category: APFloat::fcNormal, .roundingMode: APFloat::rmTowardPositive}, |
3073 | {.x: MaxQuad, .y: MinQuad, .result: "0x1.ffffffffffffffffffffffffffffp-111" , .status: APFloat::opOK, |
3074 | .category: APFloat::fcNormal, .roundingMode: APFloat::rmTowardNegative}, |
3075 | {.x: MaxQuad, .y: MinQuad, .result: "0x1.ffffffffffffffffffffffffffffp-111" , .status: APFloat::opOK, |
3076 | .category: APFloat::fcNormal, .roundingMode: APFloat::rmTowardZero}, |
3077 | {.x: MaxQuad, .y: MinQuad, .result: "0x1.ffffffffffffffffffffffffffffp-111" , .status: APFloat::opOK, |
3078 | .category: APFloat::fcNormal, .roundingMode: APFloat::rmNearestTiesToAway}, |
3079 | |
3080 | {.x: MaxQuad, .y: NMinQuad, .result: "-0x1.ffffffffffffffffffffffffffffp-111" , .status: APFloat::opOK, |
3081 | .category: APFloat::fcNormal, .roundingMode: APFloat::rmNearestTiesToEven}, |
3082 | {.x: MaxQuad, .y: NMinQuad, .result: "-0x1.ffffffffffffffffffffffffffffp-111" , .status: APFloat::opOK, |
3083 | .category: APFloat::fcNormal, .roundingMode: APFloat::rmTowardPositive}, |
3084 | {.x: MaxQuad, .y: NMinQuad, .result: "-0x1.ffffffffffffffffffffffffffffp-111" , .status: APFloat::opOK, |
3085 | .category: APFloat::fcNormal, .roundingMode: APFloat::rmTowardNegative}, |
3086 | {.x: MaxQuad, .y: NMinQuad, .result: "-0x1.ffffffffffffffffffffffffffffp-111" , .status: APFloat::opOK, |
3087 | .category: APFloat::fcNormal, .roundingMode: APFloat::rmTowardZero}, |
3088 | {.x: MaxQuad, .y: NMinQuad, .result: "-0x1.ffffffffffffffffffffffffffffp-111" , .status: APFloat::opOK, |
3089 | .category: APFloat::fcNormal, .roundingMode: APFloat::rmNearestTiesToAway}, |
3090 | |
3091 | {.x: MaxQuad, .y: MaxQuad, .result: "inf" , .status: OverflowStatus, .category: APFloat::fcInfinity, |
3092 | .roundingMode: APFloat::rmNearestTiesToEven}, |
3093 | {.x: MaxQuad, .y: MaxQuad, .result: "inf" , .status: OverflowStatus, .category: APFloat::fcInfinity, |
3094 | .roundingMode: APFloat::rmTowardPositive}, |
3095 | {.x: MaxQuad, .y: MaxQuad, .result: "0x1.ffffffffffffffffffffffffffffp+16383" , |
3096 | .status: APFloat::opInexact, .category: APFloat::fcNormal, .roundingMode: APFloat::rmTowardNegative}, |
3097 | {.x: MaxQuad, .y: MaxQuad, .result: "0x1.ffffffffffffffffffffffffffffp+16383" , |
3098 | .status: APFloat::opInexact, .category: APFloat::fcNormal, .roundingMode: APFloat::rmTowardZero}, |
3099 | {.x: MaxQuad, .y: MaxQuad, .result: "inf" , .status: OverflowStatus, .category: APFloat::fcInfinity, |
3100 | .roundingMode: APFloat::rmNearestTiesToAway}, |
3101 | |
3102 | {.x: MinQuad, .y: MinQuad, .result: "0" , .status: UnderflowStatus, .category: APFloat::fcZero, |
3103 | .roundingMode: APFloat::rmNearestTiesToEven}, |
3104 | {.x: MinQuad, .y: MinQuad, .result: "0x0.0000000000000000000000000001p-16382" , |
3105 | .status: UnderflowStatus, .category: APFloat::fcNormal, .roundingMode: APFloat::rmTowardPositive}, |
3106 | {.x: MinQuad, .y: MinQuad, .result: "0" , .status: UnderflowStatus, .category: APFloat::fcZero, |
3107 | .roundingMode: APFloat::rmTowardNegative}, |
3108 | {.x: MinQuad, .y: MinQuad, .result: "0" , .status: UnderflowStatus, .category: APFloat::fcZero, |
3109 | .roundingMode: APFloat::rmTowardZero}, |
3110 | {.x: MinQuad, .y: MinQuad, .result: "0" , .status: UnderflowStatus, .category: APFloat::fcZero, |
3111 | .roundingMode: APFloat::rmNearestTiesToAway}, |
3112 | |
3113 | {.x: MinQuad, .y: NMinQuad, .result: "-0" , .status: UnderflowStatus, .category: APFloat::fcZero, |
3114 | .roundingMode: APFloat::rmNearestTiesToEven}, |
3115 | {.x: MinQuad, .y: NMinQuad, .result: "-0" , .status: UnderflowStatus, .category: APFloat::fcZero, |
3116 | .roundingMode: APFloat::rmTowardPositive}, |
3117 | {.x: MinQuad, .y: NMinQuad, .result: "-0x0.0000000000000000000000000001p-16382" , |
3118 | .status: UnderflowStatus, .category: APFloat::fcNormal, .roundingMode: APFloat::rmTowardNegative}, |
3119 | {.x: MinQuad, .y: NMinQuad, .result: "-0" , .status: UnderflowStatus, .category: APFloat::fcZero, |
3120 | .roundingMode: APFloat::rmTowardZero}, |
3121 | {.x: MinQuad, .y: NMinQuad, .result: "-0" , .status: UnderflowStatus, .category: APFloat::fcZero, |
3122 | .roundingMode: APFloat::rmNearestTiesToAway}, |
3123 | }; |
3124 | |
3125 | for (size_t i = 0; i < std::size(SpecialCaseTests); ++i) { |
3126 | APFloat x(SpecialCaseTests[i].x); |
3127 | APFloat y(SpecialCaseTests[i].y); |
3128 | APFloat::opStatus status = x.multiply(RHS: y, RM: SpecialCaseTests[i].roundingMode); |
3129 | |
3130 | APFloat result(x.getSemantics(), SpecialCaseTests[i].result); |
3131 | |
3132 | EXPECT_TRUE(result.bitwiseIsEqual(x)); |
3133 | EXPECT_EQ(SpecialCaseTests[i].status, (int)status); |
3134 | EXPECT_EQ(SpecialCaseTests[i].category, (int)x.getCategory()); |
3135 | } |
3136 | } |
3137 | |
3138 | TEST(APFloatTest, divide) { |
3139 | // Test Special Cases against each other and normal values. |
3140 | |
3141 | APFloat PInf = APFloat::getInf(Sem: APFloat::IEEEsingle(), Negative: false); |
3142 | APFloat MInf = APFloat::getInf(Sem: APFloat::IEEEsingle(), Negative: true); |
3143 | APFloat PZero = APFloat::getZero(Sem: APFloat::IEEEsingle(), Negative: false); |
3144 | APFloat MZero = APFloat::getZero(Sem: APFloat::IEEEsingle(), Negative: true); |
3145 | APFloat QNaN = APFloat::getNaN(Sem: APFloat::IEEEsingle(), Negative: false); |
3146 | APFloat SNaN = APFloat(APFloat::IEEEsingle(), "snan123" ); |
3147 | APFloat PNormalValue = APFloat(APFloat::IEEEsingle(), "0x1p+0" ); |
3148 | APFloat MNormalValue = APFloat(APFloat::IEEEsingle(), "-0x1p+0" ); |
3149 | APFloat PLargestValue = APFloat::getLargest(Sem: APFloat::IEEEsingle(), Negative: false); |
3150 | APFloat MLargestValue = APFloat::getLargest(Sem: APFloat::IEEEsingle(), Negative: true); |
3151 | APFloat PSmallestValue = APFloat::getSmallest(Sem: APFloat::IEEEsingle(), Negative: false); |
3152 | APFloat MSmallestValue = APFloat::getSmallest(Sem: APFloat::IEEEsingle(), Negative: true); |
3153 | APFloat PSmallestNormalized = |
3154 | APFloat::getSmallestNormalized(Sem: APFloat::IEEEsingle(), Negative: false); |
3155 | APFloat MSmallestNormalized = |
3156 | APFloat::getSmallestNormalized(Sem: APFloat::IEEEsingle(), Negative: true); |
3157 | |
3158 | APFloat MaxQuad(APFloat::IEEEquad(), |
3159 | "0x1.ffffffffffffffffffffffffffffp+16383" ); |
3160 | APFloat MinQuad(APFloat::IEEEquad(), |
3161 | "0x0.0000000000000000000000000001p-16382" ); |
3162 | APFloat NMinQuad(APFloat::IEEEquad(), |
3163 | "-0x0.0000000000000000000000000001p-16382" ); |
3164 | |
3165 | const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact; |
3166 | const int UnderflowStatus = APFloat::opUnderflow | APFloat::opInexact; |
3167 | |
3168 | struct { |
3169 | APFloat x; |
3170 | APFloat y; |
3171 | const char *result; |
3172 | int status; |
3173 | int category; |
3174 | APFloat::roundingMode roundingMode = APFloat::rmNearestTiesToEven; |
3175 | } SpecialCaseTests[] = { |
3176 | { .x: PInf, .y: PInf, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3177 | { .x: PInf, .y: MInf, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3178 | { .x: PInf, .y: PZero, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3179 | { .x: PInf, .y: MZero, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3180 | { .x: PInf, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3181 | { .x: PInf, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3182 | { .x: PInf, .y: PNormalValue, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3183 | { .x: PInf, .y: MNormalValue, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3184 | { .x: PInf, .y: PLargestValue, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3185 | { .x: PInf, .y: MLargestValue, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3186 | { .x: PInf, .y: PSmallestValue, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3187 | { .x: PInf, .y: MSmallestValue, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3188 | { .x: PInf, .y: PSmallestNormalized, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3189 | { .x: PInf, .y: MSmallestNormalized, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3190 | { .x: MInf, .y: PInf, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3191 | { .x: MInf, .y: MInf, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3192 | { .x: MInf, .y: PZero, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3193 | { .x: MInf, .y: MZero, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3194 | { .x: MInf, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3195 | { .x: MInf, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3196 | { .x: MInf, .y: PNormalValue, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3197 | { .x: MInf, .y: MNormalValue, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3198 | { .x: MInf, .y: PLargestValue, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3199 | { .x: MInf, .y: MLargestValue, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3200 | { .x: MInf, .y: PSmallestValue, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3201 | { .x: MInf, .y: MSmallestValue, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3202 | { .x: MInf, .y: PSmallestNormalized, .result: "-inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3203 | { .x: MInf, .y: MSmallestNormalized, .result: "inf" , .status: APFloat::opOK, .category: APFloat::fcInfinity }, |
3204 | { .x: PZero, .y: PInf, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3205 | { .x: PZero, .y: MInf, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3206 | { .x: PZero, .y: PZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3207 | { .x: PZero, .y: MZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3208 | { .x: PZero, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3209 | { .x: PZero, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3210 | { .x: PZero, .y: PNormalValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3211 | { .x: PZero, .y: MNormalValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3212 | { .x: PZero, .y: PLargestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3213 | { .x: PZero, .y: MLargestValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3214 | { .x: PZero, .y: PSmallestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3215 | { .x: PZero, .y: MSmallestValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3216 | { .x: PZero, .y: PSmallestNormalized, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3217 | { .x: PZero, .y: MSmallestNormalized, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3218 | { .x: MZero, .y: PInf, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3219 | { .x: MZero, .y: MInf, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3220 | { .x: MZero, .y: PZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3221 | { .x: MZero, .y: MZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3222 | { .x: MZero, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3223 | { .x: MZero, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3224 | { .x: MZero, .y: PNormalValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3225 | { .x: MZero, .y: MNormalValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3226 | { .x: MZero, .y: PLargestValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3227 | { .x: MZero, .y: MLargestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3228 | { .x: MZero, .y: PSmallestValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3229 | { .x: MZero, .y: MSmallestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3230 | { .x: MZero, .y: PSmallestNormalized, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3231 | { .x: MZero, .y: MSmallestNormalized, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3232 | { .x: QNaN, .y: PInf, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3233 | { .x: QNaN, .y: MInf, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3234 | { .x: QNaN, .y: PZero, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3235 | { .x: QNaN, .y: MZero, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3236 | { .x: QNaN, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3237 | { .x: QNaN, .y: SNaN, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3238 | { .x: QNaN, .y: PNormalValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3239 | { .x: QNaN, .y: MNormalValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3240 | { .x: QNaN, .y: PLargestValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3241 | { .x: QNaN, .y: MLargestValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3242 | { .x: QNaN, .y: PSmallestValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3243 | { .x: QNaN, .y: MSmallestValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3244 | { .x: QNaN, .y: PSmallestNormalized, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3245 | { .x: QNaN, .y: MSmallestNormalized, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3246 | { .x: SNaN, .y: PInf, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3247 | { .x: SNaN, .y: MInf, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3248 | { .x: SNaN, .y: PZero, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3249 | { .x: SNaN, .y: MZero, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3250 | { .x: SNaN, .y: QNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3251 | { .x: SNaN, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3252 | { .x: SNaN, .y: PNormalValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3253 | { .x: SNaN, .y: MNormalValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3254 | { .x: SNaN, .y: PLargestValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3255 | { .x: SNaN, .y: MLargestValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3256 | { .x: SNaN, .y: PSmallestValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3257 | { .x: SNaN, .y: MSmallestValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3258 | { .x: SNaN, .y: PSmallestNormalized, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3259 | { .x: SNaN, .y: MSmallestNormalized, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3260 | { .x: PNormalValue, .y: PInf, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3261 | { .x: PNormalValue, .y: MInf, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3262 | { .x: PNormalValue, .y: PZero, .result: "inf" , .status: APFloat::opDivByZero, .category: APFloat::fcInfinity }, |
3263 | { .x: PNormalValue, .y: MZero, .result: "-inf" , .status: APFloat::opDivByZero, .category: APFloat::fcInfinity }, |
3264 | { .x: PNormalValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3265 | { .x: PNormalValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3266 | { .x: PNormalValue, .y: PNormalValue, .result: "0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3267 | { .x: PNormalValue, .y: MNormalValue, .result: "-0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3268 | { .x: PNormalValue, .y: PLargestValue, .result: "0x1p-128" , .status: UnderflowStatus, .category: APFloat::fcNormal }, |
3269 | { .x: PNormalValue, .y: MLargestValue, .result: "-0x1p-128" , .status: UnderflowStatus, .category: APFloat::fcNormal }, |
3270 | { .x: PNormalValue, .y: PSmallestValue, .result: "inf" , .status: OverflowStatus, .category: APFloat::fcInfinity }, |
3271 | { .x: PNormalValue, .y: MSmallestValue, .result: "-inf" , .status: OverflowStatus, .category: APFloat::fcInfinity }, |
3272 | { .x: PNormalValue, .y: PSmallestNormalized, .result: "0x1p+126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3273 | { .x: PNormalValue, .y: MSmallestNormalized, .result: "-0x1p+126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3274 | { .x: MNormalValue, .y: PInf, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3275 | { .x: MNormalValue, .y: MInf, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3276 | { .x: MNormalValue, .y: PZero, .result: "-inf" , .status: APFloat::opDivByZero, .category: APFloat::fcInfinity }, |
3277 | { .x: MNormalValue, .y: MZero, .result: "inf" , .status: APFloat::opDivByZero, .category: APFloat::fcInfinity }, |
3278 | { .x: MNormalValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3279 | { .x: MNormalValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3280 | { .x: MNormalValue, .y: PNormalValue, .result: "-0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3281 | { .x: MNormalValue, .y: MNormalValue, .result: "0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3282 | { .x: MNormalValue, .y: PLargestValue, .result: "-0x1p-128" , .status: UnderflowStatus, .category: APFloat::fcNormal }, |
3283 | { .x: MNormalValue, .y: MLargestValue, .result: "0x1p-128" , .status: UnderflowStatus, .category: APFloat::fcNormal }, |
3284 | { .x: MNormalValue, .y: PSmallestValue, .result: "-inf" , .status: OverflowStatus, .category: APFloat::fcInfinity }, |
3285 | { .x: MNormalValue, .y: MSmallestValue, .result: "inf" , .status: OverflowStatus, .category: APFloat::fcInfinity }, |
3286 | { .x: MNormalValue, .y: PSmallestNormalized, .result: "-0x1p+126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3287 | { .x: MNormalValue, .y: MSmallestNormalized, .result: "0x1p+126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3288 | { .x: PLargestValue, .y: PInf, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3289 | { .x: PLargestValue, .y: MInf, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3290 | { .x: PLargestValue, .y: PZero, .result: "inf" , .status: APFloat::opDivByZero, .category: APFloat::fcInfinity }, |
3291 | { .x: PLargestValue, .y: MZero, .result: "-inf" , .status: APFloat::opDivByZero, .category: APFloat::fcInfinity }, |
3292 | { .x: PLargestValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3293 | { .x: PLargestValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3294 | { .x: PLargestValue, .y: PNormalValue, .result: "0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3295 | { .x: PLargestValue, .y: MNormalValue, .result: "-0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3296 | { .x: PLargestValue, .y: PLargestValue, .result: "0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3297 | { .x: PLargestValue, .y: MLargestValue, .result: "-0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3298 | { .x: PLargestValue, .y: PSmallestValue, .result: "inf" , .status: OverflowStatus, .category: APFloat::fcInfinity }, |
3299 | { .x: PLargestValue, .y: MSmallestValue, .result: "-inf" , .status: OverflowStatus, .category: APFloat::fcInfinity }, |
3300 | { .x: PLargestValue, .y: PSmallestNormalized, .result: "inf" , .status: OverflowStatus, .category: APFloat::fcInfinity }, |
3301 | { .x: PLargestValue, .y: MSmallestNormalized, .result: "-inf" , .status: OverflowStatus, .category: APFloat::fcInfinity }, |
3302 | { .x: MLargestValue, .y: PInf, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3303 | { .x: MLargestValue, .y: MInf, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3304 | { .x: MLargestValue, .y: PZero, .result: "-inf" , .status: APFloat::opDivByZero, .category: APFloat::fcInfinity }, |
3305 | { .x: MLargestValue, .y: MZero, .result: "inf" , .status: APFloat::opDivByZero, .category: APFloat::fcInfinity }, |
3306 | { .x: MLargestValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3307 | { .x: MLargestValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3308 | { .x: MLargestValue, .y: PNormalValue, .result: "-0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3309 | { .x: MLargestValue, .y: MNormalValue, .result: "0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3310 | { .x: MLargestValue, .y: PLargestValue, .result: "-0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3311 | { .x: MLargestValue, .y: MLargestValue, .result: "0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3312 | { .x: MLargestValue, .y: PSmallestValue, .result: "-inf" , .status: OverflowStatus, .category: APFloat::fcInfinity }, |
3313 | { .x: MLargestValue, .y: MSmallestValue, .result: "inf" , .status: OverflowStatus, .category: APFloat::fcInfinity }, |
3314 | { .x: MLargestValue, .y: PSmallestNormalized, .result: "-inf" , .status: OverflowStatus, .category: APFloat::fcInfinity }, |
3315 | { .x: MLargestValue, .y: MSmallestNormalized, .result: "inf" , .status: OverflowStatus, .category: APFloat::fcInfinity }, |
3316 | { .x: PSmallestValue, .y: PInf, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3317 | { .x: PSmallestValue, .y: MInf, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3318 | { .x: PSmallestValue, .y: PZero, .result: "inf" , .status: APFloat::opDivByZero, .category: APFloat::fcInfinity }, |
3319 | { .x: PSmallestValue, .y: MZero, .result: "-inf" , .status: APFloat::opDivByZero, .category: APFloat::fcInfinity }, |
3320 | { .x: PSmallestValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3321 | { .x: PSmallestValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3322 | { .x: PSmallestValue, .y: PNormalValue, .result: "0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3323 | { .x: PSmallestValue, .y: MNormalValue, .result: "-0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3324 | { .x: PSmallestValue, .y: PLargestValue, .result: "0x0p+0" , .status: UnderflowStatus, .category: APFloat::fcZero }, |
3325 | { .x: PSmallestValue, .y: MLargestValue, .result: "-0x0p+0" , .status: UnderflowStatus, .category: APFloat::fcZero }, |
3326 | { .x: PSmallestValue, .y: PSmallestValue, .result: "0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3327 | { .x: PSmallestValue, .y: MSmallestValue, .result: "-0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3328 | { .x: PSmallestValue, .y: PSmallestNormalized, .result: "0x1p-23" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3329 | { .x: PSmallestValue, .y: MSmallestNormalized, .result: "-0x1p-23" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3330 | { .x: MSmallestValue, .y: PInf, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3331 | { .x: MSmallestValue, .y: MInf, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3332 | { .x: MSmallestValue, .y: PZero, .result: "-inf" , .status: APFloat::opDivByZero, .category: APFloat::fcInfinity }, |
3333 | { .x: MSmallestValue, .y: MZero, .result: "inf" , .status: APFloat::opDivByZero, .category: APFloat::fcInfinity }, |
3334 | { .x: MSmallestValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3335 | { .x: MSmallestValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3336 | { .x: MSmallestValue, .y: PNormalValue, .result: "-0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3337 | { .x: MSmallestValue, .y: MNormalValue, .result: "0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3338 | { .x: MSmallestValue, .y: PLargestValue, .result: "-0x0p+0" , .status: UnderflowStatus, .category: APFloat::fcZero }, |
3339 | { .x: MSmallestValue, .y: MLargestValue, .result: "0x0p+0" , .status: UnderflowStatus, .category: APFloat::fcZero }, |
3340 | { .x: MSmallestValue, .y: PSmallestValue, .result: "-0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3341 | { .x: MSmallestValue, .y: MSmallestValue, .result: "0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3342 | { .x: MSmallestValue, .y: PSmallestNormalized, .result: "-0x1p-23" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3343 | { .x: MSmallestValue, .y: MSmallestNormalized, .result: "0x1p-23" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3344 | { .x: PSmallestNormalized, .y: PInf, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3345 | { .x: PSmallestNormalized, .y: MInf, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3346 | { .x: PSmallestNormalized, .y: PZero, .result: "inf" , .status: APFloat::opDivByZero, .category: APFloat::fcInfinity }, |
3347 | { .x: PSmallestNormalized, .y: MZero, .result: "-inf" , .status: APFloat::opDivByZero, .category: APFloat::fcInfinity }, |
3348 | { .x: PSmallestNormalized, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3349 | { .x: PSmallestNormalized, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3350 | { .x: PSmallestNormalized, .y: PNormalValue, .result: "0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3351 | { .x: PSmallestNormalized, .y: MNormalValue, .result: "-0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3352 | { .x: PSmallestNormalized, .y: PLargestValue, .result: "0x0p+0" , .status: UnderflowStatus, .category: APFloat::fcZero }, |
3353 | { .x: PSmallestNormalized, .y: MLargestValue, .result: "-0x0p+0" , .status: UnderflowStatus, .category: APFloat::fcZero }, |
3354 | { .x: PSmallestNormalized, .y: PSmallestValue, .result: "0x1p+23" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3355 | { .x: PSmallestNormalized, .y: MSmallestValue, .result: "-0x1p+23" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3356 | { .x: PSmallestNormalized, .y: PSmallestNormalized, .result: "0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3357 | { .x: PSmallestNormalized, .y: MSmallestNormalized, .result: "-0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3358 | { .x: MSmallestNormalized, .y: PInf, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3359 | { .x: MSmallestNormalized, .y: MInf, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
3360 | { .x: MSmallestNormalized, .y: PZero, .result: "-inf" , .status: APFloat::opDivByZero, .category: APFloat::fcInfinity }, |
3361 | { .x: MSmallestNormalized, .y: MZero, .result: "inf" , .status: APFloat::opDivByZero, .category: APFloat::fcInfinity }, |
3362 | { .x: MSmallestNormalized, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
3363 | { .x: MSmallestNormalized, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
3364 | { .x: MSmallestNormalized, .y: PNormalValue, .result: "-0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3365 | { .x: MSmallestNormalized, .y: MNormalValue, .result: "0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3366 | { .x: MSmallestNormalized, .y: PLargestValue, .result: "-0x0p+0" , .status: UnderflowStatus, .category: APFloat::fcZero }, |
3367 | { .x: MSmallestNormalized, .y: MLargestValue, .result: "0x0p+0" , .status: UnderflowStatus, .category: APFloat::fcZero }, |
3368 | { .x: MSmallestNormalized, .y: PSmallestValue, .result: "-0x1p+23" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3369 | { .x: MSmallestNormalized, .y: MSmallestValue, .result: "0x1p+23" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3370 | { .x: MSmallestNormalized, .y: PSmallestNormalized, .result: "-0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3371 | { .x: MSmallestNormalized, .y: MSmallestNormalized, .result: "0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
3372 | |
3373 | {.x: MaxQuad, .y: NMinQuad, .result: "-inf" , .status: OverflowStatus, .category: APFloat::fcInfinity, |
3374 | .roundingMode: APFloat::rmNearestTiesToEven}, |
3375 | {.x: MaxQuad, .y: NMinQuad, .result: "-0x1.ffffffffffffffffffffffffffffp+16383" , |
3376 | .status: APFloat::opInexact, .category: APFloat::fcNormal, .roundingMode: APFloat::rmTowardPositive}, |
3377 | {.x: MaxQuad, .y: NMinQuad, .result: "-inf" , .status: OverflowStatus, .category: APFloat::fcInfinity, |
3378 | .roundingMode: APFloat::rmTowardNegative}, |
3379 | {.x: MaxQuad, .y: NMinQuad, .result: "-0x1.ffffffffffffffffffffffffffffp+16383" , |
3380 | .status: APFloat::opInexact, .category: APFloat::fcNormal, .roundingMode: APFloat::rmTowardZero}, |
3381 | {.x: MaxQuad, .y: NMinQuad, .result: "-inf" , .status: OverflowStatus, .category: APFloat::fcInfinity, |
3382 | .roundingMode: APFloat::rmNearestTiesToAway}, |
3383 | |
3384 | {.x: MinQuad, .y: MaxQuad, .result: "0" , .status: UnderflowStatus, .category: APFloat::fcZero, |
3385 | .roundingMode: APFloat::rmNearestTiesToEven}, |
3386 | {.x: MinQuad, .y: MaxQuad, .result: "0x0.0000000000000000000000000001p-16382" , |
3387 | .status: UnderflowStatus, .category: APFloat::fcNormal, .roundingMode: APFloat::rmTowardPositive}, |
3388 | {.x: MinQuad, .y: MaxQuad, .result: "0" , .status: UnderflowStatus, .category: APFloat::fcZero, |
3389 | .roundingMode: APFloat::rmTowardNegative}, |
3390 | {.x: MinQuad, .y: MaxQuad, .result: "0" , .status: UnderflowStatus, .category: APFloat::fcZero, |
3391 | .roundingMode: APFloat::rmTowardZero}, |
3392 | {.x: MinQuad, .y: MaxQuad, .result: "0" , .status: UnderflowStatus, .category: APFloat::fcZero, |
3393 | .roundingMode: APFloat::rmNearestTiesToAway}, |
3394 | |
3395 | {.x: NMinQuad, .y: MaxQuad, .result: "-0" , .status: UnderflowStatus, .category: APFloat::fcZero, |
3396 | .roundingMode: APFloat::rmNearestTiesToEven}, |
3397 | {.x: NMinQuad, .y: MaxQuad, .result: "-0" , .status: UnderflowStatus, .category: APFloat::fcZero, |
3398 | .roundingMode: APFloat::rmTowardPositive}, |
3399 | {.x: NMinQuad, .y: MaxQuad, .result: "-0x0.0000000000000000000000000001p-16382" , |
3400 | .status: UnderflowStatus, .category: APFloat::fcNormal, .roundingMode: APFloat::rmTowardNegative}, |
3401 | {.x: NMinQuad, .y: MaxQuad, .result: "-0" , .status: UnderflowStatus, .category: APFloat::fcZero, |
3402 | .roundingMode: APFloat::rmTowardZero}, |
3403 | {.x: NMinQuad, .y: MaxQuad, .result: "-0" , .status: UnderflowStatus, .category: APFloat::fcZero, |
3404 | .roundingMode: APFloat::rmNearestTiesToAway}, |
3405 | }; |
3406 | |
3407 | for (size_t i = 0; i < std::size(SpecialCaseTests); ++i) { |
3408 | APFloat x(SpecialCaseTests[i].x); |
3409 | APFloat y(SpecialCaseTests[i].y); |
3410 | APFloat::opStatus status = x.divide(RHS: y, RM: SpecialCaseTests[i].roundingMode); |
3411 | |
3412 | APFloat result(x.getSemantics(), SpecialCaseTests[i].result); |
3413 | |
3414 | EXPECT_TRUE(result.bitwiseIsEqual(x)); |
3415 | EXPECT_EQ(SpecialCaseTests[i].status, (int)status); |
3416 | EXPECT_EQ(SpecialCaseTests[i].category, (int)x.getCategory()); |
3417 | } |
3418 | } |
3419 | |
3420 | TEST(APFloatTest, operatorOverloads) { |
3421 | // This is mostly testing that these operator overloads compile. |
3422 | APFloat One = APFloat(APFloat::IEEEsingle(), "0x1p+0" ); |
3423 | APFloat Two = APFloat(APFloat::IEEEsingle(), "0x2p+0" ); |
3424 | EXPECT_TRUE(Two.bitwiseIsEqual(One + One)); |
3425 | EXPECT_TRUE(One.bitwiseIsEqual(Two - One)); |
3426 | EXPECT_TRUE(Two.bitwiseIsEqual(One * Two)); |
3427 | EXPECT_TRUE(One.bitwiseIsEqual(Two / Two)); |
3428 | } |
3429 | |
3430 | TEST(APFloatTest, Comparisons) { |
3431 | enum {MNan, MInf, MBig, MOne, MZer, PZer, POne, PBig, PInf, PNan, NumVals}; |
3432 | APFloat Vals[NumVals] = { |
3433 | APFloat::getNaN(Sem: APFloat::IEEEsingle(), Negative: true), |
3434 | APFloat::getInf(Sem: APFloat::IEEEsingle(), Negative: true), |
3435 | APFloat::getLargest(Sem: APFloat::IEEEsingle(), Negative: true), |
3436 | APFloat(APFloat::IEEEsingle(), "-0x1p+0" ), |
3437 | APFloat::getZero(Sem: APFloat::IEEEsingle(), Negative: true), |
3438 | APFloat::getZero(Sem: APFloat::IEEEsingle(), Negative: false), |
3439 | APFloat(APFloat::IEEEsingle(), "0x1p+0" ), |
3440 | APFloat::getLargest(Sem: APFloat::IEEEsingle(), Negative: false), |
3441 | APFloat::getInf(Sem: APFloat::IEEEsingle(), Negative: false), |
3442 | APFloat::getNaN(Sem: APFloat::IEEEsingle(), Negative: false), |
3443 | }; |
3444 | using Relation = void (*)(const APFloat &, const APFloat &); |
3445 | Relation LT = [](const APFloat &LHS, const APFloat &RHS) { |
3446 | EXPECT_FALSE(LHS == RHS); |
3447 | EXPECT_TRUE(LHS != RHS); |
3448 | EXPECT_TRUE(LHS < RHS); |
3449 | EXPECT_FALSE(LHS > RHS); |
3450 | EXPECT_TRUE(LHS <= RHS); |
3451 | EXPECT_FALSE(LHS >= RHS); |
3452 | }; |
3453 | Relation EQ = [](const APFloat &LHS, const APFloat &RHS) { |
3454 | EXPECT_TRUE(LHS == RHS); |
3455 | EXPECT_FALSE(LHS != RHS); |
3456 | EXPECT_FALSE(LHS < RHS); |
3457 | EXPECT_FALSE(LHS > RHS); |
3458 | EXPECT_TRUE(LHS <= RHS); |
3459 | EXPECT_TRUE(LHS >= RHS); |
3460 | }; |
3461 | Relation GT = [](const APFloat &LHS, const APFloat &RHS) { |
3462 | EXPECT_FALSE(LHS == RHS); |
3463 | EXPECT_TRUE(LHS != RHS); |
3464 | EXPECT_FALSE(LHS < RHS); |
3465 | EXPECT_TRUE(LHS > RHS); |
3466 | EXPECT_FALSE(LHS <= RHS); |
3467 | EXPECT_TRUE(LHS >= RHS); |
3468 | }; |
3469 | Relation UN = [](const APFloat &LHS, const APFloat &RHS) { |
3470 | EXPECT_FALSE(LHS == RHS); |
3471 | EXPECT_TRUE(LHS != RHS); |
3472 | EXPECT_FALSE(LHS < RHS); |
3473 | EXPECT_FALSE(LHS > RHS); |
3474 | EXPECT_FALSE(LHS <= RHS); |
3475 | EXPECT_FALSE(LHS >= RHS); |
3476 | }; |
3477 | Relation Relations[NumVals][NumVals] = { |
3478 | // -N -I -B -1 -0 +0 +1 +B +I +N |
3479 | /* MNan */ {UN, UN, UN, UN, UN, UN, UN, UN, UN, UN}, |
3480 | /* MInf */ {UN, EQ, LT, LT, LT, LT, LT, LT, LT, UN}, |
3481 | /* MBig */ {UN, GT, EQ, LT, LT, LT, LT, LT, LT, UN}, |
3482 | /* MOne */ {UN, GT, GT, EQ, LT, LT, LT, LT, LT, UN}, |
3483 | /* MZer */ {UN, GT, GT, GT, EQ, EQ, LT, LT, LT, UN}, |
3484 | /* PZer */ {UN, GT, GT, GT, EQ, EQ, LT, LT, LT, UN}, |
3485 | /* POne */ {UN, GT, GT, GT, GT, GT, EQ, LT, LT, UN}, |
3486 | /* PBig */ {UN, GT, GT, GT, GT, GT, GT, EQ, LT, UN}, |
3487 | /* PInf */ {UN, GT, GT, GT, GT, GT, GT, GT, EQ, UN}, |
3488 | /* PNan */ {UN, UN, UN, UN, UN, UN, UN, UN, UN, UN}, |
3489 | }; |
3490 | for (unsigned I = 0; I < NumVals; ++I) |
3491 | for (unsigned J = 0; J < NumVals; ++J) |
3492 | Relations[I][J](Vals[I], Vals[J]); |
3493 | } |
3494 | |
3495 | TEST(APFloatTest, abs) { |
3496 | APFloat PInf = APFloat::getInf(Sem: APFloat::IEEEsingle(), Negative: false); |
3497 | APFloat MInf = APFloat::getInf(Sem: APFloat::IEEEsingle(), Negative: true); |
3498 | APFloat PZero = APFloat::getZero(Sem: APFloat::IEEEsingle(), Negative: false); |
3499 | APFloat MZero = APFloat::getZero(Sem: APFloat::IEEEsingle(), Negative: true); |
3500 | APFloat PQNaN = APFloat::getNaN(Sem: APFloat::IEEEsingle(), Negative: false); |
3501 | APFloat MQNaN = APFloat::getNaN(Sem: APFloat::IEEEsingle(), Negative: true); |
3502 | APFloat PSNaN = APFloat::getSNaN(Sem: APFloat::IEEEsingle(), Negative: false); |
3503 | APFloat MSNaN = APFloat::getSNaN(Sem: APFloat::IEEEsingle(), Negative: true); |
3504 | APFloat PNormalValue = APFloat(APFloat::IEEEsingle(), "0x1p+0" ); |
3505 | APFloat MNormalValue = APFloat(APFloat::IEEEsingle(), "-0x1p+0" ); |
3506 | APFloat PLargestValue = APFloat::getLargest(Sem: APFloat::IEEEsingle(), Negative: false); |
3507 | APFloat MLargestValue = APFloat::getLargest(Sem: APFloat::IEEEsingle(), Negative: true); |
3508 | APFloat PSmallestValue = APFloat::getSmallest(Sem: APFloat::IEEEsingle(), Negative: false); |
3509 | APFloat MSmallestValue = APFloat::getSmallest(Sem: APFloat::IEEEsingle(), Negative: true); |
3510 | APFloat PSmallestNormalized = |
3511 | APFloat::getSmallestNormalized(Sem: APFloat::IEEEsingle(), Negative: false); |
3512 | APFloat MSmallestNormalized = |
3513 | APFloat::getSmallestNormalized(Sem: APFloat::IEEEsingle(), Negative: true); |
3514 | |
3515 | EXPECT_TRUE(PInf.bitwiseIsEqual(abs(PInf))); |
3516 | EXPECT_TRUE(PInf.bitwiseIsEqual(abs(MInf))); |
3517 | EXPECT_TRUE(PZero.bitwiseIsEqual(abs(PZero))); |
3518 | EXPECT_TRUE(PZero.bitwiseIsEqual(abs(MZero))); |
3519 | EXPECT_TRUE(PQNaN.bitwiseIsEqual(abs(PQNaN))); |
3520 | EXPECT_TRUE(PQNaN.bitwiseIsEqual(abs(MQNaN))); |
3521 | EXPECT_TRUE(PSNaN.bitwiseIsEqual(abs(PSNaN))); |
3522 | EXPECT_TRUE(PSNaN.bitwiseIsEqual(abs(MSNaN))); |
3523 | EXPECT_TRUE(PNormalValue.bitwiseIsEqual(abs(PNormalValue))); |
3524 | EXPECT_TRUE(PNormalValue.bitwiseIsEqual(abs(MNormalValue))); |
3525 | EXPECT_TRUE(PLargestValue.bitwiseIsEqual(abs(PLargestValue))); |
3526 | EXPECT_TRUE(PLargestValue.bitwiseIsEqual(abs(MLargestValue))); |
3527 | EXPECT_TRUE(PSmallestValue.bitwiseIsEqual(abs(PSmallestValue))); |
3528 | EXPECT_TRUE(PSmallestValue.bitwiseIsEqual(abs(MSmallestValue))); |
3529 | EXPECT_TRUE(PSmallestNormalized.bitwiseIsEqual(abs(PSmallestNormalized))); |
3530 | EXPECT_TRUE(PSmallestNormalized.bitwiseIsEqual(abs(MSmallestNormalized))); |
3531 | } |
3532 | |
3533 | TEST(APFloatTest, neg) { |
3534 | APFloat One = APFloat(APFloat::IEEEsingle(), "1.0" ); |
3535 | APFloat NegOne = APFloat(APFloat::IEEEsingle(), "-1.0" ); |
3536 | APFloat Zero = APFloat::getZero(Sem: APFloat::IEEEsingle(), Negative: false); |
3537 | APFloat NegZero = APFloat::getZero(Sem: APFloat::IEEEsingle(), Negative: true); |
3538 | APFloat Inf = APFloat::getInf(Sem: APFloat::IEEEsingle(), Negative: false); |
3539 | APFloat NegInf = APFloat::getInf(Sem: APFloat::IEEEsingle(), Negative: true); |
3540 | APFloat QNaN = APFloat::getNaN(Sem: APFloat::IEEEsingle(), Negative: false); |
3541 | APFloat NegQNaN = APFloat::getNaN(Sem: APFloat::IEEEsingle(), Negative: true); |
3542 | |
3543 | EXPECT_TRUE(NegOne.bitwiseIsEqual(neg(One))); |
3544 | EXPECT_TRUE(One.bitwiseIsEqual(neg(NegOne))); |
3545 | EXPECT_TRUE(NegZero.bitwiseIsEqual(neg(Zero))); |
3546 | EXPECT_TRUE(Zero.bitwiseIsEqual(neg(NegZero))); |
3547 | EXPECT_TRUE(NegInf.bitwiseIsEqual(neg(Inf))); |
3548 | EXPECT_TRUE(Inf.bitwiseIsEqual(neg(NegInf))); |
3549 | EXPECT_TRUE(NegInf.bitwiseIsEqual(neg(Inf))); |
3550 | EXPECT_TRUE(Inf.bitwiseIsEqual(neg(NegInf))); |
3551 | EXPECT_TRUE(NegQNaN.bitwiseIsEqual(neg(QNaN))); |
3552 | EXPECT_TRUE(QNaN.bitwiseIsEqual(neg(NegQNaN))); |
3553 | |
3554 | EXPECT_TRUE(NegOne.bitwiseIsEqual(-One)); |
3555 | EXPECT_TRUE(One.bitwiseIsEqual(-NegOne)); |
3556 | EXPECT_TRUE(NegZero.bitwiseIsEqual(-Zero)); |
3557 | EXPECT_TRUE(Zero.bitwiseIsEqual(-NegZero)); |
3558 | EXPECT_TRUE(NegInf.bitwiseIsEqual(-Inf)); |
3559 | EXPECT_TRUE(Inf.bitwiseIsEqual(-NegInf)); |
3560 | EXPECT_TRUE(NegInf.bitwiseIsEqual(-Inf)); |
3561 | EXPECT_TRUE(Inf.bitwiseIsEqual(-NegInf)); |
3562 | EXPECT_TRUE(NegQNaN.bitwiseIsEqual(-QNaN)); |
3563 | EXPECT_TRUE(QNaN.bitwiseIsEqual(-NegQNaN)); |
3564 | } |
3565 | |
3566 | TEST(APFloatTest, ilogb) { |
3567 | EXPECT_EQ(-1074, ilogb(APFloat::getSmallest(APFloat::IEEEdouble(), false))); |
3568 | EXPECT_EQ(-1074, ilogb(APFloat::getSmallest(APFloat::IEEEdouble(), true))); |
3569 | EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1024" ))); |
3570 | EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1023" ))); |
3571 | EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble(), "-0x1.ffffffffffffep-1023" ))); |
3572 | EXPECT_EQ(-51, ilogb(APFloat(APFloat::IEEEdouble(), "0x1p-51" ))); |
3573 | EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp-1023" ))); |
3574 | EXPECT_EQ(-2, ilogb(APFloat(APFloat::IEEEdouble(), "0x0.ffffp-1" ))); |
3575 | EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble(), "0x1.fffep-1023" ))); |
3576 | EXPECT_EQ(1023, ilogb(APFloat::getLargest(APFloat::IEEEdouble(), false))); |
3577 | EXPECT_EQ(1023, ilogb(APFloat::getLargest(APFloat::IEEEdouble(), true))); |
3578 | |
3579 | |
3580 | EXPECT_EQ(0, ilogb(APFloat(APFloat::IEEEsingle(), "0x1p+0" ))); |
3581 | EXPECT_EQ(0, ilogb(APFloat(APFloat::IEEEsingle(), "-0x1p+0" ))); |
3582 | EXPECT_EQ(42, ilogb(APFloat(APFloat::IEEEsingle(), "0x1p+42" ))); |
3583 | EXPECT_EQ(-42, ilogb(APFloat(APFloat::IEEEsingle(), "0x1p-42" ))); |
3584 | |
3585 | EXPECT_EQ(APFloat::IEK_Inf, |
3586 | ilogb(APFloat::getInf(APFloat::IEEEsingle(), false))); |
3587 | EXPECT_EQ(APFloat::IEK_Inf, |
3588 | ilogb(APFloat::getInf(APFloat::IEEEsingle(), true))); |
3589 | EXPECT_EQ(APFloat::IEK_Zero, |
3590 | ilogb(APFloat::getZero(APFloat::IEEEsingle(), false))); |
3591 | EXPECT_EQ(APFloat::IEK_Zero, |
3592 | ilogb(APFloat::getZero(APFloat::IEEEsingle(), true))); |
3593 | EXPECT_EQ(APFloat::IEK_NaN, |
3594 | ilogb(APFloat::getNaN(APFloat::IEEEsingle(), false))); |
3595 | EXPECT_EQ(APFloat::IEK_NaN, |
3596 | ilogb(APFloat::getSNaN(APFloat::IEEEsingle(), false))); |
3597 | |
3598 | EXPECT_EQ(127, ilogb(APFloat::getLargest(APFloat::IEEEsingle(), false))); |
3599 | EXPECT_EQ(127, ilogb(APFloat::getLargest(APFloat::IEEEsingle(), true))); |
3600 | |
3601 | EXPECT_EQ(-149, ilogb(APFloat::getSmallest(APFloat::IEEEsingle(), false))); |
3602 | EXPECT_EQ(-149, ilogb(APFloat::getSmallest(APFloat::IEEEsingle(), true))); |
3603 | EXPECT_EQ(-126, |
3604 | ilogb(APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false))); |
3605 | EXPECT_EQ(-126, |
3606 | ilogb(APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true))); |
3607 | } |
3608 | |
3609 | TEST(APFloatTest, scalbn) { |
3610 | |
3611 | const APFloat::roundingMode RM = APFloat::rmNearestTiesToEven; |
3612 | EXPECT_TRUE( |
3613 | APFloat(APFloat::IEEEsingle(), "0x1p+0" ) |
3614 | .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEsingle(), "0x1p+0" ), 0, RM))); |
3615 | EXPECT_TRUE( |
3616 | APFloat(APFloat::IEEEsingle(), "0x1p+42" ) |
3617 | .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEsingle(), "0x1p+0" ), 42, RM))); |
3618 | EXPECT_TRUE( |
3619 | APFloat(APFloat::IEEEsingle(), "0x1p-42" ) |
3620 | .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEsingle(), "0x1p+0" ), -42, RM))); |
3621 | |
3622 | APFloat PInf = APFloat::getInf(Sem: APFloat::IEEEsingle(), Negative: false); |
3623 | APFloat MInf = APFloat::getInf(Sem: APFloat::IEEEsingle(), Negative: true); |
3624 | APFloat PZero = APFloat::getZero(Sem: APFloat::IEEEsingle(), Negative: false); |
3625 | APFloat MZero = APFloat::getZero(Sem: APFloat::IEEEsingle(), Negative: true); |
3626 | APFloat QPNaN = APFloat::getNaN(Sem: APFloat::IEEEsingle(), Negative: false); |
3627 | APFloat QMNaN = APFloat::getNaN(Sem: APFloat::IEEEsingle(), Negative: true); |
3628 | APFloat SNaN = APFloat::getSNaN(Sem: APFloat::IEEEsingle(), Negative: false); |
3629 | |
3630 | EXPECT_TRUE(PInf.bitwiseIsEqual(scalbn(PInf, 0, RM))); |
3631 | EXPECT_TRUE(MInf.bitwiseIsEqual(scalbn(MInf, 0, RM))); |
3632 | EXPECT_TRUE(PZero.bitwiseIsEqual(scalbn(PZero, 0, RM))); |
3633 | EXPECT_TRUE(MZero.bitwiseIsEqual(scalbn(MZero, 0, RM))); |
3634 | EXPECT_TRUE(QPNaN.bitwiseIsEqual(scalbn(QPNaN, 0, RM))); |
3635 | EXPECT_TRUE(QMNaN.bitwiseIsEqual(scalbn(QMNaN, 0, RM))); |
3636 | EXPECT_FALSE(scalbn(SNaN, 0, RM).isSignaling()); |
3637 | |
3638 | APFloat ScalbnSNaN = scalbn(X: SNaN, Exp: 1, RM); |
3639 | EXPECT_TRUE(ScalbnSNaN.isNaN() && !ScalbnSNaN.isSignaling()); |
3640 | |
3641 | // Make sure highest bit of payload is preserved. |
3642 | const APInt Payload(64, (UINT64_C(1) << 50) | |
3643 | (UINT64_C(1) << 49) | |
3644 | (UINT64_C(1234) << 32) | |
3645 | 1); |
3646 | |
3647 | APFloat SNaNWithPayload = APFloat::getSNaN(Sem: APFloat::IEEEdouble(), Negative: false, |
3648 | payload: &Payload); |
3649 | APFloat QuietPayload = scalbn(X: SNaNWithPayload, Exp: 1, RM); |
3650 | EXPECT_TRUE(QuietPayload.isNaN() && !QuietPayload.isSignaling()); |
3651 | EXPECT_EQ(Payload, QuietPayload.bitcastToAPInt().getLoBits(51)); |
3652 | |
3653 | EXPECT_TRUE(PInf.bitwiseIsEqual( |
3654 | scalbn(APFloat(APFloat::IEEEsingle(), "0x1p+0" ), 128, RM))); |
3655 | EXPECT_TRUE(MInf.bitwiseIsEqual( |
3656 | scalbn(APFloat(APFloat::IEEEsingle(), "-0x1p+0" ), 128, RM))); |
3657 | EXPECT_TRUE(PInf.bitwiseIsEqual( |
3658 | scalbn(APFloat(APFloat::IEEEsingle(), "0x1p+127" ), 1, RM))); |
3659 | EXPECT_TRUE(PZero.bitwiseIsEqual( |
3660 | scalbn(APFloat(APFloat::IEEEsingle(), "0x1p-127" ), -127, RM))); |
3661 | EXPECT_TRUE(MZero.bitwiseIsEqual( |
3662 | scalbn(APFloat(APFloat::IEEEsingle(), "-0x1p-127" ), -127, RM))); |
3663 | EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "-0x1p-149" ).bitwiseIsEqual( |
3664 | scalbn(APFloat(APFloat::IEEEsingle(), "-0x1p-127" ), -22, RM))); |
3665 | EXPECT_TRUE(PZero.bitwiseIsEqual( |
3666 | scalbn(APFloat(APFloat::IEEEsingle(), "0x1p-126" ), -24, RM))); |
3667 | |
3668 | |
3669 | APFloat SmallestF64 = APFloat::getSmallest(Sem: APFloat::IEEEdouble(), Negative: false); |
3670 | APFloat NegSmallestF64 = APFloat::getSmallest(Sem: APFloat::IEEEdouble(), Negative: true); |
3671 | |
3672 | APFloat LargestF64 = APFloat::getLargest(Sem: APFloat::IEEEdouble(), Negative: false); |
3673 | APFloat NegLargestF64 = APFloat::getLargest(Sem: APFloat::IEEEdouble(), Negative: true); |
3674 | |
3675 | APFloat SmallestNormalizedF64 |
3676 | = APFloat::getSmallestNormalized(Sem: APFloat::IEEEdouble(), Negative: false); |
3677 | APFloat NegSmallestNormalizedF64 |
3678 | = APFloat::getSmallestNormalized(Sem: APFloat::IEEEdouble(), Negative: true); |
3679 | |
3680 | APFloat LargestDenormalF64(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1023" ); |
3681 | APFloat NegLargestDenormalF64(APFloat::IEEEdouble(), "-0x1.ffffffffffffep-1023" ); |
3682 | |
3683 | |
3684 | EXPECT_TRUE(SmallestF64.bitwiseIsEqual( |
3685 | scalbn(APFloat(APFloat::IEEEdouble(), "0x1p-1074" ), 0, RM))); |
3686 | EXPECT_TRUE(NegSmallestF64.bitwiseIsEqual( |
3687 | scalbn(APFloat(APFloat::IEEEdouble(), "-0x1p-1074" ), 0, RM))); |
3688 | |
3689 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p+1023" ) |
3690 | .bitwiseIsEqual(scalbn(SmallestF64, 2097, RM))); |
3691 | |
3692 | EXPECT_TRUE(scalbn(SmallestF64, -2097, RM).isPosZero()); |
3693 | EXPECT_TRUE(scalbn(SmallestF64, -2098, RM).isPosZero()); |
3694 | EXPECT_TRUE(scalbn(SmallestF64, -2099, RM).isPosZero()); |
3695 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p+1022" ) |
3696 | .bitwiseIsEqual(scalbn(SmallestF64, 2096, RM))); |
3697 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p+1023" ) |
3698 | .bitwiseIsEqual(scalbn(SmallestF64, 2097, RM))); |
3699 | EXPECT_TRUE(scalbn(SmallestF64, 2098, RM).isInfinity()); |
3700 | EXPECT_TRUE(scalbn(SmallestF64, 2099, RM).isInfinity()); |
3701 | |
3702 | // Test for integer overflows when adding to exponent. |
3703 | EXPECT_TRUE(scalbn(SmallestF64, -INT_MAX, RM).isPosZero()); |
3704 | EXPECT_TRUE(scalbn(LargestF64, INT_MAX, RM).isInfinity()); |
3705 | |
3706 | EXPECT_TRUE(LargestDenormalF64 |
3707 | .bitwiseIsEqual(scalbn(LargestDenormalF64, 0, RM))); |
3708 | EXPECT_TRUE(NegLargestDenormalF64 |
3709 | .bitwiseIsEqual(scalbn(NegLargestDenormalF64, 0, RM))); |
3710 | |
3711 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1022" ) |
3712 | .bitwiseIsEqual(scalbn(LargestDenormalF64, 1, RM))); |
3713 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1.ffffffffffffep-1021" ) |
3714 | .bitwiseIsEqual(scalbn(NegLargestDenormalF64, 2, RM))); |
3715 | |
3716 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep+1" ) |
3717 | .bitwiseIsEqual(scalbn(LargestDenormalF64, 1024, RM))); |
3718 | EXPECT_TRUE(scalbn(LargestDenormalF64, -1023, RM).isPosZero()); |
3719 | EXPECT_TRUE(scalbn(LargestDenormalF64, -1024, RM).isPosZero()); |
3720 | EXPECT_TRUE(scalbn(LargestDenormalF64, -2048, RM).isPosZero()); |
3721 | EXPECT_TRUE(scalbn(LargestDenormalF64, 2047, RM).isInfinity()); |
3722 | EXPECT_TRUE(scalbn(LargestDenormalF64, 2098, RM).isInfinity()); |
3723 | EXPECT_TRUE(scalbn(LargestDenormalF64, 2099, RM).isInfinity()); |
3724 | |
3725 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-2" ) |
3726 | .bitwiseIsEqual(scalbn(LargestDenormalF64, 1021, RM))); |
3727 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1" ) |
3728 | .bitwiseIsEqual(scalbn(LargestDenormalF64, 1022, RM))); |
3729 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep+0" ) |
3730 | .bitwiseIsEqual(scalbn(LargestDenormalF64, 1023, RM))); |
3731 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep+1023" ) |
3732 | .bitwiseIsEqual(scalbn(LargestDenormalF64, 2046, RM))); |
3733 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p+974" ) |
3734 | .bitwiseIsEqual(scalbn(SmallestF64, 2048, RM))); |
3735 | |
3736 | APFloat RandomDenormalF64(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp+51" ); |
3737 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp-972" ) |
3738 | .bitwiseIsEqual(scalbn(RandomDenormalF64, -1023, RM))); |
3739 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp-1" ) |
3740 | .bitwiseIsEqual(scalbn(RandomDenormalF64, -52, RM))); |
3741 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp-2" ) |
3742 | .bitwiseIsEqual(scalbn(RandomDenormalF64, -53, RM))); |
3743 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp+0" ) |
3744 | .bitwiseIsEqual(scalbn(RandomDenormalF64, -51, RM))); |
3745 | |
3746 | EXPECT_TRUE(scalbn(RandomDenormalF64, -2097, RM).isPosZero()); |
3747 | EXPECT_TRUE(scalbn(RandomDenormalF64, -2090, RM).isPosZero()); |
3748 | |
3749 | |
3750 | EXPECT_TRUE( |
3751 | APFloat(APFloat::IEEEdouble(), "-0x1p-1073" ) |
3752 | .bitwiseIsEqual(scalbn(NegLargestF64, -2097, RM))); |
3753 | |
3754 | EXPECT_TRUE( |
3755 | APFloat(APFloat::IEEEdouble(), "-0x1p-1024" ) |
3756 | .bitwiseIsEqual(scalbn(NegLargestF64, -2048, RM))); |
3757 | |
3758 | EXPECT_TRUE( |
3759 | APFloat(APFloat::IEEEdouble(), "0x1p-1073" ) |
3760 | .bitwiseIsEqual(scalbn(LargestF64, -2097, RM))); |
3761 | |
3762 | EXPECT_TRUE( |
3763 | APFloat(APFloat::IEEEdouble(), "0x1p-1074" ) |
3764 | .bitwiseIsEqual(scalbn(LargestF64, -2098, RM))); |
3765 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1p-1074" ) |
3766 | .bitwiseIsEqual(scalbn(NegLargestF64, -2098, RM))); |
3767 | EXPECT_TRUE(scalbn(NegLargestF64, -2099, RM).isNegZero()); |
3768 | EXPECT_TRUE(scalbn(LargestF64, 1, RM).isInfinity()); |
3769 | |
3770 | |
3771 | EXPECT_TRUE( |
3772 | APFloat(APFloat::IEEEdouble(), "0x1p+0" ) |
3773 | .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEdouble(), "0x1p+52" ), -52, RM))); |
3774 | |
3775 | EXPECT_TRUE( |
3776 | APFloat(APFloat::IEEEdouble(), "0x1p-103" ) |
3777 | .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEdouble(), "0x1p-51" ), -52, RM))); |
3778 | } |
3779 | |
3780 | TEST(APFloatTest, frexp) { |
3781 | const APFloat::roundingMode RM = APFloat::rmNearestTiesToEven; |
3782 | |
3783 | APFloat PZero = APFloat::getZero(Sem: APFloat::IEEEdouble(), Negative: false); |
3784 | APFloat MZero = APFloat::getZero(Sem: APFloat::IEEEdouble(), Negative: true); |
3785 | APFloat One(1.0); |
3786 | APFloat MOne(-1.0); |
3787 | APFloat Two(2.0); |
3788 | APFloat MTwo(-2.0); |
3789 | |
3790 | APFloat LargestDenormal(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1023" ); |
3791 | APFloat NegLargestDenormal(APFloat::IEEEdouble(), "-0x1.ffffffffffffep-1023" ); |
3792 | |
3793 | APFloat Smallest = APFloat::getSmallest(Sem: APFloat::IEEEdouble(), Negative: false); |
3794 | APFloat NegSmallest = APFloat::getSmallest(Sem: APFloat::IEEEdouble(), Negative: true); |
3795 | |
3796 | APFloat Largest = APFloat::getLargest(Sem: APFloat::IEEEdouble(), Negative: false); |
3797 | APFloat NegLargest = APFloat::getLargest(Sem: APFloat::IEEEdouble(), Negative: true); |
3798 | |
3799 | APFloat PInf = APFloat::getInf(Sem: APFloat::IEEEdouble(), Negative: false); |
3800 | APFloat MInf = APFloat::getInf(Sem: APFloat::IEEEdouble(), Negative: true); |
3801 | |
3802 | APFloat QPNaN = APFloat::getNaN(Sem: APFloat::IEEEdouble(), Negative: false); |
3803 | APFloat QMNaN = APFloat::getNaN(Sem: APFloat::IEEEdouble(), Negative: true); |
3804 | APFloat SNaN = APFloat::getSNaN(Sem: APFloat::IEEEdouble(), Negative: false); |
3805 | |
3806 | // Make sure highest bit of payload is preserved. |
3807 | const APInt Payload(64, (UINT64_C(1) << 50) | |
3808 | (UINT64_C(1) << 49) | |
3809 | (UINT64_C(1234) << 32) | |
3810 | 1); |
3811 | |
3812 | APFloat SNaNWithPayload = APFloat::getSNaN(Sem: APFloat::IEEEdouble(), Negative: false, |
3813 | payload: &Payload); |
3814 | |
3815 | APFloat SmallestNormalized |
3816 | = APFloat::getSmallestNormalized(Sem: APFloat::IEEEdouble(), Negative: false); |
3817 | APFloat NegSmallestNormalized |
3818 | = APFloat::getSmallestNormalized(Sem: APFloat::IEEEdouble(), Negative: true); |
3819 | |
3820 | int Exp; |
3821 | APFloat Frac(APFloat::IEEEdouble()); |
3822 | |
3823 | |
3824 | Frac = frexp(X: PZero, Exp, RM); |
3825 | EXPECT_EQ(0, Exp); |
3826 | EXPECT_TRUE(Frac.isPosZero()); |
3827 | |
3828 | Frac = frexp(X: MZero, Exp, RM); |
3829 | EXPECT_EQ(0, Exp); |
3830 | EXPECT_TRUE(Frac.isNegZero()); |
3831 | |
3832 | |
3833 | Frac = frexp(X: One, Exp, RM); |
3834 | EXPECT_EQ(1, Exp); |
3835 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p-1" ).bitwiseIsEqual(Frac)); |
3836 | |
3837 | Frac = frexp(X: MOne, Exp, RM); |
3838 | EXPECT_EQ(1, Exp); |
3839 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1p-1" ).bitwiseIsEqual(Frac)); |
3840 | |
3841 | Frac = frexp(X: LargestDenormal, Exp, RM); |
3842 | EXPECT_EQ(-1022, Exp); |
3843 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1" ).bitwiseIsEqual(Frac)); |
3844 | |
3845 | Frac = frexp(X: NegLargestDenormal, Exp, RM); |
3846 | EXPECT_EQ(-1022, Exp); |
3847 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1.ffffffffffffep-1" ).bitwiseIsEqual(Frac)); |
3848 | |
3849 | |
3850 | Frac = frexp(X: Smallest, Exp, RM); |
3851 | EXPECT_EQ(-1073, Exp); |
3852 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p-1" ).bitwiseIsEqual(Frac)); |
3853 | |
3854 | Frac = frexp(X: NegSmallest, Exp, RM); |
3855 | EXPECT_EQ(-1073, Exp); |
3856 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1p-1" ).bitwiseIsEqual(Frac)); |
3857 | |
3858 | |
3859 | Frac = frexp(X: Largest, Exp, RM); |
3860 | EXPECT_EQ(1024, Exp); |
3861 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.fffffffffffffp-1" ).bitwiseIsEqual(Frac)); |
3862 | |
3863 | Frac = frexp(X: NegLargest, Exp, RM); |
3864 | EXPECT_EQ(1024, Exp); |
3865 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1.fffffffffffffp-1" ).bitwiseIsEqual(Frac)); |
3866 | |
3867 | |
3868 | Frac = frexp(X: PInf, Exp, RM); |
3869 | EXPECT_EQ(INT_MAX, Exp); |
3870 | EXPECT_TRUE(Frac.isInfinity() && !Frac.isNegative()); |
3871 | |
3872 | Frac = frexp(X: MInf, Exp, RM); |
3873 | EXPECT_EQ(INT_MAX, Exp); |
3874 | EXPECT_TRUE(Frac.isInfinity() && Frac.isNegative()); |
3875 | |
3876 | Frac = frexp(X: QPNaN, Exp, RM); |
3877 | EXPECT_EQ(INT_MIN, Exp); |
3878 | EXPECT_TRUE(Frac.isNaN()); |
3879 | |
3880 | Frac = frexp(X: QMNaN, Exp, RM); |
3881 | EXPECT_EQ(INT_MIN, Exp); |
3882 | EXPECT_TRUE(Frac.isNaN()); |
3883 | |
3884 | Frac = frexp(X: SNaN, Exp, RM); |
3885 | EXPECT_EQ(INT_MIN, Exp); |
3886 | EXPECT_TRUE(Frac.isNaN() && !Frac.isSignaling()); |
3887 | |
3888 | Frac = frexp(X: SNaNWithPayload, Exp, RM); |
3889 | EXPECT_EQ(INT_MIN, Exp); |
3890 | EXPECT_TRUE(Frac.isNaN() && !Frac.isSignaling()); |
3891 | EXPECT_EQ(Payload, Frac.bitcastToAPInt().getLoBits(51)); |
3892 | |
3893 | Frac = frexp(X: APFloat(APFloat::IEEEdouble(), "0x0.ffffp-1" ), Exp, RM); |
3894 | EXPECT_EQ(-1, Exp); |
3895 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.fffep-1" ).bitwiseIsEqual(Frac)); |
3896 | |
3897 | Frac = frexp(X: APFloat(APFloat::IEEEdouble(), "0x1p-51" ), Exp, RM); |
3898 | EXPECT_EQ(-50, Exp); |
3899 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p-1" ).bitwiseIsEqual(Frac)); |
3900 | |
3901 | Frac = frexp(X: APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp+51" ), Exp, RM); |
3902 | EXPECT_EQ(52, Exp); |
3903 | EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp-1" ).bitwiseIsEqual(Frac)); |
3904 | } |
3905 | |
3906 | TEST(APFloatTest, mod) { |
3907 | { |
3908 | APFloat f1(APFloat::IEEEdouble(), "1.5" ); |
3909 | APFloat f2(APFloat::IEEEdouble(), "1.0" ); |
3910 | APFloat expected(APFloat::IEEEdouble(), "0.5" ); |
3911 | EXPECT_EQ(f1.mod(f2), APFloat::opOK); |
3912 | EXPECT_TRUE(f1.bitwiseIsEqual(expected)); |
3913 | } |
3914 | { |
3915 | APFloat f1(APFloat::IEEEdouble(), "0.5" ); |
3916 | APFloat f2(APFloat::IEEEdouble(), "1.0" ); |
3917 | APFloat expected(APFloat::IEEEdouble(), "0.5" ); |
3918 | EXPECT_EQ(f1.mod(f2), APFloat::opOK); |
3919 | EXPECT_TRUE(f1.bitwiseIsEqual(expected)); |
3920 | } |
3921 | { |
3922 | APFloat f1(APFloat::IEEEdouble(), "0x1.3333333333333p-2" ); // 0.3 |
3923 | APFloat f2(APFloat::IEEEdouble(), "0x1.47ae147ae147bp-7" ); // 0.01 |
3924 | APFloat expected(APFloat::IEEEdouble(), |
3925 | "0x1.47ae147ae1471p-7" ); // 0.009999999999999983 |
3926 | EXPECT_EQ(f1.mod(f2), APFloat::opOK); |
3927 | EXPECT_TRUE(f1.bitwiseIsEqual(expected)); |
3928 | } |
3929 | { |
3930 | APFloat f1(APFloat::IEEEdouble(), "0x1p64" ); // 1.8446744073709552e19 |
3931 | APFloat f2(APFloat::IEEEdouble(), "1.5" ); |
3932 | APFloat expected(APFloat::IEEEdouble(), "1.0" ); |
3933 | EXPECT_EQ(f1.mod(f2), APFloat::opOK); |
3934 | EXPECT_TRUE(f1.bitwiseIsEqual(expected)); |
3935 | } |
3936 | { |
3937 | APFloat f1(APFloat::IEEEdouble(), "0x1p1000" ); |
3938 | APFloat f2(APFloat::IEEEdouble(), "0x1p-1000" ); |
3939 | APFloat expected(APFloat::IEEEdouble(), "0.0" ); |
3940 | EXPECT_EQ(f1.mod(f2), APFloat::opOK); |
3941 | EXPECT_TRUE(f1.bitwiseIsEqual(expected)); |
3942 | } |
3943 | { |
3944 | APFloat f1(APFloat::IEEEdouble(), "0.0" ); |
3945 | APFloat f2(APFloat::IEEEdouble(), "1.0" ); |
3946 | APFloat expected(APFloat::IEEEdouble(), "0.0" ); |
3947 | EXPECT_EQ(f1.mod(f2), APFloat::opOK); |
3948 | EXPECT_TRUE(f1.bitwiseIsEqual(expected)); |
3949 | } |
3950 | { |
3951 | APFloat f1(APFloat::IEEEdouble(), "1.0" ); |
3952 | APFloat f2(APFloat::IEEEdouble(), "0.0" ); |
3953 | EXPECT_EQ(f1.mod(f2), APFloat::opInvalidOp); |
3954 | EXPECT_TRUE(f1.isNaN()); |
3955 | } |
3956 | { |
3957 | APFloat f1(APFloat::IEEEdouble(), "0.0" ); |
3958 | APFloat f2(APFloat::IEEEdouble(), "0.0" ); |
3959 | EXPECT_EQ(f1.mod(f2), APFloat::opInvalidOp); |
3960 | EXPECT_TRUE(f1.isNaN()); |
3961 | } |
3962 | { |
3963 | APFloat f1 = APFloat::getInf(Sem: APFloat::IEEEdouble(), Negative: false); |
3964 | APFloat f2(APFloat::IEEEdouble(), "1.0" ); |
3965 | EXPECT_EQ(f1.mod(f2), APFloat::opInvalidOp); |
3966 | EXPECT_TRUE(f1.isNaN()); |
3967 | } |
3968 | { |
3969 | APFloat f1(APFloat::IEEEdouble(), "-4.0" ); |
3970 | APFloat f2(APFloat::IEEEdouble(), "-2.0" ); |
3971 | APFloat expected(APFloat::IEEEdouble(), "-0.0" ); |
3972 | EXPECT_EQ(f1.mod(f2), APFloat::opOK); |
3973 | EXPECT_TRUE(f1.bitwiseIsEqual(expected)); |
3974 | } |
3975 | { |
3976 | APFloat f1(APFloat::IEEEdouble(), "-4.0" ); |
3977 | APFloat f2(APFloat::IEEEdouble(), "2.0" ); |
3978 | APFloat expected(APFloat::IEEEdouble(), "-0.0" ); |
3979 | EXPECT_EQ(f1.mod(f2), APFloat::opOK); |
3980 | EXPECT_TRUE(f1.bitwiseIsEqual(expected)); |
3981 | } |
3982 | { |
3983 | // Test E4M3FN mod where the LHS exponent is maxExponent (8) and the RHS is |
3984 | // the max value whose exponent is minExponent (-6). This requires special |
3985 | // logic in the mod implementation to prevent overflow to NaN. |
3986 | APFloat f1(APFloat::Float8E4M3FN(), "0x1p8" ); // 256 |
3987 | APFloat f2(APFloat::Float8E4M3FN(), "0x1.ep-6" ); // 0.029296875 |
3988 | APFloat expected(APFloat::Float8E4M3FN(), "0x1p-8" ); // 0.00390625 |
3989 | EXPECT_EQ(f1.mod(f2), APFloat::opOK); |
3990 | EXPECT_TRUE(f1.bitwiseIsEqual(expected)); |
3991 | } |
3992 | } |
3993 | |
3994 | TEST(APFloatTest, remainder) { |
3995 | // Test Special Cases against each other and normal values. |
3996 | |
3997 | APFloat PInf = APFloat::getInf(Sem: APFloat::IEEEsingle(), Negative: false); |
3998 | APFloat MInf = APFloat::getInf(Sem: APFloat::IEEEsingle(), Negative: true); |
3999 | APFloat PZero = APFloat::getZero(Sem: APFloat::IEEEsingle(), Negative: false); |
4000 | APFloat MZero = APFloat::getZero(Sem: APFloat::IEEEsingle(), Negative: true); |
4001 | APFloat QNaN = APFloat::getNaN(Sem: APFloat::IEEEsingle(), Negative: false); |
4002 | APFloat SNaN = APFloat(APFloat::IEEEsingle(), "snan123" ); |
4003 | APFloat PNormalValue = APFloat(APFloat::IEEEsingle(), "0x1p+0" ); |
4004 | APFloat MNormalValue = APFloat(APFloat::IEEEsingle(), "-0x1p+0" ); |
4005 | APFloat PLargestValue = APFloat::getLargest(Sem: APFloat::IEEEsingle(), Negative: false); |
4006 | APFloat MLargestValue = APFloat::getLargest(Sem: APFloat::IEEEsingle(), Negative: true); |
4007 | APFloat PSmallestValue = APFloat::getSmallest(Sem: APFloat::IEEEsingle(), Negative: false); |
4008 | APFloat MSmallestValue = APFloat::getSmallest(Sem: APFloat::IEEEsingle(), Negative: true); |
4009 | APFloat PSmallestNormalized = |
4010 | APFloat::getSmallestNormalized(Sem: APFloat::IEEEsingle(), Negative: false); |
4011 | APFloat MSmallestNormalized = |
4012 | APFloat::getSmallestNormalized(Sem: APFloat::IEEEsingle(), Negative: true); |
4013 | |
4014 | APFloat PVal1(APFloat::IEEEsingle(), "0x1.fffffep+126" ); |
4015 | APFloat MVal1(APFloat::IEEEsingle(), "-0x1.fffffep+126" ); |
4016 | APFloat PVal2(APFloat::IEEEsingle(), "0x1.fffffep-126" ); |
4017 | APFloat MVal2(APFloat::IEEEsingle(), "-0x1.fffffep-126" ); |
4018 | APFloat PVal3(APFloat::IEEEsingle(), "0x1p-125" ); |
4019 | APFloat MVal3(APFloat::IEEEsingle(), "-0x1p-125" ); |
4020 | APFloat PVal4(APFloat::IEEEsingle(), "0x1p+127" ); |
4021 | APFloat MVal4(APFloat::IEEEsingle(), "-0x1p+127" ); |
4022 | APFloat PVal5(APFloat::IEEEsingle(), "1.5" ); |
4023 | APFloat MVal5(APFloat::IEEEsingle(), "-1.5" ); |
4024 | APFloat PVal6(APFloat::IEEEsingle(), "1" ); |
4025 | APFloat MVal6(APFloat::IEEEsingle(), "-1" ); |
4026 | |
4027 | struct { |
4028 | APFloat x; |
4029 | APFloat y; |
4030 | const char *result; |
4031 | int status; |
4032 | int category; |
4033 | } SpecialCaseTests[] = { |
4034 | { .x: PInf, .y: PInf, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4035 | { .x: PInf, .y: MInf, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4036 | { .x: PInf, .y: PZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4037 | { .x: PInf, .y: MZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4038 | { .x: PInf, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
4039 | { .x: PInf, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4040 | { .x: PInf, .y: PNormalValue, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4041 | { .x: PInf, .y: MNormalValue, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4042 | { .x: PInf, .y: PLargestValue, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4043 | { .x: PInf, .y: MLargestValue, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4044 | { .x: PInf, .y: PSmallestValue, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4045 | { .x: PInf, .y: MSmallestValue, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4046 | { .x: PInf, .y: PSmallestNormalized, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4047 | { .x: PInf, .y: MSmallestNormalized, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4048 | { .x: MInf, .y: PInf, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4049 | { .x: MInf, .y: MInf, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4050 | { .x: MInf, .y: PZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4051 | { .x: MInf, .y: MZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4052 | { .x: MInf, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
4053 | { .x: MInf, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4054 | { .x: MInf, .y: PNormalValue, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4055 | { .x: MInf, .y: MNormalValue, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4056 | { .x: MInf, .y: PLargestValue, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4057 | { .x: MInf, .y: MLargestValue, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4058 | { .x: MInf, .y: PSmallestValue, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4059 | { .x: MInf, .y: MSmallestValue, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4060 | { .x: MInf, .y: PSmallestNormalized, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4061 | { .x: MInf, .y: MSmallestNormalized, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4062 | { .x: PZero, .y: PInf, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4063 | { .x: PZero, .y: MInf, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4064 | { .x: PZero, .y: PZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4065 | { .x: PZero, .y: MZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4066 | { .x: PZero, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
4067 | { .x: PZero, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4068 | { .x: PZero, .y: PNormalValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4069 | { .x: PZero, .y: MNormalValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4070 | { .x: PZero, .y: PLargestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4071 | { .x: PZero, .y: MLargestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4072 | { .x: PZero, .y: PSmallestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4073 | { .x: PZero, .y: MSmallestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4074 | { .x: PZero, .y: PSmallestNormalized, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4075 | { .x: PZero, .y: MSmallestNormalized, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4076 | { .x: MZero, .y: PInf, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4077 | { .x: MZero, .y: MInf, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4078 | { .x: MZero, .y: PZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4079 | { .x: MZero, .y: MZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4080 | { .x: MZero, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
4081 | { .x: MZero, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4082 | { .x: MZero, .y: PNormalValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4083 | { .x: MZero, .y: MNormalValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4084 | { .x: MZero, .y: PLargestValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4085 | { .x: MZero, .y: MLargestValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4086 | { .x: MZero, .y: PSmallestValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4087 | { .x: MZero, .y: MSmallestValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4088 | { .x: MZero, .y: PSmallestNormalized, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4089 | { .x: MZero, .y: MSmallestNormalized, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4090 | { .x: QNaN, .y: PInf, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
4091 | { .x: QNaN, .y: MInf, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
4092 | { .x: QNaN, .y: PZero, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
4093 | { .x: QNaN, .y: MZero, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
4094 | { .x: QNaN, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
4095 | { .x: QNaN, .y: SNaN, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4096 | { .x: QNaN, .y: PNormalValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
4097 | { .x: QNaN, .y: MNormalValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
4098 | { .x: QNaN, .y: PLargestValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
4099 | { .x: QNaN, .y: MLargestValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
4100 | { .x: QNaN, .y: PSmallestValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
4101 | { .x: QNaN, .y: MSmallestValue, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
4102 | { .x: QNaN, .y: PSmallestNormalized, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
4103 | { .x: QNaN, .y: MSmallestNormalized, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
4104 | { .x: SNaN, .y: PInf, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4105 | { .x: SNaN, .y: MInf, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4106 | { .x: SNaN, .y: PZero, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4107 | { .x: SNaN, .y: MZero, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4108 | { .x: SNaN, .y: QNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4109 | { .x: SNaN, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4110 | { .x: SNaN, .y: PNormalValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4111 | { .x: SNaN, .y: MNormalValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4112 | { .x: SNaN, .y: PLargestValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4113 | { .x: SNaN, .y: MLargestValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4114 | { .x: SNaN, .y: PSmallestValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4115 | { .x: SNaN, .y: MSmallestValue, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4116 | { .x: SNaN, .y: PSmallestNormalized, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4117 | { .x: SNaN, .y: MSmallestNormalized, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4118 | { .x: PNormalValue, .y: PInf, .result: "0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4119 | { .x: PNormalValue, .y: MInf, .result: "0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4120 | { .x: PNormalValue, .y: PZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4121 | { .x: PNormalValue, .y: MZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4122 | { .x: PNormalValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
4123 | { .x: PNormalValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4124 | { .x: PNormalValue, .y: PNormalValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4125 | { .x: PNormalValue, .y: MNormalValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4126 | { .x: PNormalValue, .y: PLargestValue, .result: "0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4127 | { .x: PNormalValue, .y: MLargestValue, .result: "0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4128 | { .x: PNormalValue, .y: PSmallestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4129 | { .x: PNormalValue, .y: MSmallestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4130 | { .x: PNormalValue, .y: PSmallestNormalized, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4131 | { .x: PNormalValue, .y: MSmallestNormalized, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4132 | { .x: MNormalValue, .y: PInf, .result: "-0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4133 | { .x: MNormalValue, .y: MInf, .result: "-0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4134 | { .x: MNormalValue, .y: PZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4135 | { .x: MNormalValue, .y: MZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4136 | { .x: MNormalValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
4137 | { .x: MNormalValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4138 | { .x: MNormalValue, .y: PNormalValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4139 | { .x: MNormalValue, .y: MNormalValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4140 | { .x: MNormalValue, .y: PLargestValue, .result: "-0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4141 | { .x: MNormalValue, .y: MLargestValue, .result: "-0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4142 | { .x: MNormalValue, .y: PSmallestValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4143 | { .x: MNormalValue, .y: MSmallestValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4144 | { .x: MNormalValue, .y: PSmallestNormalized, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4145 | { .x: MNormalValue, .y: MSmallestNormalized, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4146 | { .x: PLargestValue, .y: PInf, .result: "0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4147 | { .x: PLargestValue, .y: MInf, .result: "0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4148 | { .x: PLargestValue, .y: PZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4149 | { .x: PLargestValue, .y: MZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4150 | { .x: PLargestValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
4151 | { .x: PLargestValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4152 | { .x: PLargestValue, .y: PNormalValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4153 | { .x: PLargestValue, .y: MNormalValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4154 | { .x: PLargestValue, .y: PLargestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4155 | { .x: PLargestValue, .y: MLargestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4156 | { .x: PLargestValue, .y: PSmallestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4157 | { .x: PLargestValue, .y: MSmallestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4158 | { .x: PLargestValue, .y: PSmallestNormalized, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4159 | { .x: PLargestValue, .y: MSmallestNormalized, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4160 | { .x: MLargestValue, .y: PInf, .result: "-0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4161 | { .x: MLargestValue, .y: MInf, .result: "-0x1.fffffep+127" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4162 | { .x: MLargestValue, .y: PZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4163 | { .x: MLargestValue, .y: MZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4164 | { .x: MLargestValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
4165 | { .x: MLargestValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4166 | { .x: MLargestValue, .y: PNormalValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4167 | { .x: MLargestValue, .y: MNormalValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4168 | { .x: MLargestValue, .y: PLargestValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4169 | { .x: MLargestValue, .y: MLargestValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4170 | { .x: MLargestValue, .y: PSmallestValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4171 | { .x: MLargestValue, .y: MSmallestValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4172 | { .x: MLargestValue, .y: PSmallestNormalized, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4173 | { .x: MLargestValue, .y: MSmallestNormalized, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4174 | { .x: PSmallestValue, .y: PInf, .result: "0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4175 | { .x: PSmallestValue, .y: MInf, .result: "0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4176 | { .x: PSmallestValue, .y: PZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4177 | { .x: PSmallestValue, .y: MZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4178 | { .x: PSmallestValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
4179 | { .x: PSmallestValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4180 | { .x: PSmallestValue, .y: PNormalValue, .result: "0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4181 | { .x: PSmallestValue, .y: MNormalValue, .result: "0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4182 | { .x: PSmallestValue, .y: PLargestValue, .result: "0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4183 | { .x: PSmallestValue, .y: MLargestValue, .result: "0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4184 | { .x: PSmallestValue, .y: PSmallestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4185 | { .x: PSmallestValue, .y: MSmallestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4186 | { .x: PSmallestValue, .y: PSmallestNormalized, .result: "0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4187 | { .x: PSmallestValue, .y: MSmallestNormalized, .result: "0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4188 | { .x: MSmallestValue, .y: PInf, .result: "-0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4189 | { .x: MSmallestValue, .y: MInf, .result: "-0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4190 | { .x: MSmallestValue, .y: PZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4191 | { .x: MSmallestValue, .y: MZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4192 | { .x: MSmallestValue, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
4193 | { .x: MSmallestValue, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4194 | { .x: MSmallestValue, .y: PNormalValue, .result: "-0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4195 | { .x: MSmallestValue, .y: MNormalValue, .result: "-0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4196 | { .x: MSmallestValue, .y: PLargestValue, .result: "-0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4197 | { .x: MSmallestValue, .y: MLargestValue, .result: "-0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4198 | { .x: MSmallestValue, .y: PSmallestValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4199 | { .x: MSmallestValue, .y: MSmallestValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4200 | { .x: MSmallestValue, .y: PSmallestNormalized, .result: "-0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4201 | { .x: MSmallestValue, .y: MSmallestNormalized, .result: "-0x1p-149" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4202 | { .x: PSmallestNormalized, .y: PInf, .result: "0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4203 | { .x: PSmallestNormalized, .y: MInf, .result: "0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4204 | { .x: PSmallestNormalized, .y: PZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4205 | { .x: PSmallestNormalized, .y: MZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4206 | { .x: PSmallestNormalized, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
4207 | { .x: PSmallestNormalized, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4208 | { .x: PSmallestNormalized, .y: PNormalValue, .result: "0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4209 | { .x: PSmallestNormalized, .y: MNormalValue, .result: "0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4210 | { .x: PSmallestNormalized, .y: PLargestValue, .result: "0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4211 | { .x: PSmallestNormalized, .y: MLargestValue, .result: "0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4212 | { .x: PSmallestNormalized, .y: PSmallestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4213 | { .x: PSmallestNormalized, .y: MSmallestValue, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4214 | { .x: PSmallestNormalized, .y: PSmallestNormalized, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4215 | { .x: PSmallestNormalized, .y: MSmallestNormalized, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4216 | { .x: MSmallestNormalized, .y: PInf, .result: "-0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4217 | { .x: MSmallestNormalized, .y: MInf, .result: "-0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4218 | { .x: MSmallestNormalized, .y: PZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4219 | { .x: MSmallestNormalized, .y: MZero, .result: "nan" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4220 | { .x: MSmallestNormalized, .y: QNaN, .result: "nan" , .status: APFloat::opOK, .category: APFloat::fcNaN }, |
4221 | { .x: MSmallestNormalized, .y: SNaN, .result: "nan123" , .status: APFloat::opInvalidOp, .category: APFloat::fcNaN }, |
4222 | { .x: MSmallestNormalized, .y: PNormalValue, .result: "-0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4223 | { .x: MSmallestNormalized, .y: MNormalValue, .result: "-0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4224 | { .x: MSmallestNormalized, .y: PLargestValue, .result: "-0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4225 | { .x: MSmallestNormalized, .y: MLargestValue, .result: "-0x1p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4226 | { .x: MSmallestNormalized, .y: PSmallestValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4227 | { .x: MSmallestNormalized, .y: MSmallestValue, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4228 | { .x: MSmallestNormalized, .y: PSmallestNormalized, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4229 | { .x: MSmallestNormalized, .y: MSmallestNormalized, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4230 | |
4231 | { .x: PVal1, .y: PVal1, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4232 | { .x: PVal1, .y: MVal1, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4233 | { .x: PVal1, .y: PVal2, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4234 | { .x: PVal1, .y: MVal2, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4235 | { .x: PVal1, .y: PVal3, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4236 | { .x: PVal1, .y: MVal3, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4237 | { .x: PVal1, .y: PVal4, .result: "-0x1p+103" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4238 | { .x: PVal1, .y: MVal4, .result: "-0x1p+103" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4239 | { .x: PVal1, .y: PVal5, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4240 | { .x: PVal1, .y: MVal5, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4241 | { .x: PVal1, .y: PVal6, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4242 | { .x: PVal1, .y: MVal6, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4243 | { .x: MVal1, .y: PVal1, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4244 | { .x: MVal1, .y: MVal1, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4245 | { .x: MVal1, .y: PVal2, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4246 | { .x: MVal1, .y: MVal2, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4247 | { .x: MVal1, .y: PVal3, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4248 | { .x: MVal1, .y: MVal3, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4249 | { .x: MVal1, .y: PVal4, .result: "0x1p+103" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4250 | { .x: MVal1, .y: MVal4, .result: "0x1p+103" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4251 | { .x: MVal1, .y: PVal5, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4252 | { .x: MVal1, .y: MVal5, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4253 | { .x: MVal1, .y: PVal6, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4254 | { .x: MVal1, .y: MVal6, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4255 | { .x: PVal2, .y: PVal1, .result: "0x1.fffffep-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4256 | { .x: PVal2, .y: MVal1, .result: "0x1.fffffep-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4257 | { .x: PVal2, .y: PVal2, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4258 | { .x: PVal2, .y: MVal2, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4259 | { .x: PVal2, .y: PVal3, .result: "-0x0.000002p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4260 | { .x: PVal2, .y: MVal3, .result: "-0x0.000002p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4261 | { .x: PVal2, .y: PVal4, .result: "0x1.fffffep-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4262 | { .x: PVal2, .y: MVal4, .result: "0x1.fffffep-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4263 | { .x: PVal2, .y: PVal5, .result: "0x1.fffffep-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4264 | { .x: PVal2, .y: MVal5, .result: "0x1.fffffep-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4265 | { .x: PVal2, .y: PVal6, .result: "0x1.fffffep-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4266 | { .x: PVal2, .y: MVal6, .result: "0x1.fffffep-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4267 | { .x: MVal2, .y: PVal1, .result: "-0x1.fffffep-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4268 | { .x: MVal2, .y: MVal1, .result: "-0x1.fffffep-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4269 | { .x: MVal2, .y: PVal2, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4270 | { .x: MVal2, .y: MVal2, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4271 | { .x: MVal2, .y: PVal3, .result: "0x0.000002p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4272 | { .x: MVal2, .y: MVal3, .result: "0x0.000002p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4273 | { .x: MVal2, .y: PVal4, .result: "-0x1.fffffep-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4274 | { .x: MVal2, .y: MVal4, .result: "-0x1.fffffep-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4275 | { .x: MVal2, .y: PVal5, .result: "-0x1.fffffep-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4276 | { .x: MVal2, .y: MVal5, .result: "-0x1.fffffep-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4277 | { .x: MVal2, .y: PVal6, .result: "-0x1.fffffep-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4278 | { .x: MVal2, .y: MVal6, .result: "-0x1.fffffep-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4279 | { .x: PVal3, .y: PVal1, .result: "0x1p-125" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4280 | { .x: PVal3, .y: MVal1, .result: "0x1p-125" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4281 | { .x: PVal3, .y: PVal2, .result: "0x0.000002p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4282 | { .x: PVal3, .y: MVal2, .result: "0x0.000002p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4283 | { .x: PVal3, .y: PVal3, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4284 | { .x: PVal3, .y: MVal3, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4285 | { .x: PVal3, .y: PVal4, .result: "0x1p-125" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4286 | { .x: PVal3, .y: MVal4, .result: "0x1p-125" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4287 | { .x: PVal3, .y: PVal5, .result: "0x1p-125" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4288 | { .x: PVal3, .y: MVal5, .result: "0x1p-125" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4289 | { .x: PVal3, .y: PVal6, .result: "0x1p-125" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4290 | { .x: PVal3, .y: MVal6, .result: "0x1p-125" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4291 | { .x: MVal3, .y: PVal1, .result: "-0x1p-125" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4292 | { .x: MVal3, .y: MVal1, .result: "-0x1p-125" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4293 | { .x: MVal3, .y: PVal2, .result: "-0x0.000002p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4294 | { .x: MVal3, .y: MVal2, .result: "-0x0.000002p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4295 | { .x: MVal3, .y: PVal3, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4296 | { .x: MVal3, .y: MVal3, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4297 | { .x: MVal3, .y: PVal4, .result: "-0x1p-125" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4298 | { .x: MVal3, .y: MVal4, .result: "-0x1p-125" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4299 | { .x: MVal3, .y: PVal5, .result: "-0x1p-125" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4300 | { .x: MVal3, .y: MVal5, .result: "-0x1p-125" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4301 | { .x: MVal3, .y: PVal6, .result: "-0x1p-125" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4302 | { .x: MVal3, .y: MVal6, .result: "-0x1p-125" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4303 | { .x: PVal4, .y: PVal1, .result: "0x1p+103" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4304 | { .x: PVal4, .y: MVal1, .result: "0x1p+103" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4305 | { .x: PVal4, .y: PVal2, .result: "0x0.002p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4306 | { .x: PVal4, .y: MVal2, .result: "0x0.002p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4307 | { .x: PVal4, .y: PVal3, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4308 | { .x: PVal4, .y: MVal3, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4309 | { .x: PVal4, .y: PVal4, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4310 | { .x: PVal4, .y: MVal4, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4311 | { .x: PVal4, .y: PVal5, .result: "0.5" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4312 | { .x: PVal4, .y: MVal5, .result: "0.5" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4313 | { .x: PVal4, .y: PVal6, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4314 | { .x: PVal4, .y: MVal6, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4315 | { .x: MVal4, .y: PVal1, .result: "-0x1p+103" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4316 | { .x: MVal4, .y: MVal1, .result: "-0x1p+103" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4317 | { .x: MVal4, .y: PVal2, .result: "-0x0.002p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4318 | { .x: MVal4, .y: MVal2, .result: "-0x0.002p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4319 | { .x: MVal4, .y: PVal3, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4320 | { .x: MVal4, .y: MVal3, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4321 | { .x: MVal4, .y: PVal4, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4322 | { .x: MVal4, .y: MVal4, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4323 | { .x: MVal4, .y: PVal5, .result: "-0.5" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4324 | { .x: MVal4, .y: MVal5, .result: "-0.5" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4325 | { .x: MVal4, .y: PVal6, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4326 | { .x: MVal4, .y: MVal6, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4327 | { .x: PVal5, .y: PVal1, .result: "1.5" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4328 | { .x: PVal5, .y: MVal1, .result: "1.5" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4329 | { .x: PVal5, .y: PVal2, .result: "0x0.00006p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4330 | { .x: PVal5, .y: MVal2, .result: "0x0.00006p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4331 | { .x: PVal5, .y: PVal3, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4332 | { .x: PVal5, .y: MVal3, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4333 | { .x: PVal5, .y: PVal4, .result: "1.5" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4334 | { .x: PVal5, .y: MVal4, .result: "1.5" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4335 | { .x: PVal5, .y: PVal5, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4336 | { .x: PVal5, .y: MVal5, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4337 | { .x: PVal5, .y: PVal6, .result: "-0.5" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4338 | { .x: PVal5, .y: MVal6, .result: "-0.5" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4339 | { .x: MVal5, .y: PVal1, .result: "-1.5" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4340 | { .x: MVal5, .y: MVal1, .result: "-1.5" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4341 | { .x: MVal5, .y: PVal2, .result: "-0x0.00006p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4342 | { .x: MVal5, .y: MVal2, .result: "-0x0.00006p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4343 | { .x: MVal5, .y: PVal3, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4344 | { .x: MVal5, .y: MVal3, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4345 | { .x: MVal5, .y: PVal4, .result: "-1.5" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4346 | { .x: MVal5, .y: MVal4, .result: "-1.5" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4347 | { .x: MVal5, .y: PVal5, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4348 | { .x: MVal5, .y: MVal5, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4349 | { .x: MVal5, .y: PVal6, .result: "0.5" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4350 | { .x: MVal5, .y: MVal6, .result: "0.5" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4351 | { .x: PVal6, .y: PVal1, .result: "0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4352 | { .x: PVal6, .y: MVal1, .result: "0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4353 | { .x: PVal6, .y: PVal2, .result: "0x0.00004p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4354 | { .x: PVal6, .y: MVal2, .result: "0x0.00004p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4355 | { .x: PVal6, .y: PVal3, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4356 | { .x: PVal6, .y: MVal3, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4357 | { .x: PVal6, .y: PVal4, .result: "0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4358 | { .x: PVal6, .y: MVal4, .result: "0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4359 | { .x: PVal6, .y: PVal5, .result: "-0.5" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4360 | { .x: PVal6, .y: MVal5, .result: "-0.5" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4361 | { .x: PVal6, .y: PVal6, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4362 | { .x: PVal6, .y: MVal6, .result: "0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4363 | { .x: MVal6, .y: PVal1, .result: "-0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4364 | { .x: MVal6, .y: MVal1, .result: "-0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4365 | { .x: MVal6, .y: PVal2, .result: "-0x0.00004p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4366 | { .x: MVal6, .y: MVal2, .result: "-0x0.00004p-126" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4367 | { .x: MVal6, .y: PVal3, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4368 | { .x: MVal6, .y: MVal3, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4369 | { .x: MVal6, .y: PVal4, .result: "-0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4370 | { .x: MVal6, .y: MVal4, .result: "-0x1p+0" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4371 | { .x: MVal6, .y: PVal5, .result: "0.5" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4372 | { .x: MVal6, .y: MVal5, .result: "0.5" , .status: APFloat::opOK, .category: APFloat::fcNormal }, |
4373 | { .x: MVal6, .y: PVal6, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4374 | { .x: MVal6, .y: MVal6, .result: "-0x0p+0" , .status: APFloat::opOK, .category: APFloat::fcZero }, |
4375 | }; |
4376 | |
4377 | for (size_t i = 0; i < std::size(SpecialCaseTests); ++i) { |
4378 | APFloat x(SpecialCaseTests[i].x); |
4379 | APFloat y(SpecialCaseTests[i].y); |
4380 | APFloat::opStatus status = x.remainder(RHS: y); |
4381 | |
4382 | APFloat result(x.getSemantics(), SpecialCaseTests[i].result); |
4383 | |
4384 | EXPECT_TRUE(result.bitwiseIsEqual(x)); |
4385 | EXPECT_EQ(SpecialCaseTests[i].status, (int)status); |
4386 | EXPECT_EQ(SpecialCaseTests[i].category, (int)x.getCategory()); |
4387 | } |
4388 | |
4389 | { |
4390 | APFloat f1(APFloat::IEEEdouble(), "0x1.3333333333333p-2" ); // 0.3 |
4391 | APFloat f2(APFloat::IEEEdouble(), "0x1.47ae147ae147bp-7" ); // 0.01 |
4392 | APFloat expected(APFloat::IEEEdouble(), "-0x1.4p-56" ); |
4393 | EXPECT_EQ(APFloat::opOK, f1.remainder(f2)); |
4394 | EXPECT_TRUE(f1.bitwiseIsEqual(expected)); |
4395 | } |
4396 | { |
4397 | APFloat f1(APFloat::IEEEdouble(), "0x1p64" ); // 1.8446744073709552e19 |
4398 | APFloat f2(APFloat::IEEEdouble(), "1.5" ); |
4399 | APFloat expected(APFloat::IEEEdouble(), "-0.5" ); |
4400 | EXPECT_EQ(APFloat::opOK, f1.remainder(f2)); |
4401 | EXPECT_TRUE(f1.bitwiseIsEqual(expected)); |
4402 | } |
4403 | { |
4404 | APFloat f1(APFloat::IEEEdouble(), "0x1p1000" ); |
4405 | APFloat f2(APFloat::IEEEdouble(), "0x1p-1000" ); |
4406 | APFloat expected(APFloat::IEEEdouble(), "0.0" ); |
4407 | EXPECT_EQ(APFloat::opOK, f1.remainder(f2)); |
4408 | EXPECT_TRUE(f1.bitwiseIsEqual(expected)); |
4409 | } |
4410 | { |
4411 | APFloat f1 = APFloat::getInf(Sem: APFloat::IEEEdouble(), Negative: false); |
4412 | APFloat f2(APFloat::IEEEdouble(), "1.0" ); |
4413 | EXPECT_EQ(f1.remainder(f2), APFloat::opInvalidOp); |
4414 | EXPECT_TRUE(f1.isNaN()); |
4415 | } |
4416 | { |
4417 | APFloat f1(APFloat::IEEEdouble(), "-4.0" ); |
4418 | APFloat f2(APFloat::IEEEdouble(), "-2.0" ); |
4419 | APFloat expected(APFloat::IEEEdouble(), "-0.0" ); |
4420 | EXPECT_EQ(APFloat::opOK, f1.remainder(f2)); |
4421 | EXPECT_TRUE(f1.bitwiseIsEqual(expected)); |
4422 | } |
4423 | { |
4424 | APFloat f1(APFloat::IEEEdouble(), "-4.0" ); |
4425 | APFloat f2(APFloat::IEEEdouble(), "2.0" ); |
4426 | APFloat expected(APFloat::IEEEdouble(), "-0.0" ); |
4427 | EXPECT_EQ(APFloat::opOK, f1.remainder(f2)); |
4428 | EXPECT_TRUE(f1.bitwiseIsEqual(expected)); |
4429 | } |
4430 | } |
4431 | |
4432 | TEST(APFloatTest, PPCDoubleDoubleAddSpecial) { |
4433 | using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, |
4434 | APFloat::fltCategory, APFloat::roundingMode>; |
4435 | DataType Data[] = { |
4436 | // (1 + 0) + (-1 + 0) = fcZero |
4437 | std::make_tuple(args: 0x3ff0000000000000ull, args: 0, args: 0xbff0000000000000ull, args: 0, |
4438 | args: APFloat::fcZero, args: APFloat::rmNearestTiesToEven), |
4439 | // LDBL_MAX + (1.1 >> (1023 - 106) + 0)) = fcInfinity |
4440 | std::make_tuple(args: 0x7fefffffffffffffull, args: 0x7c8ffffffffffffeull, |
4441 | args: 0x7948000000000000ull, args: 0ull, args: APFloat::fcInfinity, |
4442 | args: APFloat::rmNearestTiesToEven), |
4443 | // TODO: change the 4th 0x75effffffffffffe to 0x75efffffffffffff when |
4444 | // semPPCDoubleDoubleLegacy is gone. |
4445 | // LDBL_MAX + (1.011111... >> (1023 - 106) + (1.1111111...0 >> (1023 - |
4446 | // 160))) = fcNormal |
4447 | std::make_tuple(args: 0x7fefffffffffffffull, args: 0x7c8ffffffffffffeull, |
4448 | args: 0x7947ffffffffffffull, args: 0x75effffffffffffeull, |
4449 | args: APFloat::fcNormal, args: APFloat::rmNearestTiesToEven), |
4450 | // LDBL_MAX + (1.1 >> (1023 - 106) + 0)) = fcInfinity |
4451 | std::make_tuple(args: 0x7fefffffffffffffull, args: 0x7c8ffffffffffffeull, |
4452 | args: 0x7fefffffffffffffull, args: 0x7c8ffffffffffffeull, |
4453 | args: APFloat::fcInfinity, args: APFloat::rmNearestTiesToEven), |
4454 | // NaN + (1 + 0) = fcNaN |
4455 | std::make_tuple(args: 0x7ff8000000000000ull, args: 0, args: 0x3ff0000000000000ull, args: 0, |
4456 | args: APFloat::fcNaN, args: APFloat::rmNearestTiesToEven), |
4457 | }; |
4458 | |
4459 | for (auto Tp : Data) { |
4460 | uint64_t Op1[2], Op2[2]; |
4461 | APFloat::fltCategory Expected; |
4462 | APFloat::roundingMode RM; |
4463 | std::tie(args&: Op1[0], args&: Op1[1], args&: Op2[0], args&: Op2[1], args&: Expected, args&: RM) = Tp; |
4464 | |
4465 | { |
4466 | APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1)); |
4467 | APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2)); |
4468 | A1.add(RHS: A2, RM); |
4469 | |
4470 | EXPECT_EQ(Expected, A1.getCategory()) |
4471 | << formatv(Fmt: "({0:x} + {1:x}) + ({2:x} + {3:x})" , Vals&: Op1[0], Vals&: Op1[1], |
4472 | Vals&: Op2[0], Vals&: Op2[1]) |
4473 | .str(); |
4474 | } |
4475 | { |
4476 | APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1)); |
4477 | APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2)); |
4478 | A2.add(RHS: A1, RM); |
4479 | |
4480 | EXPECT_EQ(Expected, A2.getCategory()) |
4481 | << formatv(Fmt: "({0:x} + {1:x}) + ({2:x} + {3:x})" , Vals&: Op2[0], Vals&: Op2[1], |
4482 | Vals&: Op1[0], Vals&: Op1[1]) |
4483 | .str(); |
4484 | } |
4485 | } |
4486 | } |
4487 | |
4488 | TEST(APFloatTest, PPCDoubleDoubleAdd) { |
4489 | using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, |
4490 | uint64_t, APFloat::roundingMode>; |
4491 | DataType Data[] = { |
4492 | // (1 + 0) + (1e-105 + 0) = (1 + 1e-105) |
4493 | std::make_tuple(args: 0x3ff0000000000000ull, args: 0, args: 0x3960000000000000ull, args: 0, |
4494 | args: 0x3ff0000000000000ull, args: 0x3960000000000000ull, |
4495 | args: APFloat::rmNearestTiesToEven), |
4496 | // (1 + 0) + (1e-106 + 0) = (1 + 1e-106) |
4497 | std::make_tuple(args: 0x3ff0000000000000ull, args: 0, args: 0x3950000000000000ull, args: 0, |
4498 | args: 0x3ff0000000000000ull, args: 0x3950000000000000ull, |
4499 | args: APFloat::rmNearestTiesToEven), |
4500 | // (1 + 1e-106) + (1e-106 + 0) = (1 + 1e-105) |
4501 | std::make_tuple(args: 0x3ff0000000000000ull, args: 0x3950000000000000ull, |
4502 | args: 0x3950000000000000ull, args: 0, args: 0x3ff0000000000000ull, |
4503 | args: 0x3960000000000000ull, args: APFloat::rmNearestTiesToEven), |
4504 | // (1 + 0) + (epsilon + 0) = (1 + epsilon) |
4505 | std::make_tuple(args: 0x3ff0000000000000ull, args: 0, args: 0x0000000000000001ull, args: 0, |
4506 | args: 0x3ff0000000000000ull, args: 0x0000000000000001ull, |
4507 | args: APFloat::rmNearestTiesToEven), |
4508 | // TODO: change 0xf950000000000000 to 0xf940000000000000, when |
4509 | // semPPCDoubleDoubleLegacy is gone. |
4510 | // (DBL_MAX - 1 << (1023 - 105)) + (1 << (1023 - 53) + 0) = DBL_MAX + |
4511 | // 1.11111... << (1023 - 52) |
4512 | std::make_tuple(args: 0x7fefffffffffffffull, args: 0xf950000000000000ull, |
4513 | args: 0x7c90000000000000ull, args: 0, args: 0x7fefffffffffffffull, |
4514 | args: 0x7c8ffffffffffffeull, args: APFloat::rmNearestTiesToEven), |
4515 | // TODO: change 0xf950000000000000 to 0xf940000000000000, when |
4516 | // semPPCDoubleDoubleLegacy is gone. |
4517 | // (1 << (1023 - 53) + 0) + (DBL_MAX - 1 << (1023 - 105)) = DBL_MAX + |
4518 | // 1.11111... << (1023 - 52) |
4519 | std::make_tuple(args: 0x7c90000000000000ull, args: 0, args: 0x7fefffffffffffffull, |
4520 | args: 0xf950000000000000ull, args: 0x7fefffffffffffffull, |
4521 | args: 0x7c8ffffffffffffeull, args: APFloat::rmNearestTiesToEven), |
4522 | }; |
4523 | |
4524 | for (auto Tp : Data) { |
4525 | uint64_t Op1[2], Op2[2], Expected[2]; |
4526 | APFloat::roundingMode RM; |
4527 | std::tie(args&: Op1[0], args&: Op1[1], args&: Op2[0], args&: Op2[1], args&: Expected[0], args&: Expected[1], args&: RM) = Tp; |
4528 | |
4529 | { |
4530 | APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1)); |
4531 | APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2)); |
4532 | A1.add(RHS: A2, RM); |
4533 | |
4534 | EXPECT_EQ(Expected[0], A1.bitcastToAPInt().getRawData()[0]) |
4535 | << formatv(Fmt: "({0:x} + {1:x}) + ({2:x} + {3:x})" , Vals&: Op1[0], Vals&: Op1[1], |
4536 | Vals&: Op2[0], Vals&: Op2[1]) |
4537 | .str(); |
4538 | EXPECT_EQ(Expected[1], A1.bitcastToAPInt().getRawData()[1]) |
4539 | << formatv(Fmt: "({0:x} + {1:x}) + ({2:x} + {3:x})" , Vals&: Op1[0], Vals&: Op1[1], |
4540 | Vals&: Op2[0], Vals&: Op2[1]) |
4541 | .str(); |
4542 | } |
4543 | { |
4544 | APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1)); |
4545 | APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2)); |
4546 | A2.add(RHS: A1, RM); |
4547 | |
4548 | EXPECT_EQ(Expected[0], A2.bitcastToAPInt().getRawData()[0]) |
4549 | << formatv(Fmt: "({0:x} + {1:x}) + ({2:x} + {3:x})" , Vals&: Op2[0], Vals&: Op2[1], |
4550 | Vals&: Op1[0], Vals&: Op1[1]) |
4551 | .str(); |
4552 | EXPECT_EQ(Expected[1], A2.bitcastToAPInt().getRawData()[1]) |
4553 | << formatv(Fmt: "({0:x} + {1:x}) + ({2:x} + {3:x})" , Vals&: Op2[0], Vals&: Op2[1], |
4554 | Vals&: Op1[0], Vals&: Op1[1]) |
4555 | .str(); |
4556 | } |
4557 | } |
4558 | } |
4559 | |
4560 | TEST(APFloatTest, PPCDoubleDoubleSubtract) { |
4561 | using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, |
4562 | uint64_t, APFloat::roundingMode>; |
4563 | DataType Data[] = { |
4564 | // (1 + 0) - (-1e-105 + 0) = (1 + 1e-105) |
4565 | std::make_tuple(args: 0x3ff0000000000000ull, args: 0, args: 0xb960000000000000ull, args: 0, |
4566 | args: 0x3ff0000000000000ull, args: 0x3960000000000000ull, |
4567 | args: APFloat::rmNearestTiesToEven), |
4568 | // (1 + 0) - (-1e-106 + 0) = (1 + 1e-106) |
4569 | std::make_tuple(args: 0x3ff0000000000000ull, args: 0, args: 0xb950000000000000ull, args: 0, |
4570 | args: 0x3ff0000000000000ull, args: 0x3950000000000000ull, |
4571 | args: APFloat::rmNearestTiesToEven), |
4572 | }; |
4573 | |
4574 | for (auto Tp : Data) { |
4575 | uint64_t Op1[2], Op2[2], Expected[2]; |
4576 | APFloat::roundingMode RM; |
4577 | std::tie(args&: Op1[0], args&: Op1[1], args&: Op2[0], args&: Op2[1], args&: Expected[0], args&: Expected[1], args&: RM) = Tp; |
4578 | |
4579 | APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1)); |
4580 | APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2)); |
4581 | A1.subtract(RHS: A2, RM); |
4582 | |
4583 | EXPECT_EQ(Expected[0], A1.bitcastToAPInt().getRawData()[0]) |
4584 | << formatv(Fmt: "({0:x} + {1:x}) - ({2:x} + {3:x})" , Vals&: Op1[0], Vals&: Op1[1], Vals&: Op2[0], |
4585 | Vals&: Op2[1]) |
4586 | .str(); |
4587 | EXPECT_EQ(Expected[1], A1.bitcastToAPInt().getRawData()[1]) |
4588 | << formatv(Fmt: "({0:x} + {1:x}) - ({2:x} + {3:x})" , Vals&: Op1[0], Vals&: Op1[1], Vals&: Op2[0], |
4589 | Vals&: Op2[1]) |
4590 | .str(); |
4591 | } |
4592 | } |
4593 | |
4594 | TEST(APFloatTest, PPCDoubleDoubleMultiplySpecial) { |
4595 | using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, |
4596 | APFloat::fltCategory, APFloat::roundingMode>; |
4597 | DataType Data[] = { |
4598 | // fcNaN * fcNaN = fcNaN |
4599 | std::make_tuple(args: 0x7ff8000000000000ull, args: 0, args: 0x7ff8000000000000ull, args: 0, |
4600 | args: APFloat::fcNaN, args: APFloat::rmNearestTiesToEven), |
4601 | // fcNaN * fcZero = fcNaN |
4602 | std::make_tuple(args: 0x7ff8000000000000ull, args: 0, args: 0, args: 0, args: APFloat::fcNaN, |
4603 | args: APFloat::rmNearestTiesToEven), |
4604 | // fcNaN * fcInfinity = fcNaN |
4605 | std::make_tuple(args: 0x7ff8000000000000ull, args: 0, args: 0x7ff0000000000000ull, args: 0, |
4606 | args: APFloat::fcNaN, args: APFloat::rmNearestTiesToEven), |
4607 | // fcNaN * fcNormal = fcNaN |
4608 | std::make_tuple(args: 0x7ff8000000000000ull, args: 0, args: 0x3ff0000000000000ull, args: 0, |
4609 | args: APFloat::fcNaN, args: APFloat::rmNearestTiesToEven), |
4610 | // fcInfinity * fcInfinity = fcInfinity |
4611 | std::make_tuple(args: 0x7ff0000000000000ull, args: 0, args: 0x7ff0000000000000ull, args: 0, |
4612 | args: APFloat::fcInfinity, args: APFloat::rmNearestTiesToEven), |
4613 | // fcInfinity * fcZero = fcNaN |
4614 | std::make_tuple(args: 0x7ff0000000000000ull, args: 0, args: 0, args: 0, args: APFloat::fcNaN, |
4615 | args: APFloat::rmNearestTiesToEven), |
4616 | // fcInfinity * fcNormal = fcInfinity |
4617 | std::make_tuple(args: 0x7ff0000000000000ull, args: 0, args: 0x3ff0000000000000ull, args: 0, |
4618 | args: APFloat::fcInfinity, args: APFloat::rmNearestTiesToEven), |
4619 | // fcZero * fcZero = fcZero |
4620 | std::make_tuple(args: 0, args: 0, args: 0, args: 0, args: APFloat::fcZero, |
4621 | args: APFloat::rmNearestTiesToEven), |
4622 | // fcZero * fcNormal = fcZero |
4623 | std::make_tuple(args: 0, args: 0, args: 0x3ff0000000000000ull, args: 0, args: APFloat::fcZero, |
4624 | args: APFloat::rmNearestTiesToEven), |
4625 | }; |
4626 | |
4627 | for (auto Tp : Data) { |
4628 | uint64_t Op1[2], Op2[2]; |
4629 | APFloat::fltCategory Expected; |
4630 | APFloat::roundingMode RM; |
4631 | std::tie(args&: Op1[0], args&: Op1[1], args&: Op2[0], args&: Op2[1], args&: Expected, args&: RM) = Tp; |
4632 | |
4633 | { |
4634 | APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1)); |
4635 | APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2)); |
4636 | A1.multiply(RHS: A2, RM); |
4637 | |
4638 | EXPECT_EQ(Expected, A1.getCategory()) |
4639 | << formatv(Fmt: "({0:x} + {1:x}) * ({2:x} + {3:x})" , Vals&: Op1[0], Vals&: Op1[1], |
4640 | Vals&: Op2[0], Vals&: Op2[1]) |
4641 | .str(); |
4642 | } |
4643 | { |
4644 | APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1)); |
4645 | APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2)); |
4646 | A2.multiply(RHS: A1, RM); |
4647 | |
4648 | EXPECT_EQ(Expected, A2.getCategory()) |
4649 | << formatv(Fmt: "({0:x} + {1:x}) * ({2:x} + {3:x})" , Vals&: Op2[0], Vals&: Op2[1], |
4650 | Vals&: Op1[0], Vals&: Op1[1]) |
4651 | .str(); |
4652 | } |
4653 | } |
4654 | } |
4655 | |
4656 | TEST(APFloatTest, PPCDoubleDoubleMultiply) { |
4657 | using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, |
4658 | uint64_t, APFloat::roundingMode>; |
4659 | DataType Data[] = { |
4660 | // 1/3 * 3 = 1.0 |
4661 | std::make_tuple(args: 0x3fd5555555555555ull, args: 0x3c75555555555556ull, |
4662 | args: 0x4008000000000000ull, args: 0, args: 0x3ff0000000000000ull, args: 0, |
4663 | args: APFloat::rmNearestTiesToEven), |
4664 | // (1 + epsilon) * (1 + 0) = fcZero |
4665 | std::make_tuple(args: 0x3ff0000000000000ull, args: 0x0000000000000001ull, |
4666 | args: 0x3ff0000000000000ull, args: 0, args: 0x3ff0000000000000ull, |
4667 | args: 0x0000000000000001ull, args: APFloat::rmNearestTiesToEven), |
4668 | // (1 + epsilon) * (1 + epsilon) = 1 + 2 * epsilon |
4669 | std::make_tuple(args: 0x3ff0000000000000ull, args: 0x0000000000000001ull, |
4670 | args: 0x3ff0000000000000ull, args: 0x0000000000000001ull, |
4671 | args: 0x3ff0000000000000ull, args: 0x0000000000000002ull, |
4672 | args: APFloat::rmNearestTiesToEven), |
4673 | // -(1 + epsilon) * (1 + epsilon) = -1 |
4674 | std::make_tuple(args: 0xbff0000000000000ull, args: 0x0000000000000001ull, |
4675 | args: 0x3ff0000000000000ull, args: 0x0000000000000001ull, |
4676 | args: 0xbff0000000000000ull, args: 0, args: APFloat::rmNearestTiesToEven), |
4677 | // (0.5 + 0) * (1 + 2 * epsilon) = 0.5 + epsilon |
4678 | std::make_tuple(args: 0x3fe0000000000000ull, args: 0, args: 0x3ff0000000000000ull, |
4679 | args: 0x0000000000000002ull, args: 0x3fe0000000000000ull, |
4680 | args: 0x0000000000000001ull, args: APFloat::rmNearestTiesToEven), |
4681 | // (0.5 + 0) * (1 + epsilon) = 0.5 |
4682 | std::make_tuple(args: 0x3fe0000000000000ull, args: 0, args: 0x3ff0000000000000ull, |
4683 | args: 0x0000000000000001ull, args: 0x3fe0000000000000ull, args: 0, |
4684 | args: APFloat::rmNearestTiesToEven), |
4685 | // __LDBL_MAX__ * (1 + 1 << 106) = inf |
4686 | std::make_tuple(args: 0x7fefffffffffffffull, args: 0x7c8ffffffffffffeull, |
4687 | args: 0x3ff0000000000000ull, args: 0x3950000000000000ull, |
4688 | args: 0x7ff0000000000000ull, args: 0, args: APFloat::rmNearestTiesToEven), |
4689 | // __LDBL_MAX__ * (1 + 1 << 107) > __LDBL_MAX__, but not inf, yes =_=||| |
4690 | std::make_tuple(args: 0x7fefffffffffffffull, args: 0x7c8ffffffffffffeull, |
4691 | args: 0x3ff0000000000000ull, args: 0x3940000000000000ull, |
4692 | args: 0x7fefffffffffffffull, args: 0x7c8fffffffffffffull, |
4693 | args: APFloat::rmNearestTiesToEven), |
4694 | // __LDBL_MAX__ * (1 + 1 << 108) = __LDBL_MAX__ |
4695 | std::make_tuple(args: 0x7fefffffffffffffull, args: 0x7c8ffffffffffffeull, |
4696 | args: 0x3ff0000000000000ull, args: 0x3930000000000000ull, |
4697 | args: 0x7fefffffffffffffull, args: 0x7c8ffffffffffffeull, |
4698 | args: APFloat::rmNearestTiesToEven), |
4699 | }; |
4700 | |
4701 | for (auto Tp : Data) { |
4702 | uint64_t Op1[2], Op2[2], Expected[2]; |
4703 | APFloat::roundingMode RM; |
4704 | std::tie(args&: Op1[0], args&: Op1[1], args&: Op2[0], args&: Op2[1], args&: Expected[0], args&: Expected[1], args&: RM) = Tp; |
4705 | |
4706 | { |
4707 | APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1)); |
4708 | APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2)); |
4709 | A1.multiply(RHS: A2, RM); |
4710 | |
4711 | EXPECT_EQ(Expected[0], A1.bitcastToAPInt().getRawData()[0]) |
4712 | << formatv(Fmt: "({0:x} + {1:x}) * ({2:x} + {3:x})" , Vals&: Op1[0], Vals&: Op1[1], |
4713 | Vals&: Op2[0], Vals&: Op2[1]) |
4714 | .str(); |
4715 | EXPECT_EQ(Expected[1], A1.bitcastToAPInt().getRawData()[1]) |
4716 | << formatv(Fmt: "({0:x} + {1:x}) * ({2:x} + {3:x})" , Vals&: Op1[0], Vals&: Op1[1], |
4717 | Vals&: Op2[0], Vals&: Op2[1]) |
4718 | .str(); |
4719 | } |
4720 | { |
4721 | APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1)); |
4722 | APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2)); |
4723 | A2.multiply(RHS: A1, RM); |
4724 | |
4725 | EXPECT_EQ(Expected[0], A2.bitcastToAPInt().getRawData()[0]) |
4726 | << formatv(Fmt: "({0:x} + {1:x}) * ({2:x} + {3:x})" , Vals&: Op2[0], Vals&: Op2[1], |
4727 | Vals&: Op1[0], Vals&: Op1[1]) |
4728 | .str(); |
4729 | EXPECT_EQ(Expected[1], A2.bitcastToAPInt().getRawData()[1]) |
4730 | << formatv(Fmt: "({0:x} + {1:x}) * ({2:x} + {3:x})" , Vals&: Op2[0], Vals&: Op2[1], |
4731 | Vals&: Op1[0], Vals&: Op1[1]) |
4732 | .str(); |
4733 | } |
4734 | } |
4735 | } |
4736 | |
4737 | TEST(APFloatTest, PPCDoubleDoubleDivide) { |
4738 | using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, |
4739 | uint64_t, APFloat::roundingMode>; |
4740 | // TODO: Only a sanity check for now. Add more edge cases when the |
4741 | // double-double algorithm is implemented. |
4742 | DataType Data[] = { |
4743 | // 1 / 3 = 1/3 |
4744 | std::make_tuple(args: 0x3ff0000000000000ull, args: 0, args: 0x4008000000000000ull, args: 0, |
4745 | args: 0x3fd5555555555555ull, args: 0x3c75555555555556ull, |
4746 | args: APFloat::rmNearestTiesToEven), |
4747 | }; |
4748 | |
4749 | for (auto Tp : Data) { |
4750 | uint64_t Op1[2], Op2[2], Expected[2]; |
4751 | APFloat::roundingMode RM; |
4752 | std::tie(args&: Op1[0], args&: Op1[1], args&: Op2[0], args&: Op2[1], args&: Expected[0], args&: Expected[1], args&: RM) = Tp; |
4753 | |
4754 | APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1)); |
4755 | APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2)); |
4756 | A1.divide(RHS: A2, RM); |
4757 | |
4758 | EXPECT_EQ(Expected[0], A1.bitcastToAPInt().getRawData()[0]) |
4759 | << formatv(Fmt: "({0:x} + {1:x}) / ({2:x} + {3:x})" , Vals&: Op1[0], Vals&: Op1[1], Vals&: Op2[0], |
4760 | Vals&: Op2[1]) |
4761 | .str(); |
4762 | EXPECT_EQ(Expected[1], A1.bitcastToAPInt().getRawData()[1]) |
4763 | << formatv(Fmt: "({0:x} + {1:x}) / ({2:x} + {3:x})" , Vals&: Op1[0], Vals&: Op1[1], Vals&: Op2[0], |
4764 | Vals&: Op2[1]) |
4765 | .str(); |
4766 | } |
4767 | } |
4768 | |
4769 | TEST(APFloatTest, PPCDoubleDoubleRemainder) { |
4770 | using DataType = |
4771 | std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t>; |
4772 | DataType Data[] = { |
4773 | // remainder(3.0 + 3.0 << 53, 1.25 + 1.25 << 53) = (0.5 + 0.5 << 53) |
4774 | std::make_tuple(args: 0x4008000000000000ull, args: 0x3cb8000000000000ull, |
4775 | args: 0x3ff4000000000000ull, args: 0x3ca4000000000000ull, |
4776 | args: 0x3fe0000000000000ull, args: 0x3c90000000000000ull), |
4777 | // remainder(3.0 + 3.0 << 53, 1.75 + 1.75 << 53) = (-0.5 - 0.5 << 53) |
4778 | std::make_tuple(args: 0x4008000000000000ull, args: 0x3cb8000000000000ull, |
4779 | args: 0x3ffc000000000000ull, args: 0x3cac000000000000ull, |
4780 | args: 0xbfe0000000000000ull, args: 0xbc90000000000000ull), |
4781 | }; |
4782 | |
4783 | for (auto Tp : Data) { |
4784 | uint64_t Op1[2], Op2[2], Expected[2]; |
4785 | std::tie(args&: Op1[0], args&: Op1[1], args&: Op2[0], args&: Op2[1], args&: Expected[0], args&: Expected[1]) = Tp; |
4786 | |
4787 | APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1)); |
4788 | APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2)); |
4789 | A1.remainder(RHS: A2); |
4790 | |
4791 | EXPECT_EQ(Expected[0], A1.bitcastToAPInt().getRawData()[0]) |
4792 | << formatv(Fmt: "remainder({0:x} + {1:x}), ({2:x} + {3:x}))" , Vals&: Op1[0], Vals&: Op1[1], |
4793 | Vals&: Op2[0], Vals&: Op2[1]) |
4794 | .str(); |
4795 | EXPECT_EQ(Expected[1], A1.bitcastToAPInt().getRawData()[1]) |
4796 | << formatv(Fmt: "remainder(({0:x} + {1:x}), ({2:x} + {3:x}))" , Vals&: Op1[0], |
4797 | Vals&: Op1[1], Vals&: Op2[0], Vals&: Op2[1]) |
4798 | .str(); |
4799 | } |
4800 | } |
4801 | |
4802 | TEST(APFloatTest, PPCDoubleDoubleMod) { |
4803 | using DataType = |
4804 | std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t>; |
4805 | DataType Data[] = { |
4806 | // mod(3.0 + 3.0 << 53, 1.25 + 1.25 << 53) = (0.5 + 0.5 << 53) |
4807 | std::make_tuple(args: 0x4008000000000000ull, args: 0x3cb8000000000000ull, |
4808 | args: 0x3ff4000000000000ull, args: 0x3ca4000000000000ull, |
4809 | args: 0x3fe0000000000000ull, args: 0x3c90000000000000ull), |
4810 | // mod(3.0 + 3.0 << 53, 1.75 + 1.75 << 53) = (1.25 + 1.25 << 53) |
4811 | // 0xbc98000000000000 doesn't seem right, but it's what we currently have. |
4812 | // TODO: investigate |
4813 | std::make_tuple(args: 0x4008000000000000ull, args: 0x3cb8000000000000ull, |
4814 | args: 0x3ffc000000000000ull, args: 0x3cac000000000000ull, |
4815 | args: 0x3ff4000000000001ull, args: 0xbc98000000000000ull), |
4816 | }; |
4817 | |
4818 | for (auto Tp : Data) { |
4819 | uint64_t Op1[2], Op2[2], Expected[2]; |
4820 | std::tie(args&: Op1[0], args&: Op1[1], args&: Op2[0], args&: Op2[1], args&: Expected[0], args&: Expected[1]) = Tp; |
4821 | |
4822 | APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1)); |
4823 | APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2)); |
4824 | A1.mod(RHS: A2); |
4825 | |
4826 | EXPECT_EQ(Expected[0], A1.bitcastToAPInt().getRawData()[0]) |
4827 | << formatv(Fmt: "fmod(({0:x} + {1:x}), ({2:x} + {3:x}))" , Vals&: Op1[0], Vals&: Op1[1], |
4828 | Vals&: Op2[0], Vals&: Op2[1]) |
4829 | .str(); |
4830 | EXPECT_EQ(Expected[1], A1.bitcastToAPInt().getRawData()[1]) |
4831 | << formatv(Fmt: "fmod(({0:x} + {1:x}), ({2:x} + {3:x}))" , Vals&: Op1[0], Vals&: Op1[1], |
4832 | Vals&: Op2[0], Vals&: Op2[1]) |
4833 | .str(); |
4834 | } |
4835 | } |
4836 | |
4837 | TEST(APFloatTest, PPCDoubleDoubleFMA) { |
4838 | // Sanity check for now. |
4839 | APFloat A(APFloat::PPCDoubleDouble(), "2" ); |
4840 | A.fusedMultiplyAdd(Multiplicand: APFloat(APFloat::PPCDoubleDouble(), "3" ), |
4841 | Addend: APFloat(APFloat::PPCDoubleDouble(), "4" ), |
4842 | RM: APFloat::rmNearestTiesToEven); |
4843 | EXPECT_EQ(APFloat::cmpEqual, |
4844 | APFloat(APFloat::PPCDoubleDouble(), "10" ).compare(A)); |
4845 | } |
4846 | |
4847 | TEST(APFloatTest, PPCDoubleDoubleRoundToIntegral) { |
4848 | { |
4849 | APFloat A(APFloat::PPCDoubleDouble(), "1.5" ); |
4850 | A.roundToIntegral(RM: APFloat::rmNearestTiesToEven); |
4851 | EXPECT_EQ(APFloat::cmpEqual, |
4852 | APFloat(APFloat::PPCDoubleDouble(), "2" ).compare(A)); |
4853 | } |
4854 | { |
4855 | APFloat A(APFloat::PPCDoubleDouble(), "2.5" ); |
4856 | A.roundToIntegral(RM: APFloat::rmNearestTiesToEven); |
4857 | EXPECT_EQ(APFloat::cmpEqual, |
4858 | APFloat(APFloat::PPCDoubleDouble(), "2" ).compare(A)); |
4859 | } |
4860 | } |
4861 | |
4862 | TEST(APFloatTest, PPCDoubleDoubleCompare) { |
4863 | using DataType = |
4864 | std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, APFloat::cmpResult>; |
4865 | |
4866 | DataType Data[] = { |
4867 | // (1 + 0) = (1 + 0) |
4868 | std::make_tuple(args: 0x3ff0000000000000ull, args: 0, args: 0x3ff0000000000000ull, args: 0, |
4869 | args: APFloat::cmpEqual), |
4870 | // (1 + 0) < (1.00...1 + 0) |
4871 | std::make_tuple(args: 0x3ff0000000000000ull, args: 0, args: 0x3ff0000000000001ull, args: 0, |
4872 | args: APFloat::cmpLessThan), |
4873 | // (1.00...1 + 0) > (1 + 0) |
4874 | std::make_tuple(args: 0x3ff0000000000001ull, args: 0, args: 0x3ff0000000000000ull, args: 0, |
4875 | args: APFloat::cmpGreaterThan), |
4876 | // (1 + 0) < (1 + epsilon) |
4877 | std::make_tuple(args: 0x3ff0000000000000ull, args: 0, args: 0x3ff0000000000001ull, |
4878 | args: 0x0000000000000001ull, args: APFloat::cmpLessThan), |
4879 | // NaN != NaN |
4880 | std::make_tuple(args: 0x7ff8000000000000ull, args: 0, args: 0x7ff8000000000000ull, args: 0, |
4881 | args: APFloat::cmpUnordered), |
4882 | // (1 + 0) != NaN |
4883 | std::make_tuple(args: 0x3ff0000000000000ull, args: 0, args: 0x7ff8000000000000ull, args: 0, |
4884 | args: APFloat::cmpUnordered), |
4885 | // Inf = Inf |
4886 | std::make_tuple(args: 0x7ff0000000000000ull, args: 0, args: 0x7ff0000000000000ull, args: 0, |
4887 | args: APFloat::cmpEqual), |
4888 | }; |
4889 | |
4890 | for (auto Tp : Data) { |
4891 | uint64_t Op1[2], Op2[2]; |
4892 | APFloat::cmpResult Expected; |
4893 | std::tie(args&: Op1[0], args&: Op1[1], args&: Op2[0], args&: Op2[1], args&: Expected) = Tp; |
4894 | |
4895 | APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1)); |
4896 | APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2)); |
4897 | EXPECT_EQ(Expected, A1.compare(A2)) |
4898 | << formatv(Fmt: "compare(({0:x} + {1:x}), ({2:x} + {3:x}))" , Vals&: Op1[0], Vals&: Op1[1], |
4899 | Vals&: Op2[0], Vals&: Op2[1]) |
4900 | .str(); |
4901 | } |
4902 | } |
4903 | |
4904 | TEST(APFloatTest, PPCDoubleDoubleBitwiseIsEqual) { |
4905 | using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, bool>; |
4906 | |
4907 | DataType Data[] = { |
4908 | // (1 + 0) = (1 + 0) |
4909 | std::make_tuple(args: 0x3ff0000000000000ull, args: 0, args: 0x3ff0000000000000ull, args: 0, args: true), |
4910 | // (1 + 0) != (1.00...1 + 0) |
4911 | std::make_tuple(args: 0x3ff0000000000000ull, args: 0, args: 0x3ff0000000000001ull, args: 0, |
4912 | args: false), |
4913 | // NaN = NaN |
4914 | std::make_tuple(args: 0x7ff8000000000000ull, args: 0, args: 0x7ff8000000000000ull, args: 0, args: true), |
4915 | // NaN != NaN with a different bit pattern |
4916 | std::make_tuple(args: 0x7ff8000000000000ull, args: 0, args: 0x7ff8000000000000ull, |
4917 | args: 0x3ff0000000000000ull, args: false), |
4918 | // Inf = Inf |
4919 | std::make_tuple(args: 0x7ff0000000000000ull, args: 0, args: 0x7ff0000000000000ull, args: 0, args: true), |
4920 | }; |
4921 | |
4922 | for (auto Tp : Data) { |
4923 | uint64_t Op1[2], Op2[2]; |
4924 | bool Expected; |
4925 | std::tie(args&: Op1[0], args&: Op1[1], args&: Op2[0], args&: Op2[1], args&: Expected) = Tp; |
4926 | |
4927 | APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1)); |
4928 | APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2)); |
4929 | EXPECT_EQ(Expected, A1.bitwiseIsEqual(A2)) |
4930 | << formatv(Fmt: "({0:x} + {1:x}) = ({2:x} + {3:x})" , Vals&: Op1[0], Vals&: Op1[1], Vals&: Op2[0], |
4931 | Vals&: Op2[1]) |
4932 | .str(); |
4933 | } |
4934 | } |
4935 | |
4936 | TEST(APFloatTest, PPCDoubleDoubleHashValue) { |
4937 | uint64_t Data1[] = {0x3ff0000000000001ull, 0x0000000000000001ull}; |
4938 | uint64_t Data2[] = {0x3ff0000000000001ull, 0}; |
4939 | // The hash values are *hopefully* different. |
4940 | EXPECT_NE( |
4941 | hash_value(APFloat(APFloat::PPCDoubleDouble(), APInt(128, 2, Data1))), |
4942 | hash_value(APFloat(APFloat::PPCDoubleDouble(), APInt(128, 2, Data2)))); |
4943 | } |
4944 | |
4945 | TEST(APFloatTest, PPCDoubleDoubleChangeSign) { |
4946 | uint64_t Data[] = { |
4947 | 0x400f000000000000ull, 0xbcb0000000000000ull, |
4948 | }; |
4949 | APFloat Float(APFloat::PPCDoubleDouble(), APInt(128, 2, Data)); |
4950 | { |
4951 | APFloat Actual = |
4952 | APFloat::copySign(Value: Float, Sign: APFloat(APFloat::IEEEdouble(), "1" )); |
4953 | EXPECT_EQ(0x400f000000000000ull, Actual.bitcastToAPInt().getRawData()[0]); |
4954 | EXPECT_EQ(0xbcb0000000000000ull, Actual.bitcastToAPInt().getRawData()[1]); |
4955 | } |
4956 | { |
4957 | APFloat Actual = |
4958 | APFloat::copySign(Value: Float, Sign: APFloat(APFloat::IEEEdouble(), "-1" )); |
4959 | EXPECT_EQ(0xc00f000000000000ull, Actual.bitcastToAPInt().getRawData()[0]); |
4960 | EXPECT_EQ(0x3cb0000000000000ull, Actual.bitcastToAPInt().getRawData()[1]); |
4961 | } |
4962 | } |
4963 | |
4964 | TEST(APFloatTest, PPCDoubleDoubleFactories) { |
4965 | { |
4966 | uint64_t Data[] = { |
4967 | 0, 0, |
4968 | }; |
4969 | EXPECT_EQ(APInt(128, 2, Data), |
4970 | APFloat::getZero(APFloat::PPCDoubleDouble()).bitcastToAPInt()); |
4971 | } |
4972 | { |
4973 | uint64_t Data[] = { |
4974 | 0x7fefffffffffffffull, 0x7c8ffffffffffffeull, |
4975 | }; |
4976 | EXPECT_EQ(APInt(128, 2, Data), |
4977 | APFloat::getLargest(APFloat::PPCDoubleDouble()).bitcastToAPInt()); |
4978 | } |
4979 | { |
4980 | uint64_t Data[] = { |
4981 | 0x0000000000000001ull, 0, |
4982 | }; |
4983 | EXPECT_EQ( |
4984 | APInt(128, 2, Data), |
4985 | APFloat::getSmallest(APFloat::PPCDoubleDouble()).bitcastToAPInt()); |
4986 | } |
4987 | { |
4988 | uint64_t Data[] = {0x0360000000000000ull, 0}; |
4989 | EXPECT_EQ(APInt(128, 2, Data), |
4990 | APFloat::getSmallestNormalized(APFloat::PPCDoubleDouble()) |
4991 | .bitcastToAPInt()); |
4992 | } |
4993 | { |
4994 | uint64_t Data[] = { |
4995 | 0x8000000000000000ull, 0x0000000000000000ull, |
4996 | }; |
4997 | EXPECT_EQ( |
4998 | APInt(128, 2, Data), |
4999 | APFloat::getZero(APFloat::PPCDoubleDouble(), true).bitcastToAPInt()); |
5000 | } |
5001 | { |
5002 | uint64_t Data[] = { |
5003 | 0xffefffffffffffffull, 0xfc8ffffffffffffeull, |
5004 | }; |
5005 | EXPECT_EQ( |
5006 | APInt(128, 2, Data), |
5007 | APFloat::getLargest(APFloat::PPCDoubleDouble(), true).bitcastToAPInt()); |
5008 | } |
5009 | { |
5010 | uint64_t Data[] = { |
5011 | 0x8000000000000001ull, 0x0000000000000000ull, |
5012 | }; |
5013 | EXPECT_EQ(APInt(128, 2, Data), |
5014 | APFloat::getSmallest(APFloat::PPCDoubleDouble(), true) |
5015 | .bitcastToAPInt()); |
5016 | } |
5017 | { |
5018 | uint64_t Data[] = { |
5019 | 0x8360000000000000ull, 0x0000000000000000ull, |
5020 | }; |
5021 | EXPECT_EQ(APInt(128, 2, Data), |
5022 | APFloat::getSmallestNormalized(APFloat::PPCDoubleDouble(), true) |
5023 | .bitcastToAPInt()); |
5024 | } |
5025 | EXPECT_TRUE(APFloat::getSmallest(APFloat::PPCDoubleDouble()).isSmallest()); |
5026 | EXPECT_TRUE(APFloat::getLargest(APFloat::PPCDoubleDouble()).isLargest()); |
5027 | } |
5028 | |
5029 | TEST(APFloatTest, PPCDoubleDoubleIsDenormal) { |
5030 | EXPECT_TRUE(APFloat::getSmallest(APFloat::PPCDoubleDouble()).isDenormal()); |
5031 | EXPECT_FALSE(APFloat::getLargest(APFloat::PPCDoubleDouble()).isDenormal()); |
5032 | EXPECT_FALSE( |
5033 | APFloat::getSmallestNormalized(APFloat::PPCDoubleDouble()).isDenormal()); |
5034 | { |
5035 | // (4 + 3) is not normalized |
5036 | uint64_t Data[] = { |
5037 | 0x4010000000000000ull, 0x4008000000000000ull, |
5038 | }; |
5039 | EXPECT_TRUE( |
5040 | APFloat(APFloat::PPCDoubleDouble(), APInt(128, 2, Data)).isDenormal()); |
5041 | } |
5042 | } |
5043 | |
5044 | TEST(APFloatTest, PPCDoubleDoubleScalbn) { |
5045 | // 3.0 + 3.0 << 53 |
5046 | uint64_t Input[] = { |
5047 | 0x4008000000000000ull, 0x3cb8000000000000ull, |
5048 | }; |
5049 | APFloat Result = |
5050 | scalbn(X: APFloat(APFloat::PPCDoubleDouble(), APInt(128, 2, Input)), Exp: 1, |
5051 | RM: APFloat::rmNearestTiesToEven); |
5052 | // 6.0 + 6.0 << 53 |
5053 | EXPECT_EQ(0x4018000000000000ull, Result.bitcastToAPInt().getRawData()[0]); |
5054 | EXPECT_EQ(0x3cc8000000000000ull, Result.bitcastToAPInt().getRawData()[1]); |
5055 | } |
5056 | |
5057 | TEST(APFloatTest, PPCDoubleDoubleFrexp) { |
5058 | // 3.0 + 3.0 << 53 |
5059 | uint64_t Input[] = { |
5060 | 0x4008000000000000ull, 0x3cb8000000000000ull, |
5061 | }; |
5062 | int Exp; |
5063 | // 0.75 + 0.75 << 53 |
5064 | APFloat Result = |
5065 | frexp(X: APFloat(APFloat::PPCDoubleDouble(), APInt(128, 2, Input)), Exp, |
5066 | RM: APFloat::rmNearestTiesToEven); |
5067 | EXPECT_EQ(2, Exp); |
5068 | EXPECT_EQ(0x3fe8000000000000ull, Result.bitcastToAPInt().getRawData()[0]); |
5069 | EXPECT_EQ(0x3c98000000000000ull, Result.bitcastToAPInt().getRawData()[1]); |
5070 | } |
5071 | |
5072 | TEST(APFloatTest, x87Largest) { |
5073 | APFloat MaxX87Val = APFloat::getLargest(Sem: APFloat::x87DoubleExtended()); |
5074 | EXPECT_TRUE(MaxX87Val.isLargest()); |
5075 | } |
5076 | |
5077 | TEST(APFloatTest, x87Next) { |
5078 | APFloat F(APFloat::x87DoubleExtended(), "-1.0" ); |
5079 | F.next(nextDown: false); |
5080 | EXPECT_TRUE(ilogb(F) == -1); |
5081 | } |
5082 | |
5083 | TEST(APFloatTest, Float8ExhaustivePair) { |
5084 | // Test each pair of 8-bit floats with non-standard semantics |
5085 | for (APFloat::Semantics Sem : |
5086 | {APFloat::S_Float8E4M3FN, APFloat::S_Float8E5M2FNUZ, |
5087 | APFloat::S_Float8E4M3FNUZ, APFloat::S_Float8E4M3B11FNUZ}) { |
5088 | const llvm::fltSemantics &S = APFloat::EnumToSemantics(S: Sem); |
5089 | for (int i = 0; i < 256; i++) { |
5090 | for (int j = 0; j < 256; j++) { |
5091 | SCOPED_TRACE("sem=" + std::to_string(Sem) + ",i=" + std::to_string(i) + |
5092 | ",j=" + std::to_string(j)); |
5093 | APFloat x(S, APInt(8, i)); |
5094 | APFloat y(S, APInt(8, j)); |
5095 | |
5096 | bool losesInfo; |
5097 | APFloat x16 = x; |
5098 | x16.convert(ToSemantics: APFloat::IEEEhalf(), RM: APFloat::rmNearestTiesToEven, |
5099 | losesInfo: &losesInfo); |
5100 | EXPECT_FALSE(losesInfo); |
5101 | APFloat y16 = y; |
5102 | y16.convert(ToSemantics: APFloat::IEEEhalf(), RM: APFloat::rmNearestTiesToEven, |
5103 | losesInfo: &losesInfo); |
5104 | EXPECT_FALSE(losesInfo); |
5105 | |
5106 | // Add |
5107 | APFloat z = x; |
5108 | z.add(RHS: y, RM: APFloat::rmNearestTiesToEven); |
5109 | APFloat z16 = x16; |
5110 | z16.add(RHS: y16, RM: APFloat::rmNearestTiesToEven); |
5111 | z16.convert(ToSemantics: S, RM: APFloat::rmNearestTiesToEven, losesInfo: &losesInfo); |
5112 | EXPECT_TRUE(z.bitwiseIsEqual(z16)) |
5113 | << "sem=" << Sem << ", i=" << i << ", j=" << j; |
5114 | |
5115 | // Subtract |
5116 | z = x; |
5117 | z.subtract(RHS: y, RM: APFloat::rmNearestTiesToEven); |
5118 | z16 = x16; |
5119 | z16.subtract(RHS: y16, RM: APFloat::rmNearestTiesToEven); |
5120 | z16.convert(ToSemantics: S, RM: APFloat::rmNearestTiesToEven, losesInfo: &losesInfo); |
5121 | EXPECT_TRUE(z.bitwiseIsEqual(z16)) |
5122 | << "sem=" << Sem << ", i=" << i << ", j=" << j; |
5123 | |
5124 | // Multiply |
5125 | z = x; |
5126 | z.multiply(RHS: y, RM: APFloat::rmNearestTiesToEven); |
5127 | z16 = x16; |
5128 | z16.multiply(RHS: y16, RM: APFloat::rmNearestTiesToEven); |
5129 | z16.convert(ToSemantics: S, RM: APFloat::rmNearestTiesToEven, losesInfo: &losesInfo); |
5130 | EXPECT_TRUE(z.bitwiseIsEqual(z16)) |
5131 | << "sem=" << Sem << ", i=" << i << ", j=" << j; |
5132 | |
5133 | // Divide |
5134 | z = x; |
5135 | z.divide(RHS: y, RM: APFloat::rmNearestTiesToEven); |
5136 | z16 = x16; |
5137 | z16.divide(RHS: y16, RM: APFloat::rmNearestTiesToEven); |
5138 | z16.convert(ToSemantics: S, RM: APFloat::rmNearestTiesToEven, losesInfo: &losesInfo); |
5139 | EXPECT_TRUE(z.bitwiseIsEqual(z16)) |
5140 | << "sem=" << Sem << ", i=" << i << ", j=" << j; |
5141 | |
5142 | // Mod |
5143 | z = x; |
5144 | z.mod(RHS: y); |
5145 | z16 = x16; |
5146 | z16.mod(RHS: y16); |
5147 | z16.convert(ToSemantics: S, RM: APFloat::rmNearestTiesToEven, losesInfo: &losesInfo); |
5148 | EXPECT_TRUE(z.bitwiseIsEqual(z16)) |
5149 | << "sem=" << Sem << ", i=" << i << ", j=" << j; |
5150 | |
5151 | // Remainder |
5152 | z = x; |
5153 | z.remainder(RHS: y); |
5154 | z16 = x16; |
5155 | z16.remainder(RHS: y16); |
5156 | z16.convert(ToSemantics: S, RM: APFloat::rmNearestTiesToEven, losesInfo: &losesInfo); |
5157 | EXPECT_TRUE(z.bitwiseIsEqual(z16)) |
5158 | << "sem=" << Sem << ", i=" << i << ", j=" << j; |
5159 | } |
5160 | } |
5161 | } |
5162 | } |
5163 | |
5164 | TEST(APFloatTest, ConvertE4M3FNToE5M2) { |
5165 | bool losesInfo; |
5166 | APFloat test(APFloat::Float8E4M3FN(), "1.0" ); |
5167 | APFloat::opStatus status = test.convert( |
5168 | ToSemantics: APFloat::Float8E5M2(), RM: APFloat::rmNearestTiesToEven, losesInfo: &losesInfo); |
5169 | EXPECT_EQ(1.0f, test.convertToFloat()); |
5170 | EXPECT_FALSE(losesInfo); |
5171 | EXPECT_EQ(status, APFloat::opOK); |
5172 | |
5173 | test = APFloat(APFloat::Float8E4M3FN(), "0.0" ); |
5174 | status = test.convert(ToSemantics: APFloat::Float8E5M2(), RM: APFloat::rmNearestTiesToEven, |
5175 | losesInfo: &losesInfo); |
5176 | EXPECT_EQ(0.0f, test.convertToFloat()); |
5177 | EXPECT_FALSE(losesInfo); |
5178 | EXPECT_EQ(status, APFloat::opOK); |
5179 | |
5180 | test = APFloat(APFloat::Float8E4M3FN(), "0x1.2p0" ); // 1.125 |
5181 | status = test.convert(ToSemantics: APFloat::Float8E5M2(), RM: APFloat::rmNearestTiesToEven, |
5182 | losesInfo: &losesInfo); |
5183 | EXPECT_EQ(0x1.0p0 /* 1.0 */, test.convertToFloat()); |
5184 | EXPECT_TRUE(losesInfo); |
5185 | EXPECT_EQ(status, APFloat::opInexact); |
5186 | |
5187 | test = APFloat(APFloat::Float8E4M3FN(), "0x1.6p0" ); // 1.375 |
5188 | status = test.convert(ToSemantics: APFloat::Float8E5M2(), RM: APFloat::rmNearestTiesToEven, |
5189 | losesInfo: &losesInfo); |
5190 | EXPECT_EQ(0x1.8p0 /* 1.5 */, test.convertToFloat()); |
5191 | EXPECT_TRUE(losesInfo); |
5192 | EXPECT_EQ(status, APFloat::opInexact); |
5193 | |
5194 | // Convert E4M3 denormal to E5M2 normal. Should not be truncated, despite the |
5195 | // destination format having one fewer significand bit |
5196 | test = APFloat(APFloat::Float8E4M3FN(), "0x1.Cp-7" ); |
5197 | status = test.convert(ToSemantics: APFloat::Float8E5M2(), RM: APFloat::rmNearestTiesToEven, |
5198 | losesInfo: &losesInfo); |
5199 | EXPECT_EQ(0x1.Cp-7, test.convertToFloat()); |
5200 | EXPECT_FALSE(losesInfo); |
5201 | EXPECT_EQ(status, APFloat::opOK); |
5202 | |
5203 | // Test convert from NaN |
5204 | test = APFloat(APFloat::Float8E4M3FN(), "nan" ); |
5205 | status = test.convert(ToSemantics: APFloat::Float8E5M2(), RM: APFloat::rmNearestTiesToEven, |
5206 | losesInfo: &losesInfo); |
5207 | EXPECT_TRUE(std::isnan(test.convertToFloat())); |
5208 | EXPECT_FALSE(losesInfo); |
5209 | EXPECT_EQ(status, APFloat::opOK); |
5210 | } |
5211 | |
5212 | TEST(APFloatTest, ConvertE5M2ToE4M3FN) { |
5213 | bool losesInfo; |
5214 | APFloat test(APFloat::Float8E5M2(), "1.0" ); |
5215 | APFloat::opStatus status = test.convert( |
5216 | ToSemantics: APFloat::Float8E4M3FN(), RM: APFloat::rmNearestTiesToEven, losesInfo: &losesInfo); |
5217 | EXPECT_EQ(1.0f, test.convertToFloat()); |
5218 | EXPECT_FALSE(losesInfo); |
5219 | EXPECT_EQ(status, APFloat::opOK); |
5220 | |
5221 | test = APFloat(APFloat::Float8E5M2(), "0.0" ); |
5222 | status = test.convert(ToSemantics: APFloat::Float8E4M3FN(), RM: APFloat::rmNearestTiesToEven, |
5223 | losesInfo: &losesInfo); |
5224 | EXPECT_EQ(0.0f, test.convertToFloat()); |
5225 | EXPECT_FALSE(losesInfo); |
5226 | EXPECT_EQ(status, APFloat::opOK); |
5227 | |
5228 | test = APFloat(APFloat::Float8E5M2(), "0x1.Cp8" ); // 448 |
5229 | status = test.convert(ToSemantics: APFloat::Float8E4M3FN(), RM: APFloat::rmNearestTiesToEven, |
5230 | losesInfo: &losesInfo); |
5231 | EXPECT_EQ(0x1.Cp8 /* 448 */, test.convertToFloat()); |
5232 | EXPECT_FALSE(losesInfo); |
5233 | EXPECT_EQ(status, APFloat::opOK); |
5234 | |
5235 | // Test overflow |
5236 | test = APFloat(APFloat::Float8E5M2(), "0x1.0p9" ); // 512 |
5237 | status = test.convert(ToSemantics: APFloat::Float8E4M3FN(), RM: APFloat::rmNearestTiesToEven, |
5238 | losesInfo: &losesInfo); |
5239 | EXPECT_TRUE(std::isnan(test.convertToFloat())); |
5240 | EXPECT_TRUE(losesInfo); |
5241 | EXPECT_EQ(status, APFloat::opOverflow | APFloat::opInexact); |
5242 | |
5243 | // Test underflow |
5244 | test = APFloat(APFloat::Float8E5M2(), "0x1.0p-10" ); |
5245 | status = test.convert(ToSemantics: APFloat::Float8E4M3FN(), RM: APFloat::rmNearestTiesToEven, |
5246 | losesInfo: &losesInfo); |
5247 | EXPECT_EQ(0., test.convertToFloat()); |
5248 | EXPECT_TRUE(losesInfo); |
5249 | EXPECT_EQ(status, APFloat::opUnderflow | APFloat::opInexact); |
5250 | |
5251 | // Test rounding up to smallest denormal number |
5252 | test = APFloat(APFloat::Float8E5M2(), "0x1.8p-10" ); |
5253 | status = test.convert(ToSemantics: APFloat::Float8E4M3FN(), RM: APFloat::rmNearestTiesToEven, |
5254 | losesInfo: &losesInfo); |
5255 | EXPECT_EQ(0x1.0p-9, test.convertToFloat()); |
5256 | EXPECT_TRUE(losesInfo); |
5257 | EXPECT_EQ(status, APFloat::opUnderflow | APFloat::opInexact); |
5258 | |
5259 | // Testing inexact rounding to denormal number |
5260 | test = APFloat(APFloat::Float8E5M2(), "0x1.8p-9" ); |
5261 | status = test.convert(ToSemantics: APFloat::Float8E4M3FN(), RM: APFloat::rmNearestTiesToEven, |
5262 | losesInfo: &losesInfo); |
5263 | EXPECT_EQ(0x1.0p-8, test.convertToFloat()); |
5264 | EXPECT_TRUE(losesInfo); |
5265 | EXPECT_EQ(status, APFloat::opUnderflow | APFloat::opInexact); |
5266 | |
5267 | APFloat nan = APFloat(APFloat::Float8E4M3FN(), "nan" ); |
5268 | |
5269 | // Testing convert from Inf |
5270 | test = APFloat(APFloat::Float8E5M2(), "inf" ); |
5271 | status = test.convert(ToSemantics: APFloat::Float8E4M3FN(), RM: APFloat::rmNearestTiesToEven, |
5272 | losesInfo: &losesInfo); |
5273 | EXPECT_TRUE(std::isnan(test.convertToFloat())); |
5274 | EXPECT_TRUE(losesInfo); |
5275 | EXPECT_EQ(status, APFloat::opInexact); |
5276 | EXPECT_TRUE(test.bitwiseIsEqual(nan)); |
5277 | |
5278 | // Testing convert from quiet NaN |
5279 | test = APFloat(APFloat::Float8E5M2(), "nan" ); |
5280 | status = test.convert(ToSemantics: APFloat::Float8E4M3FN(), RM: APFloat::rmNearestTiesToEven, |
5281 | losesInfo: &losesInfo); |
5282 | EXPECT_TRUE(std::isnan(test.convertToFloat())); |
5283 | EXPECT_TRUE(losesInfo); |
5284 | EXPECT_EQ(status, APFloat::opOK); |
5285 | EXPECT_TRUE(test.bitwiseIsEqual(nan)); |
5286 | |
5287 | // Testing convert from signaling NaN |
5288 | test = APFloat(APFloat::Float8E5M2(), "snan" ); |
5289 | status = test.convert(ToSemantics: APFloat::Float8E4M3FN(), RM: APFloat::rmNearestTiesToEven, |
5290 | losesInfo: &losesInfo); |
5291 | EXPECT_TRUE(std::isnan(test.convertToFloat())); |
5292 | EXPECT_TRUE(losesInfo); |
5293 | EXPECT_EQ(status, APFloat::opInvalidOp); |
5294 | EXPECT_TRUE(test.bitwiseIsEqual(nan)); |
5295 | } |
5296 | |
5297 | TEST(APFloatTest, Float8E4M3FNGetInf) { |
5298 | APFloat t = APFloat::getInf(Sem: APFloat::Float8E4M3FN()); |
5299 | EXPECT_TRUE(t.isNaN()); |
5300 | EXPECT_FALSE(t.isInfinity()); |
5301 | } |
5302 | |
5303 | TEST(APFloatTest, Float8E4M3FNFromString) { |
5304 | // Exactly representable |
5305 | EXPECT_EQ(448, APFloat(APFloat::Float8E4M3FN(), "448" ).convertToDouble()); |
5306 | // Round down to maximum value |
5307 | EXPECT_EQ(448, APFloat(APFloat::Float8E4M3FN(), "464" ).convertToDouble()); |
5308 | // Round up, causing overflow to NaN |
5309 | EXPECT_TRUE(APFloat(APFloat::Float8E4M3FN(), "465" ).isNaN()); |
5310 | // Overflow without rounding |
5311 | EXPECT_TRUE(APFloat(APFloat::Float8E4M3FN(), "480" ).isNaN()); |
5312 | // Inf converted to NaN |
5313 | EXPECT_TRUE(APFloat(APFloat::Float8E4M3FN(), "inf" ).isNaN()); |
5314 | // NaN converted to NaN |
5315 | EXPECT_TRUE(APFloat(APFloat::Float8E4M3FN(), "nan" ).isNaN()); |
5316 | } |
5317 | |
5318 | TEST(APFloatTest, Float8E4M3FNAdd) { |
5319 | APFloat QNaN = APFloat::getNaN(Sem: APFloat::Float8E4M3FN(), Negative: false); |
5320 | |
5321 | auto FromStr = [](StringRef S) { |
5322 | return APFloat(APFloat::Float8E4M3FN(), S); |
5323 | }; |
5324 | |
5325 | struct { |
5326 | APFloat x; |
5327 | APFloat y; |
5328 | const char *result; |
5329 | int status; |
5330 | int category; |
5331 | APFloat::roundingMode roundingMode = APFloat::rmNearestTiesToEven; |
5332 | } AdditionTests[] = { |
5333 | // Test addition operations involving NaN, overflow, and the max E4M3 |
5334 | // value (448) because E4M3 differs from IEEE-754 types in these regards |
5335 | {.x: FromStr("448" ), .y: FromStr("16" ), .result: "448" , .status: APFloat::opInexact, |
5336 | .category: APFloat::fcNormal}, |
5337 | {.x: FromStr("448" ), .y: FromStr("18" ), .result: "NaN" , |
5338 | .status: APFloat::opOverflow | APFloat::opInexact, .category: APFloat::fcNaN}, |
5339 | {.x: FromStr("448" ), .y: FromStr("32" ), .result: "NaN" , |
5340 | .status: APFloat::opOverflow | APFloat::opInexact, .category: APFloat::fcNaN}, |
5341 | {.x: FromStr("-448" ), .y: FromStr("-32" ), .result: "-NaN" , |
5342 | .status: APFloat::opOverflow | APFloat::opInexact, .category: APFloat::fcNaN}, |
5343 | {.x: QNaN, .y: FromStr("-448" ), .result: "NaN" , .status: APFloat::opOK, .category: APFloat::fcNaN}, |
5344 | {.x: FromStr("448" ), .y: FromStr("-32" ), .result: "416" , .status: APFloat::opOK, .category: APFloat::fcNormal}, |
5345 | {.x: FromStr("448" ), .y: FromStr("0" ), .result: "448" , .status: APFloat::opOK, .category: APFloat::fcNormal}, |
5346 | {.x: FromStr("448" ), .y: FromStr("32" ), .result: "448" , .status: APFloat::opInexact, |
5347 | .category: APFloat::fcNormal, .roundingMode: APFloat::rmTowardZero}, |
5348 | {.x: FromStr("448" ), .y: FromStr("448" ), .result: "448" , .status: APFloat::opInexact, |
5349 | .category: APFloat::fcNormal, .roundingMode: APFloat::rmTowardZero}, |
5350 | }; |
5351 | |
5352 | for (size_t i = 0; i < std::size(AdditionTests); ++i) { |
5353 | APFloat x(AdditionTests[i].x); |
5354 | APFloat y(AdditionTests[i].y); |
5355 | APFloat::opStatus status = x.add(RHS: y, RM: AdditionTests[i].roundingMode); |
5356 | |
5357 | APFloat result(APFloat::Float8E4M3FN(), AdditionTests[i].result); |
5358 | |
5359 | EXPECT_TRUE(result.bitwiseIsEqual(x)); |
5360 | EXPECT_EQ(AdditionTests[i].status, (int)status); |
5361 | EXPECT_EQ(AdditionTests[i].category, (int)x.getCategory()); |
5362 | } |
5363 | } |
5364 | |
5365 | TEST(APFloatTest, Float8E4M3FNDivideByZero) { |
5366 | APFloat x(APFloat::Float8E4M3FN(), "1" ); |
5367 | APFloat zero(APFloat::Float8E4M3FN(), "0" ); |
5368 | EXPECT_EQ(x.divide(zero, APFloat::rmNearestTiesToEven), APFloat::opDivByZero); |
5369 | EXPECT_TRUE(x.isNaN()); |
5370 | } |
5371 | |
5372 | TEST(APFloatTest, Float8E4M3FNNext) { |
5373 | APFloat test(APFloat::Float8E4M3FN(), APFloat::uninitialized); |
5374 | APFloat expected(APFloat::Float8E4M3FN(), APFloat::uninitialized); |
5375 | |
5376 | // nextUp on positive numbers |
5377 | for (int i = 0; i < 127; i++) { |
5378 | test = APFloat(APFloat::Float8E4M3FN(), APInt(8, i)); |
5379 | expected = APFloat(APFloat::Float8E4M3FN(), APInt(8, i + 1)); |
5380 | EXPECT_EQ(test.next(false), APFloat::opOK); |
5381 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
5382 | } |
5383 | |
5384 | // nextUp on negative zero |
5385 | test = APFloat::getZero(Sem: APFloat::Float8E4M3FN(), Negative: true); |
5386 | expected = APFloat::getSmallest(Sem: APFloat::Float8E4M3FN(), Negative: false); |
5387 | EXPECT_EQ(test.next(false), APFloat::opOK); |
5388 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
5389 | |
5390 | // nextUp on negative nonzero numbers |
5391 | for (int i = 129; i < 255; i++) { |
5392 | test = APFloat(APFloat::Float8E4M3FN(), APInt(8, i)); |
5393 | expected = APFloat(APFloat::Float8E4M3FN(), APInt(8, i - 1)); |
5394 | EXPECT_EQ(test.next(false), APFloat::opOK); |
5395 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
5396 | } |
5397 | |
5398 | // nextUp on NaN |
5399 | test = APFloat::getQNaN(Sem: APFloat::Float8E4M3FN(), Negative: false); |
5400 | expected = APFloat::getQNaN(Sem: APFloat::Float8E4M3FN(), Negative: false); |
5401 | EXPECT_EQ(test.next(false), APFloat::opOK); |
5402 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
5403 | |
5404 | // nextDown on positive nonzero finite numbers |
5405 | for (int i = 1; i < 127; i++) { |
5406 | test = APFloat(APFloat::Float8E4M3FN(), APInt(8, i)); |
5407 | expected = APFloat(APFloat::Float8E4M3FN(), APInt(8, i - 1)); |
5408 | EXPECT_EQ(test.next(true), APFloat::opOK); |
5409 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
5410 | } |
5411 | |
5412 | // nextDown on positive zero |
5413 | test = APFloat::getZero(Sem: APFloat::Float8E4M3FN(), Negative: true); |
5414 | expected = APFloat::getSmallest(Sem: APFloat::Float8E4M3FN(), Negative: true); |
5415 | EXPECT_EQ(test.next(true), APFloat::opOK); |
5416 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
5417 | |
5418 | // nextDown on negative finite numbers |
5419 | for (int i = 128; i < 255; i++) { |
5420 | test = APFloat(APFloat::Float8E4M3FN(), APInt(8, i)); |
5421 | expected = APFloat(APFloat::Float8E4M3FN(), APInt(8, i + 1)); |
5422 | EXPECT_EQ(test.next(true), APFloat::opOK); |
5423 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
5424 | } |
5425 | |
5426 | // nextDown on NaN |
5427 | test = APFloat::getQNaN(Sem: APFloat::Float8E4M3FN(), Negative: false); |
5428 | expected = APFloat::getQNaN(Sem: APFloat::Float8E4M3FN(), Negative: false); |
5429 | EXPECT_EQ(test.next(true), APFloat::opOK); |
5430 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
5431 | } |
5432 | |
5433 | TEST(APFloatTest, Float8E4M3FNExhaustive) { |
5434 | // Test each of the 256 Float8E4M3FN values. |
5435 | for (int i = 0; i < 256; i++) { |
5436 | APFloat test(APFloat::Float8E4M3FN(), APInt(8, i)); |
5437 | SCOPED_TRACE("i=" + std::to_string(i)); |
5438 | |
5439 | // isLargest |
5440 | if (i == 126 || i == 254) { |
5441 | EXPECT_TRUE(test.isLargest()); |
5442 | EXPECT_EQ(abs(test).convertToDouble(), 448.); |
5443 | } else { |
5444 | EXPECT_FALSE(test.isLargest()); |
5445 | } |
5446 | |
5447 | // isSmallest |
5448 | if (i == 1 || i == 129) { |
5449 | EXPECT_TRUE(test.isSmallest()); |
5450 | EXPECT_EQ(abs(test).convertToDouble(), 0x1p-9); |
5451 | } else { |
5452 | EXPECT_FALSE(test.isSmallest()); |
5453 | } |
5454 | |
5455 | // convert to BFloat |
5456 | APFloat test2 = test; |
5457 | bool losesInfo; |
5458 | APFloat::opStatus status = test2.convert( |
5459 | ToSemantics: APFloat::BFloat(), RM: APFloat::rmNearestTiesToEven, losesInfo: &losesInfo); |
5460 | EXPECT_EQ(status, APFloat::opOK); |
5461 | EXPECT_FALSE(losesInfo); |
5462 | if (i == 127 || i == 255) |
5463 | EXPECT_TRUE(test2.isNaN()); |
5464 | else |
5465 | EXPECT_EQ(test.convertToFloat(), test2.convertToFloat()); |
5466 | |
5467 | // bitcastToAPInt |
5468 | EXPECT_EQ(i, test.bitcastToAPInt()); |
5469 | } |
5470 | } |
5471 | |
5472 | TEST(APFloatTest, Float8E5M2FNUZNext) { |
5473 | APFloat test(APFloat::Float8E5M2FNUZ(), APFloat::uninitialized); |
5474 | APFloat expected(APFloat::Float8E5M2FNUZ(), APFloat::uninitialized); |
5475 | |
5476 | // 1. NextUp of largest bit pattern is nan |
5477 | test = APFloat::getLargest(Sem: APFloat::Float8E5M2FNUZ()); |
5478 | expected = APFloat::getNaN(Sem: APFloat::Float8E5M2FNUZ()); |
5479 | EXPECT_EQ(test.next(false), APFloat::opOK); |
5480 | EXPECT_FALSE(test.isInfinity()); |
5481 | EXPECT_FALSE(test.isZero()); |
5482 | EXPECT_TRUE(test.isNaN()); |
5483 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
5484 | |
5485 | // 2. NextUp of smallest negative denormal is +0 |
5486 | test = APFloat::getSmallest(Sem: APFloat::Float8E5M2FNUZ(), Negative: true); |
5487 | expected = APFloat::getZero(Sem: APFloat::Float8E5M2FNUZ(), Negative: false); |
5488 | EXPECT_EQ(test.next(false), APFloat::opOK); |
5489 | EXPECT_FALSE(test.isNegZero()); |
5490 | EXPECT_TRUE(test.isPosZero()); |
5491 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
5492 | |
5493 | // 3. nextDown of negative of largest value is NaN |
5494 | test = APFloat::getLargest(Sem: APFloat::Float8E5M2FNUZ(), Negative: true); |
5495 | expected = APFloat::getNaN(Sem: APFloat::Float8E5M2FNUZ()); |
5496 | EXPECT_EQ(test.next(true), APFloat::opOK); |
5497 | EXPECT_FALSE(test.isInfinity()); |
5498 | EXPECT_FALSE(test.isZero()); |
5499 | EXPECT_TRUE(test.isNaN()); |
5500 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
5501 | |
5502 | // 4. nextDown of +0 is smallest negative denormal |
5503 | test = APFloat::getZero(Sem: APFloat::Float8E5M2FNUZ(), Negative: false); |
5504 | expected = APFloat::getSmallest(Sem: APFloat::Float8E5M2FNUZ(), Negative: true); |
5505 | EXPECT_EQ(test.next(true), APFloat::opOK); |
5506 | EXPECT_FALSE(test.isZero()); |
5507 | EXPECT_TRUE(test.isDenormal()); |
5508 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
5509 | |
5510 | // 5. nextUp of NaN is NaN |
5511 | test = APFloat::getNaN(Sem: APFloat::Float8E5M2FNUZ(), Negative: false); |
5512 | expected = APFloat::getNaN(Sem: APFloat::Float8E5M2FNUZ(), Negative: true); |
5513 | EXPECT_EQ(test.next(false), APFloat::opOK); |
5514 | EXPECT_TRUE(test.isNaN()); |
5515 | |
5516 | // 6. nextDown of NaN is NaN |
5517 | test = APFloat::getNaN(Sem: APFloat::Float8E5M2FNUZ(), Negative: false); |
5518 | expected = APFloat::getNaN(Sem: APFloat::Float8E5M2FNUZ(), Negative: true); |
5519 | EXPECT_EQ(test.next(true), APFloat::opOK); |
5520 | EXPECT_TRUE(test.isNaN()); |
5521 | } |
5522 | |
5523 | TEST(APFloatTest, Float8E5M2FNUZChangeSign) { |
5524 | APFloat test = APFloat(APFloat::Float8E5M2FNUZ(), "1.0" ); |
5525 | APFloat expected = APFloat(APFloat::Float8E5M2FNUZ(), "-1.0" ); |
5526 | test.changeSign(); |
5527 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
5528 | |
5529 | test = APFloat::getZero(Sem: APFloat::Float8E5M2FNUZ()); |
5530 | expected = test; |
5531 | test.changeSign(); |
5532 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
5533 | |
5534 | test = APFloat::getNaN(Sem: APFloat::Float8E5M2FNUZ()); |
5535 | expected = test; |
5536 | test.changeSign(); |
5537 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
5538 | } |
5539 | |
5540 | TEST(APFloatTest, Float8E5M2FNUZFromString) { |
5541 | // Exactly representable |
5542 | EXPECT_EQ(57344, |
5543 | APFloat(APFloat::Float8E5M2FNUZ(), "57344" ).convertToDouble()); |
5544 | // Round down to maximum value |
5545 | EXPECT_EQ(57344, |
5546 | APFloat(APFloat::Float8E5M2FNUZ(), "59392" ).convertToDouble()); |
5547 | // Round up, causing overflow to NaN |
5548 | EXPECT_TRUE(APFloat(APFloat::Float8E5M2FNUZ(), "61440" ).isNaN()); |
5549 | // Overflow without rounding |
5550 | EXPECT_TRUE(APFloat(APFloat::Float8E5M2FNUZ(), "131072" ).isNaN()); |
5551 | // Inf converted to NaN |
5552 | EXPECT_TRUE(APFloat(APFloat::Float8E5M2FNUZ(), "inf" ).isNaN()); |
5553 | // NaN converted to NaN |
5554 | EXPECT_TRUE(APFloat(APFloat::Float8E5M2FNUZ(), "nan" ).isNaN()); |
5555 | // Negative zero converted to positive zero |
5556 | EXPECT_TRUE(APFloat(APFloat::Float8E5M2FNUZ(), "-0" ).isPosZero()); |
5557 | } |
5558 | |
5559 | TEST(APFloatTest, UnsignedZeroArithmeticSpecial) { |
5560 | // Float semantics with only unsigned zero (ex. Float8E4M3FNUZ) violate the |
5561 | // IEEE rules about signs in arithmetic operations when producing zeros, |
5562 | // because they only have one zero. Most of the rest of the complexities of |
5563 | // arithmetic on these values are covered by the other Float8 types' test |
5564 | // cases and so are not repeated here. |
5565 | |
5566 | // The IEEE round towards negative rule doesn't apply |
5567 | for (APFloat::Semantics S : |
5568 | {APFloat::S_Float8E4M3FNUZ, APFloat::S_Float8E4M3B11FNUZ}) { |
5569 | const llvm::fltSemantics &Sem = APFloat::EnumToSemantics(S); |
5570 | APFloat test = APFloat::getSmallest(Sem); |
5571 | APFloat rhs = test; |
5572 | EXPECT_EQ(test.subtract(rhs, APFloat::rmTowardNegative), APFloat::opOK); |
5573 | EXPECT_TRUE(test.isZero()); |
5574 | EXPECT_FALSE(test.isNegative()); |
5575 | |
5576 | // Multiplication of (small) * (-small) is +0 |
5577 | test = APFloat::getSmallestNormalized(Sem); |
5578 | rhs = -test; |
5579 | EXPECT_EQ(test.multiply(rhs, APFloat::rmNearestTiesToAway), |
5580 | APFloat::opInexact | APFloat::opUnderflow); |
5581 | EXPECT_TRUE(test.isZero()); |
5582 | EXPECT_FALSE(test.isNegative()); |
5583 | |
5584 | // Dividing the negatize float_min by anything gives +0 |
5585 | test = APFloat::getSmallest(Sem, Negative: true); |
5586 | rhs = APFloat(Sem, "2.0" ); |
5587 | EXPECT_EQ(test.divide(rhs, APFloat::rmNearestTiesToEven), |
5588 | APFloat::opInexact | APFloat::opUnderflow); |
5589 | EXPECT_TRUE(test.isZero()); |
5590 | EXPECT_FALSE(test.isNegative()); |
5591 | |
5592 | // Remainder can't copy sign because there's only one zero |
5593 | test = APFloat(Sem, "-4.0" ); |
5594 | rhs = APFloat(Sem, "2.0" ); |
5595 | EXPECT_EQ(test.remainder(rhs), APFloat::opOK); |
5596 | EXPECT_TRUE(test.isZero()); |
5597 | EXPECT_FALSE(test.isNegative()); |
5598 | |
5599 | // And same for mod |
5600 | test = APFloat(Sem, "-4.0" ); |
5601 | rhs = APFloat(Sem, "2.0" ); |
5602 | EXPECT_EQ(test.mod(rhs), APFloat::opOK); |
5603 | EXPECT_TRUE(test.isZero()); |
5604 | EXPECT_FALSE(test.isNegative()); |
5605 | |
5606 | // FMA correctly handles both the multiply and add parts of all this |
5607 | test = APFloat(Sem, "2.0" ); |
5608 | rhs = test; |
5609 | APFloat addend = APFloat(Sem, "-4.0" ); |
5610 | EXPECT_EQ(test.fusedMultiplyAdd(rhs, addend, APFloat::rmTowardNegative), |
5611 | APFloat::opOK); |
5612 | EXPECT_TRUE(test.isZero()); |
5613 | EXPECT_FALSE(test.isNegative()); |
5614 | } |
5615 | } |
5616 | |
5617 | TEST(APFloatTest, Float8E5M2FNUZAdd) { |
5618 | APFloat QNaN = APFloat::getNaN(Sem: APFloat::Float8E5M2FNUZ(), Negative: false); |
5619 | |
5620 | auto FromStr = [](StringRef S) { |
5621 | return APFloat(APFloat::Float8E5M2FNUZ(), S); |
5622 | }; |
5623 | |
5624 | struct { |
5625 | APFloat x; |
5626 | APFloat y; |
5627 | const char *result; |
5628 | int status; |
5629 | int category; |
5630 | APFloat::roundingMode roundingMode = APFloat::rmNearestTiesToEven; |
5631 | } AdditionTests[] = { |
5632 | // Test addition operations involving NaN, overflow, and the max E5M2FNUZ |
5633 | // value (57344) because E5M2FNUZ differs from IEEE-754 types in these |
5634 | // regards |
5635 | {.x: FromStr("57344" ), .y: FromStr("2048" ), .result: "57344" , .status: APFloat::opInexact, |
5636 | .category: APFloat::fcNormal}, |
5637 | {.x: FromStr("57344" ), .y: FromStr("4096" ), .result: "NaN" , |
5638 | .status: APFloat::opOverflow | APFloat::opInexact, .category: APFloat::fcNaN}, |
5639 | {.x: FromStr("-57344" ), .y: FromStr("-4096" ), .result: "NaN" , |
5640 | .status: APFloat::opOverflow | APFloat::opInexact, .category: APFloat::fcNaN}, |
5641 | {.x: QNaN, .y: FromStr("-57344" ), .result: "NaN" , .status: APFloat::opOK, .category: APFloat::fcNaN}, |
5642 | {.x: FromStr("57344" ), .y: FromStr("-8192" ), .result: "49152" , .status: APFloat::opOK, |
5643 | .category: APFloat::fcNormal}, |
5644 | {.x: FromStr("57344" ), .y: FromStr("0" ), .result: "57344" , .status: APFloat::opOK, |
5645 | .category: APFloat::fcNormal}, |
5646 | {.x: FromStr("57344" ), .y: FromStr("4096" ), .result: "57344" , .status: APFloat::opInexact, |
5647 | .category: APFloat::fcNormal, .roundingMode: APFloat::rmTowardZero}, |
5648 | {.x: FromStr("57344" ), .y: FromStr("57344" ), .result: "57344" , .status: APFloat::opInexact, |
5649 | .category: APFloat::fcNormal, .roundingMode: APFloat::rmTowardZero}, |
5650 | }; |
5651 | |
5652 | for (size_t i = 0; i < std::size(AdditionTests); ++i) { |
5653 | APFloat x(AdditionTests[i].x); |
5654 | APFloat y(AdditionTests[i].y); |
5655 | APFloat::opStatus status = x.add(RHS: y, RM: AdditionTests[i].roundingMode); |
5656 | |
5657 | APFloat result(APFloat::Float8E5M2FNUZ(), AdditionTests[i].result); |
5658 | |
5659 | EXPECT_TRUE(result.bitwiseIsEqual(x)); |
5660 | EXPECT_EQ(AdditionTests[i].status, (int)status); |
5661 | EXPECT_EQ(AdditionTests[i].category, (int)x.getCategory()); |
5662 | } |
5663 | } |
5664 | |
5665 | TEST(APFloatTest, Float8E5M2FNUZDivideByZero) { |
5666 | APFloat x(APFloat::Float8E5M2FNUZ(), "1" ); |
5667 | APFloat zero(APFloat::Float8E5M2FNUZ(), "0" ); |
5668 | EXPECT_EQ(x.divide(zero, APFloat::rmNearestTiesToEven), APFloat::opDivByZero); |
5669 | EXPECT_TRUE(x.isNaN()); |
5670 | } |
5671 | |
5672 | TEST(APFloatTest, Float8UnsignedZeroExhaustive) { |
5673 | struct { |
5674 | const fltSemantics *semantics; |
5675 | const double largest; |
5676 | const double smallest; |
5677 | } const exhaustiveTests[] = {{.semantics: &APFloat::Float8E5M2FNUZ(), .largest: 57344., .smallest: 0x1.0p-17}, |
5678 | {.semantics: &APFloat::Float8E4M3FNUZ(), .largest: 240., .smallest: 0x1.0p-10}, |
5679 | {.semantics: &APFloat::Float8E4M3B11FNUZ(), .largest: 30., .smallest: 0x1.0p-13}}; |
5680 | for (const auto &testInfo : exhaustiveTests) { |
5681 | const fltSemantics &sem = *testInfo.semantics; |
5682 | SCOPED_TRACE("Semantics=" + std::to_string(APFloat::SemanticsToEnum(sem))); |
5683 | // Test each of the 256 values. |
5684 | for (int i = 0; i < 256; i++) { |
5685 | SCOPED_TRACE("i=" + std::to_string(i)); |
5686 | APFloat test(sem, APInt(8, i)); |
5687 | |
5688 | // isLargest |
5689 | if (i == 127 || i == 255) { |
5690 | EXPECT_TRUE(test.isLargest()); |
5691 | EXPECT_EQ(abs(test).convertToDouble(), testInfo.largest); |
5692 | } else { |
5693 | EXPECT_FALSE(test.isLargest()); |
5694 | } |
5695 | |
5696 | // isSmallest |
5697 | if (i == 1 || i == 129) { |
5698 | EXPECT_TRUE(test.isSmallest()); |
5699 | EXPECT_EQ(abs(test).convertToDouble(), testInfo.smallest); |
5700 | } else { |
5701 | EXPECT_FALSE(test.isSmallest()); |
5702 | } |
5703 | |
5704 | // convert to BFloat |
5705 | APFloat test2 = test; |
5706 | bool losesInfo; |
5707 | APFloat::opStatus status = test2.convert( |
5708 | ToSemantics: APFloat::BFloat(), RM: APFloat::rmNearestTiesToEven, losesInfo: &losesInfo); |
5709 | EXPECT_EQ(status, APFloat::opOK); |
5710 | EXPECT_FALSE(losesInfo); |
5711 | if (i == 128) |
5712 | EXPECT_TRUE(test2.isNaN()); |
5713 | else |
5714 | EXPECT_EQ(test.convertToFloat(), test2.convertToFloat()); |
5715 | |
5716 | // bitcastToAPInt |
5717 | EXPECT_EQ(i, test.bitcastToAPInt()); |
5718 | } |
5719 | } |
5720 | } |
5721 | |
5722 | TEST(APFloatTest, Float8E4M3FNUZNext) { |
5723 | for (APFloat::Semantics S : |
5724 | {APFloat::S_Float8E4M3FNUZ, APFloat::S_Float8E4M3B11FNUZ}) { |
5725 | const llvm::fltSemantics &Sem = APFloat::EnumToSemantics(S); |
5726 | APFloat test(Sem, APFloat::uninitialized); |
5727 | APFloat expected(Sem, APFloat::uninitialized); |
5728 | |
5729 | // 1. NextUp of largest bit pattern is nan |
5730 | test = APFloat::getLargest(Sem); |
5731 | expected = APFloat::getNaN(Sem); |
5732 | EXPECT_EQ(test.next(false), APFloat::opOK); |
5733 | EXPECT_FALSE(test.isInfinity()); |
5734 | EXPECT_FALSE(test.isZero()); |
5735 | EXPECT_TRUE(test.isNaN()); |
5736 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
5737 | |
5738 | // 2. NextUp of smallest negative denormal is +0 |
5739 | test = APFloat::getSmallest(Sem, Negative: true); |
5740 | expected = APFloat::getZero(Sem, Negative: false); |
5741 | EXPECT_EQ(test.next(false), APFloat::opOK); |
5742 | EXPECT_FALSE(test.isNegZero()); |
5743 | EXPECT_TRUE(test.isPosZero()); |
5744 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
5745 | |
5746 | // 3. nextDown of negative of largest value is NaN |
5747 | test = APFloat::getLargest(Sem, Negative: true); |
5748 | expected = APFloat::getNaN(Sem); |
5749 | EXPECT_EQ(test.next(true), APFloat::opOK); |
5750 | EXPECT_FALSE(test.isInfinity()); |
5751 | EXPECT_FALSE(test.isZero()); |
5752 | EXPECT_TRUE(test.isNaN()); |
5753 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
5754 | |
5755 | // 4. nextDown of +0 is smallest negative denormal |
5756 | test = APFloat::getZero(Sem, Negative: false); |
5757 | expected = APFloat::getSmallest(Sem, Negative: true); |
5758 | EXPECT_EQ(test.next(true), APFloat::opOK); |
5759 | EXPECT_FALSE(test.isZero()); |
5760 | EXPECT_TRUE(test.isDenormal()); |
5761 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
5762 | |
5763 | // 5. nextUp of NaN is NaN |
5764 | test = APFloat::getNaN(Sem, Negative: false); |
5765 | expected = APFloat::getNaN(Sem, Negative: true); |
5766 | EXPECT_EQ(test.next(false), APFloat::opOK); |
5767 | EXPECT_TRUE(test.isNaN()); |
5768 | |
5769 | // 6. nextDown of NaN is NaN |
5770 | test = APFloat::getNaN(Sem, Negative: false); |
5771 | expected = APFloat::getNaN(Sem, Negative: true); |
5772 | EXPECT_EQ(test.next(true), APFloat::opOK); |
5773 | EXPECT_TRUE(test.isNaN()); |
5774 | } |
5775 | } |
5776 | |
5777 | TEST(APFloatTest, Float8E4M3FNUZChangeSign) { |
5778 | for (APFloat::Semantics S : |
5779 | {APFloat::S_Float8E4M3FNUZ, APFloat::S_Float8E4M3B11FNUZ}) { |
5780 | const llvm::fltSemantics &Sem = APFloat::EnumToSemantics(S); |
5781 | APFloat test = APFloat(Sem, "1.0" ); |
5782 | APFloat expected = APFloat(Sem, "-1.0" ); |
5783 | test.changeSign(); |
5784 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
5785 | |
5786 | test = APFloat::getZero(Sem); |
5787 | expected = test; |
5788 | test.changeSign(); |
5789 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
5790 | |
5791 | test = APFloat::getNaN(Sem); |
5792 | expected = test; |
5793 | test.changeSign(); |
5794 | EXPECT_TRUE(test.bitwiseIsEqual(expected)); |
5795 | } |
5796 | } |
5797 | |
5798 | TEST(APFloatTest, Float8E4M3FNUZFromString) { |
5799 | // Exactly representable |
5800 | EXPECT_EQ(240, APFloat(APFloat::Float8E4M3FNUZ(), "240" ).convertToDouble()); |
5801 | // Round down to maximum value |
5802 | EXPECT_EQ(240, APFloat(APFloat::Float8E4M3FNUZ(), "247" ).convertToDouble()); |
5803 | // Round up, causing overflow to NaN |
5804 | EXPECT_TRUE(APFloat(APFloat::Float8E4M3FNUZ(), "248" ).isNaN()); |
5805 | // Overflow without rounding |
5806 | EXPECT_TRUE(APFloat(APFloat::Float8E4M3FNUZ(), "480" ).isNaN()); |
5807 | // Inf converted to NaN |
5808 | EXPECT_TRUE(APFloat(APFloat::Float8E4M3FNUZ(), "inf" ).isNaN()); |
5809 | // NaN converted to NaN |
5810 | EXPECT_TRUE(APFloat(APFloat::Float8E4M3FNUZ(), "nan" ).isNaN()); |
5811 | // Negative zero converted to positive zero |
5812 | EXPECT_TRUE(APFloat(APFloat::Float8E4M3FNUZ(), "-0" ).isPosZero()); |
5813 | } |
5814 | |
5815 | TEST(APFloatTest, Float8E4M3FNUZAdd) { |
5816 | APFloat QNaN = APFloat::getNaN(Sem: APFloat::Float8E4M3FNUZ(), Negative: false); |
5817 | |
5818 | auto FromStr = [](StringRef S) { |
5819 | return APFloat(APFloat::Float8E4M3FNUZ(), S); |
5820 | }; |
5821 | |
5822 | struct { |
5823 | APFloat x; |
5824 | APFloat y; |
5825 | const char *result; |
5826 | int status; |
5827 | int category; |
5828 | APFloat::roundingMode roundingMode = APFloat::rmNearestTiesToEven; |
5829 | } AdditionTests[] = { |
5830 | // Test addition operations involving NaN, overflow, and the max E4M3FNUZ |
5831 | // value (240) because E4M3FNUZ differs from IEEE-754 types in these |
5832 | // regards |
5833 | {.x: FromStr("240" ), .y: FromStr("4" ), .result: "240" , .status: APFloat::opInexact, |
5834 | .category: APFloat::fcNormal}, |
5835 | {.x: FromStr("240" ), .y: FromStr("8" ), .result: "NaN" , |
5836 | .status: APFloat::opOverflow | APFloat::opInexact, .category: APFloat::fcNaN}, |
5837 | {.x: FromStr("240" ), .y: FromStr("16" ), .result: "NaN" , |
5838 | .status: APFloat::opOverflow | APFloat::opInexact, .category: APFloat::fcNaN}, |
5839 | {.x: FromStr("-240" ), .y: FromStr("-16" ), .result: "NaN" , |
5840 | .status: APFloat::opOverflow | APFloat::opInexact, .category: APFloat::fcNaN}, |
5841 | {.x: QNaN, .y: FromStr("-240" ), .result: "NaN" , .status: APFloat::opOK, .category: APFloat::fcNaN}, |
5842 | {.x: FromStr("240" ), .y: FromStr("-16" ), .result: "224" , .status: APFloat::opOK, .category: APFloat::fcNormal}, |
5843 | {.x: FromStr("240" ), .y: FromStr("0" ), .result: "240" , .status: APFloat::opOK, .category: APFloat::fcNormal}, |
5844 | {.x: FromStr("240" ), .y: FromStr("32" ), .result: "240" , .status: APFloat::opInexact, |
5845 | .category: APFloat::fcNormal, .roundingMode: APFloat::rmTowardZero}, |
5846 | {.x: FromStr("240" ), .y: FromStr("240" ), .result: "240" , .status: APFloat::opInexact, |
5847 | .category: APFloat::fcNormal, .roundingMode: APFloat::rmTowardZero}, |
5848 | }; |
5849 | |
5850 | for (size_t i = 0; i < std::size(AdditionTests); ++i) { |
5851 | APFloat x(AdditionTests[i].x); |
5852 | APFloat y(AdditionTests[i].y); |
5853 | APFloat::opStatus status = x.add(RHS: y, RM: AdditionTests[i].roundingMode); |
5854 | |
5855 | APFloat result(APFloat::Float8E4M3FNUZ(), AdditionTests[i].result); |
5856 | |
5857 | EXPECT_TRUE(result.bitwiseIsEqual(x)); |
5858 | EXPECT_EQ(AdditionTests[i].status, (int)status); |
5859 | EXPECT_EQ(AdditionTests[i].category, (int)x.getCategory()); |
5860 | } |
5861 | } |
5862 | |
5863 | TEST(APFloatTest, Float8E4M3FNUZDivideByZero) { |
5864 | APFloat x(APFloat::Float8E4M3FNUZ(), "1" ); |
5865 | APFloat zero(APFloat::Float8E4M3FNUZ(), "0" ); |
5866 | EXPECT_EQ(x.divide(zero, APFloat::rmNearestTiesToEven), APFloat::opDivByZero); |
5867 | EXPECT_TRUE(x.isNaN()); |
5868 | } |
5869 | |
5870 | TEST(APFloatTest, ConvertE5M2FNUZToE4M3FNUZ) { |
5871 | bool losesInfo; |
5872 | APFloat test(APFloat::Float8E5M2FNUZ(), "1.0" ); |
5873 | APFloat::opStatus status = test.convert( |
5874 | ToSemantics: APFloat::Float8E4M3FNUZ(), RM: APFloat::rmNearestTiesToEven, losesInfo: &losesInfo); |
5875 | EXPECT_EQ(1.0f, test.convertToFloat()); |
5876 | EXPECT_FALSE(losesInfo); |
5877 | EXPECT_EQ(status, APFloat::opOK); |
5878 | |
5879 | losesInfo = true; |
5880 | test = APFloat(APFloat::Float8E5M2FNUZ(), "0.0" ); |
5881 | status = test.convert(ToSemantics: APFloat::Float8E4M3FNUZ(), RM: APFloat::rmNearestTiesToEven, |
5882 | losesInfo: &losesInfo); |
5883 | EXPECT_EQ(0.0f, test.convertToFloat()); |
5884 | EXPECT_FALSE(losesInfo); |
5885 | EXPECT_EQ(status, APFloat::opOK); |
5886 | |
5887 | losesInfo = true; |
5888 | test = APFloat(APFloat::Float8E5M2FNUZ(), "0x1.Cp7" ); // 224 |
5889 | status = test.convert(ToSemantics: APFloat::Float8E4M3FNUZ(), RM: APFloat::rmNearestTiesToEven, |
5890 | losesInfo: &losesInfo); |
5891 | EXPECT_EQ(0x1.Cp7 /* 224 */, test.convertToFloat()); |
5892 | EXPECT_FALSE(losesInfo); |
5893 | EXPECT_EQ(status, APFloat::opOK); |
5894 | |
5895 | // Test overflow |
5896 | losesInfo = false; |
5897 | test = APFloat(APFloat::Float8E5M2FNUZ(), "0x1.0p8" ); // 256 |
5898 | status = test.convert(ToSemantics: APFloat::Float8E4M3FNUZ(), RM: APFloat::rmNearestTiesToEven, |
5899 | losesInfo: &losesInfo); |
5900 | EXPECT_TRUE(std::isnan(test.convertToFloat())); |
5901 | EXPECT_TRUE(losesInfo); |
5902 | EXPECT_EQ(status, APFloat::opOverflow | APFloat::opInexact); |
5903 | |
5904 | // Test underflow |
5905 | test = APFloat(APFloat::Float8E5M2FNUZ(), "0x1.0p-11" ); |
5906 | status = test.convert(ToSemantics: APFloat::Float8E4M3FNUZ(), RM: APFloat::rmNearestTiesToEven, |
5907 | losesInfo: &losesInfo); |
5908 | EXPECT_EQ(0., test.convertToFloat()); |
5909 | EXPECT_TRUE(losesInfo); |
5910 | EXPECT_EQ(status, APFloat::opUnderflow | APFloat::opInexact); |
5911 | |
5912 | // Test rounding up to smallest denormal number |
5913 | losesInfo = false; |
5914 | test = APFloat(APFloat::Float8E5M2FNUZ(), "0x1.8p-11" ); |
5915 | status = test.convert(ToSemantics: APFloat::Float8E4M3FNUZ(), RM: APFloat::rmNearestTiesToEven, |
5916 | losesInfo: &losesInfo); |
5917 | EXPECT_EQ(0x1.0p-10, test.convertToFloat()); |
5918 | EXPECT_TRUE(losesInfo); |
5919 | EXPECT_EQ(status, APFloat::opUnderflow | APFloat::opInexact); |
5920 | |
5921 | // Testing inexact rounding to denormal number |
5922 | losesInfo = false; |
5923 | test = APFloat(APFloat::Float8E5M2FNUZ(), "0x1.8p-10" ); |
5924 | status = test.convert(ToSemantics: APFloat::Float8E4M3FNUZ(), RM: APFloat::rmNearestTiesToEven, |
5925 | losesInfo: &losesInfo); |
5926 | EXPECT_EQ(0x1.0p-9, test.convertToFloat()); |
5927 | EXPECT_TRUE(losesInfo); |
5928 | EXPECT_EQ(status, APFloat::opUnderflow | APFloat::opInexact); |
5929 | } |
5930 | |
5931 | TEST(APFloatTest, ConvertE4M3FNUZToE5M2FNUZ) { |
5932 | bool losesInfo; |
5933 | APFloat test(APFloat::Float8E4M3FNUZ(), "1.0" ); |
5934 | APFloat::opStatus status = test.convert( |
5935 | ToSemantics: APFloat::Float8E5M2FNUZ(), RM: APFloat::rmNearestTiesToEven, losesInfo: &losesInfo); |
5936 | EXPECT_EQ(1.0f, test.convertToFloat()); |
5937 | EXPECT_FALSE(losesInfo); |
5938 | EXPECT_EQ(status, APFloat::opOK); |
5939 | |
5940 | losesInfo = true; |
5941 | test = APFloat(APFloat::Float8E4M3FNUZ(), "0.0" ); |
5942 | status = test.convert(ToSemantics: APFloat::Float8E5M2FNUZ(), RM: APFloat::rmNearestTiesToEven, |
5943 | losesInfo: &losesInfo); |
5944 | EXPECT_EQ(0.0f, test.convertToFloat()); |
5945 | EXPECT_FALSE(losesInfo); |
5946 | EXPECT_EQ(status, APFloat::opOK); |
5947 | |
5948 | losesInfo = false; |
5949 | test = APFloat(APFloat::Float8E4M3FNUZ(), "0x1.2p0" ); // 1.125 |
5950 | status = test.convert(ToSemantics: APFloat::Float8E5M2FNUZ(), RM: APFloat::rmNearestTiesToEven, |
5951 | losesInfo: &losesInfo); |
5952 | EXPECT_EQ(0x1.0p0 /* 1.0 */, test.convertToFloat()); |
5953 | EXPECT_TRUE(losesInfo); |
5954 | EXPECT_EQ(status, APFloat::opInexact); |
5955 | |
5956 | losesInfo = false; |
5957 | test = APFloat(APFloat::Float8E4M3FNUZ(), "0x1.6p0" ); // 1.375 |
5958 | status = test.convert(ToSemantics: APFloat::Float8E5M2FNUZ(), RM: APFloat::rmNearestTiesToEven, |
5959 | losesInfo: &losesInfo); |
5960 | EXPECT_EQ(0x1.8p0 /* 1.5 */, test.convertToFloat()); |
5961 | EXPECT_TRUE(losesInfo); |
5962 | EXPECT_EQ(status, APFloat::opInexact); |
5963 | |
5964 | // Convert E4M3 denormal to E5M2 normal. Should not be truncated, despite the |
5965 | // destination format having one fewer significand bit |
5966 | losesInfo = true; |
5967 | test = APFloat(APFloat::Float8E4M3FNUZ(), "0x1.Cp-8" ); |
5968 | status = test.convert(ToSemantics: APFloat::Float8E5M2FNUZ(), RM: APFloat::rmNearestTiesToEven, |
5969 | losesInfo: &losesInfo); |
5970 | EXPECT_EQ(0x1.Cp-8, test.convertToFloat()); |
5971 | EXPECT_FALSE(losesInfo); |
5972 | EXPECT_EQ(status, APFloat::opOK); |
5973 | } |
5974 | |
5975 | TEST(APFloatTest, F8ToString) { |
5976 | for (APFloat::Semantics S : |
5977 | {APFloat::S_Float8E5M2, APFloat::S_Float8E4M3FN, |
5978 | APFloat::S_Float8E5M2FNUZ, APFloat::S_Float8E4M3FNUZ, |
5979 | APFloat::S_Float8E4M3B11FNUZ}) { |
5980 | SCOPED_TRACE("Semantics=" + std::to_string(S)); |
5981 | for (int i = 0; i < 256; i++) { |
5982 | SCOPED_TRACE("i=" + std::to_string(i)); |
5983 | APFloat test(APFloat::EnumToSemantics(S), APInt(8, i)); |
5984 | llvm::SmallString<128> str; |
5985 | test.toString(Str&: str); |
5986 | |
5987 | if (test.isNaN()) { |
5988 | EXPECT_EQ(str, "NaN" ); |
5989 | } else { |
5990 | APFloat test2(APFloat::EnumToSemantics(S), str); |
5991 | EXPECT_TRUE(test.bitwiseIsEqual(test2)); |
5992 | } |
5993 | } |
5994 | } |
5995 | } |
5996 | |
5997 | TEST(APFloatTest, BitsToF8ToBits) { |
5998 | for (APFloat::Semantics S : |
5999 | {APFloat::S_Float8E5M2, APFloat::S_Float8E4M3FN, |
6000 | APFloat::S_Float8E5M2FNUZ, APFloat::S_Float8E4M3FNUZ, |
6001 | APFloat::S_Float8E4M3B11FNUZ}) { |
6002 | SCOPED_TRACE("Semantics=" + std::to_string(S)); |
6003 | for (int i = 0; i < 256; i++) { |
6004 | SCOPED_TRACE("i=" + std::to_string(i)); |
6005 | APInt bits_in = APInt(8, i); |
6006 | APFloat test(APFloat::EnumToSemantics(S), bits_in); |
6007 | APInt bits_out = test.bitcastToAPInt(); |
6008 | EXPECT_EQ(bits_in, bits_out); |
6009 | } |
6010 | } |
6011 | } |
6012 | |
6013 | TEST(APFloatTest, F8ToBitsToF8) { |
6014 | for (APFloat::Semantics S : |
6015 | {APFloat::S_Float8E5M2, APFloat::S_Float8E4M3FN, |
6016 | APFloat::S_Float8E5M2FNUZ, APFloat::S_Float8E4M3FNUZ, |
6017 | APFloat::S_Float8E4M3B11FNUZ}) { |
6018 | SCOPED_TRACE("Semantics=" + std::to_string(S)); |
6019 | auto &Sem = APFloat::EnumToSemantics(S); |
6020 | for (bool negative : {false, true}) { |
6021 | SCOPED_TRACE("negative=" + std::to_string(negative)); |
6022 | APFloat test = APFloat::getZero(Sem, /*Negative=*/negative); |
6023 | for (int i = 0; i < 128; i++, test.next(/*nextDown=*/negative)) { |
6024 | SCOPED_TRACE("i=" + std::to_string(i)); |
6025 | APInt bits = test.bitcastToAPInt(); |
6026 | APFloat test2 = APFloat(Sem, bits); |
6027 | if (test.isNaN()) { |
6028 | EXPECT_TRUE(test2.isNaN()); |
6029 | } else { |
6030 | EXPECT_TRUE(test.bitwiseIsEqual(test2)); |
6031 | } |
6032 | } |
6033 | } |
6034 | } |
6035 | } |
6036 | |
6037 | TEST(APFloatTest, IEEEdoubleToDouble) { |
6038 | APFloat DPosZero(0.0); |
6039 | APFloat DPosZeroToDouble(DPosZero.convertToDouble()); |
6040 | EXPECT_TRUE(DPosZeroToDouble.isPosZero()); |
6041 | APFloat DNegZero(-0.0); |
6042 | APFloat DNegZeroToDouble(DNegZero.convertToDouble()); |
6043 | EXPECT_TRUE(DNegZeroToDouble.isNegZero()); |
6044 | |
6045 | APFloat DOne(1.0); |
6046 | EXPECT_EQ(1.0, DOne.convertToDouble()); |
6047 | APFloat DPosLargest = APFloat::getLargest(Sem: APFloat::IEEEdouble(), Negative: false); |
6048 | EXPECT_EQ(std::numeric_limits<double>::max(), DPosLargest.convertToDouble()); |
6049 | APFloat DNegLargest = APFloat::getLargest(Sem: APFloat::IEEEdouble(), Negative: true); |
6050 | EXPECT_EQ(-std::numeric_limits<double>::max(), DNegLargest.convertToDouble()); |
6051 | APFloat DPosSmallest = |
6052 | APFloat::getSmallestNormalized(Sem: APFloat::IEEEdouble(), Negative: false); |
6053 | EXPECT_EQ(std::numeric_limits<double>::min(), DPosSmallest.convertToDouble()); |
6054 | APFloat DNegSmallest = |
6055 | APFloat::getSmallestNormalized(Sem: APFloat::IEEEdouble(), Negative: true); |
6056 | EXPECT_EQ(-std::numeric_limits<double>::min(), |
6057 | DNegSmallest.convertToDouble()); |
6058 | |
6059 | APFloat DSmallestDenorm = APFloat::getSmallest(Sem: APFloat::IEEEdouble(), Negative: false); |
6060 | EXPECT_EQ(std::numeric_limits<double>::denorm_min(), |
6061 | DSmallestDenorm.convertToDouble()); |
6062 | APFloat DLargestDenorm(APFloat::IEEEdouble(), "0x0.FFFFFFFFFFFFFp-1022" ); |
6063 | EXPECT_EQ(/*0x0.FFFFFFFFFFFFFp-1022*/ 2.225073858507201e-308, |
6064 | DLargestDenorm.convertToDouble()); |
6065 | |
6066 | APFloat DPosInf = APFloat::getInf(Sem: APFloat::IEEEdouble()); |
6067 | EXPECT_EQ(std::numeric_limits<double>::infinity(), DPosInf.convertToDouble()); |
6068 | APFloat DNegInf = APFloat::getInf(Sem: APFloat::IEEEdouble(), Negative: true); |
6069 | EXPECT_EQ(-std::numeric_limits<double>::infinity(), |
6070 | DNegInf.convertToDouble()); |
6071 | APFloat DQNaN = APFloat::getQNaN(Sem: APFloat::IEEEdouble()); |
6072 | EXPECT_TRUE(std::isnan(DQNaN.convertToDouble())); |
6073 | } |
6074 | |
6075 | TEST(APFloatTest, IEEEsingleToDouble) { |
6076 | APFloat FPosZero(0.0F); |
6077 | APFloat FPosZeroToDouble(FPosZero.convertToDouble()); |
6078 | EXPECT_TRUE(FPosZeroToDouble.isPosZero()); |
6079 | APFloat FNegZero(-0.0F); |
6080 | APFloat FNegZeroToDouble(FNegZero.convertToDouble()); |
6081 | EXPECT_TRUE(FNegZeroToDouble.isNegZero()); |
6082 | |
6083 | APFloat FOne(1.0F); |
6084 | EXPECT_EQ(1.0, FOne.convertToDouble()); |
6085 | APFloat FPosLargest = APFloat::getLargest(Sem: APFloat::IEEEsingle(), Negative: false); |
6086 | EXPECT_EQ(std::numeric_limits<float>::max(), FPosLargest.convertToDouble()); |
6087 | APFloat FNegLargest = APFloat::getLargest(Sem: APFloat::IEEEsingle(), Negative: true); |
6088 | EXPECT_EQ(-std::numeric_limits<float>::max(), FNegLargest.convertToDouble()); |
6089 | APFloat FPosSmallest = |
6090 | APFloat::getSmallestNormalized(Sem: APFloat::IEEEsingle(), Negative: false); |
6091 | EXPECT_EQ(std::numeric_limits<float>::min(), FPosSmallest.convertToDouble()); |
6092 | APFloat FNegSmallest = |
6093 | APFloat::getSmallestNormalized(Sem: APFloat::IEEEsingle(), Negative: true); |
6094 | EXPECT_EQ(-std::numeric_limits<float>::min(), FNegSmallest.convertToDouble()); |
6095 | |
6096 | APFloat FSmallestDenorm = APFloat::getSmallest(Sem: APFloat::IEEEsingle(), Negative: false); |
6097 | EXPECT_EQ(std::numeric_limits<float>::denorm_min(), |
6098 | FSmallestDenorm.convertToDouble()); |
6099 | APFloat FLargestDenorm(APFloat::IEEEdouble(), "0x0.FFFFFEp-126" ); |
6100 | EXPECT_EQ(/*0x0.FFFFFEp-126*/ 1.1754942106924411e-38, |
6101 | FLargestDenorm.convertToDouble()); |
6102 | |
6103 | APFloat FPosInf = APFloat::getInf(Sem: APFloat::IEEEsingle()); |
6104 | EXPECT_EQ(std::numeric_limits<double>::infinity(), FPosInf.convertToDouble()); |
6105 | APFloat FNegInf = APFloat::getInf(Sem: APFloat::IEEEsingle(), Negative: true); |
6106 | EXPECT_EQ(-std::numeric_limits<double>::infinity(), |
6107 | FNegInf.convertToDouble()); |
6108 | APFloat FQNaN = APFloat::getQNaN(Sem: APFloat::IEEEsingle()); |
6109 | EXPECT_TRUE(std::isnan(FQNaN.convertToDouble())); |
6110 | } |
6111 | |
6112 | TEST(APFloatTest, IEEEhalfToDouble) { |
6113 | APFloat HPosZero = APFloat::getZero(Sem: APFloat::IEEEhalf()); |
6114 | APFloat HPosZeroToDouble(HPosZero.convertToDouble()); |
6115 | EXPECT_TRUE(HPosZeroToDouble.isPosZero()); |
6116 | APFloat HNegZero = APFloat::getZero(Sem: APFloat::IEEEhalf(), Negative: true); |
6117 | APFloat HNegZeroToDouble(HNegZero.convertToDouble()); |
6118 | EXPECT_TRUE(HNegZeroToDouble.isNegZero()); |
6119 | |
6120 | APFloat HOne(APFloat::IEEEhalf(), "1.0" ); |
6121 | EXPECT_EQ(1.0, HOne.convertToDouble()); |
6122 | APFloat HPosLargest = APFloat::getLargest(Sem: APFloat::IEEEhalf(), Negative: false); |
6123 | EXPECT_EQ(65504.0, HPosLargest.convertToDouble()); |
6124 | APFloat HNegLargest = APFloat::getLargest(Sem: APFloat::IEEEhalf(), Negative: true); |
6125 | EXPECT_EQ(-65504.0, HNegLargest.convertToDouble()); |
6126 | APFloat HPosSmallest = |
6127 | APFloat::getSmallestNormalized(Sem: APFloat::IEEEhalf(), Negative: false); |
6128 | EXPECT_EQ(/*0x1.p-14*/ 6.103515625e-05, HPosSmallest.convertToDouble()); |
6129 | APFloat HNegSmallest = |
6130 | APFloat::getSmallestNormalized(Sem: APFloat::IEEEhalf(), Negative: true); |
6131 | EXPECT_EQ(/*-0x1.p-14*/ -6.103515625e-05, HNegSmallest.convertToDouble()); |
6132 | |
6133 | APFloat HSmallestDenorm = APFloat::getSmallest(Sem: APFloat::IEEEhalf(), Negative: false); |
6134 | EXPECT_EQ(/*0x1.p-24*/ 5.960464477539063e-08, |
6135 | HSmallestDenorm.convertToDouble()); |
6136 | APFloat HLargestDenorm(APFloat::IEEEhalf(), "0x1.FFCp-14" ); |
6137 | EXPECT_EQ(/*0x1.FFCp-14*/ 0.00012201070785522461, |
6138 | HLargestDenorm.convertToDouble()); |
6139 | |
6140 | APFloat HPosInf = APFloat::getInf(Sem: APFloat::IEEEhalf()); |
6141 | EXPECT_EQ(std::numeric_limits<double>::infinity(), HPosInf.convertToDouble()); |
6142 | APFloat HNegInf = APFloat::getInf(Sem: APFloat::IEEEhalf(), Negative: true); |
6143 | EXPECT_EQ(-std::numeric_limits<double>::infinity(), |
6144 | HNegInf.convertToDouble()); |
6145 | APFloat HQNaN = APFloat::getQNaN(Sem: APFloat::IEEEhalf()); |
6146 | EXPECT_TRUE(std::isnan(HQNaN.convertToDouble())); |
6147 | |
6148 | APFloat BPosZero = APFloat::getZero(Sem: APFloat::IEEEhalf()); |
6149 | APFloat BPosZeroToDouble(BPosZero.convertToDouble()); |
6150 | EXPECT_TRUE(BPosZeroToDouble.isPosZero()); |
6151 | APFloat BNegZero = APFloat::getZero(Sem: APFloat::IEEEhalf(), Negative: true); |
6152 | APFloat BNegZeroToDouble(BNegZero.convertToDouble()); |
6153 | EXPECT_TRUE(BNegZeroToDouble.isNegZero()); |
6154 | } |
6155 | |
6156 | TEST(APFloatTest, BFloatToDouble) { |
6157 | APFloat BOne(APFloat::BFloat(), "1.0" ); |
6158 | EXPECT_EQ(1.0, BOne.convertToDouble()); |
6159 | APFloat BPosLargest = APFloat::getLargest(Sem: APFloat::BFloat(), Negative: false); |
6160 | EXPECT_EQ(/*0x1.FEp127*/ 3.3895313892515355e+38, |
6161 | BPosLargest.convertToDouble()); |
6162 | APFloat BNegLargest = APFloat::getLargest(Sem: APFloat::BFloat(), Negative: true); |
6163 | EXPECT_EQ(/*-0x1.FEp127*/ -3.3895313892515355e+38, |
6164 | BNegLargest.convertToDouble()); |
6165 | APFloat BPosSmallest = |
6166 | APFloat::getSmallestNormalized(Sem: APFloat::BFloat(), Negative: false); |
6167 | EXPECT_EQ(/*0x1.p-126*/ 1.1754943508222875e-38, |
6168 | BPosSmallest.convertToDouble()); |
6169 | APFloat BNegSmallest = |
6170 | APFloat::getSmallestNormalized(Sem: APFloat::BFloat(), Negative: true); |
6171 | EXPECT_EQ(/*-0x1.p-126*/ -1.1754943508222875e-38, |
6172 | BNegSmallest.convertToDouble()); |
6173 | |
6174 | APFloat BSmallestDenorm = APFloat::getSmallest(Sem: APFloat::BFloat(), Negative: false); |
6175 | EXPECT_EQ(/*0x1.p-133*/ 9.183549615799121e-41, |
6176 | BSmallestDenorm.convertToDouble()); |
6177 | APFloat BLargestDenorm(APFloat::BFloat(), "0x1.FCp-127" ); |
6178 | EXPECT_EQ(/*0x1.FCp-127*/ 1.1663108012064884e-38, |
6179 | BLargestDenorm.convertToDouble()); |
6180 | |
6181 | APFloat BPosInf = APFloat::getInf(Sem: APFloat::BFloat()); |
6182 | EXPECT_EQ(std::numeric_limits<double>::infinity(), BPosInf.convertToDouble()); |
6183 | APFloat BNegInf = APFloat::getInf(Sem: APFloat::BFloat(), Negative: true); |
6184 | EXPECT_EQ(-std::numeric_limits<double>::infinity(), |
6185 | BNegInf.convertToDouble()); |
6186 | APFloat BQNaN = APFloat::getQNaN(Sem: APFloat::BFloat()); |
6187 | EXPECT_TRUE(std::isnan(BQNaN.convertToDouble())); |
6188 | } |
6189 | |
6190 | TEST(APFloatTest, Float8E5M2ToDouble) { |
6191 | APFloat One(APFloat::Float8E5M2(), "1.0" ); |
6192 | EXPECT_EQ(1.0, One.convertToDouble()); |
6193 | APFloat Two(APFloat::Float8E5M2(), "2.0" ); |
6194 | EXPECT_EQ(2.0, Two.convertToDouble()); |
6195 | APFloat PosLargest = APFloat::getLargest(Sem: APFloat::Float8E5M2(), Negative: false); |
6196 | EXPECT_EQ(5.734400e+04, PosLargest.convertToDouble()); |
6197 | APFloat NegLargest = APFloat::getLargest(Sem: APFloat::Float8E5M2(), Negative: true); |
6198 | EXPECT_EQ(-5.734400e+04, NegLargest.convertToDouble()); |
6199 | APFloat PosSmallest = |
6200 | APFloat::getSmallestNormalized(Sem: APFloat::Float8E5M2(), Negative: false); |
6201 | EXPECT_EQ(0x1.p-14, PosSmallest.convertToDouble()); |
6202 | APFloat NegSmallest = |
6203 | APFloat::getSmallestNormalized(Sem: APFloat::Float8E5M2(), Negative: true); |
6204 | EXPECT_EQ(-0x1.p-14, NegSmallest.convertToDouble()); |
6205 | |
6206 | APFloat SmallestDenorm = APFloat::getSmallest(Sem: APFloat::Float8E5M2(), Negative: false); |
6207 | EXPECT_TRUE(SmallestDenorm.isDenormal()); |
6208 | EXPECT_EQ(0x1p-16, SmallestDenorm.convertToDouble()); |
6209 | |
6210 | APFloat PosInf = APFloat::getInf(Sem: APFloat::Float8E5M2()); |
6211 | EXPECT_EQ(std::numeric_limits<double>::infinity(), PosInf.convertToDouble()); |
6212 | APFloat NegInf = APFloat::getInf(Sem: APFloat::Float8E5M2(), Negative: true); |
6213 | EXPECT_EQ(-std::numeric_limits<double>::infinity(), NegInf.convertToDouble()); |
6214 | APFloat QNaN = APFloat::getQNaN(Sem: APFloat::Float8E5M2()); |
6215 | EXPECT_TRUE(std::isnan(QNaN.convertToDouble())); |
6216 | } |
6217 | |
6218 | TEST(APFloatTest, Float8E4M3FNToDouble) { |
6219 | APFloat One(APFloat::Float8E4M3FN(), "1.0" ); |
6220 | EXPECT_EQ(1.0, One.convertToDouble()); |
6221 | APFloat Two(APFloat::Float8E4M3FN(), "2.0" ); |
6222 | EXPECT_EQ(2.0, Two.convertToDouble()); |
6223 | APFloat PosLargest = APFloat::getLargest(Sem: APFloat::Float8E4M3FN(), Negative: false); |
6224 | EXPECT_EQ(448., PosLargest.convertToDouble()); |
6225 | APFloat NegLargest = APFloat::getLargest(Sem: APFloat::Float8E4M3FN(), Negative: true); |
6226 | EXPECT_EQ(-448., NegLargest.convertToDouble()); |
6227 | APFloat PosSmallest = |
6228 | APFloat::getSmallestNormalized(Sem: APFloat::Float8E4M3FN(), Negative: false); |
6229 | EXPECT_EQ(0x1.p-6, PosSmallest.convertToDouble()); |
6230 | APFloat NegSmallest = |
6231 | APFloat::getSmallestNormalized(Sem: APFloat::Float8E4M3FN(), Negative: true); |
6232 | EXPECT_EQ(-0x1.p-6, NegSmallest.convertToDouble()); |
6233 | |
6234 | APFloat SmallestDenorm = APFloat::getSmallest(Sem: APFloat::Float8E4M3FN(), Negative: false); |
6235 | EXPECT_TRUE(SmallestDenorm.isDenormal()); |
6236 | EXPECT_EQ(0x1p-9, SmallestDenorm.convertToDouble()); |
6237 | |
6238 | APFloat QNaN = APFloat::getQNaN(Sem: APFloat::Float8E4M3FN()); |
6239 | EXPECT_TRUE(std::isnan(QNaN.convertToDouble())); |
6240 | } |
6241 | |
6242 | TEST(APFloatTest, Float8E5M2FNUZToDouble) { |
6243 | APFloat One(APFloat::Float8E5M2FNUZ(), "1.0" ); |
6244 | EXPECT_EQ(1.0, One.convertToDouble()); |
6245 | APFloat Two(APFloat::Float8E5M2FNUZ(), "2.0" ); |
6246 | EXPECT_EQ(2.0, Two.convertToDouble()); |
6247 | APFloat PosLargest = APFloat::getLargest(Sem: APFloat::Float8E5M2FNUZ(), Negative: false); |
6248 | EXPECT_EQ(57344., PosLargest.convertToDouble()); |
6249 | APFloat NegLargest = APFloat::getLargest(Sem: APFloat::Float8E5M2FNUZ(), Negative: true); |
6250 | EXPECT_EQ(-57344., NegLargest.convertToDouble()); |
6251 | APFloat PosSmallest = |
6252 | APFloat::getSmallestNormalized(Sem: APFloat::Float8E5M2FNUZ(), Negative: false); |
6253 | EXPECT_EQ(0x1.p-15, PosSmallest.convertToDouble()); |
6254 | APFloat NegSmallest = |
6255 | APFloat::getSmallestNormalized(Sem: APFloat::Float8E5M2FNUZ(), Negative: true); |
6256 | EXPECT_EQ(-0x1.p-15, NegSmallest.convertToDouble()); |
6257 | |
6258 | APFloat SmallestDenorm = |
6259 | APFloat::getSmallest(Sem: APFloat::Float8E5M2FNUZ(), Negative: false); |
6260 | EXPECT_TRUE(SmallestDenorm.isDenormal()); |
6261 | EXPECT_EQ(0x1p-17, SmallestDenorm.convertToDouble()); |
6262 | |
6263 | APFloat QNaN = APFloat::getQNaN(Sem: APFloat::Float8E5M2FNUZ()); |
6264 | EXPECT_TRUE(std::isnan(QNaN.convertToDouble())); |
6265 | } |
6266 | |
6267 | TEST(APFloatTest, Float8E4M3FNUZToDouble) { |
6268 | APFloat One(APFloat::Float8E4M3FNUZ(), "1.0" ); |
6269 | EXPECT_EQ(1.0, One.convertToDouble()); |
6270 | APFloat Two(APFloat::Float8E4M3FNUZ(), "2.0" ); |
6271 | EXPECT_EQ(2.0, Two.convertToDouble()); |
6272 | APFloat PosLargest = APFloat::getLargest(Sem: APFloat::Float8E4M3FNUZ(), Negative: false); |
6273 | EXPECT_EQ(240., PosLargest.convertToDouble()); |
6274 | APFloat NegLargest = APFloat::getLargest(Sem: APFloat::Float8E4M3FNUZ(), Negative: true); |
6275 | EXPECT_EQ(-240., NegLargest.convertToDouble()); |
6276 | APFloat PosSmallest = |
6277 | APFloat::getSmallestNormalized(Sem: APFloat::Float8E4M3FNUZ(), Negative: false); |
6278 | EXPECT_EQ(0x1.p-7, PosSmallest.convertToDouble()); |
6279 | APFloat NegSmallest = |
6280 | APFloat::getSmallestNormalized(Sem: APFloat::Float8E4M3FNUZ(), Negative: true); |
6281 | EXPECT_EQ(-0x1.p-7, NegSmallest.convertToDouble()); |
6282 | |
6283 | APFloat SmallestDenorm = |
6284 | APFloat::getSmallest(Sem: APFloat::Float8E4M3FNUZ(), Negative: false); |
6285 | EXPECT_TRUE(SmallestDenorm.isDenormal()); |
6286 | EXPECT_EQ(0x1p-10, SmallestDenorm.convertToDouble()); |
6287 | |
6288 | APFloat QNaN = APFloat::getQNaN(Sem: APFloat::Float8E4M3FNUZ()); |
6289 | EXPECT_TRUE(std::isnan(QNaN.convertToDouble())); |
6290 | } |
6291 | |
6292 | TEST(APFloatTest, FloatTF32ToDouble) { |
6293 | APFloat One(APFloat::FloatTF32(), "1.0" ); |
6294 | EXPECT_EQ(1.0, One.convertToDouble()); |
6295 | APFloat PosLargest = APFloat::getLargest(Sem: APFloat::FloatTF32(), Negative: false); |
6296 | EXPECT_EQ(3.401162134214653489792616e+38, PosLargest.convertToDouble()); |
6297 | APFloat NegLargest = APFloat::getLargest(Sem: APFloat::FloatTF32(), Negative: true); |
6298 | EXPECT_EQ(-3.401162134214653489792616e+38, NegLargest.convertToDouble()); |
6299 | APFloat PosSmallest = |
6300 | APFloat::getSmallestNormalized(Sem: APFloat::FloatTF32(), Negative: false); |
6301 | EXPECT_EQ(1.1754943508222875079687e-38, PosSmallest.convertToDouble()); |
6302 | APFloat NegSmallest = |
6303 | APFloat::getSmallestNormalized(Sem: APFloat::FloatTF32(), Negative: true); |
6304 | EXPECT_EQ(-1.1754943508222875079687e-38, NegSmallest.convertToDouble()); |
6305 | |
6306 | APFloat SmallestDenorm = APFloat::getSmallest(Sem: APFloat::FloatTF32(), Negative: false); |
6307 | EXPECT_EQ(1.1479437019748901445007e-41, SmallestDenorm.convertToDouble()); |
6308 | APFloat LargestDenorm(APFloat::FloatTF32(), "0x1.FF8p-127" ); |
6309 | EXPECT_EQ(/*0x1.FF8p-127*/ 1.1743464071203126178242e-38, |
6310 | LargestDenorm.convertToDouble()); |
6311 | |
6312 | APFloat PosInf = APFloat::getInf(Sem: APFloat::FloatTF32()); |
6313 | EXPECT_EQ(std::numeric_limits<double>::infinity(), PosInf.convertToDouble()); |
6314 | APFloat NegInf = APFloat::getInf(Sem: APFloat::FloatTF32(), Negative: true); |
6315 | EXPECT_EQ(-std::numeric_limits<double>::infinity(), NegInf.convertToDouble()); |
6316 | APFloat QNaN = APFloat::getQNaN(Sem: APFloat::FloatTF32()); |
6317 | EXPECT_TRUE(std::isnan(QNaN.convertToDouble())); |
6318 | } |
6319 | |
6320 | TEST(APFloatTest, Float8E5M2FNUZToFloat) { |
6321 | APFloat PosZero = APFloat::getZero(Sem: APFloat::Float8E5M2FNUZ()); |
6322 | APFloat PosZeroToFloat(PosZero.convertToFloat()); |
6323 | EXPECT_TRUE(PosZeroToFloat.isPosZero()); |
6324 | // Negative zero is not supported |
6325 | APFloat NegZero = APFloat::getZero(Sem: APFloat::Float8E5M2FNUZ(), Negative: true); |
6326 | APFloat NegZeroToFloat(NegZero.convertToFloat()); |
6327 | EXPECT_TRUE(NegZeroToFloat.isPosZero()); |
6328 | APFloat One(APFloat::Float8E5M2FNUZ(), "1.0" ); |
6329 | EXPECT_EQ(1.0F, One.convertToFloat()); |
6330 | APFloat Two(APFloat::Float8E5M2FNUZ(), "2.0" ); |
6331 | EXPECT_EQ(2.0F, Two.convertToFloat()); |
6332 | APFloat PosLargest = APFloat::getLargest(Sem: APFloat::Float8E5M2FNUZ(), Negative: false); |
6333 | EXPECT_EQ(57344.F, PosLargest.convertToFloat()); |
6334 | APFloat NegLargest = APFloat::getLargest(Sem: APFloat::Float8E5M2FNUZ(), Negative: true); |
6335 | EXPECT_EQ(-57344.F, NegLargest.convertToFloat()); |
6336 | APFloat PosSmallest = |
6337 | APFloat::getSmallestNormalized(Sem: APFloat::Float8E5M2FNUZ(), Negative: false); |
6338 | EXPECT_EQ(0x1.p-15F, PosSmallest.convertToFloat()); |
6339 | APFloat NegSmallest = |
6340 | APFloat::getSmallestNormalized(Sem: APFloat::Float8E5M2FNUZ(), Negative: true); |
6341 | EXPECT_EQ(-0x1.p-15F, NegSmallest.convertToFloat()); |
6342 | |
6343 | APFloat SmallestDenorm = |
6344 | APFloat::getSmallest(Sem: APFloat::Float8E5M2FNUZ(), Negative: false); |
6345 | EXPECT_TRUE(SmallestDenorm.isDenormal()); |
6346 | EXPECT_EQ(0x1p-17F, SmallestDenorm.convertToFloat()); |
6347 | |
6348 | APFloat QNaN = APFloat::getQNaN(Sem: APFloat::Float8E5M2FNUZ()); |
6349 | EXPECT_TRUE(std::isnan(QNaN.convertToFloat())); |
6350 | } |
6351 | |
6352 | TEST(APFloatTest, Float8E4M3FNUZToFloat) { |
6353 | APFloat PosZero = APFloat::getZero(Sem: APFloat::Float8E4M3FNUZ()); |
6354 | APFloat PosZeroToFloat(PosZero.convertToFloat()); |
6355 | EXPECT_TRUE(PosZeroToFloat.isPosZero()); |
6356 | // Negative zero is not supported |
6357 | APFloat NegZero = APFloat::getZero(Sem: APFloat::Float8E4M3FNUZ(), Negative: true); |
6358 | APFloat NegZeroToFloat(NegZero.convertToFloat()); |
6359 | EXPECT_TRUE(NegZeroToFloat.isPosZero()); |
6360 | APFloat One(APFloat::Float8E4M3FNUZ(), "1.0" ); |
6361 | EXPECT_EQ(1.0F, One.convertToFloat()); |
6362 | APFloat Two(APFloat::Float8E4M3FNUZ(), "2.0" ); |
6363 | EXPECT_EQ(2.0F, Two.convertToFloat()); |
6364 | APFloat PosLargest = APFloat::getLargest(Sem: APFloat::Float8E4M3FNUZ(), Negative: false); |
6365 | EXPECT_EQ(240.F, PosLargest.convertToFloat()); |
6366 | APFloat NegLargest = APFloat::getLargest(Sem: APFloat::Float8E4M3FNUZ(), Negative: true); |
6367 | EXPECT_EQ(-240.F, NegLargest.convertToFloat()); |
6368 | APFloat PosSmallest = |
6369 | APFloat::getSmallestNormalized(Sem: APFloat::Float8E4M3FNUZ(), Negative: false); |
6370 | EXPECT_EQ(0x1.p-7F, PosSmallest.convertToFloat()); |
6371 | APFloat NegSmallest = |
6372 | APFloat::getSmallestNormalized(Sem: APFloat::Float8E4M3FNUZ(), Negative: true); |
6373 | EXPECT_EQ(-0x1.p-7F, NegSmallest.convertToFloat()); |
6374 | |
6375 | APFloat SmallestDenorm = |
6376 | APFloat::getSmallest(Sem: APFloat::Float8E4M3FNUZ(), Negative: false); |
6377 | EXPECT_TRUE(SmallestDenorm.isDenormal()); |
6378 | EXPECT_EQ(0x1p-10F, SmallestDenorm.convertToFloat()); |
6379 | |
6380 | APFloat QNaN = APFloat::getQNaN(Sem: APFloat::Float8E4M3FNUZ()); |
6381 | EXPECT_TRUE(std::isnan(QNaN.convertToFloat())); |
6382 | } |
6383 | |
6384 | TEST(APFloatTest, IEEEsingleToFloat) { |
6385 | APFloat FPosZero(0.0F); |
6386 | APFloat FPosZeroToFloat(FPosZero.convertToFloat()); |
6387 | EXPECT_TRUE(FPosZeroToFloat.isPosZero()); |
6388 | APFloat FNegZero(-0.0F); |
6389 | APFloat FNegZeroToFloat(FNegZero.convertToFloat()); |
6390 | EXPECT_TRUE(FNegZeroToFloat.isNegZero()); |
6391 | |
6392 | APFloat FOne(1.0F); |
6393 | EXPECT_EQ(1.0F, FOne.convertToFloat()); |
6394 | APFloat FPosLargest = APFloat::getLargest(Sem: APFloat::IEEEsingle(), Negative: false); |
6395 | EXPECT_EQ(std::numeric_limits<float>::max(), FPosLargest.convertToFloat()); |
6396 | APFloat FNegLargest = APFloat::getLargest(Sem: APFloat::IEEEsingle(), Negative: true); |
6397 | EXPECT_EQ(-std::numeric_limits<float>::max(), FNegLargest.convertToFloat()); |
6398 | APFloat FPosSmallest = |
6399 | APFloat::getSmallestNormalized(Sem: APFloat::IEEEsingle(), Negative: false); |
6400 | EXPECT_EQ(std::numeric_limits<float>::min(), FPosSmallest.convertToFloat()); |
6401 | APFloat FNegSmallest = |
6402 | APFloat::getSmallestNormalized(Sem: APFloat::IEEEsingle(), Negative: true); |
6403 | EXPECT_EQ(-std::numeric_limits<float>::min(), FNegSmallest.convertToFloat()); |
6404 | |
6405 | APFloat FSmallestDenorm = APFloat::getSmallest(Sem: APFloat::IEEEsingle(), Negative: false); |
6406 | EXPECT_EQ(std::numeric_limits<float>::denorm_min(), |
6407 | FSmallestDenorm.convertToFloat()); |
6408 | APFloat FLargestDenorm(APFloat::IEEEsingle(), "0x1.FFFFFEp-126" ); |
6409 | EXPECT_EQ(/*0x1.FFFFFEp-126*/ 2.3509885615147286e-38F, |
6410 | FLargestDenorm.convertToFloat()); |
6411 | |
6412 | APFloat FPosInf = APFloat::getInf(Sem: APFloat::IEEEsingle()); |
6413 | EXPECT_EQ(std::numeric_limits<float>::infinity(), FPosInf.convertToFloat()); |
6414 | APFloat FNegInf = APFloat::getInf(Sem: APFloat::IEEEsingle(), Negative: true); |
6415 | EXPECT_EQ(-std::numeric_limits<float>::infinity(), FNegInf.convertToFloat()); |
6416 | APFloat FQNaN = APFloat::getQNaN(Sem: APFloat::IEEEsingle()); |
6417 | EXPECT_TRUE(std::isnan(FQNaN.convertToFloat())); |
6418 | } |
6419 | |
6420 | TEST(APFloatTest, IEEEhalfToFloat) { |
6421 | APFloat HPosZero = APFloat::getZero(Sem: APFloat::IEEEhalf()); |
6422 | APFloat HPosZeroToFloat(HPosZero.convertToFloat()); |
6423 | EXPECT_TRUE(HPosZeroToFloat.isPosZero()); |
6424 | APFloat HNegZero = APFloat::getZero(Sem: APFloat::IEEEhalf(), Negative: true); |
6425 | APFloat HNegZeroToFloat(HNegZero.convertToFloat()); |
6426 | EXPECT_TRUE(HNegZeroToFloat.isNegZero()); |
6427 | |
6428 | APFloat HOne(APFloat::IEEEhalf(), "1.0" ); |
6429 | EXPECT_EQ(1.0F, HOne.convertToFloat()); |
6430 | APFloat HPosLargest = APFloat::getLargest(Sem: APFloat::IEEEhalf(), Negative: false); |
6431 | EXPECT_EQ(/*0x1.FFCp15*/ 65504.0F, HPosLargest.convertToFloat()); |
6432 | APFloat HNegLargest = APFloat::getLargest(Sem: APFloat::IEEEhalf(), Negative: true); |
6433 | EXPECT_EQ(/*-0x1.FFCp15*/ -65504.0F, HNegLargest.convertToFloat()); |
6434 | APFloat HPosSmallest = |
6435 | APFloat::getSmallestNormalized(Sem: APFloat::IEEEhalf(), Negative: false); |
6436 | EXPECT_EQ(/*0x1.p-14*/ 6.103515625e-05F, HPosSmallest.convertToFloat()); |
6437 | APFloat HNegSmallest = |
6438 | APFloat::getSmallestNormalized(Sem: APFloat::IEEEhalf(), Negative: true); |
6439 | EXPECT_EQ(/*-0x1.p-14*/ -6.103515625e-05F, HNegSmallest.convertToFloat()); |
6440 | |
6441 | APFloat HSmallestDenorm = APFloat::getSmallest(Sem: APFloat::IEEEhalf(), Negative: false); |
6442 | EXPECT_EQ(/*0x1.p-24*/ 5.960464477539063e-08F, |
6443 | HSmallestDenorm.convertToFloat()); |
6444 | APFloat HLargestDenorm(APFloat::IEEEhalf(), "0x1.FFCp-14" ); |
6445 | EXPECT_EQ(/*0x1.FFCp-14*/ 0.00012201070785522461F, |
6446 | HLargestDenorm.convertToFloat()); |
6447 | |
6448 | APFloat HPosInf = APFloat::getInf(Sem: APFloat::IEEEhalf()); |
6449 | EXPECT_EQ(std::numeric_limits<float>::infinity(), HPosInf.convertToFloat()); |
6450 | APFloat HNegInf = APFloat::getInf(Sem: APFloat::IEEEhalf(), Negative: true); |
6451 | EXPECT_EQ(-std::numeric_limits<float>::infinity(), HNegInf.convertToFloat()); |
6452 | APFloat HQNaN = APFloat::getQNaN(Sem: APFloat::IEEEhalf()); |
6453 | EXPECT_TRUE(std::isnan(HQNaN.convertToFloat())); |
6454 | } |
6455 | |
6456 | TEST(APFloatTest, BFloatToFloat) { |
6457 | APFloat BPosZero = APFloat::getZero(Sem: APFloat::BFloat()); |
6458 | APFloat BPosZeroToDouble(BPosZero.convertToFloat()); |
6459 | EXPECT_TRUE(BPosZeroToDouble.isPosZero()); |
6460 | APFloat BNegZero = APFloat::getZero(Sem: APFloat::BFloat(), Negative: true); |
6461 | APFloat BNegZeroToDouble(BNegZero.convertToFloat()); |
6462 | EXPECT_TRUE(BNegZeroToDouble.isNegZero()); |
6463 | |
6464 | APFloat BOne(APFloat::BFloat(), "1.0" ); |
6465 | EXPECT_EQ(1.0F, BOne.convertToFloat()); |
6466 | APFloat BPosLargest = APFloat::getLargest(Sem: APFloat::BFloat(), Negative: false); |
6467 | EXPECT_EQ(/*0x1.FEp127*/ 3.3895313892515355e+38F, |
6468 | BPosLargest.convertToFloat()); |
6469 | APFloat BNegLargest = APFloat::getLargest(Sem: APFloat::BFloat(), Negative: true); |
6470 | EXPECT_EQ(/*-0x1.FEp127*/ -3.3895313892515355e+38F, |
6471 | BNegLargest.convertToFloat()); |
6472 | APFloat BPosSmallest = |
6473 | APFloat::getSmallestNormalized(Sem: APFloat::BFloat(), Negative: false); |
6474 | EXPECT_EQ(/*0x1.p-126*/ 1.1754943508222875e-38F, |
6475 | BPosSmallest.convertToFloat()); |
6476 | APFloat BNegSmallest = |
6477 | APFloat::getSmallestNormalized(Sem: APFloat::BFloat(), Negative: true); |
6478 | EXPECT_EQ(/*-0x1.p-126*/ -1.1754943508222875e-38F, |
6479 | BNegSmallest.convertToFloat()); |
6480 | |
6481 | APFloat BSmallestDenorm = APFloat::getSmallest(Sem: APFloat::BFloat(), Negative: false); |
6482 | EXPECT_EQ(/*0x1.p-133*/ 9.183549615799121e-41F, |
6483 | BSmallestDenorm.convertToFloat()); |
6484 | APFloat BLargestDenorm(APFloat::BFloat(), "0x1.FCp-127" ); |
6485 | EXPECT_EQ(/*0x1.FCp-127*/ 1.1663108012064884e-38F, |
6486 | BLargestDenorm.convertToFloat()); |
6487 | |
6488 | APFloat BPosInf = APFloat::getInf(Sem: APFloat::BFloat()); |
6489 | EXPECT_EQ(std::numeric_limits<float>::infinity(), BPosInf.convertToFloat()); |
6490 | APFloat BNegInf = APFloat::getInf(Sem: APFloat::BFloat(), Negative: true); |
6491 | EXPECT_EQ(-std::numeric_limits<float>::infinity(), BNegInf.convertToFloat()); |
6492 | APFloat BQNaN = APFloat::getQNaN(Sem: APFloat::BFloat()); |
6493 | EXPECT_TRUE(std::isnan(BQNaN.convertToFloat())); |
6494 | } |
6495 | |
6496 | TEST(APFloatTest, Float8E5M2ToFloat) { |
6497 | APFloat PosZero = APFloat::getZero(Sem: APFloat::Float8E5M2()); |
6498 | APFloat PosZeroToFloat(PosZero.convertToFloat()); |
6499 | EXPECT_TRUE(PosZeroToFloat.isPosZero()); |
6500 | APFloat NegZero = APFloat::getZero(Sem: APFloat::Float8E5M2(), Negative: true); |
6501 | APFloat NegZeroToFloat(NegZero.convertToFloat()); |
6502 | EXPECT_TRUE(NegZeroToFloat.isNegZero()); |
6503 | |
6504 | APFloat One(APFloat::Float8E5M2(), "1.0" ); |
6505 | EXPECT_EQ(1.0F, One.convertToFloat()); |
6506 | APFloat Two(APFloat::Float8E5M2(), "2.0" ); |
6507 | EXPECT_EQ(2.0F, Two.convertToFloat()); |
6508 | |
6509 | APFloat PosLargest = APFloat::getLargest(Sem: APFloat::Float8E5M2(), Negative: false); |
6510 | EXPECT_EQ(5.734400e+04, PosLargest.convertToFloat()); |
6511 | APFloat NegLargest = APFloat::getLargest(Sem: APFloat::Float8E5M2(), Negative: true); |
6512 | EXPECT_EQ(-5.734400e+04, NegLargest.convertToFloat()); |
6513 | APFloat PosSmallest = |
6514 | APFloat::getSmallestNormalized(Sem: APFloat::Float8E5M2(), Negative: false); |
6515 | EXPECT_EQ(0x1.p-14, PosSmallest.convertToFloat()); |
6516 | APFloat NegSmallest = |
6517 | APFloat::getSmallestNormalized(Sem: APFloat::Float8E5M2(), Negative: true); |
6518 | EXPECT_EQ(-0x1.p-14, NegSmallest.convertToFloat()); |
6519 | |
6520 | APFloat SmallestDenorm = APFloat::getSmallest(Sem: APFloat::Float8E5M2(), Negative: false); |
6521 | EXPECT_TRUE(SmallestDenorm.isDenormal()); |
6522 | EXPECT_EQ(0x1.p-16, SmallestDenorm.convertToFloat()); |
6523 | |
6524 | APFloat PosInf = APFloat::getInf(Sem: APFloat::Float8E5M2()); |
6525 | EXPECT_EQ(std::numeric_limits<float>::infinity(), PosInf.convertToFloat()); |
6526 | APFloat NegInf = APFloat::getInf(Sem: APFloat::Float8E5M2(), Negative: true); |
6527 | EXPECT_EQ(-std::numeric_limits<float>::infinity(), NegInf.convertToFloat()); |
6528 | APFloat QNaN = APFloat::getQNaN(Sem: APFloat::Float8E5M2()); |
6529 | EXPECT_TRUE(std::isnan(QNaN.convertToFloat())); |
6530 | } |
6531 | |
6532 | TEST(APFloatTest, Float8E4M3FNToFloat) { |
6533 | APFloat PosZero = APFloat::getZero(Sem: APFloat::Float8E4M3FN()); |
6534 | APFloat PosZeroToFloat(PosZero.convertToFloat()); |
6535 | EXPECT_TRUE(PosZeroToFloat.isPosZero()); |
6536 | APFloat NegZero = APFloat::getZero(Sem: APFloat::Float8E4M3FN(), Negative: true); |
6537 | APFloat NegZeroToFloat(NegZero.convertToFloat()); |
6538 | EXPECT_TRUE(NegZeroToFloat.isNegZero()); |
6539 | |
6540 | APFloat One(APFloat::Float8E4M3FN(), "1.0" ); |
6541 | EXPECT_EQ(1.0F, One.convertToFloat()); |
6542 | APFloat Two(APFloat::Float8E4M3FN(), "2.0" ); |
6543 | EXPECT_EQ(2.0F, Two.convertToFloat()); |
6544 | |
6545 | APFloat PosLargest = APFloat::getLargest(Sem: APFloat::Float8E4M3FN(), Negative: false); |
6546 | EXPECT_EQ(448., PosLargest.convertToFloat()); |
6547 | APFloat NegLargest = APFloat::getLargest(Sem: APFloat::Float8E4M3FN(), Negative: true); |
6548 | EXPECT_EQ(-448, NegLargest.convertToFloat()); |
6549 | APFloat PosSmallest = |
6550 | APFloat::getSmallestNormalized(Sem: APFloat::Float8E4M3FN(), Negative: false); |
6551 | EXPECT_EQ(0x1.p-6, PosSmallest.convertToFloat()); |
6552 | APFloat NegSmallest = |
6553 | APFloat::getSmallestNormalized(Sem: APFloat::Float8E4M3FN(), Negative: true); |
6554 | EXPECT_EQ(-0x1.p-6, NegSmallest.convertToFloat()); |
6555 | |
6556 | APFloat SmallestDenorm = APFloat::getSmallest(Sem: APFloat::Float8E4M3FN(), Negative: false); |
6557 | EXPECT_TRUE(SmallestDenorm.isDenormal()); |
6558 | EXPECT_EQ(0x1.p-9, SmallestDenorm.convertToFloat()); |
6559 | |
6560 | APFloat QNaN = APFloat::getQNaN(Sem: APFloat::Float8E4M3FN()); |
6561 | EXPECT_TRUE(std::isnan(QNaN.convertToFloat())); |
6562 | } |
6563 | |
6564 | TEST(APFloatTest, FloatTF32ToFloat) { |
6565 | APFloat PosZero = APFloat::getZero(Sem: APFloat::FloatTF32()); |
6566 | APFloat PosZeroToFloat(PosZero.convertToFloat()); |
6567 | EXPECT_TRUE(PosZeroToFloat.isPosZero()); |
6568 | APFloat NegZero = APFloat::getZero(Sem: APFloat::FloatTF32(), Negative: true); |
6569 | APFloat NegZeroToFloat(NegZero.convertToFloat()); |
6570 | EXPECT_TRUE(NegZeroToFloat.isNegZero()); |
6571 | |
6572 | APFloat One(APFloat::FloatTF32(), "1.0" ); |
6573 | EXPECT_EQ(1.0F, One.convertToFloat()); |
6574 | APFloat Two(APFloat::FloatTF32(), "2.0" ); |
6575 | EXPECT_EQ(2.0F, Two.convertToFloat()); |
6576 | |
6577 | APFloat PosLargest = APFloat::getLargest(Sem: APFloat::FloatTF32(), Negative: false); |
6578 | EXPECT_EQ(3.40116213421e+38F, PosLargest.convertToFloat()); |
6579 | |
6580 | APFloat NegLargest = APFloat::getLargest(Sem: APFloat::FloatTF32(), Negative: true); |
6581 | EXPECT_EQ(-3.40116213421e+38F, NegLargest.convertToFloat()); |
6582 | |
6583 | APFloat PosSmallest = |
6584 | APFloat::getSmallestNormalized(Sem: APFloat::FloatTF32(), Negative: false); |
6585 | EXPECT_EQ(/*0x1.p-126*/ 1.1754943508222875e-38F, |
6586 | PosSmallest.convertToFloat()); |
6587 | APFloat NegSmallest = |
6588 | APFloat::getSmallestNormalized(Sem: APFloat::FloatTF32(), Negative: true); |
6589 | EXPECT_EQ(/*-0x1.p-126*/ -1.1754943508222875e-38F, |
6590 | NegSmallest.convertToFloat()); |
6591 | |
6592 | APFloat SmallestDenorm = APFloat::getSmallest(Sem: APFloat::FloatTF32(), Negative: false); |
6593 | EXPECT_TRUE(SmallestDenorm.isDenormal()); |
6594 | EXPECT_EQ(0x0.004p-126, SmallestDenorm.convertToFloat()); |
6595 | |
6596 | APFloat QNaN = APFloat::getQNaN(Sem: APFloat::FloatTF32()); |
6597 | EXPECT_TRUE(std::isnan(QNaN.convertToFloat())); |
6598 | } |
6599 | |
6600 | TEST(APFloatTest, getExactLog2) { |
6601 | for (unsigned I = 0; I != APFloat::S_MaxSemantics + 1; ++I) { |
6602 | auto = static_cast<APFloat::Semantics>(I); |
6603 | const fltSemantics &Semantics = APFloat::EnumToSemantics(S: SemEnum); |
6604 | |
6605 | APFloat One(Semantics, "1.0" ); |
6606 | |
6607 | if (I == APFloat::S_PPCDoubleDouble) { |
6608 | // Not implemented |
6609 | EXPECT_EQ(INT_MIN, One.getExactLog2()); |
6610 | EXPECT_EQ(INT_MIN, One.getExactLog2Abs()); |
6611 | continue; |
6612 | } |
6613 | |
6614 | int MinExp = APFloat::semanticsMinExponent(Semantics); |
6615 | int MaxExp = APFloat::semanticsMaxExponent(Semantics); |
6616 | int Precision = APFloat::semanticsPrecision(Semantics); |
6617 | |
6618 | EXPECT_EQ(0, One.getExactLog2()); |
6619 | EXPECT_EQ(INT_MIN, APFloat(Semantics, "3.0" ).getExactLog2()); |
6620 | EXPECT_EQ(INT_MIN, APFloat(Semantics, "-3.0" ).getExactLog2()); |
6621 | EXPECT_EQ(INT_MIN, APFloat(Semantics, "3.0" ).getExactLog2Abs()); |
6622 | EXPECT_EQ(INT_MIN, APFloat(Semantics, "-3.0" ).getExactLog2Abs()); |
6623 | EXPECT_EQ(3, APFloat(Semantics, "8.0" ).getExactLog2()); |
6624 | EXPECT_EQ(INT_MIN, APFloat(Semantics, "-8.0" ).getExactLog2()); |
6625 | EXPECT_EQ(-2, APFloat(Semantics, "0.25" ).getExactLog2()); |
6626 | EXPECT_EQ(-2, APFloat(Semantics, "0.25" ).getExactLog2Abs()); |
6627 | EXPECT_EQ(INT_MIN, APFloat(Semantics, "-0.25" ).getExactLog2()); |
6628 | EXPECT_EQ(-2, APFloat(Semantics, "-0.25" ).getExactLog2Abs()); |
6629 | EXPECT_EQ(3, APFloat(Semantics, "8.0" ).getExactLog2Abs()); |
6630 | EXPECT_EQ(3, APFloat(Semantics, "-8.0" ).getExactLog2Abs()); |
6631 | |
6632 | EXPECT_EQ(INT_MIN, APFloat::getZero(Semantics, false).getExactLog2()); |
6633 | EXPECT_EQ(INT_MIN, APFloat::getZero(Semantics, true).getExactLog2()); |
6634 | EXPECT_EQ(INT_MIN, APFloat::getInf(Semantics).getExactLog2()); |
6635 | EXPECT_EQ(INT_MIN, APFloat::getInf(Semantics, true).getExactLog2()); |
6636 | EXPECT_EQ(INT_MIN, APFloat::getNaN(Semantics, false).getExactLog2()); |
6637 | EXPECT_EQ(INT_MIN, APFloat::getNaN(Semantics, true).getExactLog2()); |
6638 | |
6639 | EXPECT_EQ(INT_MIN, APFloat::getZero(Semantics, false).getExactLog2Abs()); |
6640 | EXPECT_EQ(INT_MIN, APFloat::getZero(Semantics, true).getExactLog2Abs()); |
6641 | EXPECT_EQ(INT_MIN, APFloat::getInf(Semantics).getExactLog2Abs()); |
6642 | EXPECT_EQ(INT_MIN, APFloat::getInf(Semantics, true).getExactLog2Abs()); |
6643 | EXPECT_EQ(INT_MIN, APFloat::getNaN(Semantics, false).getExactLog2Abs()); |
6644 | EXPECT_EQ(INT_MIN, APFloat::getNaN(Semantics, true).getExactLog2Abs()); |
6645 | |
6646 | EXPECT_EQ(INT_MIN, |
6647 | scalbn(One, MinExp - Precision - 1, APFloat::rmNearestTiesToEven) |
6648 | .getExactLog2()); |
6649 | EXPECT_EQ(INT_MIN, |
6650 | scalbn(One, MinExp - Precision, APFloat::rmNearestTiesToEven) |
6651 | .getExactLog2()); |
6652 | |
6653 | EXPECT_EQ( |
6654 | INT_MIN, |
6655 | scalbn(One, MaxExp + 1, APFloat::rmNearestTiesToEven).getExactLog2()); |
6656 | |
6657 | for (int i = MinExp - Precision + 1; i <= MaxExp; ++i) { |
6658 | EXPECT_EQ(i, scalbn(One, i, APFloat::rmNearestTiesToEven).getExactLog2()); |
6659 | } |
6660 | } |
6661 | } |
6662 | |
6663 | } // namespace |
6664 | |