blob: a4445f6e4651c5b5278e5fc7c84e381d6292d136 [file] [log] [blame]
Erick Tryzelaar19f63b22009-08-16 23:36:19 +00001//===- llvm/unittest/ADT/APFloat.cpp - APFloat unit tests ---------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Erick Tryzelaar19f63b22009-08-16 23:36:19 +000010#include "llvm/ADT/APFloat.h"
Jeffrey Yasskin03b81a22011-07-15 07:04:56 +000011#include "llvm/ADT/APSInt.h"
Erick Tryzelaar19f63b22009-08-16 23:36:19 +000012#include "llvm/ADT/SmallString.h"
John McCall29b5c282009-12-24 08:56:26 +000013#include "llvm/ADT/SmallVector.h"
Chandler Carruth130cec22012-12-04 10:23:08 +000014#include "llvm/Support/raw_ostream.h"
15#include "gtest/gtest.h"
Benjamin Kramer37dce442015-03-09 18:35:18 +000016#include <cmath>
Chandler Carruth130cec22012-12-04 10:23:08 +000017#include <ostream>
18#include <string>
Erick Tryzelaar19f63b22009-08-16 23:36:19 +000019
20using namespace llvm;
21
Daniel Dunbarbc52e4f2009-09-03 22:57:02 +000022static double convertToDoubleFromString(const char *Str) {
23 llvm::APFloat F(0.0);
24 F.convertFromString(Str, llvm::APFloat::rmNearestTiesToEven);
25 return F.convertToDouble();
26}
27
John McCall29b5c282009-12-24 08:56:26 +000028static std::string convertToString(double d, unsigned Prec, unsigned Pad) {
29 llvm::SmallVector<char, 100> Buffer;
30 llvm::APFloat F(d);
31 F.toString(Buffer, Prec, Pad);
32 return std::string(Buffer.data(), Buffer.size());
33}
34
Erick Tryzelaar19f63b22009-08-16 23:36:19 +000035namespace {
36
Michael Gottesman0c622ea2013-05-30 18:07:13 +000037TEST(APFloatTest, isSignaling) {
38 // We test qNaN, -qNaN, +sNaN, -sNaN with and without payloads. *NOTE* The
39 // positive/negative distinction is included only since the getQNaN/getSNaN
40 // API provides the option.
41 APInt payload = APInt::getOneBitSet(4, 2);
42 EXPECT_FALSE(APFloat::getQNaN(APFloat::IEEEsingle, false).isSignaling());
43 EXPECT_FALSE(APFloat::getQNaN(APFloat::IEEEsingle, true).isSignaling());
44 EXPECT_FALSE(APFloat::getQNaN(APFloat::IEEEsingle, false, &payload).isSignaling());
45 EXPECT_FALSE(APFloat::getQNaN(APFloat::IEEEsingle, true, &payload).isSignaling());
46 EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle, false).isSignaling());
47 EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle, true).isSignaling());
48 EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle, false, &payload).isSignaling());
49 EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle, true, &payload).isSignaling());
50}
51
52TEST(APFloatTest, next) {
53
54 APFloat test(APFloat::IEEEquad, APFloat::uninitialized);
55 APFloat expected(APFloat::IEEEquad, APFloat::uninitialized);
56
57 // 1. Test Special Cases Values.
58 //
59 // Test all special values for nextUp and nextDown perscribed by IEEE-754R
60 // 2008. These are:
61 // 1. +inf
62 // 2. -inf
63 // 3. getLargest()
64 // 4. -getLargest()
65 // 5. getSmallest()
66 // 6. -getSmallest()
67 // 7. qNaN
68 // 8. sNaN
69 // 9. +0
70 // 10. -0
71
72 // nextUp(+inf) = +inf.
73 test = APFloat::getInf(APFloat::IEEEquad, false);
74 expected = APFloat::getInf(APFloat::IEEEquad, false);
75 EXPECT_EQ(test.next(false), APFloat::opOK);
76 EXPECT_TRUE(test.isInfinity());
77 EXPECT_TRUE(!test.isNegative());
78 EXPECT_TRUE(test.bitwiseIsEqual(expected));
79
80 // nextDown(+inf) = -nextUp(-inf) = -(-getLargest()) = getLargest()
81 test = APFloat::getInf(APFloat::IEEEquad, false);
82 expected = APFloat::getLargest(APFloat::IEEEquad, false);
83 EXPECT_EQ(test.next(true), APFloat::opOK);
84 EXPECT_TRUE(!test.isNegative());
85 EXPECT_TRUE(test.bitwiseIsEqual(expected));
86
87 // nextUp(-inf) = -getLargest()
88 test = APFloat::getInf(APFloat::IEEEquad, true);
89 expected = APFloat::getLargest(APFloat::IEEEquad, true);
90 EXPECT_EQ(test.next(false), APFloat::opOK);
91 EXPECT_TRUE(test.isNegative());
92 EXPECT_TRUE(test.bitwiseIsEqual(expected));
93
94 // nextDown(-inf) = -nextUp(+inf) = -(+inf) = -inf.
95 test = APFloat::getInf(APFloat::IEEEquad, true);
96 expected = APFloat::getInf(APFloat::IEEEquad, true);
97 EXPECT_EQ(test.next(true), APFloat::opOK);
98 EXPECT_TRUE(test.isInfinity() && test.isNegative());
99 EXPECT_TRUE(test.bitwiseIsEqual(expected));
100
101 // nextUp(getLargest()) = +inf
102 test = APFloat::getLargest(APFloat::IEEEquad, false);
103 expected = APFloat::getInf(APFloat::IEEEquad, false);
104 EXPECT_EQ(test.next(false), APFloat::opOK);
105 EXPECT_TRUE(test.isInfinity() && !test.isNegative());
106 EXPECT_TRUE(test.bitwiseIsEqual(expected));
107
108 // nextDown(getLargest()) = -nextUp(-getLargest())
109 // = -(-getLargest() + inc)
110 // = getLargest() - inc.
111 test = APFloat::getLargest(APFloat::IEEEquad, false);
112 expected = APFloat(APFloat::IEEEquad,
113 "0x1.fffffffffffffffffffffffffffep+16383");
114 EXPECT_EQ(test.next(true), APFloat::opOK);
115 EXPECT_TRUE(!test.isInfinity() && !test.isNegative());
116 EXPECT_TRUE(test.bitwiseIsEqual(expected));
117
118 // nextUp(-getLargest()) = -getLargest() + inc.
119 test = APFloat::getLargest(APFloat::IEEEquad, true);
120 expected = APFloat(APFloat::IEEEquad,
121 "-0x1.fffffffffffffffffffffffffffep+16383");
122 EXPECT_EQ(test.next(false), APFloat::opOK);
123 EXPECT_TRUE(test.bitwiseIsEqual(expected));
124
125 // nextDown(-getLargest()) = -nextUp(getLargest()) = -(inf) = -inf.
126 test = APFloat::getLargest(APFloat::IEEEquad, true);
127 expected = APFloat::getInf(APFloat::IEEEquad, true);
128 EXPECT_EQ(test.next(true), APFloat::opOK);
129 EXPECT_TRUE(test.isInfinity() && test.isNegative());
130 EXPECT_TRUE(test.bitwiseIsEqual(expected));
131
132 // nextUp(getSmallest()) = getSmallest() + inc.
133 test = APFloat(APFloat::IEEEquad, "0x0.0000000000000000000000000001p-16382");
134 expected = APFloat(APFloat::IEEEquad,
135 "0x0.0000000000000000000000000002p-16382");
136 EXPECT_EQ(test.next(false), APFloat::opOK);
137 EXPECT_TRUE(test.bitwiseIsEqual(expected));
138
139 // nextDown(getSmallest()) = -nextUp(-getSmallest()) = -(-0) = +0.
140 test = APFloat(APFloat::IEEEquad, "0x0.0000000000000000000000000001p-16382");
141 expected = APFloat::getZero(APFloat::IEEEquad, false);
142 EXPECT_EQ(test.next(true), APFloat::opOK);
143 EXPECT_TRUE(test.isZero() && !test.isNegative());
144 EXPECT_TRUE(test.bitwiseIsEqual(expected));
145
146 // nextUp(-getSmallest()) = -0.
147 test = APFloat(APFloat::IEEEquad, "-0x0.0000000000000000000000000001p-16382");
148 expected = APFloat::getZero(APFloat::IEEEquad, true);
149 EXPECT_EQ(test.next(false), APFloat::opOK);
150 EXPECT_TRUE(test.isZero() && test.isNegative());
151 EXPECT_TRUE(test.bitwiseIsEqual(expected));
152
153 // nextDown(-getSmallest()) = -nextUp(getSmallest()) = -getSmallest() - inc.
154 test = APFloat(APFloat::IEEEquad, "-0x0.0000000000000000000000000001p-16382");
155 expected = APFloat(APFloat::IEEEquad,
156 "-0x0.0000000000000000000000000002p-16382");
157 EXPECT_EQ(test.next(true), APFloat::opOK);
158 EXPECT_TRUE(test.bitwiseIsEqual(expected));
159
160 // nextUp(qNaN) = qNaN
161 test = APFloat::getQNaN(APFloat::IEEEquad, false);
162 expected = APFloat::getQNaN(APFloat::IEEEquad, false);
163 EXPECT_EQ(test.next(false), APFloat::opOK);
164 EXPECT_TRUE(test.bitwiseIsEqual(expected));
165
166 // nextDown(qNaN) = qNaN
167 test = APFloat::getQNaN(APFloat::IEEEquad, false);
168 expected = APFloat::getQNaN(APFloat::IEEEquad, false);
169 EXPECT_EQ(test.next(true), APFloat::opOK);
170 EXPECT_TRUE(test.bitwiseIsEqual(expected));
171
172 // nextUp(sNaN) = qNaN
173 test = APFloat::getSNaN(APFloat::IEEEquad, false);
174 expected = APFloat::getQNaN(APFloat::IEEEquad, false);
175 EXPECT_EQ(test.next(false), APFloat::opInvalidOp);
176 EXPECT_TRUE(test.bitwiseIsEqual(expected));
177
178 // nextDown(sNaN) = qNaN
179 test = APFloat::getSNaN(APFloat::IEEEquad, false);
180 expected = APFloat::getQNaN(APFloat::IEEEquad, false);
181 EXPECT_EQ(test.next(true), APFloat::opInvalidOp);
182 EXPECT_TRUE(test.bitwiseIsEqual(expected));
183
184 // nextUp(+0) = +getSmallest()
185 test = APFloat::getZero(APFloat::IEEEquad, false);
186 expected = APFloat::getSmallest(APFloat::IEEEquad, false);
187 EXPECT_EQ(test.next(false), APFloat::opOK);
188 EXPECT_TRUE(test.bitwiseIsEqual(expected));
189
190 // nextDown(+0) = -nextUp(-0) = -getSmallest()
191 test = APFloat::getZero(APFloat::IEEEquad, false);
192 expected = APFloat::getSmallest(APFloat::IEEEquad, true);
193 EXPECT_EQ(test.next(true), APFloat::opOK);
194 EXPECT_TRUE(test.bitwiseIsEqual(expected));
195
196 // nextUp(-0) = +getSmallest()
197 test = APFloat::getZero(APFloat::IEEEquad, true);
198 expected = APFloat::getSmallest(APFloat::IEEEquad, false);
199 EXPECT_EQ(test.next(false), APFloat::opOK);
200 EXPECT_TRUE(test.bitwiseIsEqual(expected));
201
202 // nextDown(-0) = -nextUp(0) = -getSmallest()
203 test = APFloat::getZero(APFloat::IEEEquad, true);
204 expected = APFloat::getSmallest(APFloat::IEEEquad, true);
205 EXPECT_EQ(test.next(true), APFloat::opOK);
206 EXPECT_TRUE(test.bitwiseIsEqual(expected));
207
208 // 2. Binade Boundary Tests.
209
210 // 2a. Test denormal <-> normal binade boundaries.
211 // * nextUp(+Largest Denormal) -> +Smallest Normal.
212 // * nextDown(-Largest Denormal) -> -Smallest Normal.
213 // * nextUp(-Smallest Normal) -> -Largest Denormal.
214 // * nextDown(+Smallest Normal) -> +Largest Denormal.
215
216 // nextUp(+Largest Denormal) -> +Smallest Normal.
217 test = APFloat(APFloat::IEEEquad, "0x0.ffffffffffffffffffffffffffffp-16382");
218 expected = APFloat(APFloat::IEEEquad,
219 "0x1.0000000000000000000000000000p-16382");
220 EXPECT_EQ(test.next(false), APFloat::opOK);
221 EXPECT_FALSE(test.isDenormal());
222 EXPECT_TRUE(test.bitwiseIsEqual(expected));
223
224 // nextDown(-Largest Denormal) -> -Smallest Normal.
225 test = APFloat(APFloat::IEEEquad,
226 "-0x0.ffffffffffffffffffffffffffffp-16382");
227 expected = APFloat(APFloat::IEEEquad,
228 "-0x1.0000000000000000000000000000p-16382");
229 EXPECT_EQ(test.next(true), APFloat::opOK);
230 EXPECT_FALSE(test.isDenormal());
231 EXPECT_TRUE(test.bitwiseIsEqual(expected));
232
233 // nextUp(-Smallest Normal) -> -LargestDenormal.
234 test = APFloat(APFloat::IEEEquad,
235 "-0x1.0000000000000000000000000000p-16382");
236 expected = APFloat(APFloat::IEEEquad,
237 "-0x0.ffffffffffffffffffffffffffffp-16382");
238 EXPECT_EQ(test.next(false), APFloat::opOK);
239 EXPECT_TRUE(test.isDenormal());
240 EXPECT_TRUE(test.bitwiseIsEqual(expected));
241
242 // nextDown(+Smallest Normal) -> +Largest Denormal.
243 test = APFloat(APFloat::IEEEquad,
244 "+0x1.0000000000000000000000000000p-16382");
245 expected = APFloat(APFloat::IEEEquad,
246 "+0x0.ffffffffffffffffffffffffffffp-16382");
247 EXPECT_EQ(test.next(true), APFloat::opOK);
248 EXPECT_TRUE(test.isDenormal());
249 EXPECT_TRUE(test.bitwiseIsEqual(expected));
250
251 // 2b. Test normal <-> normal binade boundaries.
252 // * nextUp(-Normal Binade Boundary) -> -Normal Binade Boundary + 1.
253 // * nextDown(+Normal Binade Boundary) -> +Normal Binade Boundary - 1.
254 // * nextUp(+Normal Binade Boundary - 1) -> +Normal Binade Boundary.
255 // * nextDown(-Normal Binade Boundary + 1) -> -Normal Binade Boundary.
256
257 // nextUp(-Normal Binade Boundary) -> -Normal Binade Boundary + 1.
258 test = APFloat(APFloat::IEEEquad, "-0x1p+1");
259 expected = APFloat(APFloat::IEEEquad,
260 "-0x1.ffffffffffffffffffffffffffffp+0");
261 EXPECT_EQ(test.next(false), APFloat::opOK);
262 EXPECT_TRUE(test.bitwiseIsEqual(expected));
263
264 // nextDown(+Normal Binade Boundary) -> +Normal Binade Boundary - 1.
265 test = APFloat(APFloat::IEEEquad, "0x1p+1");
266 expected = APFloat(APFloat::IEEEquad, "0x1.ffffffffffffffffffffffffffffp+0");
267 EXPECT_EQ(test.next(true), APFloat::opOK);
268 EXPECT_TRUE(test.bitwiseIsEqual(expected));
269
270 // nextUp(+Normal Binade Boundary - 1) -> +Normal Binade Boundary.
271 test = APFloat(APFloat::IEEEquad, "0x1.ffffffffffffffffffffffffffffp+0");
272 expected = APFloat(APFloat::IEEEquad, "0x1p+1");
273 EXPECT_EQ(test.next(false), APFloat::opOK);
274 EXPECT_TRUE(test.bitwiseIsEqual(expected));
275
276 // nextDown(-Normal Binade Boundary + 1) -> -Normal Binade Boundary.
277 test = APFloat(APFloat::IEEEquad, "-0x1.ffffffffffffffffffffffffffffp+0");
278 expected = APFloat(APFloat::IEEEquad, "-0x1p+1");
279 EXPECT_EQ(test.next(true), APFloat::opOK);
280 EXPECT_TRUE(test.bitwiseIsEqual(expected));
281
282 // 2c. Test using next at binade boundaries with a direction away from the
283 // binade boundary. Away from denormal <-> normal boundaries.
284 //
285 // This is to make sure that even though we are at a binade boundary, since
286 // we are rounding away, we do not trigger the binade boundary code. Thus we
287 // test:
288 // * nextUp(-Largest Denormal) -> -Largest Denormal + inc.
289 // * nextDown(+Largest Denormal) -> +Largest Denormal - inc.
290 // * nextUp(+Smallest Normal) -> +Smallest Normal + inc.
291 // * nextDown(-Smallest Normal) -> -Smallest Normal - inc.
292
293 // nextUp(-Largest Denormal) -> -Largest Denormal + inc.
294 test = APFloat(APFloat::IEEEquad, "-0x0.ffffffffffffffffffffffffffffp-16382");
295 expected = APFloat(APFloat::IEEEquad,
296 "-0x0.fffffffffffffffffffffffffffep-16382");
297 EXPECT_EQ(test.next(false), APFloat::opOK);
298 EXPECT_TRUE(test.isDenormal());
299 EXPECT_TRUE(test.isNegative());
300 EXPECT_TRUE(test.bitwiseIsEqual(expected));
301
302 // nextDown(+Largest Denormal) -> +Largest Denormal - inc.
303 test = APFloat(APFloat::IEEEquad, "0x0.ffffffffffffffffffffffffffffp-16382");
304 expected = APFloat(APFloat::IEEEquad,
305 "0x0.fffffffffffffffffffffffffffep-16382");
306 EXPECT_EQ(test.next(true), APFloat::opOK);
307 EXPECT_TRUE(test.isDenormal());
308 EXPECT_TRUE(!test.isNegative());
309 EXPECT_TRUE(test.bitwiseIsEqual(expected));
310
311 // nextUp(+Smallest Normal) -> +Smallest Normal + inc.
312 test = APFloat(APFloat::IEEEquad, "0x1.0000000000000000000000000000p-16382");
313 expected = APFloat(APFloat::IEEEquad,
314 "0x1.0000000000000000000000000001p-16382");
315 EXPECT_EQ(test.next(false), APFloat::opOK);
316 EXPECT_TRUE(!test.isDenormal());
317 EXPECT_TRUE(!test.isNegative());
318 EXPECT_TRUE(test.bitwiseIsEqual(expected));
319
320 // nextDown(-Smallest Normal) -> -Smallest Normal - inc.
321 test = APFloat(APFloat::IEEEquad, "-0x1.0000000000000000000000000000p-16382");
322 expected = APFloat(APFloat::IEEEquad,
323 "-0x1.0000000000000000000000000001p-16382");
324 EXPECT_EQ(test.next(true), APFloat::opOK);
325 EXPECT_TRUE(!test.isDenormal());
326 EXPECT_TRUE(test.isNegative());
327 EXPECT_TRUE(test.bitwiseIsEqual(expected));
328
329 // 2d. Test values which cause our exponent to go to min exponent. This
330 // is to ensure that guards in the code to check for min exponent
331 // trigger properly.
332 // * nextUp(-0x1p-16381) -> -0x1.ffffffffffffffffffffffffffffp-16382
333 // * nextDown(-0x1.ffffffffffffffffffffffffffffp-16382) ->
334 // -0x1p-16381
335 // * nextUp(0x1.ffffffffffffffffffffffffffffp-16382) -> 0x1p-16382
336 // * nextDown(0x1p-16382) -> 0x1.ffffffffffffffffffffffffffffp-16382
337
338 // nextUp(-0x1p-16381) -> -0x1.ffffffffffffffffffffffffffffp-16382
339 test = APFloat(APFloat::IEEEquad, "-0x1p-16381");
340 expected = APFloat(APFloat::IEEEquad,
341 "-0x1.ffffffffffffffffffffffffffffp-16382");
342 EXPECT_EQ(test.next(false), APFloat::opOK);
343 EXPECT_TRUE(test.bitwiseIsEqual(expected));
344
345 // nextDown(-0x1.ffffffffffffffffffffffffffffp-16382) ->
346 // -0x1p-16381
347 test = APFloat(APFloat::IEEEquad, "-0x1.ffffffffffffffffffffffffffffp-16382");
348 expected = APFloat(APFloat::IEEEquad, "-0x1p-16381");
349 EXPECT_EQ(test.next(true), APFloat::opOK);
350 EXPECT_TRUE(test.bitwiseIsEqual(expected));
351
352 // nextUp(0x1.ffffffffffffffffffffffffffffp-16382) -> 0x1p-16381
353 test = APFloat(APFloat::IEEEquad, "0x1.ffffffffffffffffffffffffffffp-16382");
354 expected = APFloat(APFloat::IEEEquad, "0x1p-16381");
355 EXPECT_EQ(test.next(false), APFloat::opOK);
356 EXPECT_TRUE(test.bitwiseIsEqual(expected));
357
358 // nextDown(0x1p-16381) -> 0x1.ffffffffffffffffffffffffffffp-16382
359 test = APFloat(APFloat::IEEEquad, "0x1p-16381");
360 expected = APFloat(APFloat::IEEEquad,
361 "0x1.ffffffffffffffffffffffffffffp-16382");
362 EXPECT_EQ(test.next(true), APFloat::opOK);
363 EXPECT_TRUE(test.bitwiseIsEqual(expected));
364
365 // 3. Now we test both denormal/normal computation which will not cause us
366 // to go across binade boundaries. Specifically we test:
367 // * nextUp(+Denormal) -> +Denormal.
368 // * nextDown(+Denormal) -> +Denormal.
369 // * nextUp(-Denormal) -> -Denormal.
370 // * nextDown(-Denormal) -> -Denormal.
371 // * nextUp(+Normal) -> +Normal.
372 // * nextDown(+Normal) -> +Normal.
373 // * nextUp(-Normal) -> -Normal.
374 // * nextDown(-Normal) -> -Normal.
375
376 // nextUp(+Denormal) -> +Denormal.
377 test = APFloat(APFloat::IEEEquad,
378 "0x0.ffffffffffffffffffffffff000cp-16382");
379 expected = APFloat(APFloat::IEEEquad,
380 "0x0.ffffffffffffffffffffffff000dp-16382");
381 EXPECT_EQ(test.next(false), APFloat::opOK);
382 EXPECT_TRUE(test.isDenormal());
383 EXPECT_TRUE(!test.isNegative());
384 EXPECT_TRUE(test.bitwiseIsEqual(expected));
385
386 // nextDown(+Denormal) -> +Denormal.
387 test = APFloat(APFloat::IEEEquad,
388 "0x0.ffffffffffffffffffffffff000cp-16382");
389 expected = APFloat(APFloat::IEEEquad,
390 "0x0.ffffffffffffffffffffffff000bp-16382");
391 EXPECT_EQ(test.next(true), APFloat::opOK);
392 EXPECT_TRUE(test.isDenormal());
393 EXPECT_TRUE(!test.isNegative());
394 EXPECT_TRUE(test.bitwiseIsEqual(expected));
395
396 // nextUp(-Denormal) -> -Denormal.
397 test = APFloat(APFloat::IEEEquad,
398 "-0x0.ffffffffffffffffffffffff000cp-16382");
399 expected = APFloat(APFloat::IEEEquad,
400 "-0x0.ffffffffffffffffffffffff000bp-16382");
401 EXPECT_EQ(test.next(false), APFloat::opOK);
402 EXPECT_TRUE(test.isDenormal());
403 EXPECT_TRUE(test.isNegative());
404 EXPECT_TRUE(test.bitwiseIsEqual(expected));
405
406 // nextDown(-Denormal) -> -Denormal
407 test = APFloat(APFloat::IEEEquad,
408 "-0x0.ffffffffffffffffffffffff000cp-16382");
409 expected = APFloat(APFloat::IEEEquad,
410 "-0x0.ffffffffffffffffffffffff000dp-16382");
411 EXPECT_EQ(test.next(true), APFloat::opOK);
412 EXPECT_TRUE(test.isDenormal());
413 EXPECT_TRUE(test.isNegative());
414 EXPECT_TRUE(test.bitwiseIsEqual(expected));
415
416 // nextUp(+Normal) -> +Normal.
417 test = APFloat(APFloat::IEEEquad,
418 "0x1.ffffffffffffffffffffffff000cp-16000");
419 expected = APFloat(APFloat::IEEEquad,
420 "0x1.ffffffffffffffffffffffff000dp-16000");
421 EXPECT_EQ(test.next(false), APFloat::opOK);
422 EXPECT_TRUE(!test.isDenormal());
423 EXPECT_TRUE(!test.isNegative());
424 EXPECT_TRUE(test.bitwiseIsEqual(expected));
425
426 // nextDown(+Normal) -> +Normal.
427 test = APFloat(APFloat::IEEEquad,
428 "0x1.ffffffffffffffffffffffff000cp-16000");
429 expected = APFloat(APFloat::IEEEquad,
430 "0x1.ffffffffffffffffffffffff000bp-16000");
431 EXPECT_EQ(test.next(true), APFloat::opOK);
432 EXPECT_TRUE(!test.isDenormal());
433 EXPECT_TRUE(!test.isNegative());
434 EXPECT_TRUE(test.bitwiseIsEqual(expected));
435
436 // nextUp(-Normal) -> -Normal.
437 test = APFloat(APFloat::IEEEquad,
438 "-0x1.ffffffffffffffffffffffff000cp-16000");
439 expected = APFloat(APFloat::IEEEquad,
440 "-0x1.ffffffffffffffffffffffff000bp-16000");
441 EXPECT_EQ(test.next(false), APFloat::opOK);
442 EXPECT_TRUE(!test.isDenormal());
443 EXPECT_TRUE(test.isNegative());
444 EXPECT_TRUE(test.bitwiseIsEqual(expected));
445
446 // nextDown(-Normal) -> -Normal.
447 test = APFloat(APFloat::IEEEquad,
448 "-0x1.ffffffffffffffffffffffff000cp-16000");
449 expected = APFloat(APFloat::IEEEquad,
450 "-0x1.ffffffffffffffffffffffff000dp-16000");
451 EXPECT_EQ(test.next(true), APFloat::opOK);
452 EXPECT_TRUE(!test.isDenormal());
453 EXPECT_TRUE(test.isNegative());
454 EXPECT_TRUE(test.bitwiseIsEqual(expected));
455}
456
Shuxin Yangbbddbac2013-05-13 18:03:12 +0000457TEST(APFloatTest, FMA) {
458 APFloat::roundingMode rdmd = APFloat::rmNearestTiesToEven;
459
460 {
461 APFloat f1(14.5f);
462 APFloat f2(-14.5f);
463 APFloat f3(225.0f);
464 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);
465 EXPECT_EQ(14.75f, f1.convertToFloat());
466 }
467
468 {
469 APFloat Val2(2.0f);
470 APFloat f1((float)1.17549435e-38F);
471 APFloat f2((float)1.17549435e-38F);
472 f1.divide(Val2, rdmd);
473 f2.divide(Val2, rdmd);
474 APFloat f3(12.0f);
475 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);
476 EXPECT_EQ(12.0f, f1.convertToFloat());
477 }
Lang Hames56c0eb22014-11-19 19:15:41 +0000478
Lang Hames12b12e82015-01-04 01:20:55 +0000479 // Test for correct zero sign when answer is exactly zero.
480 // fma(1.0, -1.0, 1.0) -> +ve 0.
481 {
482 APFloat f1(1.0);
483 APFloat f2(-1.0);
484 APFloat f3(1.0);
485 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);
486 EXPECT_TRUE(!f1.isNegative() && f1.isZero());
487 }
488
489 // Test for correct zero sign when answer is exactly zero and rounding towards
490 // negative.
491 // fma(1.0, -1.0, 1.0) -> +ve 0.
492 {
493 APFloat f1(1.0);
494 APFloat f2(-1.0);
495 APFloat f3(1.0);
496 f1.fusedMultiplyAdd(f2, f3, APFloat::rmTowardNegative);
497 EXPECT_TRUE(f1.isNegative() && f1.isZero());
498 }
499
500 // Test for correct (in this case -ve) sign when adding like signed zeros.
501 // Test fma(0.0, -0.0, -0.0) -> -ve 0.
502 {
503 APFloat f1(0.0);
504 APFloat f2(-0.0);
505 APFloat f3(-0.0);
506 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);
507 EXPECT_TRUE(f1.isNegative() && f1.isZero());
508 }
509
510 // Test -ve sign preservation when small negative results underflow.
511 {
512 APFloat f1(APFloat::IEEEdouble, "-0x1p-1074");
513 APFloat f2(APFloat::IEEEdouble, "+0x1p-1074");
514 APFloat f3(0.0);
515 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);
516 EXPECT_TRUE(f1.isNegative() && f1.isZero());
517 }
518
519 // Test x87 extended precision case from http://llvm.org/PR20728.
Lang Hames56c0eb22014-11-19 19:15:41 +0000520 {
521 APFloat M1(APFloat::x87DoubleExtended, 1.0);
522 APFloat M2(APFloat::x87DoubleExtended, 1.0);
523 APFloat A(APFloat::x87DoubleExtended, 3.0);
524
525 bool losesInfo = false;
526 M1.fusedMultiplyAdd(M1, A, APFloat::rmNearestTiesToEven);
527 M1.convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven, &losesInfo);
528 EXPECT_FALSE(losesInfo);
529 EXPECT_EQ(4.0f, M1.convertToFloat());
530 }
Shuxin Yangbbddbac2013-05-13 18:03:12 +0000531}
532
Matt Arsenault5ccdb982014-10-10 05:21:32 +0000533TEST(APFloatTest, MinNum) {
534 APFloat f1(1.0);
535 APFloat f2(2.0);
536 APFloat nan = APFloat::getNaN(APFloat::IEEEdouble);
537
538 EXPECT_EQ(1.0, minnum(f1, f2).convertToDouble());
539 EXPECT_EQ(1.0, minnum(f2, f1).convertToDouble());
540 EXPECT_EQ(1.0, minnum(f1, nan).convertToDouble());
541 EXPECT_EQ(1.0, minnum(nan, f1).convertToDouble());
542}
543
544TEST(APFloatTest, MaxNum) {
545 APFloat f1(1.0);
546 APFloat f2(2.0);
547 APFloat nan = APFloat::getNaN(APFloat::IEEEdouble);
548
549 EXPECT_EQ(2.0, maxnum(f1, f2).convertToDouble());
550 EXPECT_EQ(2.0, maxnum(f2, f1).convertToDouble());
551 EXPECT_EQ(1.0, maxnum(f1, nan).convertToDouble());
552 EXPECT_EQ(1.0, minnum(nan, f1).convertToDouble());
553}
554
Shuxin Yang4fb504f2013-01-07 18:59:35 +0000555TEST(APFloatTest, Denormal) {
556 APFloat::roundingMode rdmd = APFloat::rmNearestTiesToEven;
557
558 // Test single precision
559 {
560 const char *MinNormalStr = "1.17549435082228750797e-38";
561 EXPECT_FALSE(APFloat(APFloat::IEEEsingle, MinNormalStr).isDenormal());
562 EXPECT_FALSE(APFloat(APFloat::IEEEsingle, 0.0).isDenormal());
563
564 APFloat Val2(APFloat::IEEEsingle, 2.0e0);
565 APFloat T(APFloat::IEEEsingle, MinNormalStr);
566 T.divide(Val2, rdmd);
567 EXPECT_TRUE(T.isDenormal());
568 }
569
570 // Test double precision
571 {
572 const char *MinNormalStr = "2.22507385850720138309e-308";
573 EXPECT_FALSE(APFloat(APFloat::IEEEdouble, MinNormalStr).isDenormal());
574 EXPECT_FALSE(APFloat(APFloat::IEEEdouble, 0.0).isDenormal());
575
576 APFloat Val2(APFloat::IEEEdouble, 2.0e0);
577 APFloat T(APFloat::IEEEdouble, MinNormalStr);
578 T.divide(Val2, rdmd);
579 EXPECT_TRUE(T.isDenormal());
580 }
581
582 // Test Intel double-ext
583 {
584 const char *MinNormalStr = "3.36210314311209350626e-4932";
585 EXPECT_FALSE(APFloat(APFloat::x87DoubleExtended, MinNormalStr).isDenormal());
586 EXPECT_FALSE(APFloat(APFloat::x87DoubleExtended, 0.0).isDenormal());
587
588 APFloat Val2(APFloat::x87DoubleExtended, 2.0e0);
589 APFloat T(APFloat::x87DoubleExtended, MinNormalStr);
590 T.divide(Val2, rdmd);
591 EXPECT_TRUE(T.isDenormal());
592 }
593
594 // Test quadruple precision
595 {
596 const char *MinNormalStr = "3.36210314311209350626267781732175260e-4932";
597 EXPECT_FALSE(APFloat(APFloat::IEEEquad, MinNormalStr).isDenormal());
598 EXPECT_FALSE(APFloat(APFloat::IEEEquad, 0.0).isDenormal());
599
600 APFloat Val2(APFloat::IEEEquad, 2.0e0);
601 APFloat T(APFloat::IEEEquad, MinNormalStr);
602 T.divide(Val2, rdmd);
603 EXPECT_TRUE(T.isDenormal());
604 }
605}
606
Erick Tryzelaar19f63b22009-08-16 23:36:19 +0000607TEST(APFloatTest, Zero) {
Matt Beaumont-Gaya421ee12011-08-29 17:54:20 +0000608 EXPECT_EQ(0.0f, APFloat(0.0f).convertToFloat());
609 EXPECT_EQ(-0.0f, APFloat(-0.0f).convertToFloat());
610 EXPECT_TRUE(APFloat(-0.0f).isNegative());
Erick Tryzelaar19f63b22009-08-16 23:36:19 +0000611
Matt Beaumont-Gaya421ee12011-08-29 17:54:20 +0000612 EXPECT_EQ(0.0, APFloat(0.0).convertToDouble());
613 EXPECT_EQ(-0.0, APFloat(-0.0).convertToDouble());
614 EXPECT_TRUE(APFloat(-0.0).isNegative());
Erick Tryzelaar19f63b22009-08-16 23:36:19 +0000615}
616
Michael Gottesman228156c2013-07-01 23:54:08 +0000617TEST(APFloatTest, DecimalStringsWithoutNullTerminators) {
618 // Make sure that we can parse strings without null terminators.
619 // rdar://14323230.
620 APFloat Val(APFloat::IEEEdouble);
621 Val.convertFromString(StringRef("0.00", 3),
622 llvm::APFloat::rmNearestTiesToEven);
623 EXPECT_EQ(Val.convertToDouble(), 0.0);
624 Val.convertFromString(StringRef("0.01", 3),
625 llvm::APFloat::rmNearestTiesToEven);
626 EXPECT_EQ(Val.convertToDouble(), 0.0);
627 Val.convertFromString(StringRef("0.09", 3),
628 llvm::APFloat::rmNearestTiesToEven);
629 EXPECT_EQ(Val.convertToDouble(), 0.0);
630 Val.convertFromString(StringRef("0.095", 4),
631 llvm::APFloat::rmNearestTiesToEven);
632 EXPECT_EQ(Val.convertToDouble(), 0.09);
633 Val.convertFromString(StringRef("0.00e+3", 7),
634 llvm::APFloat::rmNearestTiesToEven);
635 EXPECT_EQ(Val.convertToDouble(), 0.00);
636 Val.convertFromString(StringRef("0e+3", 4),
637 llvm::APFloat::rmNearestTiesToEven);
638 EXPECT_EQ(Val.convertToDouble(), 0.00);
639
640}
641
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000642TEST(APFloatTest, fromZeroDecimalString) {
643 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0").convertToDouble());
644 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0").convertToDouble());
Erick Tryzelaarbc0d7492009-08-17 00:14:11 +0000645 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000646
647 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0.").convertToDouble());
648 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0.").convertToDouble());
Erick Tryzelaarbc0d7492009-08-17 00:14:11 +0000649 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0.").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000650
651 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, ".0").convertToDouble());
652 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+.0").convertToDouble());
Erick Tryzelaarbc0d7492009-08-17 00:14:11 +0000653 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-.0").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000654
655 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0.0").convertToDouble());
656 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0.0").convertToDouble());
Erick Tryzelaarbc0d7492009-08-17 00:14:11 +0000657 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0.0").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000658
659 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "00000.").convertToDouble());
660 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+00000.").convertToDouble());
661 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-00000.").convertToDouble());
662
Erick Tryzelaarbc0d7492009-08-17 00:14:11 +0000663 EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble, ".00000").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000664 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+.00000").convertToDouble());
665 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-.00000").convertToDouble());
666
667 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0000.00000").convertToDouble());
668 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0000.00000").convertToDouble());
669 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0000.00000").convertToDouble());
670}
671
672TEST(APFloatTest, fromZeroDecimalSingleExponentString) {
673 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0e1").convertToDouble());
674 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0e1").convertToDouble());
675 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0e1").convertToDouble());
676
677 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0e+1").convertToDouble());
678 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0e+1").convertToDouble());
679 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0e+1").convertToDouble());
680
681 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0e-1").convertToDouble());
682 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0e-1").convertToDouble());
683 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0e-1").convertToDouble());
684
685
686 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0.e1").convertToDouble());
687 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0.e1").convertToDouble());
688 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0.e1").convertToDouble());
689
690 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0.e+1").convertToDouble());
691 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0.e+1").convertToDouble());
692 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0.e+1").convertToDouble());
693
694 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0.e-1").convertToDouble());
695 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0.e-1").convertToDouble());
696 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0.e-1").convertToDouble());
697
698 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, ".0e1").convertToDouble());
699 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+.0e1").convertToDouble());
700 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-.0e1").convertToDouble());
701
702 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, ".0e+1").convertToDouble());
703 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+.0e+1").convertToDouble());
704 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-.0e+1").convertToDouble());
705
706 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, ".0e-1").convertToDouble());
707 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+.0e-1").convertToDouble());
708 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-.0e-1").convertToDouble());
709
710
711 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0.0e1").convertToDouble());
712 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0.0e1").convertToDouble());
713 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0.0e1").convertToDouble());
714
715 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0.0e+1").convertToDouble());
716 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0.0e+1").convertToDouble());
717 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0.0e+1").convertToDouble());
718
719 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0.0e-1").convertToDouble());
720 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0.0e-1").convertToDouble());
721 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0.0e-1").convertToDouble());
722
723
724 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "000.0000e1").convertToDouble());
725 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+000.0000e+1").convertToDouble());
726 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-000.0000e+1").convertToDouble());
727}
728
729TEST(APFloatTest, fromZeroDecimalLargeExponentString) {
730 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0e1234").convertToDouble());
731 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0e1234").convertToDouble());
732 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0e1234").convertToDouble());
733
734 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0e+1234").convertToDouble());
735 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0e+1234").convertToDouble());
736 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0e+1234").convertToDouble());
737
738 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0e-1234").convertToDouble());
739 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0e-1234").convertToDouble());
740 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0e-1234").convertToDouble());
741
Erick Tryzelaarbc0d7492009-08-17 00:14:11 +0000742 EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble, "000.0000e1234").convertToDouble());
743 EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble, "000.0000e-1234").convertToDouble());
Erick Tryzelaar19f63b22009-08-16 23:36:19 +0000744
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000745 EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble, StringRef("0e1234\02", 6)).convertToDouble());
746}
Erick Tryzelaar19f63b22009-08-16 23:36:19 +0000747
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000748TEST(APFloatTest, fromZeroHexadecimalString) {
749 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x0p1").convertToDouble());
750 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0x0p1").convertToDouble());
751 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0x0p1").convertToDouble());
752
753 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x0p+1").convertToDouble());
754 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0x0p+1").convertToDouble());
755 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0x0p+1").convertToDouble());
756
757 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x0p-1").convertToDouble());
758 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0x0p-1").convertToDouble());
759 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0x0p-1").convertToDouble());
760
761
762 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x0.p1").convertToDouble());
763 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0x0.p1").convertToDouble());
764 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0x0.p1").convertToDouble());
765
766 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x0.p+1").convertToDouble());
767 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0x0.p+1").convertToDouble());
768 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0x0.p+1").convertToDouble());
769
770 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x0.p-1").convertToDouble());
771 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0x0.p-1").convertToDouble());
772 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0x0.p-1").convertToDouble());
773
774
775 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x.0p1").convertToDouble());
776 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0x.0p1").convertToDouble());
777 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0x.0p1").convertToDouble());
778
779 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x.0p+1").convertToDouble());
780 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0x.0p+1").convertToDouble());
781 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0x.0p+1").convertToDouble());
782
783 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x.0p-1").convertToDouble());
784 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0x.0p-1").convertToDouble());
785 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0x.0p-1").convertToDouble());
786
787
788 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x0.0p1").convertToDouble());
789 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0x0.0p1").convertToDouble());
790 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0x0.0p1").convertToDouble());
791
792 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x0.0p+1").convertToDouble());
793 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0x0.0p+1").convertToDouble());
794 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0x0.0p+1").convertToDouble());
795
796 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x0.0p-1").convertToDouble());
797 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0x0.0p-1").convertToDouble());
798 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0x0.0p-1").convertToDouble());
799
800
801 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x00000.p1").convertToDouble());
802 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x0000.00000p1").convertToDouble());
803 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x.00000p1").convertToDouble());
804 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x0.p1").convertToDouble());
805 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x0p1234").convertToDouble());
806 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0x0p1234").convertToDouble());
807 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x00000.p1234").convertToDouble());
808 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x0000.00000p1234").convertToDouble());
809 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x.00000p1234").convertToDouble());
810 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x0.p1234").convertToDouble());
811}
812
813TEST(APFloatTest, fromDecimalString) {
814 EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble, "1").convertToDouble());
815 EXPECT_EQ(2.0, APFloat(APFloat::IEEEdouble, "2.").convertToDouble());
816 EXPECT_EQ(0.5, APFloat(APFloat::IEEEdouble, ".5").convertToDouble());
817 EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble, "1.0").convertToDouble());
818 EXPECT_EQ(-2.0, APFloat(APFloat::IEEEdouble, "-2").convertToDouble());
819 EXPECT_EQ(-4.0, APFloat(APFloat::IEEEdouble, "-4.").convertToDouble());
820 EXPECT_EQ(-0.5, APFloat(APFloat::IEEEdouble, "-.5").convertToDouble());
821 EXPECT_EQ(-1.5, APFloat(APFloat::IEEEdouble, "-1.5").convertToDouble());
822 EXPECT_EQ(1.25e12, APFloat(APFloat::IEEEdouble, "1.25e12").convertToDouble());
823 EXPECT_EQ(1.25e+12, APFloat(APFloat::IEEEdouble, "1.25e+12").convertToDouble());
824 EXPECT_EQ(1.25e-12, APFloat(APFloat::IEEEdouble, "1.25e-12").convertToDouble());
825 EXPECT_EQ(1024.0, APFloat(APFloat::IEEEdouble, "1024.").convertToDouble());
826 EXPECT_EQ(1024.05, APFloat(APFloat::IEEEdouble, "1024.05000").convertToDouble());
827 EXPECT_EQ(0.05, APFloat(APFloat::IEEEdouble, ".05000").convertToDouble());
828 EXPECT_EQ(2.0, APFloat(APFloat::IEEEdouble, "2.").convertToDouble());
829 EXPECT_EQ(2.0e2, APFloat(APFloat::IEEEdouble, "2.e2").convertToDouble());
830 EXPECT_EQ(2.0e+2, APFloat(APFloat::IEEEdouble, "2.e+2").convertToDouble());
831 EXPECT_EQ(2.0e-2, APFloat(APFloat::IEEEdouble, "2.e-2").convertToDouble());
832 EXPECT_EQ(2.05e2, APFloat(APFloat::IEEEdouble, "002.05000e2").convertToDouble());
833 EXPECT_EQ(2.05e+2, APFloat(APFloat::IEEEdouble, "002.05000e+2").convertToDouble());
834 EXPECT_EQ(2.05e-2, APFloat(APFloat::IEEEdouble, "002.05000e-2").convertToDouble());
835 EXPECT_EQ(2.05e12, APFloat(APFloat::IEEEdouble, "002.05000e12").convertToDouble());
836 EXPECT_EQ(2.05e+12, APFloat(APFloat::IEEEdouble, "002.05000e+12").convertToDouble());
837 EXPECT_EQ(2.05e-12, APFloat(APFloat::IEEEdouble, "002.05000e-12").convertToDouble());
John McCallb42cc682010-02-26 22:20:41 +0000838
839 // These are "carefully selected" to overflow the fast log-base
840 // calculations in APFloat.cpp
841 EXPECT_TRUE(APFloat(APFloat::IEEEdouble, "99e99999").isInfinity());
842 EXPECT_TRUE(APFloat(APFloat::IEEEdouble, "-99e99999").isInfinity());
843 EXPECT_TRUE(APFloat(APFloat::IEEEdouble, "1e-99999").isPosZero());
844 EXPECT_TRUE(APFloat(APFloat::IEEEdouble, "-1e-99999").isNegZero());
Eli Friedmand2eb07a2013-07-17 22:17:29 +0000845
846 EXPECT_EQ(2.71828, convertToDoubleFromString("2.71828"));
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000847}
848
849TEST(APFloatTest, fromHexadecimalString) {
850 EXPECT_EQ( 1.0, APFloat(APFloat::IEEEdouble, "0x1p0").convertToDouble());
851 EXPECT_EQ(+1.0, APFloat(APFloat::IEEEdouble, "+0x1p0").convertToDouble());
852 EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble, "-0x1p0").convertToDouble());
853
854 EXPECT_EQ( 1.0, APFloat(APFloat::IEEEdouble, "0x1p+0").convertToDouble());
855 EXPECT_EQ(+1.0, APFloat(APFloat::IEEEdouble, "+0x1p+0").convertToDouble());
856 EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble, "-0x1p+0").convertToDouble());
857
858 EXPECT_EQ( 1.0, APFloat(APFloat::IEEEdouble, "0x1p-0").convertToDouble());
859 EXPECT_EQ(+1.0, APFloat(APFloat::IEEEdouble, "+0x1p-0").convertToDouble());
860 EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble, "-0x1p-0").convertToDouble());
861
862
863 EXPECT_EQ( 2.0, APFloat(APFloat::IEEEdouble, "0x1p1").convertToDouble());
864 EXPECT_EQ(+2.0, APFloat(APFloat::IEEEdouble, "+0x1p1").convertToDouble());
865 EXPECT_EQ(-2.0, APFloat(APFloat::IEEEdouble, "-0x1p1").convertToDouble());
866
867 EXPECT_EQ( 2.0, APFloat(APFloat::IEEEdouble, "0x1p+1").convertToDouble());
868 EXPECT_EQ(+2.0, APFloat(APFloat::IEEEdouble, "+0x1p+1").convertToDouble());
869 EXPECT_EQ(-2.0, APFloat(APFloat::IEEEdouble, "-0x1p+1").convertToDouble());
870
871 EXPECT_EQ( 0.5, APFloat(APFloat::IEEEdouble, "0x1p-1").convertToDouble());
872 EXPECT_EQ(+0.5, APFloat(APFloat::IEEEdouble, "+0x1p-1").convertToDouble());
873 EXPECT_EQ(-0.5, APFloat(APFloat::IEEEdouble, "-0x1p-1").convertToDouble());
874
875
876 EXPECT_EQ( 3.0, APFloat(APFloat::IEEEdouble, "0x1.8p1").convertToDouble());
877 EXPECT_EQ(+3.0, APFloat(APFloat::IEEEdouble, "+0x1.8p1").convertToDouble());
878 EXPECT_EQ(-3.0, APFloat(APFloat::IEEEdouble, "-0x1.8p1").convertToDouble());
879
880 EXPECT_EQ( 3.0, APFloat(APFloat::IEEEdouble, "0x1.8p+1").convertToDouble());
881 EXPECT_EQ(+3.0, APFloat(APFloat::IEEEdouble, "+0x1.8p+1").convertToDouble());
882 EXPECT_EQ(-3.0, APFloat(APFloat::IEEEdouble, "-0x1.8p+1").convertToDouble());
883
884 EXPECT_EQ( 0.75, APFloat(APFloat::IEEEdouble, "0x1.8p-1").convertToDouble());
885 EXPECT_EQ(+0.75, APFloat(APFloat::IEEEdouble, "+0x1.8p-1").convertToDouble());
886 EXPECT_EQ(-0.75, APFloat(APFloat::IEEEdouble, "-0x1.8p-1").convertToDouble());
887
888
889 EXPECT_EQ( 8192.0, APFloat(APFloat::IEEEdouble, "0x1000.000p1").convertToDouble());
890 EXPECT_EQ(+8192.0, APFloat(APFloat::IEEEdouble, "+0x1000.000p1").convertToDouble());
891 EXPECT_EQ(-8192.0, APFloat(APFloat::IEEEdouble, "-0x1000.000p1").convertToDouble());
892
893 EXPECT_EQ( 8192.0, APFloat(APFloat::IEEEdouble, "0x1000.000p+1").convertToDouble());
894 EXPECT_EQ(+8192.0, APFloat(APFloat::IEEEdouble, "+0x1000.000p+1").convertToDouble());
895 EXPECT_EQ(-8192.0, APFloat(APFloat::IEEEdouble, "-0x1000.000p+1").convertToDouble());
896
897 EXPECT_EQ( 2048.0, APFloat(APFloat::IEEEdouble, "0x1000.000p-1").convertToDouble());
898 EXPECT_EQ(+2048.0, APFloat(APFloat::IEEEdouble, "+0x1000.000p-1").convertToDouble());
899 EXPECT_EQ(-2048.0, APFloat(APFloat::IEEEdouble, "-0x1000.000p-1").convertToDouble());
900
901
902 EXPECT_EQ( 8192.0, APFloat(APFloat::IEEEdouble, "0x1000p1").convertToDouble());
903 EXPECT_EQ(+8192.0, APFloat(APFloat::IEEEdouble, "+0x1000p1").convertToDouble());
904 EXPECT_EQ(-8192.0, APFloat(APFloat::IEEEdouble, "-0x1000p1").convertToDouble());
905
906 EXPECT_EQ( 8192.0, APFloat(APFloat::IEEEdouble, "0x1000p+1").convertToDouble());
907 EXPECT_EQ(+8192.0, APFloat(APFloat::IEEEdouble, "+0x1000p+1").convertToDouble());
908 EXPECT_EQ(-8192.0, APFloat(APFloat::IEEEdouble, "-0x1000p+1").convertToDouble());
909
910 EXPECT_EQ( 2048.0, APFloat(APFloat::IEEEdouble, "0x1000p-1").convertToDouble());
911 EXPECT_EQ(+2048.0, APFloat(APFloat::IEEEdouble, "+0x1000p-1").convertToDouble());
912 EXPECT_EQ(-2048.0, APFloat(APFloat::IEEEdouble, "-0x1000p-1").convertToDouble());
913
914
915 EXPECT_EQ( 16384.0, APFloat(APFloat::IEEEdouble, "0x10p10").convertToDouble());
916 EXPECT_EQ(+16384.0, APFloat(APFloat::IEEEdouble, "+0x10p10").convertToDouble());
917 EXPECT_EQ(-16384.0, APFloat(APFloat::IEEEdouble, "-0x10p10").convertToDouble());
918
919 EXPECT_EQ( 16384.0, APFloat(APFloat::IEEEdouble, "0x10p+10").convertToDouble());
920 EXPECT_EQ(+16384.0, APFloat(APFloat::IEEEdouble, "+0x10p+10").convertToDouble());
921 EXPECT_EQ(-16384.0, APFloat(APFloat::IEEEdouble, "-0x10p+10").convertToDouble());
922
923 EXPECT_EQ( 0.015625, APFloat(APFloat::IEEEdouble, "0x10p-10").convertToDouble());
924 EXPECT_EQ(+0.015625, APFloat(APFloat::IEEEdouble, "+0x10p-10").convertToDouble());
925 EXPECT_EQ(-0.015625, APFloat(APFloat::IEEEdouble, "-0x10p-10").convertToDouble());
926
927 EXPECT_EQ(1.0625, APFloat(APFloat::IEEEdouble, "0x1.1p0").convertToDouble());
928 EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble, "0x1p0").convertToDouble());
Daniel Dunbarbc52e4f2009-09-03 22:57:02 +0000929
Eli Friedmand2eb07a2013-07-17 22:17:29 +0000930 EXPECT_EQ(convertToDoubleFromString("0x1p-150"),
931 convertToDoubleFromString("+0x800000000000000001.p-221"));
932 EXPECT_EQ(2251799813685248.5,
933 convertToDoubleFromString("0x80000000000004000000.010p-28"));
Erick Tryzelaar19f63b22009-08-16 23:36:19 +0000934}
935
John McCall29b5c282009-12-24 08:56:26 +0000936TEST(APFloatTest, toString) {
937 ASSERT_EQ("10", convertToString(10.0, 6, 3));
938 ASSERT_EQ("1.0E+1", convertToString(10.0, 6, 0));
939 ASSERT_EQ("10100", convertToString(1.01E+4, 5, 2));
940 ASSERT_EQ("1.01E+4", convertToString(1.01E+4, 4, 2));
941 ASSERT_EQ("1.01E+4", convertToString(1.01E+4, 5, 1));
942 ASSERT_EQ("0.0101", convertToString(1.01E-2, 5, 2));
John McCalldd5044a2009-12-24 23:18:09 +0000943 ASSERT_EQ("0.0101", convertToString(1.01E-2, 4, 2));
John McCall29b5c282009-12-24 08:56:26 +0000944 ASSERT_EQ("1.01E-2", convertToString(1.01E-2, 5, 1));
Eli Friedmane72f1322013-08-29 23:44:34 +0000945 ASSERT_EQ("0.78539816339744828", convertToString(0.78539816339744830961, 0, 3));
946 ASSERT_EQ("4.9406564584124654E-324", convertToString(4.9406564584124654e-324, 0, 3));
947 ASSERT_EQ("873.18340000000001", convertToString(873.1834, 0, 1));
948 ASSERT_EQ("8.7318340000000001E+2", convertToString(873.1834, 0, 0));
949 ASSERT_EQ("1.7976931348623157E+308", convertToString(1.7976931348623157E+308, 0, 0));
John McCall29b5c282009-12-24 08:56:26 +0000950}
951
Jeffrey Yasskin03b81a22011-07-15 07:04:56 +0000952TEST(APFloatTest, toInteger) {
953 bool isExact = false;
954 APSInt result(5, /*isUnsigned=*/true);
955
956 EXPECT_EQ(APFloat::opOK,
957 APFloat(APFloat::IEEEdouble, "10")
958 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
959 EXPECT_TRUE(isExact);
960 EXPECT_EQ(APSInt(APInt(5, 10), true), result);
961
962 EXPECT_EQ(APFloat::opInvalidOp,
963 APFloat(APFloat::IEEEdouble, "-10")
964 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
965 EXPECT_FALSE(isExact);
966 EXPECT_EQ(APSInt::getMinValue(5, true), result);
967
968 EXPECT_EQ(APFloat::opInvalidOp,
969 APFloat(APFloat::IEEEdouble, "32")
970 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
971 EXPECT_FALSE(isExact);
972 EXPECT_EQ(APSInt::getMaxValue(5, true), result);
973
974 EXPECT_EQ(APFloat::opInexact,
975 APFloat(APFloat::IEEEdouble, "7.9")
976 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
977 EXPECT_FALSE(isExact);
978 EXPECT_EQ(APSInt(APInt(5, 7), true), result);
979
980 result.setIsUnsigned(false);
981 EXPECT_EQ(APFloat::opOK,
982 APFloat(APFloat::IEEEdouble, "-10")
983 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
984 EXPECT_TRUE(isExact);
985 EXPECT_EQ(APSInt(APInt(5, -10, true), false), result);
986
987 EXPECT_EQ(APFloat::opInvalidOp,
988 APFloat(APFloat::IEEEdouble, "-17")
989 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
990 EXPECT_FALSE(isExact);
991 EXPECT_EQ(APSInt::getMinValue(5, false), result);
992
993 EXPECT_EQ(APFloat::opInvalidOp,
994 APFloat(APFloat::IEEEdouble, "16")
995 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
996 EXPECT_FALSE(isExact);
997 EXPECT_EQ(APSInt::getMaxValue(5, false), result);
998}
999
John McCalldcb9a7a2010-02-28 02:51:25 +00001000static APInt nanbits(const fltSemantics &Sem,
1001 bool SNaN, bool Negative, uint64_t fill) {
1002 APInt apfill(64, fill);
1003 if (SNaN)
1004 return APFloat::getSNaN(Sem, Negative, &apfill).bitcastToAPInt();
1005 else
1006 return APFloat::getQNaN(Sem, Negative, &apfill).bitcastToAPInt();
1007}
1008
1009TEST(APFloatTest, makeNaN) {
1010 ASSERT_EQ(0x7fc00000, nanbits(APFloat::IEEEsingle, false, false, 0));
1011 ASSERT_EQ(0xffc00000, nanbits(APFloat::IEEEsingle, false, true, 0));
1012 ASSERT_EQ(0x7fc0ae72, nanbits(APFloat::IEEEsingle, false, false, 0xae72));
1013 ASSERT_EQ(0x7fffae72, nanbits(APFloat::IEEEsingle, false, false, 0xffffae72));
1014 ASSERT_EQ(0x7fa00000, nanbits(APFloat::IEEEsingle, true, false, 0));
1015 ASSERT_EQ(0xffa00000, nanbits(APFloat::IEEEsingle, true, true, 0));
1016 ASSERT_EQ(0x7f80ae72, nanbits(APFloat::IEEEsingle, true, false, 0xae72));
1017 ASSERT_EQ(0x7fbfae72, nanbits(APFloat::IEEEsingle, true, false, 0xffffae72));
1018
1019 ASSERT_EQ(0x7ff8000000000000ULL, nanbits(APFloat::IEEEdouble, false, false, 0));
1020 ASSERT_EQ(0xfff8000000000000ULL, nanbits(APFloat::IEEEdouble, false, true, 0));
1021 ASSERT_EQ(0x7ff800000000ae72ULL, nanbits(APFloat::IEEEdouble, false, false, 0xae72));
1022 ASSERT_EQ(0x7fffffffffffae72ULL, nanbits(APFloat::IEEEdouble, false, false, 0xffffffffffffae72ULL));
1023 ASSERT_EQ(0x7ff4000000000000ULL, nanbits(APFloat::IEEEdouble, true, false, 0));
1024 ASSERT_EQ(0xfff4000000000000ULL, nanbits(APFloat::IEEEdouble, true, true, 0));
1025 ASSERT_EQ(0x7ff000000000ae72ULL, nanbits(APFloat::IEEEdouble, true, false, 0xae72));
1026 ASSERT_EQ(0x7ff7ffffffffae72ULL, nanbits(APFloat::IEEEdouble, true, false, 0xffffffffffffae72ULL));
1027}
1028
Erick Tryzelaar927191f2009-08-17 00:55:33 +00001029#ifdef GTEST_HAS_DEATH_TEST
Jeffrey Yasskinb5cd0132010-03-17 01:18:45 +00001030#ifndef NDEBUG
Erick Tryzelaar927191f2009-08-17 00:55:33 +00001031TEST(APFloatTest, SemanticsDeath) {
1032 EXPECT_DEATH(APFloat(APFloat::IEEEsingle, 0.0f).convertToDouble(), "Float semantics are not IEEEdouble");
1033 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, 0.0 ).convertToFloat(), "Float semantics are not IEEEsingle");
1034}
1035
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001036TEST(APFloatTest, StringDecimalDeath) {
1037 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, ""), "Invalid string length");
1038 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+"), "String has no digits");
1039 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-"), "String has no digits");
Erick Tryzelaar19f63b22009-08-16 23:36:19 +00001040
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001041 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("\0", 1)), "Invalid character in significand");
1042 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("1\0", 2)), "Invalid character in significand");
1043 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("1\02", 3)), "Invalid character in significand");
1044 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("1\02e1", 5)), "Invalid character in significand");
Erick Tryzelaarbc0d7492009-08-17 00:14:11 +00001045 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("1e\0", 3)), "Invalid character in exponent");
1046 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("1e1\0", 4)), "Invalid character in exponent");
1047 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("1e1\02", 5)), "Invalid character in exponent");
Erick Tryzelaar19f63b22009-08-16 23:36:19 +00001048
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001049 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "1.0f"), "Invalid character in significand");
Erick Tryzelaar19f63b22009-08-16 23:36:19 +00001050
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001051 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, ".."), "String contains multiple dots");
1052 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "..0"), "String contains multiple dots");
1053 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "1.0.0"), "String contains multiple dots");
1054}
1055
1056TEST(APFloatTest, StringDecimalSignificandDeath) {
1057 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "."), "Significand has no digits");
1058 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+."), "Significand has no digits");
1059 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-."), "Significand has no digits");
1060
1061
1062 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "e"), "Significand has no digits");
1063 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+e"), "Significand has no digits");
1064 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-e"), "Significand has no digits");
1065
1066 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "e1"), "Significand has no digits");
1067 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+e1"), "Significand has no digits");
1068 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-e1"), "Significand has no digits");
1069
1070 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, ".e1"), "Significand has no digits");
1071 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+.e1"), "Significand has no digits");
1072 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-.e1"), "Significand has no digits");
1073
1074
1075 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, ".e"), "Significand has no digits");
1076 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+.e"), "Significand has no digits");
1077 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-.e"), "Significand has no digits");
1078}
1079
1080TEST(APFloatTest, StringDecimalExponentDeath) {
1081 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "1e"), "Exponent has no digits");
1082 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+1e"), "Exponent has no digits");
1083 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-1e"), "Exponent has no digits");
1084
1085 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "1.e"), "Exponent has no digits");
1086 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+1.e"), "Exponent has no digits");
1087 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-1.e"), "Exponent has no digits");
1088
1089 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, ".1e"), "Exponent has no digits");
1090 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+.1e"), "Exponent has no digits");
1091 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-.1e"), "Exponent has no digits");
1092
1093 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "1.1e"), "Exponent has no digits");
1094 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+1.1e"), "Exponent has no digits");
1095 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-1.1e"), "Exponent has no digits");
1096
1097
1098 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "1e+"), "Exponent has no digits");
1099 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "1e-"), "Exponent has no digits");
1100
1101 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, ".1e"), "Exponent has no digits");
1102 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, ".1e+"), "Exponent has no digits");
1103 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, ".1e-"), "Exponent has no digits");
1104
1105 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "1.0e"), "Exponent has no digits");
1106 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "1.0e+"), "Exponent has no digits");
1107 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "1.0e-"), "Exponent has no digits");
1108}
1109
1110TEST(APFloatTest, StringHexadecimalDeath) {
1111 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x"), "Invalid string");
1112 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x"), "Invalid string");
1113 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x"), "Invalid string");
1114
1115 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x0"), "Hex strings require an exponent");
1116 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x0"), "Hex strings require an exponent");
1117 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x0"), "Hex strings require an exponent");
1118
1119 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x0."), "Hex strings require an exponent");
1120 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x0."), "Hex strings require an exponent");
1121 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x0."), "Hex strings require an exponent");
1122
1123 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x.0"), "Hex strings require an exponent");
1124 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x.0"), "Hex strings require an exponent");
1125 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x.0"), "Hex strings require an exponent");
1126
1127 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x0.0"), "Hex strings require an exponent");
1128 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x0.0"), "Hex strings require an exponent");
1129 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x0.0"), "Hex strings require an exponent");
1130
1131 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("0x\0", 3)), "Invalid character in significand");
1132 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("0x1\0", 4)), "Invalid character in significand");
1133 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("0x1\02", 5)), "Invalid character in significand");
1134 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("0x1\02p1", 7)), "Invalid character in significand");
Erick Tryzelaarbc0d7492009-08-17 00:14:11 +00001135 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("0x1p\0", 5)), "Invalid character in exponent");
1136 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("0x1p1\0", 6)), "Invalid character in exponent");
1137 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("0x1p1\02", 7)), "Invalid character in exponent");
Erick Tryzelaar19f63b22009-08-16 23:36:19 +00001138
Erick Tryzelaarbc0d7492009-08-17 00:14:11 +00001139 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x1p0f"), "Invalid character in exponent");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001140
1141 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x..p1"), "String contains multiple dots");
1142 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x..0p1"), "String contains multiple dots");
1143 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x1.0.0p1"), "String contains multiple dots");
1144}
1145
1146TEST(APFloatTest, StringHexadecimalSignificandDeath) {
1147 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x."), "Significand has no digits");
1148 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x."), "Significand has no digits");
1149 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x."), "Significand has no digits");
1150
1151 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0xp"), "Significand has no digits");
1152 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0xp"), "Significand has no digits");
1153 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0xp"), "Significand has no digits");
1154
1155 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0xp+"), "Significand has no digits");
1156 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0xp+"), "Significand has no digits");
1157 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0xp+"), "Significand has no digits");
1158
1159 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0xp-"), "Significand has no digits");
1160 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0xp-"), "Significand has no digits");
1161 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0xp-"), "Significand has no digits");
1162
1163
1164 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x.p"), "Significand has no digits");
1165 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x.p"), "Significand has no digits");
1166 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x.p"), "Significand has no digits");
1167
1168 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x.p+"), "Significand has no digits");
1169 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x.p+"), "Significand has no digits");
1170 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x.p+"), "Significand has no digits");
1171
1172 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x.p-"), "Significand has no digits");
1173 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x.p-"), "Significand has no digits");
1174 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x.p-"), "Significand has no digits");
1175}
1176
1177TEST(APFloatTest, StringHexadecimalExponentDeath) {
1178 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x1p"), "Exponent has no digits");
1179 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x1p"), "Exponent has no digits");
1180 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x1p"), "Exponent has no digits");
1181
1182 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x1p+"), "Exponent has no digits");
1183 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x1p+"), "Exponent has no digits");
1184 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x1p+"), "Exponent has no digits");
1185
1186 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x1p-"), "Exponent has no digits");
1187 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x1p-"), "Exponent has no digits");
1188 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x1p-"), "Exponent has no digits");
1189
1190
1191 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x1.p"), "Exponent has no digits");
1192 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x1.p"), "Exponent has no digits");
1193 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x1.p"), "Exponent has no digits");
1194
1195 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x1.p+"), "Exponent has no digits");
1196 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x1.p+"), "Exponent has no digits");
1197 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x1.p+"), "Exponent has no digits");
1198
1199 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x1.p-"), "Exponent has no digits");
1200 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x1.p-"), "Exponent has no digits");
1201 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x1.p-"), "Exponent has no digits");
1202
1203
1204 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x.1p"), "Exponent has no digits");
1205 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x.1p"), "Exponent has no digits");
1206 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x.1p"), "Exponent has no digits");
1207
1208 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x.1p+"), "Exponent has no digits");
1209 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x.1p+"), "Exponent has no digits");
1210 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x.1p+"), "Exponent has no digits");
1211
1212 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x.1p-"), "Exponent has no digits");
1213 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x.1p-"), "Exponent has no digits");
1214 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x.1p-"), "Exponent has no digits");
1215
1216
1217 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x1.1p"), "Exponent has no digits");
1218 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x1.1p"), "Exponent has no digits");
1219 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x1.1p"), "Exponent has no digits");
1220
1221 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x1.1p+"), "Exponent has no digits");
1222 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x1.1p+"), "Exponent has no digits");
1223 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x1.1p+"), "Exponent has no digits");
1224
1225 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x1.1p-"), "Exponent has no digits");
1226 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x1.1p-"), "Exponent has no digits");
1227 EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x1.1p-"), "Exponent has no digits");
Erick Tryzelaar19f63b22009-08-16 23:36:19 +00001228}
Erick Tryzelaar927191f2009-08-17 00:55:33 +00001229#endif
Jeffrey Yasskinb5cd0132010-03-17 01:18:45 +00001230#endif
Erick Tryzelaar19f63b22009-08-16 23:36:19 +00001231
Benjamin Kramer03fd6722011-03-30 15:42:27 +00001232TEST(APFloatTest, exactInverse) {
1233 APFloat inv(0.0f);
1234
1235 // Trivial operation.
1236 EXPECT_TRUE(APFloat(2.0).getExactInverse(&inv));
1237 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(0.5)));
1238 EXPECT_TRUE(APFloat(2.0f).getExactInverse(&inv));
1239 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(0.5f)));
Benjamin Kramer08be41a2012-11-08 13:58:10 +00001240 EXPECT_TRUE(APFloat(APFloat::IEEEquad, "2.0").getExactInverse(&inv));
1241 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(APFloat::IEEEquad, "0.5")));
1242 EXPECT_TRUE(APFloat(APFloat::PPCDoubleDouble, "2.0").getExactInverse(&inv));
1243 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(APFloat::PPCDoubleDouble, "0.5")));
1244 EXPECT_TRUE(APFloat(APFloat::x87DoubleExtended, "2.0").getExactInverse(&inv));
1245 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(APFloat::x87DoubleExtended, "0.5")));
Benjamin Kramer03fd6722011-03-30 15:42:27 +00001246
1247 // FLT_MIN
1248 EXPECT_TRUE(APFloat(1.17549435e-38f).getExactInverse(&inv));
1249 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(8.5070592e+37f)));
1250
Benjamin Krameraf0ed952011-03-30 17:02:54 +00001251 // Large float, inverse is a denormal.
Craig Topper66f09ad2014-06-08 22:29:17 +00001252 EXPECT_FALSE(APFloat(1.7014118e38f).getExactInverse(nullptr));
Benjamin Kramer03fd6722011-03-30 15:42:27 +00001253 // Zero
Craig Topper66f09ad2014-06-08 22:29:17 +00001254 EXPECT_FALSE(APFloat(0.0).getExactInverse(nullptr));
Benjamin Kramer03fd6722011-03-30 15:42:27 +00001255 // Denormalized float
Craig Topper66f09ad2014-06-08 22:29:17 +00001256 EXPECT_FALSE(APFloat(1.40129846e-45f).getExactInverse(nullptr));
Benjamin Kramer03fd6722011-03-30 15:42:27 +00001257}
1258
Owen Anderson1ff74b02012-08-15 05:39:46 +00001259TEST(APFloatTest, roundToIntegral) {
Owen Anderson352dfff2012-08-15 18:28:45 +00001260 APFloat T(-0.5), S(3.14), R(APFloat::getLargest(APFloat::IEEEdouble)), P(0.0);
Owen Anderson1ff74b02012-08-15 05:39:46 +00001261
1262 P = T;
1263 P.roundToIntegral(APFloat::rmTowardZero);
1264 EXPECT_EQ(-0.0, P.convertToDouble());
1265 P = T;
1266 P.roundToIntegral(APFloat::rmTowardNegative);
1267 EXPECT_EQ(-1.0, P.convertToDouble());
1268 P = T;
1269 P.roundToIntegral(APFloat::rmTowardPositive);
1270 EXPECT_EQ(-0.0, P.convertToDouble());
1271 P = T;
1272 P.roundToIntegral(APFloat::rmNearestTiesToEven);
1273 EXPECT_EQ(-0.0, P.convertToDouble());
1274
1275 P = S;
1276 P.roundToIntegral(APFloat::rmTowardZero);
1277 EXPECT_EQ(3.0, P.convertToDouble());
1278 P = S;
1279 P.roundToIntegral(APFloat::rmTowardNegative);
1280 EXPECT_EQ(3.0, P.convertToDouble());
1281 P = S;
1282 P.roundToIntegral(APFloat::rmTowardPositive);
1283 EXPECT_EQ(4.0, P.convertToDouble());
1284 P = S;
1285 P.roundToIntegral(APFloat::rmNearestTiesToEven);
1286 EXPECT_EQ(3.0, P.convertToDouble());
Owen Anderson352dfff2012-08-15 18:28:45 +00001287
1288 P = R;
1289 P.roundToIntegral(APFloat::rmTowardZero);
1290 EXPECT_EQ(R.convertToDouble(), P.convertToDouble());
1291 P = R;
1292 P.roundToIntegral(APFloat::rmTowardNegative);
1293 EXPECT_EQ(R.convertToDouble(), P.convertToDouble());
1294 P = R;
1295 P.roundToIntegral(APFloat::rmTowardPositive);
1296 EXPECT_EQ(R.convertToDouble(), P.convertToDouble());
1297 P = R;
1298 P.roundToIntegral(APFloat::rmNearestTiesToEven);
1299 EXPECT_EQ(R.convertToDouble(), P.convertToDouble());
Benjamin Kramerc38fab22012-09-26 14:06:58 +00001300
1301 P = APFloat::getZero(APFloat::IEEEdouble);
1302 P.roundToIntegral(APFloat::rmTowardZero);
1303 EXPECT_EQ(0.0, P.convertToDouble());
1304 P = APFloat::getZero(APFloat::IEEEdouble, true);
1305 P.roundToIntegral(APFloat::rmTowardZero);
1306 EXPECT_EQ(-0.0, P.convertToDouble());
1307 P = APFloat::getNaN(APFloat::IEEEdouble);
1308 P.roundToIntegral(APFloat::rmTowardZero);
Benjamin Kramer37dce442015-03-09 18:35:18 +00001309 EXPECT_TRUE(std::isnan(P.convertToDouble()));
Benjamin Kramerc38fab22012-09-26 14:06:58 +00001310 P = APFloat::getInf(APFloat::IEEEdouble);
1311 P.roundToIntegral(APFloat::rmTowardZero);
Benjamin Kramer37dce442015-03-09 18:35:18 +00001312 EXPECT_TRUE(std::isinf(P.convertToDouble()) && P.convertToDouble() > 0.0);
Benjamin Kramerc38fab22012-09-26 14:06:58 +00001313 P = APFloat::getInf(APFloat::IEEEdouble, true);
1314 P.roundToIntegral(APFloat::rmTowardZero);
Benjamin Kramer37dce442015-03-09 18:35:18 +00001315 EXPECT_TRUE(std::isinf(P.convertToDouble()) && P.convertToDouble() < 0.0);
Benjamin Kramerc38fab22012-09-26 14:06:58 +00001316
Owen Anderson1ff74b02012-08-15 05:39:46 +00001317}
1318
Eli Friedmanc5322012011-10-12 21:51:36 +00001319TEST(APFloatTest, getLargest) {
Eli Friedman212e4472011-10-12 23:14:41 +00001320 EXPECT_EQ(3.402823466e+38f, APFloat::getLargest(APFloat::IEEEsingle).convertToFloat());
1321 EXPECT_EQ(1.7976931348623158e+308, APFloat::getLargest(APFloat::IEEEdouble).convertToDouble());
Eli Friedmanc5322012011-10-12 21:51:36 +00001322}
1323
Michael Gottesman63e6d212013-05-29 23:58:29 +00001324TEST(APFloatTest, getSmallest) {
1325 APFloat test = APFloat::getSmallest(APFloat::IEEEsingle, false);
1326 APFloat expected = APFloat(APFloat::IEEEsingle, "0x0.000002p-126");
Michael Gottesman5455d5b2013-05-30 00:18:44 +00001327 EXPECT_FALSE(test.isNegative());
Michael Gottesmanb5101ab2013-06-19 21:53:45 +00001328 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman5455d5b2013-05-30 00:18:44 +00001329 EXPECT_TRUE(test.isDenormal());
Michael Gottesman63e6d212013-05-29 23:58:29 +00001330 EXPECT_TRUE(test.bitwiseIsEqual(expected));
1331
1332 test = APFloat::getSmallest(APFloat::IEEEsingle, true);
1333 expected = APFloat(APFloat::IEEEsingle, "-0x0.000002p-126");
1334 EXPECT_TRUE(test.isNegative());
Michael Gottesmanb5101ab2013-06-19 21:53:45 +00001335 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman5455d5b2013-05-30 00:18:44 +00001336 EXPECT_TRUE(test.isDenormal());
Michael Gottesman63e6d212013-05-29 23:58:29 +00001337 EXPECT_TRUE(test.bitwiseIsEqual(expected));
1338
1339 test = APFloat::getSmallest(APFloat::IEEEquad, false);
1340 expected = APFloat(APFloat::IEEEquad, "0x0.0000000000000000000000000001p-16382");
Michael Gottesman5455d5b2013-05-30 00:18:44 +00001341 EXPECT_FALSE(test.isNegative());
Michael Gottesmanb5101ab2013-06-19 21:53:45 +00001342 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman5455d5b2013-05-30 00:18:44 +00001343 EXPECT_TRUE(test.isDenormal());
Michael Gottesman63e6d212013-05-29 23:58:29 +00001344 EXPECT_TRUE(test.bitwiseIsEqual(expected));
1345
1346 test = APFloat::getSmallest(APFloat::IEEEquad, true);
1347 expected = APFloat(APFloat::IEEEquad, "-0x0.0000000000000000000000000001p-16382");
1348 EXPECT_TRUE(test.isNegative());
Michael Gottesmanb5101ab2013-06-19 21:53:45 +00001349 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman5455d5b2013-05-30 00:18:44 +00001350 EXPECT_TRUE(test.isDenormal());
Michael Gottesmanf9899292013-06-24 09:58:09 +00001351 EXPECT_TRUE(test.bitwiseIsEqual(expected));
Michael Gottesman63e6d212013-05-29 23:58:29 +00001352}
1353
Michael Gottesman0db7c272013-05-30 00:18:47 +00001354TEST(APFloatTest, getSmallestNormalized) {
1355 APFloat test = APFloat::getSmallestNormalized(APFloat::IEEEsingle, false);
1356 APFloat expected = APFloat(APFloat::IEEEsingle, "0x1p-126");
1357 EXPECT_FALSE(test.isNegative());
Michael Gottesmanb5101ab2013-06-19 21:53:45 +00001358 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman0db7c272013-05-30 00:18:47 +00001359 EXPECT_FALSE(test.isDenormal());
1360 EXPECT_TRUE(test.bitwiseIsEqual(expected));
1361
1362 test = APFloat::getSmallestNormalized(APFloat::IEEEsingle, true);
1363 expected = APFloat(APFloat::IEEEsingle, "-0x1p-126");
1364 EXPECT_TRUE(test.isNegative());
Michael Gottesmanb5101ab2013-06-19 21:53:45 +00001365 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman0db7c272013-05-30 00:18:47 +00001366 EXPECT_FALSE(test.isDenormal());
1367 EXPECT_TRUE(test.bitwiseIsEqual(expected));
1368
1369 test = APFloat::getSmallestNormalized(APFloat::IEEEquad, false);
1370 expected = APFloat(APFloat::IEEEquad, "0x1p-16382");
1371 EXPECT_FALSE(test.isNegative());
Michael Gottesmanb5101ab2013-06-19 21:53:45 +00001372 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman0db7c272013-05-30 00:18:47 +00001373 EXPECT_FALSE(test.isDenormal());
1374 EXPECT_TRUE(test.bitwiseIsEqual(expected));
1375
1376 test = APFloat::getSmallestNormalized(APFloat::IEEEquad, true);
1377 expected = APFloat(APFloat::IEEEquad, "-0x1p-16382");
1378 EXPECT_TRUE(test.isNegative());
Michael Gottesmanb5101ab2013-06-19 21:53:45 +00001379 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman0db7c272013-05-30 00:18:47 +00001380 EXPECT_FALSE(test.isDenormal());
Michael Gottesmanf9899292013-06-24 09:58:09 +00001381 EXPECT_TRUE(test.bitwiseIsEqual(expected));
Michael Gottesman0db7c272013-05-30 00:18:47 +00001382}
1383
Michael Gottesmanfc718c92013-05-31 18:43:34 +00001384TEST(APFloatTest, getZero) {
1385 struct {
1386 const fltSemantics *semantics;
1387 const bool sign;
1388 const unsigned long long bitPattern[2];
1389 const unsigned bitPatternLength;
Benjamin Kramer0bb474f2013-06-01 22:29:41 +00001390 } const GetZeroTest[] = {
Michael Gottesmanfc718c92013-05-31 18:43:34 +00001391 { &APFloat::IEEEhalf, false, {0, 0}, 1},
Benjamin Kramer0bb474f2013-06-01 22:29:41 +00001392 { &APFloat::IEEEhalf, true, {0x8000ULL, 0}, 1},
Michael Gottesmanfc718c92013-05-31 18:43:34 +00001393 { &APFloat::IEEEsingle, false, {0, 0}, 1},
Benjamin Kramer0bb474f2013-06-01 22:29:41 +00001394 { &APFloat::IEEEsingle, true, {0x80000000ULL, 0}, 1},
Michael Gottesmanfc718c92013-05-31 18:43:34 +00001395 { &APFloat::IEEEdouble, false, {0, 0}, 1},
Benjamin Kramer0bb474f2013-06-01 22:29:41 +00001396 { &APFloat::IEEEdouble, true, {0x8000000000000000ULL, 0}, 1},
Michael Gottesmanfc718c92013-05-31 18:43:34 +00001397 { &APFloat::IEEEquad, false, {0, 0}, 2},
Benjamin Kramer0bb474f2013-06-01 22:29:41 +00001398 { &APFloat::IEEEquad, true, {0, 0x8000000000000000ULL}, 2},
Michael Gottesmanfc718c92013-05-31 18:43:34 +00001399 { &APFloat::PPCDoubleDouble, false, {0, 0}, 2},
Benjamin Kramer0bb474f2013-06-01 22:29:41 +00001400 { &APFloat::PPCDoubleDouble, true, {0x8000000000000000ULL, 0}, 2},
Michael Gottesmanfc718c92013-05-31 18:43:34 +00001401 { &APFloat::x87DoubleExtended, false, {0, 0}, 2},
Benjamin Kramer0bb474f2013-06-01 22:29:41 +00001402 { &APFloat::x87DoubleExtended, true, {0, 0x8000ULL}, 2},
Michael Gottesmanfc718c92013-05-31 18:43:34 +00001403 };
1404 const unsigned NumGetZeroTests = 12;
1405 for (unsigned i = 0; i < NumGetZeroTests; ++i) {
1406 APFloat test = APFloat::getZero(*GetZeroTest[i].semantics,
1407 GetZeroTest[i].sign);
1408 const char *pattern = GetZeroTest[i].sign? "-0x0p+0" : "0x0p+0";
1409 APFloat expected = APFloat(*GetZeroTest[i].semantics,
1410 pattern);
1411 EXPECT_TRUE(test.isZero());
1412 EXPECT_TRUE(GetZeroTest[i].sign? test.isNegative() : !test.isNegative());
1413 EXPECT_TRUE(test.bitwiseIsEqual(expected));
1414 for (unsigned j = 0, je = GetZeroTest[i].bitPatternLength; j < je; ++j) {
1415 EXPECT_EQ(GetZeroTest[i].bitPattern[j],
1416 test.bitcastToAPInt().getRawData()[j]);
1417 }
1418 }
1419}
1420
Chandler Carruthdf782e42014-10-09 23:26:15 +00001421TEST(APFloatTest, copySign) {
1422 EXPECT_TRUE(APFloat(-42.0).bitwiseIsEqual(
1423 APFloat::copySign(APFloat(42.0), APFloat(-1.0))));
1424 EXPECT_TRUE(APFloat(42.0).bitwiseIsEqual(
1425 APFloat::copySign(APFloat(-42.0), APFloat(1.0))));
1426 EXPECT_TRUE(APFloat(-42.0).bitwiseIsEqual(
1427 APFloat::copySign(APFloat(-42.0), APFloat(-1.0))));
1428 EXPECT_TRUE(APFloat(42.0).bitwiseIsEqual(
1429 APFloat::copySign(APFloat(42.0), APFloat(1.0))));
1430}
1431
Eli Friedmana84ad7d2011-11-26 03:38:02 +00001432TEST(APFloatTest, convert) {
1433 bool losesInfo;
1434 APFloat test(APFloat::IEEEdouble, "1.0");
1435 test.convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven, &losesInfo);
1436 EXPECT_EQ(1.0f, test.convertToFloat());
1437 EXPECT_FALSE(losesInfo);
1438
1439 test = APFloat(APFloat::x87DoubleExtended, "0x1p-53");
1440 test.add(APFloat(APFloat::x87DoubleExtended, "1.0"), APFloat::rmNearestTiesToEven);
1441 test.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &losesInfo);
1442 EXPECT_EQ(1.0, test.convertToDouble());
1443 EXPECT_TRUE(losesInfo);
1444
1445 test = APFloat(APFloat::IEEEquad, "0x1p-53");
1446 test.add(APFloat(APFloat::IEEEquad, "1.0"), APFloat::rmNearestTiesToEven);
1447 test.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &losesInfo);
1448 EXPECT_EQ(1.0, test.convertToDouble());
1449 EXPECT_TRUE(losesInfo);
1450
1451 test = APFloat(APFloat::x87DoubleExtended, "0xf.fffffffp+28");
1452 test.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &losesInfo);
1453 EXPECT_EQ(4294967295.0, test.convertToDouble());
1454 EXPECT_FALSE(losesInfo);
Benjamin Kramerb361adb2013-01-25 17:01:00 +00001455
1456 test = APFloat::getSNaN(APFloat::IEEEsingle);
1457 APFloat X87SNaN = APFloat::getSNaN(APFloat::x87DoubleExtended);
1458 test.convert(APFloat::x87DoubleExtended, APFloat::rmNearestTiesToEven,
1459 &losesInfo);
1460 EXPECT_TRUE(test.bitwiseIsEqual(X87SNaN));
1461 EXPECT_FALSE(losesInfo);
1462
1463 test = APFloat::getQNaN(APFloat::IEEEsingle);
1464 APFloat X87QNaN = APFloat::getQNaN(APFloat::x87DoubleExtended);
1465 test.convert(APFloat::x87DoubleExtended, APFloat::rmNearestTiesToEven,
1466 &losesInfo);
1467 EXPECT_TRUE(test.bitwiseIsEqual(X87QNaN));
1468 EXPECT_FALSE(losesInfo);
1469
1470 test = APFloat::getSNaN(APFloat::x87DoubleExtended);
1471 test.convert(APFloat::x87DoubleExtended, APFloat::rmNearestTiesToEven,
1472 &losesInfo);
1473 EXPECT_TRUE(test.bitwiseIsEqual(X87SNaN));
1474 EXPECT_FALSE(losesInfo);
1475
1476 test = APFloat::getQNaN(APFloat::x87DoubleExtended);
1477 test.convert(APFloat::x87DoubleExtended, APFloat::rmNearestTiesToEven,
1478 &losesInfo);
1479 EXPECT_TRUE(test.bitwiseIsEqual(X87QNaN));
1480 EXPECT_FALSE(losesInfo);
Eli Friedmana84ad7d2011-11-26 03:38:02 +00001481}
Ulrich Weigandd9f7e252012-10-29 18:09:01 +00001482
1483TEST(APFloatTest, PPCDoubleDouble) {
1484 APFloat test(APFloat::PPCDoubleDouble, "1.0");
1485 EXPECT_EQ(0x3ff0000000000000ull, test.bitcastToAPInt().getRawData()[0]);
1486 EXPECT_EQ(0x0000000000000000ull, test.bitcastToAPInt().getRawData()[1]);
1487
1488 test.divide(APFloat(APFloat::PPCDoubleDouble, "3.0"), APFloat::rmNearestTiesToEven);
1489 EXPECT_EQ(0x3fd5555555555555ull, test.bitcastToAPInt().getRawData()[0]);
1490 EXPECT_EQ(0x3c75555555555556ull, test.bitcastToAPInt().getRawData()[1]);
1491
1492 // LDBL_MAX
1493 test = APFloat(APFloat::PPCDoubleDouble, "1.79769313486231580793728971405301e+308");
1494 EXPECT_EQ(0x7fefffffffffffffull, test.bitcastToAPInt().getRawData()[0]);
1495 EXPECT_EQ(0x7c8ffffffffffffeull, test.bitcastToAPInt().getRawData()[1]);
1496
1497 // LDBL_MIN
1498 test = APFloat(APFloat::PPCDoubleDouble, "2.00416836000897277799610805135016e-292");
1499 EXPECT_EQ(0x0360000000000000ull, test.bitcastToAPInt().getRawData()[0]);
1500 EXPECT_EQ(0x0000000000000000ull, test.bitcastToAPInt().getRawData()[1]);
1501
1502 test = APFloat(APFloat::PPCDoubleDouble, "1.0");
1503 test.add(APFloat(APFloat::PPCDoubleDouble, "0x1p-105"), APFloat::rmNearestTiesToEven);
1504 EXPECT_EQ(0x3ff0000000000000ull, test.bitcastToAPInt().getRawData()[0]);
1505 EXPECT_EQ(0x3960000000000000ull, test.bitcastToAPInt().getRawData()[1]);
1506
1507 test = APFloat(APFloat::PPCDoubleDouble, "1.0");
1508 test.add(APFloat(APFloat::PPCDoubleDouble, "0x1p-106"), APFloat::rmNearestTiesToEven);
1509 EXPECT_EQ(0x3ff0000000000000ull, test.bitcastToAPInt().getRawData()[0]);
1510#if 0 // XFAIL
1511 // This is what we would expect with a true double-double implementation
1512 EXPECT_EQ(0x3950000000000000ull, test.bitcastToAPInt().getRawData()[1]);
1513#else
1514 // This is what we get with our 106-bit mantissa approximation
1515 EXPECT_EQ(0x0000000000000000ull, test.bitcastToAPInt().getRawData()[1]);
1516#endif
1517}
Michael Gottesman3acedb62013-06-04 03:46:25 +00001518
1519TEST(APFloatTest, isNegative) {
1520 APFloat t(APFloat::IEEEsingle, "0x1p+0");
1521 EXPECT_FALSE(t.isNegative());
1522 t = APFloat(APFloat::IEEEsingle, "-0x1p+0");
1523 EXPECT_TRUE(t.isNegative());
Michael Gottesmanf9899292013-06-24 09:58:09 +00001524
Michael Gottesman3acedb62013-06-04 03:46:25 +00001525 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle, false).isNegative());
1526 EXPECT_TRUE(APFloat::getInf(APFloat::IEEEsingle, true).isNegative());
Michael Gottesmanf9899292013-06-24 09:58:09 +00001527
Michael Gottesman3acedb62013-06-04 03:46:25 +00001528 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle, false).isNegative());
1529 EXPECT_TRUE(APFloat::getZero(APFloat::IEEEsingle, true).isNegative());
1530
1531 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle, false).isNegative());
1532 EXPECT_TRUE(APFloat::getNaN(APFloat::IEEEsingle, true).isNegative());
1533
1534 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle, false).isNegative());
1535 EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle, true).isNegative());
1536}
1537
Michael Gottesman120c92882013-06-20 18:34:38 +00001538TEST(APFloatTest, isNormal) {
Michael Gottesman3acedb62013-06-04 03:46:25 +00001539 APFloat t(APFloat::IEEEsingle, "0x1p+0");
Michael Gottesman120c92882013-06-20 18:34:38 +00001540 EXPECT_TRUE(t.isNormal());
Michael Gottesmanf9899292013-06-24 09:58:09 +00001541
Michael Gottesman120c92882013-06-20 18:34:38 +00001542 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle, false).isNormal());
1543 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle, false).isNormal());
1544 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle, false).isNormal());
Michael Gottesmanf9899292013-06-24 09:58:09 +00001545 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle, false).isNormal());
Michael Gottesman120c92882013-06-20 18:34:38 +00001546 EXPECT_FALSE(APFloat(APFloat::IEEEsingle, "0x1p-149").isNormal());
Michael Gottesman3acedb62013-06-04 03:46:25 +00001547}
1548
1549TEST(APFloatTest, isFinite) {
1550 APFloat t(APFloat::IEEEsingle, "0x1p+0");
Michael Gottesmanf9899292013-06-24 09:58:09 +00001551 EXPECT_TRUE(t.isFinite());
Michael Gottesman3acedb62013-06-04 03:46:25 +00001552 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle, false).isFinite());
1553 EXPECT_TRUE(APFloat::getZero(APFloat::IEEEsingle, false).isFinite());
1554 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle, false).isFinite());
Michael Gottesmanf9899292013-06-24 09:58:09 +00001555 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle, false).isFinite());
1556 EXPECT_TRUE(APFloat(APFloat::IEEEsingle, "0x1p-149").isFinite());
Michael Gottesman3acedb62013-06-04 03:46:25 +00001557}
1558
1559TEST(APFloatTest, isInfinity) {
1560 APFloat t(APFloat::IEEEsingle, "0x1p+0");
1561 EXPECT_FALSE(t.isInfinity());
1562 EXPECT_TRUE(APFloat::getInf(APFloat::IEEEsingle, false).isInfinity());
1563 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle, false).isInfinity());
1564 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle, false).isInfinity());
Michael Gottesmanf9899292013-06-24 09:58:09 +00001565 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle, false).isInfinity());
Michael Gottesmand7c05612013-06-20 18:25:16 +00001566 EXPECT_FALSE(APFloat(APFloat::IEEEsingle, "0x1p-149").isInfinity());
Michael Gottesman3acedb62013-06-04 03:46:25 +00001567}
1568
1569TEST(APFloatTest, isNaN) {
1570 APFloat t(APFloat::IEEEsingle, "0x1p+0");
Michael Gottesmanf9899292013-06-24 09:58:09 +00001571 EXPECT_FALSE(t.isNaN());
Michael Gottesman3acedb62013-06-04 03:46:25 +00001572 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle, false).isNaN());
1573 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle, false).isNaN());
1574 EXPECT_TRUE(APFloat::getNaN(APFloat::IEEEsingle, false).isNaN());
Michael Gottesmanf9899292013-06-24 09:58:09 +00001575 EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle, false).isNaN());
Michael Gottesmand7c05612013-06-20 18:25:16 +00001576 EXPECT_FALSE(APFloat(APFloat::IEEEsingle, "0x1p-149").isNaN());
Michael Gottesman3acedb62013-06-04 03:46:25 +00001577}
1578
Michael Gottesmand95d4472013-06-19 21:00:17 +00001579TEST(APFloatTest, isFiniteNonZero) {
1580 // Test positive/negative normal value.
1581 EXPECT_TRUE(APFloat(APFloat::IEEEsingle, "0x1p+0").isFiniteNonZero());
1582 EXPECT_TRUE(APFloat(APFloat::IEEEsingle, "-0x1p+0").isFiniteNonZero());
1583
1584 // Test positive/negative denormal value.
1585 EXPECT_TRUE(APFloat(APFloat::IEEEsingle, "0x1p-149").isFiniteNonZero());
1586 EXPECT_TRUE(APFloat(APFloat::IEEEsingle, "-0x1p-149").isFiniteNonZero());
1587
1588 // Test +/- Infinity.
1589 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle, false).isFiniteNonZero());
1590 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle, true).isFiniteNonZero());
1591
1592 // Test +/- Zero.
1593 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle, false).isFiniteNonZero());
1594 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle, true).isFiniteNonZero());
1595
1596 // Test +/- qNaN. +/- dont mean anything with qNaN but paranoia can't hurt in
1597 // this instance.
1598 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle, false).isFiniteNonZero());
1599 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle, true).isFiniteNonZero());
1600
1601 // Test +/- sNaN. +/- dont mean anything with sNaN but paranoia can't hurt in
1602 // this instance.
Michael Gottesmanf9899292013-06-24 09:58:09 +00001603 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle, false).isFiniteNonZero());
1604 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle, true).isFiniteNonZero());
Michael Gottesmand95d4472013-06-19 21:00:17 +00001605}
1606
Michael Gottesmane45b1082013-06-24 09:58:07 +00001607TEST(APFloatTest, add) {
1608 // Test Special Cases against each other and normal values.
1609
1610 // TODOS/NOTES:
1611 // 1. Since we perform only default exception handling all operations with
1612 // signaling NaNs should have a result that is a quiet NaN. Currently they
1613 // return sNaN.
Michael Gottesmane45b1082013-06-24 09:58:07 +00001614
1615 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle, false);
1616 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle, true);
1617 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle, false);
1618 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle, true);
1619 APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle, false);
1620 APFloat SNaN = APFloat::getSNaN(APFloat::IEEEsingle, false);
1621 APFloat PNormalValue = APFloat(APFloat::IEEEsingle, "0x1p+0");
1622 APFloat MNormalValue = APFloat(APFloat::IEEEsingle, "-0x1p+0");
1623 APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle, false);
1624 APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle, true);
1625 APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle, false);
1626 APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle, true);
1627 APFloat PSmallestNormalized =
1628 APFloat::getSmallestNormalized(APFloat::IEEEsingle, false);
1629 APFloat MSmallestNormalized =
1630 APFloat::getSmallestNormalized(APFloat::IEEEsingle, true);
1631
1632 const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact;
1633
1634 const unsigned NumTests = 169;
1635 struct {
1636 APFloat x;
1637 APFloat y;
1638 const char *result;
1639 int status;
1640 int category;
1641 } SpecialCaseTests[NumTests] = {
1642 { PInf, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1643 { PInf, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1644 { PInf, PZero, "inf", APFloat::opOK, APFloat::fcInfinity },
1645 { PInf, MZero, "inf", APFloat::opOK, APFloat::fcInfinity },
1646 { PInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
1647#if 0
1648 // See Note 1.
1649 { PInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1650#endif
1651 { PInf, PNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1652 { PInf, MNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1653 { PInf, PLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1654 { PInf, MLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1655 { PInf, PSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1656 { PInf, MSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1657 { PInf, PSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
1658 { PInf, MSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
1659 { MInf, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1660 { MInf, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1661 { MInf, PZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
1662 { MInf, MZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00001663 { MInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmane45b1082013-06-24 09:58:07 +00001664#if 0
1665 // See Note 1.
1666 { MInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1667#endif
1668 { MInf, PNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1669 { MInf, MNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1670 { MInf, PLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1671 { MInf, MLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1672 { MInf, PSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1673 { MInf, MSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1674 { MInf, PSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
1675 { MInf, MSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
1676 { PZero, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1677 { PZero, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1678 { PZero, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1679 { PZero, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1680 { PZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
1681#if 0
1682 // See Note 1.
1683 { PZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1684#endif
1685 { PZero, PNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
1686 { PZero, MNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
1687 { PZero, PLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1688 { PZero, MLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1689 { PZero, PSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
1690 { PZero, MSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
1691 { PZero, PSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
1692 { PZero, MSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
1693 { MZero, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1694 { MZero, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1695 { MZero, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1696 { MZero, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00001697 { MZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmane45b1082013-06-24 09:58:07 +00001698#if 0
1699 // See Note 1.
1700 { MZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1701#endif
1702 { MZero, PNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
1703 { MZero, MNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
1704 { MZero, PLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1705 { MZero, MLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1706 { MZero, PSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
1707 { MZero, MSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
1708 { MZero, PSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
1709 { MZero, MSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
1710 { QNaN, PInf, "nan", APFloat::opOK, APFloat::fcNaN },
1711 { QNaN, MInf, "nan", APFloat::opOK, APFloat::fcNaN },
1712 { QNaN, PZero, "nan", APFloat::opOK, APFloat::fcNaN },
1713 { QNaN, MZero, "nan", APFloat::opOK, APFloat::fcNaN },
1714 { QNaN, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
1715#if 0
1716 // See Note 1.
1717 { QNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1718#endif
1719 { QNaN, PNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
1720 { QNaN, MNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
1721 { QNaN, PLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
1722 { QNaN, MLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
1723 { QNaN, PSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
1724 { QNaN, MSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
1725 { QNaN, PSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
1726 { QNaN, MSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
1727#if 0
1728 // See Note 1.
1729 { SNaN, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1730 { SNaN, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1731 { SNaN, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1732 { SNaN, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1733 { SNaN, QNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1734 { SNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1735 { SNaN, PNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1736 { SNaN, MNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1737 { SNaN, PLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1738 { SNaN, MLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1739 { SNaN, PSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1740 { SNaN, MSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1741 { SNaN, PSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1742 { SNaN, MSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1743#endif
1744 { PNormalValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1745 { PNormalValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1746 { PNormalValue, PZero, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
1747 { PNormalValue, MZero, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
1748 { PNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
1749#if 0
1750 // See Note 1.
1751 { PNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1752#endif
1753 { PNormalValue, PNormalValue, "0x1p+1", APFloat::opOK, APFloat::fcNormal },
1754 { PNormalValue, MNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1755 { PNormalValue, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1756 { PNormalValue, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1757 { PNormalValue, PSmallestValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1758 { PNormalValue, MSmallestValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1759 { PNormalValue, PSmallestNormalized, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1760 { PNormalValue, MSmallestNormalized, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1761 { MNormalValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1762 { MNormalValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1763 { MNormalValue, PZero, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
1764 { MNormalValue, MZero, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00001765 { MNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmane45b1082013-06-24 09:58:07 +00001766#if 0
1767 // See Note 1.
1768 { MNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1769#endif
1770 { MNormalValue, PNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1771 { MNormalValue, MNormalValue, "-0x1p+1", APFloat::opOK, APFloat::fcNormal },
1772 { MNormalValue, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1773 { MNormalValue, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1774 { MNormalValue, PSmallestValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1775 { MNormalValue, MSmallestValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1776 { MNormalValue, PSmallestNormalized, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1777 { MNormalValue, MSmallestNormalized, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1778 { PLargestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1779 { PLargestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1780 { PLargestValue, PZero, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1781 { PLargestValue, MZero, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1782 { PLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
1783#if 0
1784 // See Note 1.
1785 { PLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1786#endif
1787 { PLargestValue, PNormalValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1788 { PLargestValue, MNormalValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1789 { PLargestValue, PLargestValue, "inf", OverflowStatus, APFloat::fcInfinity },
1790 { PLargestValue, MLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1791 { PLargestValue, PSmallestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1792 { PLargestValue, MSmallestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1793 { PLargestValue, PSmallestNormalized, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1794 { PLargestValue, MSmallestNormalized, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1795 { MLargestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1796 { MLargestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1797 { MLargestValue, PZero, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1798 { MLargestValue, MZero, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00001799 { MLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmane45b1082013-06-24 09:58:07 +00001800#if 0
1801 // See Note 1.
1802 { MLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1803#endif
1804 { MLargestValue, PNormalValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1805 { MLargestValue, MNormalValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1806 { MLargestValue, PLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1807 { MLargestValue, MLargestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
1808 { MLargestValue, PSmallestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1809 { MLargestValue, MSmallestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1810 { MLargestValue, PSmallestNormalized, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1811 { MLargestValue, MSmallestNormalized, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1812 { PSmallestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1813 { PSmallestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1814 { PSmallestValue, PZero, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
1815 { PSmallestValue, MZero, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
1816 { PSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
1817#if 0
1818 // See Note 1.
1819 { PSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1820#endif
1821 { PSmallestValue, PNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1822 { PSmallestValue, MNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1823 { PSmallestValue, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1824 { PSmallestValue, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1825 { PSmallestValue, PSmallestValue, "0x1p-148", APFloat::opOK, APFloat::fcNormal },
1826 { PSmallestValue, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1827 { PSmallestValue, PSmallestNormalized, "0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
1828 { PSmallestValue, MSmallestNormalized, "-0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
1829 { MSmallestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1830 { MSmallestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1831 { MSmallestValue, PZero, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
1832 { MSmallestValue, MZero, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00001833 { MSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmane45b1082013-06-24 09:58:07 +00001834#if 0
1835 // See Note 1.
1836 { MSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1837#endif
1838 { MSmallestValue, PNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1839 { MSmallestValue, MNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1840 { MSmallestValue, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1841 { MSmallestValue, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1842 { MSmallestValue, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1843 { MSmallestValue, MSmallestValue, "-0x1p-148", APFloat::opOK, APFloat::fcNormal },
1844 { MSmallestValue, PSmallestNormalized, "0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
1845 { MSmallestValue, MSmallestNormalized, "-0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
1846 { PSmallestNormalized, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1847 { PSmallestNormalized, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1848 { PSmallestNormalized, PZero, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
1849 { PSmallestNormalized, MZero, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
1850 { PSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
1851#if 0
1852// See Note 1.
1853 { PSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1854#endif
1855 { PSmallestNormalized, PNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1856 { PSmallestNormalized, MNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1857 { PSmallestNormalized, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1858 { PSmallestNormalized, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1859 { PSmallestNormalized, PSmallestValue, "0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
1860 { PSmallestNormalized, MSmallestValue, "0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
1861 { PSmallestNormalized, PSmallestNormalized, "0x1p-125", APFloat::opOK, APFloat::fcNormal },
1862 { PSmallestNormalized, MSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1863 { MSmallestNormalized, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1864 { MSmallestNormalized, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1865 { MSmallestNormalized, PZero, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
1866 { MSmallestNormalized, MZero, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00001867 { MSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmane45b1082013-06-24 09:58:07 +00001868#if 0
1869 // See Note 1.
1870 { MSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1871#endif
1872 { MSmallestNormalized, PNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1873 { MSmallestNormalized, MNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1874 { MSmallestNormalized, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1875 { MSmallestNormalized, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1876 { MSmallestNormalized, PSmallestValue, "-0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
1877 { MSmallestNormalized, MSmallestValue, "-0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
1878 { MSmallestNormalized, PSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1879 { MSmallestNormalized, MSmallestNormalized, "-0x1p-125", APFloat::opOK, APFloat::fcNormal }
1880 };
1881
1882 for (size_t i = 0; i < NumTests; ++i) {
1883 APFloat x(SpecialCaseTests[i].x);
1884 APFloat y(SpecialCaseTests[i].y);
1885 APFloat::opStatus status = x.add(y, APFloat::rmNearestTiesToEven);
1886
1887 APFloat result(APFloat::IEEEsingle, SpecialCaseTests[i].result);
1888
Michael Gottesmane45b1082013-06-24 09:58:07 +00001889 EXPECT_TRUE(result.bitwiseIsEqual(x));
1890 EXPECT_TRUE((int)status == SpecialCaseTests[i].status);
1891 EXPECT_TRUE((int)x.getCategory() == SpecialCaseTests[i].category);
1892 }
1893}
1894
Michael Gottesman9368a532013-06-26 23:55:23 +00001895TEST(APFloatTest, subtract) {
1896 // Test Special Cases against each other and normal values.
1897
1898 // TODOS/NOTES:
1899 // 1. Since we perform only default exception handling all operations with
1900 // signaling NaNs should have a result that is a quiet NaN. Currently they
1901 // return sNaN.
Michael Gottesman9368a532013-06-26 23:55:23 +00001902
1903 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle, false);
1904 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle, true);
1905 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle, false);
1906 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle, true);
1907 APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle, false);
1908 APFloat SNaN = APFloat::getSNaN(APFloat::IEEEsingle, false);
1909 APFloat PNormalValue = APFloat(APFloat::IEEEsingle, "0x1p+0");
1910 APFloat MNormalValue = APFloat(APFloat::IEEEsingle, "-0x1p+0");
1911 APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle, false);
1912 APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle, true);
1913 APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle, false);
1914 APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle, true);
1915 APFloat PSmallestNormalized =
1916 APFloat::getSmallestNormalized(APFloat::IEEEsingle, false);
1917 APFloat MSmallestNormalized =
1918 APFloat::getSmallestNormalized(APFloat::IEEEsingle, true);
1919
1920 const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact;
1921
1922 const unsigned NumTests = 169;
1923 struct {
1924 APFloat x;
1925 APFloat y;
1926 const char *result;
1927 int status;
1928 int category;
1929 } SpecialCaseTests[NumTests] = {
1930 { PInf, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1931 { PInf, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1932 { PInf, PZero, "inf", APFloat::opOK, APFloat::fcInfinity },
1933 { PInf, MZero, "inf", APFloat::opOK, APFloat::fcInfinity },
Stephen Canond3278282014-06-08 16:53:31 +00001934 { PInf, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00001935#if 0
1936// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00001937 { PInf, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00001938#endif
1939 { PInf, PNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1940 { PInf, MNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1941 { PInf, PLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1942 { PInf, MLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1943 { PInf, PSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1944 { PInf, MSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1945 { PInf, PSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
1946 { PInf, MSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
1947 { MInf, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1948 { MInf, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1949 { MInf, PZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
1950 { MInf, MZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
Stephen Canond3278282014-06-08 16:53:31 +00001951 { MInf, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00001952#if 0
1953// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00001954 { MInf, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00001955#endif
1956 { MInf, PNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1957 { MInf, MNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1958 { MInf, PLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1959 { MInf, MLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1960 { MInf, PSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1961 { MInf, MSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1962 { MInf, PSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
1963 { MInf, MSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
1964 { PZero, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1965 { PZero, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1966 { PZero, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1967 { PZero, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
Stephen Canond3278282014-06-08 16:53:31 +00001968 { PZero, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00001969#if 0
1970// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00001971 { PZero, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00001972#endif
1973 { PZero, PNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
1974 { PZero, MNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
1975 { PZero, PLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1976 { PZero, MLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1977 { PZero, PSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
1978 { PZero, MSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
1979 { PZero, PSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
1980 { PZero, MSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
1981 { MZero, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1982 { MZero, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1983 { MZero, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
1984 { MZero, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
Stephen Canond3278282014-06-08 16:53:31 +00001985 { MZero, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00001986#if 0
1987// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00001988 { MZero, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00001989#endif
1990 { MZero, PNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
1991 { MZero, MNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
1992 { MZero, PLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1993 { MZero, MLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1994 { MZero, PSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
1995 { MZero, MSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
1996 { MZero, PSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
1997 { MZero, MSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
1998 { QNaN, PInf, "nan", APFloat::opOK, APFloat::fcNaN },
1999 { QNaN, MInf, "nan", APFloat::opOK, APFloat::fcNaN },
2000 { QNaN, PZero, "nan", APFloat::opOK, APFloat::fcNaN },
2001 { QNaN, MZero, "nan", APFloat::opOK, APFloat::fcNaN },
2002 { QNaN, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2003#if 0
2004// See Note 1.
2005 { QNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2006#endif
2007 { QNaN, PNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
2008 { QNaN, MNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
2009 { QNaN, PLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
2010 { QNaN, MLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
2011 { QNaN, PSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
2012 { QNaN, MSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
2013 { QNaN, PSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
2014 { QNaN, MSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
2015#if 0
2016// See Note 1.
2017 { SNaN, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2018 { SNaN, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2019 { SNaN, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2020 { SNaN, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2021 { SNaN, QNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2022 { SNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2023 { SNaN, PNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2024 { SNaN, MNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2025 { SNaN, PLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2026 { SNaN, MLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2027 { SNaN, PSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2028 { SNaN, MSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2029 { SNaN, PSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2030 { SNaN, MSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2031#endif
2032 { PNormalValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2033 { PNormalValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2034 { PNormalValue, PZero, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2035 { PNormalValue, MZero, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
Stephen Canond3278282014-06-08 16:53:31 +00002036 { PNormalValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002037#if 0
2038// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002039 { PNormalValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002040#endif
2041 { PNormalValue, PNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2042 { PNormalValue, MNormalValue, "0x1p+1", APFloat::opOK, APFloat::fcNormal },
2043 { PNormalValue, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2044 { PNormalValue, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2045 { PNormalValue, PSmallestValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2046 { PNormalValue, MSmallestValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2047 { PNormalValue, PSmallestNormalized, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2048 { PNormalValue, MSmallestNormalized, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2049 { MNormalValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2050 { MNormalValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2051 { MNormalValue, PZero, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2052 { MNormalValue, MZero, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
Stephen Canond3278282014-06-08 16:53:31 +00002053 { MNormalValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002054#if 0
2055// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002056 { MNormalValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002057#endif
2058 { MNormalValue, PNormalValue, "-0x1p+1", APFloat::opOK, APFloat::fcNormal },
2059 { MNormalValue, MNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2060 { MNormalValue, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2061 { MNormalValue, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2062 { MNormalValue, PSmallestValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2063 { MNormalValue, MSmallestValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2064 { MNormalValue, PSmallestNormalized, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2065 { MNormalValue, MSmallestNormalized, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2066 { PLargestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2067 { PLargestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2068 { PLargestValue, PZero, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2069 { PLargestValue, MZero, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
Stephen Canond3278282014-06-08 16:53:31 +00002070 { PLargestValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002071#if 0
2072// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002073 { PLargestValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002074#endif
2075 { PLargestValue, PNormalValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2076 { PLargestValue, MNormalValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2077 { PLargestValue, PLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2078 { PLargestValue, MLargestValue, "inf", OverflowStatus, APFloat::fcInfinity },
2079 { PLargestValue, PSmallestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2080 { PLargestValue, MSmallestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2081 { PLargestValue, PSmallestNormalized, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2082 { PLargestValue, MSmallestNormalized, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2083 { MLargestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2084 { MLargestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2085 { MLargestValue, PZero, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2086 { MLargestValue, MZero, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
Stephen Canond3278282014-06-08 16:53:31 +00002087 { MLargestValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002088#if 0
2089// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002090 { MLargestValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002091#endif
2092 { MLargestValue, PNormalValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2093 { MLargestValue, MNormalValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2094 { MLargestValue, PLargestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
2095 { MLargestValue, MLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2096 { MLargestValue, PSmallestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2097 { MLargestValue, MSmallestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2098 { MLargestValue, PSmallestNormalized, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2099 { MLargestValue, MSmallestNormalized, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2100 { PSmallestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2101 { PSmallestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2102 { PSmallestValue, PZero, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2103 { PSmallestValue, MZero, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
Stephen Canond3278282014-06-08 16:53:31 +00002104 { PSmallestValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002105#if 0
2106// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002107 { PSmallestValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002108#endif
2109 { PSmallestValue, PNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2110 { PSmallestValue, MNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2111 { PSmallestValue, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2112 { PSmallestValue, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2113 { PSmallestValue, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2114 { PSmallestValue, MSmallestValue, "0x1p-148", APFloat::opOK, APFloat::fcNormal },
2115 { PSmallestValue, PSmallestNormalized, "-0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
2116 { PSmallestValue, MSmallestNormalized, "0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
2117 { MSmallestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2118 { MSmallestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2119 { MSmallestValue, PZero, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2120 { MSmallestValue, MZero, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
Stephen Canond3278282014-06-08 16:53:31 +00002121 { MSmallestValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002122#if 0
2123// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002124 { MSmallestValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002125#endif
2126 { MSmallestValue, PNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2127 { MSmallestValue, MNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2128 { MSmallestValue, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2129 { MSmallestValue, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2130 { MSmallestValue, PSmallestValue, "-0x1p-148", APFloat::opOK, APFloat::fcNormal },
2131 { MSmallestValue, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2132 { MSmallestValue, PSmallestNormalized, "-0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
2133 { MSmallestValue, MSmallestNormalized, "0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
2134 { PSmallestNormalized, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2135 { PSmallestNormalized, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2136 { PSmallestNormalized, PZero, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2137 { PSmallestNormalized, MZero, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
Stephen Canond3278282014-06-08 16:53:31 +00002138 { PSmallestNormalized, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002139#if 0
2140// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002141 { PSmallestNormalized, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002142#endif
2143 { PSmallestNormalized, PNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2144 { PSmallestNormalized, MNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2145 { PSmallestNormalized, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2146 { PSmallestNormalized, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2147 { PSmallestNormalized, PSmallestValue, "0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
2148 { PSmallestNormalized, MSmallestValue, "0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
2149 { PSmallestNormalized, PSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2150 { PSmallestNormalized, MSmallestNormalized, "0x1p-125", APFloat::opOK, APFloat::fcNormal },
2151 { MSmallestNormalized, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2152 { MSmallestNormalized, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2153 { MSmallestNormalized, PZero, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2154 { MSmallestNormalized, MZero, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
Stephen Canond3278282014-06-08 16:53:31 +00002155 { MSmallestNormalized, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002156#if 0
2157// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002158 { MSmallestNormalized, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002159#endif
2160 { MSmallestNormalized, PNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2161 { MSmallestNormalized, MNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2162 { MSmallestNormalized, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2163 { MSmallestNormalized, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2164 { MSmallestNormalized, PSmallestValue, "-0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
2165 { MSmallestNormalized, MSmallestValue, "-0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
2166 { MSmallestNormalized, PSmallestNormalized, "-0x1p-125", APFloat::opOK, APFloat::fcNormal },
2167 { MSmallestNormalized, MSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero }
2168 };
2169
2170 for (size_t i = 0; i < NumTests; ++i) {
2171 APFloat x(SpecialCaseTests[i].x);
2172 APFloat y(SpecialCaseTests[i].y);
2173 APFloat::opStatus status = x.subtract(y, APFloat::rmNearestTiesToEven);
2174
2175 APFloat result(APFloat::IEEEsingle, SpecialCaseTests[i].result);
2176
Michael Gottesman9368a532013-06-26 23:55:23 +00002177 EXPECT_TRUE(result.bitwiseIsEqual(x));
2178 EXPECT_TRUE((int)status == SpecialCaseTests[i].status);
2179 EXPECT_TRUE((int)x.getCategory() == SpecialCaseTests[i].category);
2180 }
2181}
2182
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002183TEST(APFloatTest, multiply) {
2184 // Test Special Cases against each other and normal values.
2185
2186 // TODOS/NOTES:
2187 // 1. Since we perform only default exception handling all operations with
2188 // signaling NaNs should have a result that is a quiet NaN. Currently they
2189 // return sNaN.
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002190
2191 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle, false);
2192 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle, true);
2193 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle, false);
2194 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle, true);
2195 APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle, false);
2196 APFloat SNaN = APFloat::getSNaN(APFloat::IEEEsingle, false);
2197 APFloat PNormalValue = APFloat(APFloat::IEEEsingle, "0x1p+0");
2198 APFloat MNormalValue = APFloat(APFloat::IEEEsingle, "-0x1p+0");
2199 APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle, false);
2200 APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle, true);
2201 APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle, false);
2202 APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle, true);
2203 APFloat PSmallestNormalized =
2204 APFloat::getSmallestNormalized(APFloat::IEEEsingle, false);
2205 APFloat MSmallestNormalized =
2206 APFloat::getSmallestNormalized(APFloat::IEEEsingle, true);
2207
2208 const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact;
2209 const int UnderflowStatus = APFloat::opUnderflow | APFloat::opInexact;
2210
2211 const unsigned NumTests = 169;
2212 struct {
2213 APFloat x;
2214 APFloat y;
2215 const char *result;
2216 int status;
2217 int category;
2218 } SpecialCaseTests[NumTests] = {
2219 { PInf, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2220 { PInf, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2221 { PInf, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2222 { PInf, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2223 { PInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2224#if 0
2225// See Note 1.
2226 { PInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2227#endif
2228 { PInf, PNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2229 { PInf, MNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2230 { PInf, PLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2231 { PInf, MLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2232 { PInf, PSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2233 { PInf, MSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2234 { PInf, PSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
2235 { PInf, MSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
2236 { MInf, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2237 { MInf, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2238 { MInf, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2239 { MInf, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002240 { MInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002241#if 0
2242// See Note 1.
2243 { MInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2244#endif
2245 { MInf, PNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2246 { MInf, MNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2247 { MInf, PLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2248 { MInf, MLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2249 { MInf, PSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2250 { MInf, MSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2251 { MInf, PSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
2252 { MInf, MSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
2253 { PZero, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2254 { PZero, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2255 { PZero, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2256 { PZero, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2257 { PZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2258#if 0
2259// See Note 1.
2260 { PZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2261#endif
2262 { PZero, PNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2263 { PZero, MNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2264 { PZero, PLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2265 { PZero, MLargestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2266 { PZero, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2267 { PZero, MSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2268 { PZero, PSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2269 { PZero, MSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2270 { MZero, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2271 { MZero, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2272 { MZero, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2273 { MZero, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002274 { MZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002275#if 0
2276// See Note 1.
2277 { MZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2278#endif
2279 { MZero, PNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2280 { MZero, MNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2281 { MZero, PLargestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2282 { MZero, MLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2283 { MZero, PSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2284 { MZero, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2285 { MZero, PSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2286 { MZero, MSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2287 { QNaN, PInf, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002288 { QNaN, MInf, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002289 { QNaN, PZero, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002290 { QNaN, MZero, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002291 { QNaN, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2292#if 0
2293// See Note 1.
2294 { QNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2295#endif
2296 { QNaN, PNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002297 { QNaN, MNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002298 { QNaN, PLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002299 { QNaN, MLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002300 { QNaN, PSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002301 { QNaN, MSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002302 { QNaN, PSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002303 { QNaN, MSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002304#if 0
2305// See Note 1.
2306 { SNaN, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2307 { SNaN, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2308 { SNaN, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2309 { SNaN, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2310 { SNaN, QNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2311 { SNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2312 { SNaN, PNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2313 { SNaN, MNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2314 { SNaN, PLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2315 { SNaN, MLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2316 { SNaN, PSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2317 { SNaN, MSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2318 { SNaN, PSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2319 { SNaN, MSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2320#endif
2321 { PNormalValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2322 { PNormalValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2323 { PNormalValue, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2324 { PNormalValue, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2325 { PNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2326#if 0
2327// See Note 1.
2328 { PNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2329#endif
2330 { PNormalValue, PNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2331 { PNormalValue, MNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2332 { PNormalValue, PLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2333 { PNormalValue, MLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2334 { PNormalValue, PSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2335 { PNormalValue, MSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2336 { PNormalValue, PSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2337 { PNormalValue, MSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2338 { MNormalValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2339 { MNormalValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2340 { MNormalValue, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2341 { MNormalValue, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002342 { MNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002343#if 0
2344// See Note 1.
2345 { MNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2346#endif
2347 { MNormalValue, PNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2348 { MNormalValue, MNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2349 { MNormalValue, PLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2350 { MNormalValue, MLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2351 { MNormalValue, PSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2352 { MNormalValue, MSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2353 { MNormalValue, PSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2354 { MNormalValue, MSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2355 { PLargestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2356 { PLargestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2357 { PLargestValue, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2358 { PLargestValue, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2359 { PLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2360#if 0
2361// See Note 1.
2362 { PLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2363#endif
2364 { PLargestValue, PNormalValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2365 { PLargestValue, MNormalValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2366 { PLargestValue, PLargestValue, "inf", OverflowStatus, APFloat::fcInfinity },
2367 { PLargestValue, MLargestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
2368 { PLargestValue, PSmallestValue, "0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2369 { PLargestValue, MSmallestValue, "-0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2370 { PLargestValue, PSmallestNormalized, "0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2371 { PLargestValue, MSmallestNormalized, "-0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2372 { MLargestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2373 { MLargestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2374 { MLargestValue, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2375 { MLargestValue, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002376 { MLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002377#if 0
2378// See Note 1.
2379 { MLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2380#endif
2381 { MLargestValue, PNormalValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2382 { MLargestValue, MNormalValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2383 { MLargestValue, PLargestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
2384 { MLargestValue, MLargestValue, "inf", OverflowStatus, APFloat::fcInfinity },
2385 { MLargestValue, PSmallestValue, "-0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2386 { MLargestValue, MSmallestValue, "0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2387 { MLargestValue, PSmallestNormalized, "-0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2388 { MLargestValue, MSmallestNormalized, "0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2389 { PSmallestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2390 { PSmallestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2391 { PSmallestValue, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2392 { PSmallestValue, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2393 { PSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2394#if 0
2395// See Note 1.
2396 { PSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2397#endif
2398 { PSmallestValue, PNormalValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2399 { PSmallestValue, MNormalValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2400 { PSmallestValue, PLargestValue, "0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2401 { PSmallestValue, MLargestValue, "-0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2402 { PSmallestValue, PSmallestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2403 { PSmallestValue, MSmallestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2404 { PSmallestValue, PSmallestNormalized, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2405 { PSmallestValue, MSmallestNormalized, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2406 { MSmallestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2407 { MSmallestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2408 { MSmallestValue, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2409 { MSmallestValue, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002410 { MSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002411#if 0
2412// See Note 1.
2413 { MSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2414#endif
2415 { MSmallestValue, PNormalValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2416 { MSmallestValue, MNormalValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2417 { MSmallestValue, PLargestValue, "-0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2418 { MSmallestValue, MLargestValue, "0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2419 { MSmallestValue, PSmallestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2420 { MSmallestValue, MSmallestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2421 { MSmallestValue, PSmallestNormalized, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2422 { MSmallestValue, MSmallestNormalized, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2423 { PSmallestNormalized, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2424 { PSmallestNormalized, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2425 { PSmallestNormalized, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2426 { PSmallestNormalized, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2427 { PSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2428#if 0
2429// See Note 1.
2430 { PSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2431#endif
2432 { PSmallestNormalized, PNormalValue, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2433 { PSmallestNormalized, MNormalValue, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2434 { PSmallestNormalized, PLargestValue, "0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2435 { PSmallestNormalized, MLargestValue, "-0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2436 { PSmallestNormalized, PSmallestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2437 { PSmallestNormalized, MSmallestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2438 { PSmallestNormalized, PSmallestNormalized, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2439 { PSmallestNormalized, MSmallestNormalized, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2440 { MSmallestNormalized, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2441 { MSmallestNormalized, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2442 { MSmallestNormalized, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2443 { MSmallestNormalized, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002444 { MSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002445#if 0
2446// See Note 1.
2447 { MSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2448#endif
2449 { MSmallestNormalized, PNormalValue, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2450 { MSmallestNormalized, MNormalValue, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2451 { MSmallestNormalized, PLargestValue, "-0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2452 { MSmallestNormalized, MLargestValue, "0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2453 { MSmallestNormalized, PSmallestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2454 { MSmallestNormalized, MSmallestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2455 { MSmallestNormalized, PSmallestNormalized, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2456 { MSmallestNormalized, MSmallestNormalized, "0x0p+0", UnderflowStatus, APFloat::fcZero }
2457 };
2458
2459 for (size_t i = 0; i < NumTests; ++i) {
2460 APFloat x(SpecialCaseTests[i].x);
2461 APFloat y(SpecialCaseTests[i].y);
2462 APFloat::opStatus status = x.multiply(y, APFloat::rmNearestTiesToEven);
2463
2464 APFloat result(APFloat::IEEEsingle, SpecialCaseTests[i].result);
2465
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002466 EXPECT_TRUE(result.bitwiseIsEqual(x));
2467 EXPECT_TRUE((int)status == SpecialCaseTests[i].status);
2468 EXPECT_TRUE((int)x.getCategory() == SpecialCaseTests[i].category);
2469 }
2470}
Michael Gottesman9368a532013-06-26 23:55:23 +00002471
Michael Gottesman3eacb582013-06-27 00:42:00 +00002472TEST(APFloatTest, divide) {
2473 // Test Special Cases against each other and normal values.
2474
2475 // TODOS/NOTES:
2476 // 1. Since we perform only default exception handling all operations with
2477 // signaling NaNs should have a result that is a quiet NaN. Currently they
2478 // return sNaN.
Michael Gottesman3eacb582013-06-27 00:42:00 +00002479
2480 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle, false);
2481 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle, true);
2482 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle, false);
2483 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle, true);
2484 APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle, false);
2485 APFloat SNaN = APFloat::getSNaN(APFloat::IEEEsingle, false);
2486 APFloat PNormalValue = APFloat(APFloat::IEEEsingle, "0x1p+0");
2487 APFloat MNormalValue = APFloat(APFloat::IEEEsingle, "-0x1p+0");
2488 APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle, false);
2489 APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle, true);
2490 APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle, false);
2491 APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle, true);
2492 APFloat PSmallestNormalized =
2493 APFloat::getSmallestNormalized(APFloat::IEEEsingle, false);
2494 APFloat MSmallestNormalized =
2495 APFloat::getSmallestNormalized(APFloat::IEEEsingle, true);
2496
2497 const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact;
2498 const int UnderflowStatus = APFloat::opUnderflow | APFloat::opInexact;
2499
2500 const unsigned NumTests = 169;
2501 struct {
2502 APFloat x;
2503 APFloat y;
2504 const char *result;
2505 int status;
2506 int category;
2507 } SpecialCaseTests[NumTests] = {
2508 { PInf, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2509 { PInf, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2510 { PInf, PZero, "inf", APFloat::opOK, APFloat::fcInfinity },
2511 { PInf, MZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
2512 { PInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2513#if 0
2514// See Note 1.
2515 { PInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2516#endif
2517 { PInf, PNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2518 { PInf, MNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2519 { PInf, PLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2520 { PInf, MLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2521 { PInf, PSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2522 { PInf, MSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2523 { PInf, PSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
2524 { PInf, MSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
2525 { MInf, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2526 { MInf, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2527 { MInf, PZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
2528 { MInf, MZero, "inf", APFloat::opOK, APFloat::fcInfinity },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002529 { MInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002530#if 0
2531// See Note 1.
2532 { MInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2533#endif
2534 { MInf, PNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2535 { MInf, MNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2536 { MInf, PLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2537 { MInf, MLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2538 { MInf, PSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2539 { MInf, MSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2540 { MInf, PSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
2541 { MInf, MSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
2542 { PZero, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2543 { PZero, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2544 { PZero, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2545 { PZero, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2546 { PZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2547#if 0
2548// See Note 1.
2549 { PZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2550#endif
2551 { PZero, PNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2552 { PZero, MNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2553 { PZero, PLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2554 { PZero, MLargestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2555 { PZero, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2556 { PZero, MSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2557 { PZero, PSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2558 { PZero, MSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2559 { MZero, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2560 { MZero, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2561 { MZero, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2562 { MZero, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002563 { MZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002564#if 0
2565// See Note 1.
2566 { MZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2567#endif
2568 { MZero, PNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2569 { MZero, MNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2570 { MZero, PLargestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2571 { MZero, MLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2572 { MZero, PSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2573 { MZero, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2574 { MZero, PSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2575 { MZero, MSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2576 { QNaN, PInf, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002577 { QNaN, MInf, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002578 { QNaN, PZero, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002579 { QNaN, MZero, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002580 { QNaN, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2581#if 0
2582// See Note 1.
2583 { QNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2584#endif
2585 { QNaN, PNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002586 { QNaN, MNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002587 { QNaN, PLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002588 { QNaN, MLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002589 { QNaN, PSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002590 { QNaN, MSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002591 { QNaN, PSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002592 { QNaN, MSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002593#if 0
2594// See Note 1.
2595 { SNaN, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2596 { SNaN, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2597 { SNaN, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2598 { SNaN, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2599 { SNaN, QNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2600 { SNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2601 { SNaN, PNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2602 { SNaN, MNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2603 { SNaN, PLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2604 { SNaN, MLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2605 { SNaN, PSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2606 { SNaN, MSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2607 { SNaN, PSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2608 { SNaN, MSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2609#endif
2610 { PNormalValue, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2611 { PNormalValue, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2612 { PNormalValue, PZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
2613 { PNormalValue, MZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2614 { PNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2615#if 0
2616// See Note 1.
2617 { PNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2618#endif
2619 { PNormalValue, PNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2620 { PNormalValue, MNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2621 { PNormalValue, PLargestValue, "0x1p-128", UnderflowStatus, APFloat::fcNormal },
2622 { PNormalValue, MLargestValue, "-0x1p-128", UnderflowStatus, APFloat::fcNormal },
2623 { PNormalValue, PSmallestValue, "inf", OverflowStatus, APFloat::fcInfinity },
2624 { PNormalValue, MSmallestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
2625 { PNormalValue, PSmallestNormalized, "0x1p+126", APFloat::opOK, APFloat::fcNormal },
2626 { PNormalValue, MSmallestNormalized, "-0x1p+126", APFloat::opOK, APFloat::fcNormal },
2627 { MNormalValue, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2628 { MNormalValue, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2629 { MNormalValue, PZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2630 { MNormalValue, MZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002631 { MNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002632#if 0
2633// See Note 1.
2634 { MNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2635#endif
2636 { MNormalValue, PNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2637 { MNormalValue, MNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2638 { MNormalValue, PLargestValue, "-0x1p-128", UnderflowStatus, APFloat::fcNormal },
2639 { MNormalValue, MLargestValue, "0x1p-128", UnderflowStatus, APFloat::fcNormal },
2640 { MNormalValue, PSmallestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
2641 { MNormalValue, MSmallestValue, "inf", OverflowStatus, APFloat::fcInfinity },
2642 { MNormalValue, PSmallestNormalized, "-0x1p+126", APFloat::opOK, APFloat::fcNormal },
2643 { MNormalValue, MSmallestNormalized, "0x1p+126", APFloat::opOK, APFloat::fcNormal },
2644 { PLargestValue, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2645 { PLargestValue, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2646 { PLargestValue, PZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
2647 { PLargestValue, MZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2648 { PLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2649#if 0
2650// See Note 1.
2651 { PLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2652#endif
2653 { PLargestValue, PNormalValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2654 { PLargestValue, MNormalValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2655 { PLargestValue, PLargestValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2656 { PLargestValue, MLargestValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2657 { PLargestValue, PSmallestValue, "inf", OverflowStatus, APFloat::fcInfinity },
2658 { PLargestValue, MSmallestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
2659 { PLargestValue, PSmallestNormalized, "inf", OverflowStatus, APFloat::fcInfinity },
2660 { PLargestValue, MSmallestNormalized, "-inf", OverflowStatus, APFloat::fcInfinity },
2661 { MLargestValue, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2662 { MLargestValue, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2663 { MLargestValue, PZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2664 { MLargestValue, MZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002665 { MLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002666#if 0
2667// See Note 1.
2668 { MLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2669#endif
2670 { MLargestValue, PNormalValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2671 { MLargestValue, MNormalValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2672 { MLargestValue, PLargestValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2673 { MLargestValue, MLargestValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2674 { MLargestValue, PSmallestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
2675 { MLargestValue, MSmallestValue, "inf", OverflowStatus, APFloat::fcInfinity },
2676 { MLargestValue, PSmallestNormalized, "-inf", OverflowStatus, APFloat::fcInfinity },
2677 { MLargestValue, MSmallestNormalized, "inf", OverflowStatus, APFloat::fcInfinity },
2678 { PSmallestValue, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2679 { PSmallestValue, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2680 { PSmallestValue, PZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
2681 { PSmallestValue, MZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2682 { PSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2683#if 0
2684// See Note 1.
2685 { PSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2686#endif
2687 { PSmallestValue, PNormalValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2688 { PSmallestValue, MNormalValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2689 { PSmallestValue, PLargestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2690 { PSmallestValue, MLargestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2691 { PSmallestValue, PSmallestValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2692 { PSmallestValue, MSmallestValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2693 { PSmallestValue, PSmallestNormalized, "0x1p-23", APFloat::opOK, APFloat::fcNormal },
2694 { PSmallestValue, MSmallestNormalized, "-0x1p-23", APFloat::opOK, APFloat::fcNormal },
2695 { MSmallestValue, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2696 { MSmallestValue, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2697 { MSmallestValue, PZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2698 { MSmallestValue, MZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002699 { MSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002700#if 0
2701// See Note 1.
2702 { MSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2703#endif
2704 { MSmallestValue, PNormalValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2705 { MSmallestValue, MNormalValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2706 { MSmallestValue, PLargestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2707 { MSmallestValue, MLargestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2708 { MSmallestValue, PSmallestValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2709 { MSmallestValue, MSmallestValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2710 { MSmallestValue, PSmallestNormalized, "-0x1p-23", APFloat::opOK, APFloat::fcNormal },
2711 { MSmallestValue, MSmallestNormalized, "0x1p-23", APFloat::opOK, APFloat::fcNormal },
2712 { PSmallestNormalized, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2713 { PSmallestNormalized, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2714 { PSmallestNormalized, PZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
2715 { PSmallestNormalized, MZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2716 { PSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2717#if 0
2718// See Note 1.
2719 { PSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2720#endif
2721 { PSmallestNormalized, PNormalValue, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2722 { PSmallestNormalized, MNormalValue, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2723 { PSmallestNormalized, PLargestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2724 { PSmallestNormalized, MLargestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2725 { PSmallestNormalized, PSmallestValue, "0x1p+23", APFloat::opOK, APFloat::fcNormal },
2726 { PSmallestNormalized, MSmallestValue, "-0x1p+23", APFloat::opOK, APFloat::fcNormal },
2727 { PSmallestNormalized, PSmallestNormalized, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2728 { PSmallestNormalized, MSmallestNormalized, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2729 { MSmallestNormalized, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2730 { MSmallestNormalized, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2731 { MSmallestNormalized, PZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2732 { MSmallestNormalized, MZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002733 { MSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002734#if 0
2735// See Note 1.
2736 { MSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2737#endif
2738 { MSmallestNormalized, PNormalValue, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2739 { MSmallestNormalized, MNormalValue, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2740 { MSmallestNormalized, PLargestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2741 { MSmallestNormalized, MLargestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2742 { MSmallestNormalized, PSmallestValue, "-0x1p+23", APFloat::opOK, APFloat::fcNormal },
2743 { MSmallestNormalized, MSmallestValue, "0x1p+23", APFloat::opOK, APFloat::fcNormal },
2744 { MSmallestNormalized, PSmallestNormalized, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2745 { MSmallestNormalized, MSmallestNormalized, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2746 };
2747
2748 for (size_t i = 0; i < NumTests; ++i) {
2749 APFloat x(SpecialCaseTests[i].x);
2750 APFloat y(SpecialCaseTests[i].y);
2751 APFloat::opStatus status = x.divide(y, APFloat::rmNearestTiesToEven);
2752
2753 APFloat result(APFloat::IEEEsingle, SpecialCaseTests[i].result);
2754
2755 EXPECT_TRUE(result.bitwiseIsEqual(x));
2756 EXPECT_TRUE((int)status == SpecialCaseTests[i].status);
2757 EXPECT_TRUE((int)x.getCategory() == SpecialCaseTests[i].category);
2758 }
2759}
2760
Chandler Carruthdf782e42014-10-09 23:26:15 +00002761TEST(APFloatTest, operatorOverloads) {
2762 // This is mostly testing that these operator overloads compile.
2763 APFloat One = APFloat(APFloat::IEEEsingle, "0x1p+0");
2764 APFloat Two = APFloat(APFloat::IEEEsingle, "0x2p+0");
2765 EXPECT_TRUE(Two.bitwiseIsEqual(One + One));
2766 EXPECT_TRUE(One.bitwiseIsEqual(Two - One));
2767 EXPECT_TRUE(Two.bitwiseIsEqual(One * Two));
2768 EXPECT_TRUE(One.bitwiseIsEqual(Two / Two));
2769}
Chandler Carruth7468b062014-10-10 04:17:04 +00002770
Chandler Carruthafe56ae2014-10-10 08:27:22 +00002771TEST(APFloatTest, abs) {
2772 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle, false);
2773 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle, true);
2774 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle, false);
2775 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle, true);
2776 APFloat PQNaN = APFloat::getNaN(APFloat::IEEEsingle, false);
2777 APFloat MQNaN = APFloat::getNaN(APFloat::IEEEsingle, true);
2778 APFloat PSNaN = APFloat::getSNaN(APFloat::IEEEsingle, false);
2779 APFloat MSNaN = APFloat::getSNaN(APFloat::IEEEsingle, true);
2780 APFloat PNormalValue = APFloat(APFloat::IEEEsingle, "0x1p+0");
2781 APFloat MNormalValue = APFloat(APFloat::IEEEsingle, "-0x1p+0");
2782 APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle, false);
2783 APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle, true);
2784 APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle, false);
2785 APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle, true);
2786 APFloat PSmallestNormalized =
2787 APFloat::getSmallestNormalized(APFloat::IEEEsingle, false);
2788 APFloat MSmallestNormalized =
2789 APFloat::getSmallestNormalized(APFloat::IEEEsingle, true);
2790
2791 EXPECT_TRUE(PInf.bitwiseIsEqual(abs(PInf)));
2792 EXPECT_TRUE(PInf.bitwiseIsEqual(abs(MInf)));
2793 EXPECT_TRUE(PZero.bitwiseIsEqual(abs(PZero)));
2794 EXPECT_TRUE(PZero.bitwiseIsEqual(abs(MZero)));
2795 EXPECT_TRUE(PQNaN.bitwiseIsEqual(abs(PQNaN)));
2796 EXPECT_TRUE(PQNaN.bitwiseIsEqual(abs(MQNaN)));
2797 EXPECT_TRUE(PSNaN.bitwiseIsEqual(abs(PSNaN)));
2798 EXPECT_TRUE(PSNaN.bitwiseIsEqual(abs(MSNaN)));
2799 EXPECT_TRUE(PNormalValue.bitwiseIsEqual(abs(PNormalValue)));
2800 EXPECT_TRUE(PNormalValue.bitwiseIsEqual(abs(MNormalValue)));
2801 EXPECT_TRUE(PLargestValue.bitwiseIsEqual(abs(PLargestValue)));
2802 EXPECT_TRUE(PLargestValue.bitwiseIsEqual(abs(MLargestValue)));
2803 EXPECT_TRUE(PSmallestValue.bitwiseIsEqual(abs(PSmallestValue)));
2804 EXPECT_TRUE(PSmallestValue.bitwiseIsEqual(abs(MSmallestValue)));
2805 EXPECT_TRUE(PSmallestNormalized.bitwiseIsEqual(abs(PSmallestNormalized)));
2806 EXPECT_TRUE(PSmallestNormalized.bitwiseIsEqual(abs(MSmallestNormalized)));
2807}
2808
Chandler Carruthca067142014-10-10 05:14:12 +00002809TEST(APFloatTest, ilogb) {
2810 EXPECT_EQ(0, ilogb(APFloat(APFloat::IEEEsingle, "0x1p+0")));
2811 EXPECT_EQ(0, ilogb(APFloat(APFloat::IEEEsingle, "-0x1p+0")));
2812 EXPECT_EQ(42, ilogb(APFloat(APFloat::IEEEsingle, "0x1p+42")));
2813 EXPECT_EQ(-42, ilogb(APFloat(APFloat::IEEEsingle, "0x1p-42")));
Chandler Carruth7468b062014-10-10 04:17:04 +00002814
Chandler Carruthca067142014-10-10 05:14:12 +00002815 EXPECT_EQ(APFloat::IEK_Inf,
2816 ilogb(APFloat::getInf(APFloat::IEEEsingle, false)));
2817 EXPECT_EQ(APFloat::IEK_Inf,
2818 ilogb(APFloat::getInf(APFloat::IEEEsingle, true)));
2819 EXPECT_EQ(APFloat::IEK_Zero,
2820 ilogb(APFloat::getZero(APFloat::IEEEsingle, false)));
2821 EXPECT_EQ(APFloat::IEK_Zero,
2822 ilogb(APFloat::getZero(APFloat::IEEEsingle, true)));
2823 EXPECT_EQ(APFloat::IEK_NaN,
2824 ilogb(APFloat::getNaN(APFloat::IEEEsingle, false)));
2825 EXPECT_EQ(APFloat::IEK_NaN,
2826 ilogb(APFloat::getSNaN(APFloat::IEEEsingle, false)));
Chandler Carruth7468b062014-10-10 04:17:04 +00002827
Chandler Carruthca067142014-10-10 05:14:12 +00002828 EXPECT_EQ(127, ilogb(APFloat::getLargest(APFloat::IEEEsingle, false)));
2829 EXPECT_EQ(127, ilogb(APFloat::getLargest(APFloat::IEEEsingle, true)));
2830 EXPECT_EQ(-126, ilogb(APFloat::getSmallest(APFloat::IEEEsingle, false)));
2831 EXPECT_EQ(-126, ilogb(APFloat::getSmallest(APFloat::IEEEsingle, true)));
2832 EXPECT_EQ(-126,
2833 ilogb(APFloat::getSmallestNormalized(APFloat::IEEEsingle, false)));
2834 EXPECT_EQ(-126,
2835 ilogb(APFloat::getSmallestNormalized(APFloat::IEEEsingle, true)));
Chandler Carruth7468b062014-10-10 04:17:04 +00002836}
Chandler Carruthd9edd1e2014-10-10 04:54:30 +00002837
2838TEST(APFloatTest, scalbn) {
2839 EXPECT_TRUE(
2840 APFloat(APFloat::IEEEsingle, "0x1p+0")
2841 .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEsingle, "0x1p+0"), 0)));
2842 EXPECT_TRUE(
2843 APFloat(APFloat::IEEEsingle, "0x1p+42")
2844 .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEsingle, "0x1p+0"), 42)));
2845 EXPECT_TRUE(
2846 APFloat(APFloat::IEEEsingle, "0x1p-42")
2847 .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEsingle, "0x1p+0"), -42)));
2848
2849 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle, false);
2850 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle, true);
2851 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle, false);
2852 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle, true);
2853 APFloat QPNaN = APFloat::getNaN(APFloat::IEEEsingle, false);
2854 APFloat QMNaN = APFloat::getNaN(APFloat::IEEEsingle, true);
2855 APFloat SNaN = APFloat::getSNaN(APFloat::IEEEsingle, false);
2856
2857 EXPECT_TRUE(PInf.bitwiseIsEqual(scalbn(PInf, 0)));
2858 EXPECT_TRUE(MInf.bitwiseIsEqual(scalbn(MInf, 0)));
2859 EXPECT_TRUE(PZero.bitwiseIsEqual(scalbn(PZero, 0)));
2860 EXPECT_TRUE(MZero.bitwiseIsEqual(scalbn(MZero, 0)));
2861 EXPECT_TRUE(QPNaN.bitwiseIsEqual(scalbn(QPNaN, 0)));
2862 EXPECT_TRUE(QMNaN.bitwiseIsEqual(scalbn(QMNaN, 0)));
2863 EXPECT_TRUE(SNaN.bitwiseIsEqual(scalbn(SNaN, 0)));
2864
2865 EXPECT_TRUE(
2866 PInf.bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEsingle, "0x1p+0"), 128)));
2867 EXPECT_TRUE(MInf.bitwiseIsEqual(
2868 scalbn(APFloat(APFloat::IEEEsingle, "-0x1p+0"), 128)));
2869 EXPECT_TRUE(
2870 PInf.bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEsingle, "0x1p+127"), 1)));
2871 EXPECT_TRUE(PZero.bitwiseIsEqual(
2872 scalbn(APFloat(APFloat::IEEEsingle, "0x1p+0"), -127)));
2873 EXPECT_TRUE(MZero.bitwiseIsEqual(
2874 scalbn(APFloat(APFloat::IEEEsingle, "-0x1p+0"), -127)));
2875 EXPECT_TRUE(PZero.bitwiseIsEqual(
2876 scalbn(APFloat(APFloat::IEEEsingle, "0x1p-126"), -1)));
2877 EXPECT_TRUE(PZero.bitwiseIsEqual(
2878 scalbn(APFloat(APFloat::IEEEsingle, "0x1p-126"), -1)));
2879}
Erick Tryzelaar19f63b22009-08-16 23:36:19 +00002880}