blob: 64053a811a35f6ebee2897dbbfdfa38a7367d269 [file] [log] [blame]
Erick Tryzelaara15d8902009-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 Tryzelaara15d8902009-08-16 23:36:19 +000010#include "llvm/ADT/APFloat.h"
Jeffrey Yasskin3d42bfb2011-07-15 07:04:56 +000011#include "llvm/ADT/APSInt.h"
Tim Shen207a20d2017-01-23 22:39:35 +000012#include "llvm/ADT/Hashing.h"
John McCall00e65de2009-12-24 08:56:26 +000013#include "llvm/ADT/SmallVector.h"
Tim Shen1254a592016-12-16 00:47:17 +000014#include "llvm/Support/FormatVariadic.h"
Chandler Carruth5a88dda2012-12-04 10:23:08 +000015#include "llvm/Support/raw_ostream.h"
16#include "gtest/gtest.h"
Benjamin Kramer0df66b82015-03-09 18:35:18 +000017#include <cmath>
Chandler Carruth5a88dda2012-12-04 10:23:08 +000018#include <ostream>
19#include <string>
Tim Shen2229ea12016-12-12 22:16:08 +000020#include <tuple>
Erick Tryzelaara15d8902009-08-16 23:36:19 +000021
22using namespace llvm;
23
Daniel Dunbar83fecfa2009-09-03 22:57:02 +000024static double convertToDoubleFromString(const char *Str) {
25 llvm::APFloat F(0.0);
26 F.convertFromString(Str, llvm::APFloat::rmNearestTiesToEven);
27 return F.convertToDouble();
28}
29
Serguei Katkovc849a0c2017-04-21 02:52:17 +000030static std::string convertToString(double d, unsigned Prec, unsigned Pad,
31 bool Tr = true) {
John McCall00e65de2009-12-24 08:56:26 +000032 llvm::SmallVector<char, 100> Buffer;
33 llvm::APFloat F(d);
Serguei Katkovc849a0c2017-04-21 02:52:17 +000034 F.toString(Buffer, Prec, Pad, Tr);
John McCall00e65de2009-12-24 08:56:26 +000035 return std::string(Buffer.data(), Buffer.size());
36}
37
Erick Tryzelaara15d8902009-08-16 23:36:19 +000038namespace {
39
Michael Gottesman964722c2013-05-30 18:07:13 +000040TEST(APFloatTest, isSignaling) {
41 // We test qNaN, -qNaN, +sNaN, -sNaN with and without payloads. *NOTE* The
42 // positive/negative distinction is included only since the getQNaN/getSNaN
43 // API provides the option.
44 APInt payload = APInt::getOneBitSet(4, 2);
Stephan Bergmann20a600c2016-12-14 11:57:17 +000045 EXPECT_FALSE(APFloat::getQNaN(APFloat::IEEEsingle(), false).isSignaling());
46 EXPECT_FALSE(APFloat::getQNaN(APFloat::IEEEsingle(), true).isSignaling());
47 EXPECT_FALSE(APFloat::getQNaN(APFloat::IEEEsingle(), false, &payload).isSignaling());
48 EXPECT_FALSE(APFloat::getQNaN(APFloat::IEEEsingle(), true, &payload).isSignaling());
49 EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isSignaling());
50 EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle(), true).isSignaling());
51 EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle(), false, &payload).isSignaling());
52 EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle(), true, &payload).isSignaling());
Michael Gottesman964722c2013-05-30 18:07:13 +000053}
54
55TEST(APFloatTest, next) {
56
Stephan Bergmann20a600c2016-12-14 11:57:17 +000057 APFloat test(APFloat::IEEEquad(), APFloat::uninitialized);
58 APFloat expected(APFloat::IEEEquad(), APFloat::uninitialized);
Michael Gottesman964722c2013-05-30 18:07:13 +000059
60 // 1. Test Special Cases Values.
61 //
62 // Test all special values for nextUp and nextDown perscribed by IEEE-754R
63 // 2008. These are:
64 // 1. +inf
65 // 2. -inf
66 // 3. getLargest()
67 // 4. -getLargest()
68 // 5. getSmallest()
69 // 6. -getSmallest()
70 // 7. qNaN
71 // 8. sNaN
72 // 9. +0
73 // 10. -0
74
75 // nextUp(+inf) = +inf.
Stephan Bergmann20a600c2016-12-14 11:57:17 +000076 test = APFloat::getInf(APFloat::IEEEquad(), false);
77 expected = APFloat::getInf(APFloat::IEEEquad(), false);
Michael Gottesman964722c2013-05-30 18:07:13 +000078 EXPECT_EQ(test.next(false), APFloat::opOK);
79 EXPECT_TRUE(test.isInfinity());
80 EXPECT_TRUE(!test.isNegative());
81 EXPECT_TRUE(test.bitwiseIsEqual(expected));
82
83 // nextDown(+inf) = -nextUp(-inf) = -(-getLargest()) = getLargest()
Stephan Bergmann20a600c2016-12-14 11:57:17 +000084 test = APFloat::getInf(APFloat::IEEEquad(), false);
85 expected = APFloat::getLargest(APFloat::IEEEquad(), false);
Michael Gottesman964722c2013-05-30 18:07:13 +000086 EXPECT_EQ(test.next(true), APFloat::opOK);
87 EXPECT_TRUE(!test.isNegative());
88 EXPECT_TRUE(test.bitwiseIsEqual(expected));
89
90 // nextUp(-inf) = -getLargest()
Stephan Bergmann20a600c2016-12-14 11:57:17 +000091 test = APFloat::getInf(APFloat::IEEEquad(), true);
92 expected = APFloat::getLargest(APFloat::IEEEquad(), true);
Michael Gottesman964722c2013-05-30 18:07:13 +000093 EXPECT_EQ(test.next(false), APFloat::opOK);
94 EXPECT_TRUE(test.isNegative());
95 EXPECT_TRUE(test.bitwiseIsEqual(expected));
96
97 // nextDown(-inf) = -nextUp(+inf) = -(+inf) = -inf.
Stephan Bergmann20a600c2016-12-14 11:57:17 +000098 test = APFloat::getInf(APFloat::IEEEquad(), true);
99 expected = APFloat::getInf(APFloat::IEEEquad(), true);
Michael Gottesman964722c2013-05-30 18:07:13 +0000100 EXPECT_EQ(test.next(true), APFloat::opOK);
101 EXPECT_TRUE(test.isInfinity() && test.isNegative());
102 EXPECT_TRUE(test.bitwiseIsEqual(expected));
103
104 // nextUp(getLargest()) = +inf
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000105 test = APFloat::getLargest(APFloat::IEEEquad(), false);
106 expected = APFloat::getInf(APFloat::IEEEquad(), false);
Michael Gottesman964722c2013-05-30 18:07:13 +0000107 EXPECT_EQ(test.next(false), APFloat::opOK);
108 EXPECT_TRUE(test.isInfinity() && !test.isNegative());
109 EXPECT_TRUE(test.bitwiseIsEqual(expected));
110
111 // nextDown(getLargest()) = -nextUp(-getLargest())
112 // = -(-getLargest() + inc)
113 // = getLargest() - inc.
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000114 test = APFloat::getLargest(APFloat::IEEEquad(), false);
115 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000116 "0x1.fffffffffffffffffffffffffffep+16383");
117 EXPECT_EQ(test.next(true), APFloat::opOK);
118 EXPECT_TRUE(!test.isInfinity() && !test.isNegative());
119 EXPECT_TRUE(test.bitwiseIsEqual(expected));
120
121 // nextUp(-getLargest()) = -getLargest() + inc.
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000122 test = APFloat::getLargest(APFloat::IEEEquad(), true);
123 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000124 "-0x1.fffffffffffffffffffffffffffep+16383");
125 EXPECT_EQ(test.next(false), APFloat::opOK);
126 EXPECT_TRUE(test.bitwiseIsEqual(expected));
127
128 // nextDown(-getLargest()) = -nextUp(getLargest()) = -(inf) = -inf.
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000129 test = APFloat::getLargest(APFloat::IEEEquad(), true);
130 expected = APFloat::getInf(APFloat::IEEEquad(), true);
Michael Gottesman964722c2013-05-30 18:07:13 +0000131 EXPECT_EQ(test.next(true), APFloat::opOK);
132 EXPECT_TRUE(test.isInfinity() && test.isNegative());
133 EXPECT_TRUE(test.bitwiseIsEqual(expected));
134
135 // nextUp(getSmallest()) = getSmallest() + inc.
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000136 test = APFloat(APFloat::IEEEquad(), "0x0.0000000000000000000000000001p-16382");
137 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000138 "0x0.0000000000000000000000000002p-16382");
139 EXPECT_EQ(test.next(false), APFloat::opOK);
140 EXPECT_TRUE(test.bitwiseIsEqual(expected));
141
142 // nextDown(getSmallest()) = -nextUp(-getSmallest()) = -(-0) = +0.
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000143 test = APFloat(APFloat::IEEEquad(), "0x0.0000000000000000000000000001p-16382");
144 expected = APFloat::getZero(APFloat::IEEEquad(), false);
Michael Gottesman964722c2013-05-30 18:07:13 +0000145 EXPECT_EQ(test.next(true), APFloat::opOK);
Matt Arsenault2ef94692016-03-13 05:11:51 +0000146 EXPECT_TRUE(test.isPosZero());
Michael Gottesman964722c2013-05-30 18:07:13 +0000147 EXPECT_TRUE(test.bitwiseIsEqual(expected));
148
149 // nextUp(-getSmallest()) = -0.
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000150 test = APFloat(APFloat::IEEEquad(), "-0x0.0000000000000000000000000001p-16382");
151 expected = APFloat::getZero(APFloat::IEEEquad(), true);
Michael Gottesman964722c2013-05-30 18:07:13 +0000152 EXPECT_EQ(test.next(false), APFloat::opOK);
Matt Arsenault2ef94692016-03-13 05:11:51 +0000153 EXPECT_TRUE(test.isNegZero());
Michael Gottesman964722c2013-05-30 18:07:13 +0000154 EXPECT_TRUE(test.bitwiseIsEqual(expected));
155
156 // nextDown(-getSmallest()) = -nextUp(getSmallest()) = -getSmallest() - inc.
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000157 test = APFloat(APFloat::IEEEquad(), "-0x0.0000000000000000000000000001p-16382");
158 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000159 "-0x0.0000000000000000000000000002p-16382");
160 EXPECT_EQ(test.next(true), APFloat::opOK);
161 EXPECT_TRUE(test.bitwiseIsEqual(expected));
162
163 // nextUp(qNaN) = qNaN
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000164 test = APFloat::getQNaN(APFloat::IEEEquad(), false);
165 expected = APFloat::getQNaN(APFloat::IEEEquad(), false);
Michael Gottesman964722c2013-05-30 18:07:13 +0000166 EXPECT_EQ(test.next(false), APFloat::opOK);
167 EXPECT_TRUE(test.bitwiseIsEqual(expected));
168
169 // nextDown(qNaN) = qNaN
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000170 test = APFloat::getQNaN(APFloat::IEEEquad(), false);
171 expected = APFloat::getQNaN(APFloat::IEEEquad(), false);
Michael Gottesman964722c2013-05-30 18:07:13 +0000172 EXPECT_EQ(test.next(true), APFloat::opOK);
173 EXPECT_TRUE(test.bitwiseIsEqual(expected));
174
175 // nextUp(sNaN) = qNaN
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000176 test = APFloat::getSNaN(APFloat::IEEEquad(), false);
177 expected = APFloat::getQNaN(APFloat::IEEEquad(), false);
Michael Gottesman964722c2013-05-30 18:07:13 +0000178 EXPECT_EQ(test.next(false), APFloat::opInvalidOp);
179 EXPECT_TRUE(test.bitwiseIsEqual(expected));
180
181 // nextDown(sNaN) = qNaN
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000182 test = APFloat::getSNaN(APFloat::IEEEquad(), false);
183 expected = APFloat::getQNaN(APFloat::IEEEquad(), false);
Michael Gottesman964722c2013-05-30 18:07:13 +0000184 EXPECT_EQ(test.next(true), APFloat::opInvalidOp);
185 EXPECT_TRUE(test.bitwiseIsEqual(expected));
186
187 // nextUp(+0) = +getSmallest()
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000188 test = APFloat::getZero(APFloat::IEEEquad(), false);
189 expected = APFloat::getSmallest(APFloat::IEEEquad(), false);
Michael Gottesman964722c2013-05-30 18:07:13 +0000190 EXPECT_EQ(test.next(false), APFloat::opOK);
191 EXPECT_TRUE(test.bitwiseIsEqual(expected));
192
193 // nextDown(+0) = -nextUp(-0) = -getSmallest()
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000194 test = APFloat::getZero(APFloat::IEEEquad(), false);
195 expected = APFloat::getSmallest(APFloat::IEEEquad(), true);
Michael Gottesman964722c2013-05-30 18:07:13 +0000196 EXPECT_EQ(test.next(true), APFloat::opOK);
197 EXPECT_TRUE(test.bitwiseIsEqual(expected));
198
199 // nextUp(-0) = +getSmallest()
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000200 test = APFloat::getZero(APFloat::IEEEquad(), true);
201 expected = APFloat::getSmallest(APFloat::IEEEquad(), false);
Michael Gottesman964722c2013-05-30 18:07:13 +0000202 EXPECT_EQ(test.next(false), APFloat::opOK);
203 EXPECT_TRUE(test.bitwiseIsEqual(expected));
204
205 // nextDown(-0) = -nextUp(0) = -getSmallest()
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000206 test = APFloat::getZero(APFloat::IEEEquad(), true);
207 expected = APFloat::getSmallest(APFloat::IEEEquad(), true);
Michael Gottesman964722c2013-05-30 18:07:13 +0000208 EXPECT_EQ(test.next(true), APFloat::opOK);
209 EXPECT_TRUE(test.bitwiseIsEqual(expected));
210
211 // 2. Binade Boundary Tests.
212
213 // 2a. Test denormal <-> normal binade boundaries.
214 // * nextUp(+Largest Denormal) -> +Smallest Normal.
215 // * nextDown(-Largest Denormal) -> -Smallest Normal.
216 // * nextUp(-Smallest Normal) -> -Largest Denormal.
217 // * nextDown(+Smallest Normal) -> +Largest Denormal.
218
219 // nextUp(+Largest Denormal) -> +Smallest Normal.
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000220 test = APFloat(APFloat::IEEEquad(), "0x0.ffffffffffffffffffffffffffffp-16382");
221 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000222 "0x1.0000000000000000000000000000p-16382");
223 EXPECT_EQ(test.next(false), APFloat::opOK);
224 EXPECT_FALSE(test.isDenormal());
225 EXPECT_TRUE(test.bitwiseIsEqual(expected));
226
227 // nextDown(-Largest Denormal) -> -Smallest Normal.
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000228 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000229 "-0x0.ffffffffffffffffffffffffffffp-16382");
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000230 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000231 "-0x1.0000000000000000000000000000p-16382");
232 EXPECT_EQ(test.next(true), APFloat::opOK);
233 EXPECT_FALSE(test.isDenormal());
234 EXPECT_TRUE(test.bitwiseIsEqual(expected));
235
236 // nextUp(-Smallest Normal) -> -LargestDenormal.
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000237 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000238 "-0x1.0000000000000000000000000000p-16382");
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000239 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000240 "-0x0.ffffffffffffffffffffffffffffp-16382");
241 EXPECT_EQ(test.next(false), APFloat::opOK);
242 EXPECT_TRUE(test.isDenormal());
243 EXPECT_TRUE(test.bitwiseIsEqual(expected));
244
245 // nextDown(+Smallest Normal) -> +Largest Denormal.
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000246 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000247 "+0x1.0000000000000000000000000000p-16382");
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000248 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000249 "+0x0.ffffffffffffffffffffffffffffp-16382");
250 EXPECT_EQ(test.next(true), APFloat::opOK);
251 EXPECT_TRUE(test.isDenormal());
252 EXPECT_TRUE(test.bitwiseIsEqual(expected));
253
254 // 2b. Test normal <-> normal binade boundaries.
255 // * nextUp(-Normal Binade Boundary) -> -Normal Binade Boundary + 1.
256 // * nextDown(+Normal Binade Boundary) -> +Normal Binade Boundary - 1.
257 // * nextUp(+Normal Binade Boundary - 1) -> +Normal Binade Boundary.
258 // * nextDown(-Normal Binade Boundary + 1) -> -Normal Binade Boundary.
259
260 // nextUp(-Normal Binade Boundary) -> -Normal Binade Boundary + 1.
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000261 test = APFloat(APFloat::IEEEquad(), "-0x1p+1");
262 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000263 "-0x1.ffffffffffffffffffffffffffffp+0");
264 EXPECT_EQ(test.next(false), APFloat::opOK);
265 EXPECT_TRUE(test.bitwiseIsEqual(expected));
266
267 // nextDown(+Normal Binade Boundary) -> +Normal Binade Boundary - 1.
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000268 test = APFloat(APFloat::IEEEquad(), "0x1p+1");
269 expected = APFloat(APFloat::IEEEquad(), "0x1.ffffffffffffffffffffffffffffp+0");
Michael Gottesman964722c2013-05-30 18:07:13 +0000270 EXPECT_EQ(test.next(true), APFloat::opOK);
271 EXPECT_TRUE(test.bitwiseIsEqual(expected));
272
273 // nextUp(+Normal Binade Boundary - 1) -> +Normal Binade Boundary.
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000274 test = APFloat(APFloat::IEEEquad(), "0x1.ffffffffffffffffffffffffffffp+0");
275 expected = APFloat(APFloat::IEEEquad(), "0x1p+1");
Michael Gottesman964722c2013-05-30 18:07:13 +0000276 EXPECT_EQ(test.next(false), APFloat::opOK);
277 EXPECT_TRUE(test.bitwiseIsEqual(expected));
278
279 // nextDown(-Normal Binade Boundary + 1) -> -Normal Binade Boundary.
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000280 test = APFloat(APFloat::IEEEquad(), "-0x1.ffffffffffffffffffffffffffffp+0");
281 expected = APFloat(APFloat::IEEEquad(), "-0x1p+1");
Michael Gottesman964722c2013-05-30 18:07:13 +0000282 EXPECT_EQ(test.next(true), APFloat::opOK);
283 EXPECT_TRUE(test.bitwiseIsEqual(expected));
284
285 // 2c. Test using next at binade boundaries with a direction away from the
286 // binade boundary. Away from denormal <-> normal boundaries.
287 //
288 // This is to make sure that even though we are at a binade boundary, since
289 // we are rounding away, we do not trigger the binade boundary code. Thus we
290 // test:
291 // * nextUp(-Largest Denormal) -> -Largest Denormal + inc.
292 // * nextDown(+Largest Denormal) -> +Largest Denormal - inc.
293 // * nextUp(+Smallest Normal) -> +Smallest Normal + inc.
294 // * nextDown(-Smallest Normal) -> -Smallest Normal - inc.
295
296 // nextUp(-Largest Denormal) -> -Largest Denormal + inc.
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000297 test = APFloat(APFloat::IEEEquad(), "-0x0.ffffffffffffffffffffffffffffp-16382");
298 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000299 "-0x0.fffffffffffffffffffffffffffep-16382");
300 EXPECT_EQ(test.next(false), APFloat::opOK);
301 EXPECT_TRUE(test.isDenormal());
302 EXPECT_TRUE(test.isNegative());
303 EXPECT_TRUE(test.bitwiseIsEqual(expected));
304
305 // nextDown(+Largest Denormal) -> +Largest Denormal - inc.
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000306 test = APFloat(APFloat::IEEEquad(), "0x0.ffffffffffffffffffffffffffffp-16382");
307 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000308 "0x0.fffffffffffffffffffffffffffep-16382");
309 EXPECT_EQ(test.next(true), APFloat::opOK);
310 EXPECT_TRUE(test.isDenormal());
311 EXPECT_TRUE(!test.isNegative());
312 EXPECT_TRUE(test.bitwiseIsEqual(expected));
313
314 // nextUp(+Smallest Normal) -> +Smallest Normal + inc.
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000315 test = APFloat(APFloat::IEEEquad(), "0x1.0000000000000000000000000000p-16382");
316 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000317 "0x1.0000000000000000000000000001p-16382");
318 EXPECT_EQ(test.next(false), APFloat::opOK);
319 EXPECT_TRUE(!test.isDenormal());
320 EXPECT_TRUE(!test.isNegative());
321 EXPECT_TRUE(test.bitwiseIsEqual(expected));
322
323 // nextDown(-Smallest Normal) -> -Smallest Normal - inc.
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000324 test = APFloat(APFloat::IEEEquad(), "-0x1.0000000000000000000000000000p-16382");
325 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000326 "-0x1.0000000000000000000000000001p-16382");
327 EXPECT_EQ(test.next(true), APFloat::opOK);
328 EXPECT_TRUE(!test.isDenormal());
329 EXPECT_TRUE(test.isNegative());
330 EXPECT_TRUE(test.bitwiseIsEqual(expected));
331
332 // 2d. Test values which cause our exponent to go to min exponent. This
333 // is to ensure that guards in the code to check for min exponent
334 // trigger properly.
335 // * nextUp(-0x1p-16381) -> -0x1.ffffffffffffffffffffffffffffp-16382
336 // * nextDown(-0x1.ffffffffffffffffffffffffffffp-16382) ->
337 // -0x1p-16381
338 // * nextUp(0x1.ffffffffffffffffffffffffffffp-16382) -> 0x1p-16382
339 // * nextDown(0x1p-16382) -> 0x1.ffffffffffffffffffffffffffffp-16382
340
341 // nextUp(-0x1p-16381) -> -0x1.ffffffffffffffffffffffffffffp-16382
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000342 test = APFloat(APFloat::IEEEquad(), "-0x1p-16381");
343 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000344 "-0x1.ffffffffffffffffffffffffffffp-16382");
345 EXPECT_EQ(test.next(false), APFloat::opOK);
346 EXPECT_TRUE(test.bitwiseIsEqual(expected));
347
348 // nextDown(-0x1.ffffffffffffffffffffffffffffp-16382) ->
349 // -0x1p-16381
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000350 test = APFloat(APFloat::IEEEquad(), "-0x1.ffffffffffffffffffffffffffffp-16382");
351 expected = APFloat(APFloat::IEEEquad(), "-0x1p-16381");
Michael Gottesman964722c2013-05-30 18:07:13 +0000352 EXPECT_EQ(test.next(true), APFloat::opOK);
353 EXPECT_TRUE(test.bitwiseIsEqual(expected));
354
355 // nextUp(0x1.ffffffffffffffffffffffffffffp-16382) -> 0x1p-16381
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000356 test = APFloat(APFloat::IEEEquad(), "0x1.ffffffffffffffffffffffffffffp-16382");
357 expected = APFloat(APFloat::IEEEquad(), "0x1p-16381");
Michael Gottesman964722c2013-05-30 18:07:13 +0000358 EXPECT_EQ(test.next(false), APFloat::opOK);
359 EXPECT_TRUE(test.bitwiseIsEqual(expected));
360
361 // nextDown(0x1p-16381) -> 0x1.ffffffffffffffffffffffffffffp-16382
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000362 test = APFloat(APFloat::IEEEquad(), "0x1p-16381");
363 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000364 "0x1.ffffffffffffffffffffffffffffp-16382");
365 EXPECT_EQ(test.next(true), APFloat::opOK);
366 EXPECT_TRUE(test.bitwiseIsEqual(expected));
367
368 // 3. Now we test both denormal/normal computation which will not cause us
369 // to go across binade boundaries. Specifically we test:
370 // * nextUp(+Denormal) -> +Denormal.
371 // * nextDown(+Denormal) -> +Denormal.
372 // * nextUp(-Denormal) -> -Denormal.
373 // * nextDown(-Denormal) -> -Denormal.
374 // * nextUp(+Normal) -> +Normal.
375 // * nextDown(+Normal) -> +Normal.
376 // * nextUp(-Normal) -> -Normal.
377 // * nextDown(-Normal) -> -Normal.
378
379 // nextUp(+Denormal) -> +Denormal.
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000380 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000381 "0x0.ffffffffffffffffffffffff000cp-16382");
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000382 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000383 "0x0.ffffffffffffffffffffffff000dp-16382");
384 EXPECT_EQ(test.next(false), APFloat::opOK);
385 EXPECT_TRUE(test.isDenormal());
386 EXPECT_TRUE(!test.isNegative());
387 EXPECT_TRUE(test.bitwiseIsEqual(expected));
388
389 // nextDown(+Denormal) -> +Denormal.
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000390 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000391 "0x0.ffffffffffffffffffffffff000cp-16382");
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000392 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000393 "0x0.ffffffffffffffffffffffff000bp-16382");
394 EXPECT_EQ(test.next(true), APFloat::opOK);
395 EXPECT_TRUE(test.isDenormal());
396 EXPECT_TRUE(!test.isNegative());
397 EXPECT_TRUE(test.bitwiseIsEqual(expected));
398
399 // nextUp(-Denormal) -> -Denormal.
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000400 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000401 "-0x0.ffffffffffffffffffffffff000cp-16382");
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000402 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000403 "-0x0.ffffffffffffffffffffffff000bp-16382");
404 EXPECT_EQ(test.next(false), APFloat::opOK);
405 EXPECT_TRUE(test.isDenormal());
406 EXPECT_TRUE(test.isNegative());
407 EXPECT_TRUE(test.bitwiseIsEqual(expected));
408
409 // nextDown(-Denormal) -> -Denormal
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000410 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000411 "-0x0.ffffffffffffffffffffffff000cp-16382");
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000412 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000413 "-0x0.ffffffffffffffffffffffff000dp-16382");
414 EXPECT_EQ(test.next(true), APFloat::opOK);
415 EXPECT_TRUE(test.isDenormal());
416 EXPECT_TRUE(test.isNegative());
417 EXPECT_TRUE(test.bitwiseIsEqual(expected));
418
419 // nextUp(+Normal) -> +Normal.
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000420 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000421 "0x1.ffffffffffffffffffffffff000cp-16000");
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000422 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000423 "0x1.ffffffffffffffffffffffff000dp-16000");
424 EXPECT_EQ(test.next(false), APFloat::opOK);
425 EXPECT_TRUE(!test.isDenormal());
426 EXPECT_TRUE(!test.isNegative());
427 EXPECT_TRUE(test.bitwiseIsEqual(expected));
428
429 // nextDown(+Normal) -> +Normal.
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000430 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000431 "0x1.ffffffffffffffffffffffff000cp-16000");
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000432 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000433 "0x1.ffffffffffffffffffffffff000bp-16000");
434 EXPECT_EQ(test.next(true), APFloat::opOK);
435 EXPECT_TRUE(!test.isDenormal());
436 EXPECT_TRUE(!test.isNegative());
437 EXPECT_TRUE(test.bitwiseIsEqual(expected));
438
439 // nextUp(-Normal) -> -Normal.
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000440 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000441 "-0x1.ffffffffffffffffffffffff000cp-16000");
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000442 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000443 "-0x1.ffffffffffffffffffffffff000bp-16000");
444 EXPECT_EQ(test.next(false), APFloat::opOK);
445 EXPECT_TRUE(!test.isDenormal());
446 EXPECT_TRUE(test.isNegative());
447 EXPECT_TRUE(test.bitwiseIsEqual(expected));
448
449 // nextDown(-Normal) -> -Normal.
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000450 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000451 "-0x1.ffffffffffffffffffffffff000cp-16000");
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000452 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman964722c2013-05-30 18:07:13 +0000453 "-0x1.ffffffffffffffffffffffff000dp-16000");
454 EXPECT_EQ(test.next(true), APFloat::opOK);
455 EXPECT_TRUE(!test.isDenormal());
456 EXPECT_TRUE(test.isNegative());
457 EXPECT_TRUE(test.bitwiseIsEqual(expected));
458}
459
Shuxin Yang4b6b53b2013-05-13 18:03:12 +0000460TEST(APFloatTest, FMA) {
461 APFloat::roundingMode rdmd = APFloat::rmNearestTiesToEven;
462
463 {
464 APFloat f1(14.5f);
465 APFloat f2(-14.5f);
466 APFloat f3(225.0f);
467 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);
468 EXPECT_EQ(14.75f, f1.convertToFloat());
469 }
470
471 {
472 APFloat Val2(2.0f);
473 APFloat f1((float)1.17549435e-38F);
474 APFloat f2((float)1.17549435e-38F);
475 f1.divide(Val2, rdmd);
476 f2.divide(Val2, rdmd);
477 APFloat f3(12.0f);
478 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);
479 EXPECT_EQ(12.0f, f1.convertToFloat());
480 }
Lang Hames58c62e12014-11-19 19:15:41 +0000481
Lang Hamesa46dd582015-01-04 01:20:55 +0000482 // Test for correct zero sign when answer is exactly zero.
483 // fma(1.0, -1.0, 1.0) -> +ve 0.
484 {
485 APFloat f1(1.0);
486 APFloat f2(-1.0);
487 APFloat f3(1.0);
488 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);
489 EXPECT_TRUE(!f1.isNegative() && f1.isZero());
490 }
491
492 // Test for correct zero sign when answer is exactly zero and rounding towards
493 // negative.
494 // fma(1.0, -1.0, 1.0) -> +ve 0.
495 {
496 APFloat f1(1.0);
497 APFloat f2(-1.0);
498 APFloat f3(1.0);
499 f1.fusedMultiplyAdd(f2, f3, APFloat::rmTowardNegative);
500 EXPECT_TRUE(f1.isNegative() && f1.isZero());
501 }
502
503 // Test for correct (in this case -ve) sign when adding like signed zeros.
504 // Test fma(0.0, -0.0, -0.0) -> -ve 0.
505 {
506 APFloat f1(0.0);
507 APFloat f2(-0.0);
508 APFloat f3(-0.0);
509 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);
510 EXPECT_TRUE(f1.isNegative() && f1.isZero());
511 }
512
513 // Test -ve sign preservation when small negative results underflow.
514 {
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000515 APFloat f1(APFloat::IEEEdouble(), "-0x1p-1074");
516 APFloat f2(APFloat::IEEEdouble(), "+0x1p-1074");
Lang Hamesa46dd582015-01-04 01:20:55 +0000517 APFloat f3(0.0);
518 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);
519 EXPECT_TRUE(f1.isNegative() && f1.isZero());
520 }
521
522 // Test x87 extended precision case from http://llvm.org/PR20728.
Lang Hames58c62e12014-11-19 19:15:41 +0000523 {
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000524 APFloat M1(APFloat::x87DoubleExtended(), 1.0);
525 APFloat M2(APFloat::x87DoubleExtended(), 1.0);
526 APFloat A(APFloat::x87DoubleExtended(), 3.0);
Lang Hames58c62e12014-11-19 19:15:41 +0000527
528 bool losesInfo = false;
529 M1.fusedMultiplyAdd(M1, A, APFloat::rmNearestTiesToEven);
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000530 M1.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &losesInfo);
Lang Hames58c62e12014-11-19 19:15:41 +0000531 EXPECT_FALSE(losesInfo);
532 EXPECT_EQ(4.0f, M1.convertToFloat());
533 }
Shuxin Yang4b6b53b2013-05-13 18:03:12 +0000534}
535
Matt Arsenaultc08f0e32014-10-10 05:21:32 +0000536TEST(APFloatTest, MinNum) {
537 APFloat f1(1.0);
538 APFloat f2(2.0);
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000539 APFloat nan = APFloat::getNaN(APFloat::IEEEdouble());
Matt Arsenaultc08f0e32014-10-10 05:21:32 +0000540
541 EXPECT_EQ(1.0, minnum(f1, f2).convertToDouble());
542 EXPECT_EQ(1.0, minnum(f2, f1).convertToDouble());
543 EXPECT_EQ(1.0, minnum(f1, nan).convertToDouble());
544 EXPECT_EQ(1.0, minnum(nan, f1).convertToDouble());
545}
546
547TEST(APFloatTest, MaxNum) {
548 APFloat f1(1.0);
549 APFloat f2(2.0);
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000550 APFloat nan = APFloat::getNaN(APFloat::IEEEdouble());
Matt Arsenaultc08f0e32014-10-10 05:21:32 +0000551
552 EXPECT_EQ(2.0, maxnum(f1, f2).convertToDouble());
553 EXPECT_EQ(2.0, maxnum(f2, f1).convertToDouble());
554 EXPECT_EQ(1.0, maxnum(f1, nan).convertToDouble());
Chandler Carruth23efab22017-07-10 05:41:14 +0000555 EXPECT_EQ(1.0, maxnum(nan, f1).convertToDouble());
Matt Arsenaultc08f0e32014-10-10 05:21:32 +0000556}
557
Thomas Lively6e3463c2018-10-13 07:21:44 +0000558TEST(APFloatTest, Minimum) {
559 APFloat f1(1.0);
560 APFloat f2(2.0);
561 APFloat zp(0.0);
562 APFloat zn(-0.0);
563 APFloat nan = APFloat::getNaN(APFloat::IEEEdouble());
564
565 EXPECT_EQ(1.0, minimum(f1, f2).convertToDouble());
566 EXPECT_EQ(1.0, minimum(f2, f1).convertToDouble());
567 EXPECT_EQ(-0.0, minimum(zp, zn).convertToDouble());
568 EXPECT_EQ(-0.0, minimum(zn, zp).convertToDouble());
569 EXPECT_TRUE(std::isnan(minimum(f1, nan).convertToDouble()));
570 EXPECT_TRUE(std::isnan(minimum(nan, f1).convertToDouble()));
571}
572
573TEST(APFloatTest, Maximum) {
574 APFloat f1(1.0);
575 APFloat f2(2.0);
576 APFloat zp(0.0);
577 APFloat zn(-0.0);
578 APFloat nan = APFloat::getNaN(APFloat::IEEEdouble());
579
580 EXPECT_EQ(2.0, maximum(f1, f2).convertToDouble());
581 EXPECT_EQ(2.0, maximum(f2, f1).convertToDouble());
582 EXPECT_EQ(0.0, maximum(zp, zn).convertToDouble());
583 EXPECT_EQ(0.0, maximum(zn, zp).convertToDouble());
584 EXPECT_TRUE(std::isnan(maximum(f1, nan).convertToDouble()));
585 EXPECT_TRUE(std::isnan(maximum(nan, f1).convertToDouble()));
586}
587
Shuxin Yang7aa1c322013-01-07 18:59:35 +0000588TEST(APFloatTest, Denormal) {
589 APFloat::roundingMode rdmd = APFloat::rmNearestTiesToEven;
590
591 // Test single precision
592 {
593 const char *MinNormalStr = "1.17549435082228750797e-38";
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000594 EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), MinNormalStr).isDenormal());
595 EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), 0.0).isDenormal());
Shuxin Yang7aa1c322013-01-07 18:59:35 +0000596
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000597 APFloat Val2(APFloat::IEEEsingle(), 2.0e0);
598 APFloat T(APFloat::IEEEsingle(), MinNormalStr);
Shuxin Yang7aa1c322013-01-07 18:59:35 +0000599 T.divide(Val2, rdmd);
600 EXPECT_TRUE(T.isDenormal());
601 }
602
603 // Test double precision
604 {
605 const char *MinNormalStr = "2.22507385850720138309e-308";
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000606 EXPECT_FALSE(APFloat(APFloat::IEEEdouble(), MinNormalStr).isDenormal());
607 EXPECT_FALSE(APFloat(APFloat::IEEEdouble(), 0.0).isDenormal());
Shuxin Yang7aa1c322013-01-07 18:59:35 +0000608
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000609 APFloat Val2(APFloat::IEEEdouble(), 2.0e0);
610 APFloat T(APFloat::IEEEdouble(), MinNormalStr);
Shuxin Yang7aa1c322013-01-07 18:59:35 +0000611 T.divide(Val2, rdmd);
612 EXPECT_TRUE(T.isDenormal());
613 }
614
615 // Test Intel double-ext
616 {
617 const char *MinNormalStr = "3.36210314311209350626e-4932";
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000618 EXPECT_FALSE(APFloat(APFloat::x87DoubleExtended(), MinNormalStr).isDenormal());
619 EXPECT_FALSE(APFloat(APFloat::x87DoubleExtended(), 0.0).isDenormal());
Shuxin Yang7aa1c322013-01-07 18:59:35 +0000620
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000621 APFloat Val2(APFloat::x87DoubleExtended(), 2.0e0);
622 APFloat T(APFloat::x87DoubleExtended(), MinNormalStr);
Shuxin Yang7aa1c322013-01-07 18:59:35 +0000623 T.divide(Val2, rdmd);
624 EXPECT_TRUE(T.isDenormal());
625 }
626
627 // Test quadruple precision
628 {
629 const char *MinNormalStr = "3.36210314311209350626267781732175260e-4932";
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000630 EXPECT_FALSE(APFloat(APFloat::IEEEquad(), MinNormalStr).isDenormal());
631 EXPECT_FALSE(APFloat(APFloat::IEEEquad(), 0.0).isDenormal());
Shuxin Yang7aa1c322013-01-07 18:59:35 +0000632
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000633 APFloat Val2(APFloat::IEEEquad(), 2.0e0);
634 APFloat T(APFloat::IEEEquad(), MinNormalStr);
Shuxin Yang7aa1c322013-01-07 18:59:35 +0000635 T.divide(Val2, rdmd);
636 EXPECT_TRUE(T.isDenormal());
637 }
638}
639
Erick Tryzelaara15d8902009-08-16 23:36:19 +0000640TEST(APFloatTest, Zero) {
Matt Beaumont-Gay9d749092011-08-29 17:54:20 +0000641 EXPECT_EQ(0.0f, APFloat(0.0f).convertToFloat());
642 EXPECT_EQ(-0.0f, APFloat(-0.0f).convertToFloat());
643 EXPECT_TRUE(APFloat(-0.0f).isNegative());
Erick Tryzelaara15d8902009-08-16 23:36:19 +0000644
Matt Beaumont-Gay9d749092011-08-29 17:54:20 +0000645 EXPECT_EQ(0.0, APFloat(0.0).convertToDouble());
646 EXPECT_EQ(-0.0, APFloat(-0.0).convertToDouble());
647 EXPECT_TRUE(APFloat(-0.0).isNegative());
Erick Tryzelaara15d8902009-08-16 23:36:19 +0000648}
649
Michael Gottesmanb5777032013-07-01 23:54:08 +0000650TEST(APFloatTest, DecimalStringsWithoutNullTerminators) {
651 // Make sure that we can parse strings without null terminators.
652 // rdar://14323230.
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000653 APFloat Val(APFloat::IEEEdouble());
Michael Gottesmanb5777032013-07-01 23:54:08 +0000654 Val.convertFromString(StringRef("0.00", 3),
655 llvm::APFloat::rmNearestTiesToEven);
656 EXPECT_EQ(Val.convertToDouble(), 0.0);
657 Val.convertFromString(StringRef("0.01", 3),
658 llvm::APFloat::rmNearestTiesToEven);
659 EXPECT_EQ(Val.convertToDouble(), 0.0);
660 Val.convertFromString(StringRef("0.09", 3),
661 llvm::APFloat::rmNearestTiesToEven);
662 EXPECT_EQ(Val.convertToDouble(), 0.0);
663 Val.convertFromString(StringRef("0.095", 4),
664 llvm::APFloat::rmNearestTiesToEven);
665 EXPECT_EQ(Val.convertToDouble(), 0.09);
666 Val.convertFromString(StringRef("0.00e+3", 7),
667 llvm::APFloat::rmNearestTiesToEven);
668 EXPECT_EQ(Val.convertToDouble(), 0.00);
669 Val.convertFromString(StringRef("0e+3", 4),
670 llvm::APFloat::rmNearestTiesToEven);
671 EXPECT_EQ(Val.convertToDouble(), 0.00);
672
673}
674
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000675TEST(APFloatTest, fromZeroDecimalString) {
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000676 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0").convertToDouble());
677 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0").convertToDouble());
678 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000679
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000680 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.").convertToDouble());
681 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.").convertToDouble());
682 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000683
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000684 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), ".0").convertToDouble());
685 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+.0").convertToDouble());
686 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-.0").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000687
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000688 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.0").convertToDouble());
689 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.0").convertToDouble());
690 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.0").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000691
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000692 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "00000.").convertToDouble());
693 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+00000.").convertToDouble());
694 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-00000.").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000695
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000696 EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble(), ".00000").convertToDouble());
697 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+.00000").convertToDouble());
698 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-.00000").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000699
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000700 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0000.00000").convertToDouble());
701 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0000.00000").convertToDouble());
702 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0000.00000").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000703}
704
705TEST(APFloatTest, fromZeroDecimalSingleExponentString) {
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000706 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e1").convertToDouble());
707 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e1").convertToDouble());
708 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000709
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000710 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e+1").convertToDouble());
711 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e+1").convertToDouble());
712 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e+1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000713
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000714 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e-1").convertToDouble());
715 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e-1").convertToDouble());
716 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e-1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000717
718
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000719 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.e1").convertToDouble());
720 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.e1").convertToDouble());
721 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.e1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000722
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000723 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.e+1").convertToDouble());
724 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.e+1").convertToDouble());
725 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.e+1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000726
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000727 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.e-1").convertToDouble());
728 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.e-1").convertToDouble());
729 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.e-1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000730
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000731 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), ".0e1").convertToDouble());
732 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+.0e1").convertToDouble());
733 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-.0e1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000734
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000735 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), ".0e+1").convertToDouble());
736 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+.0e+1").convertToDouble());
737 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-.0e+1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000738
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000739 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), ".0e-1").convertToDouble());
740 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+.0e-1").convertToDouble());
741 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-.0e-1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000742
743
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000744 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.0e1").convertToDouble());
745 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.0e1").convertToDouble());
746 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.0e1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000747
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000748 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.0e+1").convertToDouble());
749 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.0e+1").convertToDouble());
750 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.0e+1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000751
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000752 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.0e-1").convertToDouble());
753 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.0e-1").convertToDouble());
754 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.0e-1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000755
756
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000757 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "000.0000e1").convertToDouble());
758 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+000.0000e+1").convertToDouble());
759 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-000.0000e+1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000760}
761
762TEST(APFloatTest, fromZeroDecimalLargeExponentString) {
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000763 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e1234").convertToDouble());
764 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e1234").convertToDouble());
765 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e1234").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000766
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000767 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e+1234").convertToDouble());
768 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e+1234").convertToDouble());
769 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e+1234").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000770
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000771 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e-1234").convertToDouble());
772 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e-1234").convertToDouble());
773 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e-1234").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000774
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000775 EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble(), "000.0000e1234").convertToDouble());
776 EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble(), "000.0000e-1234").convertToDouble());
Erick Tryzelaara15d8902009-08-16 23:36:19 +0000777
Chandler Carruthcf8b5602017-07-09 07:37:47 +0000778 EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble(), StringRef("0e1234" "\0" "2", 6)).convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000779}
Erick Tryzelaara15d8902009-08-16 23:36:19 +0000780
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000781TEST(APFloatTest, fromZeroHexadecimalString) {
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000782 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0p1").convertToDouble());
783 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0p1").convertToDouble());
784 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0p1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000785
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000786 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0p+1").convertToDouble());
787 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0p+1").convertToDouble());
788 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0p+1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000789
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000790 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0p-1").convertToDouble());
791 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0p-1").convertToDouble());
792 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0p-1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000793
794
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000795 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.p1").convertToDouble());
796 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.p1").convertToDouble());
797 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.p1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000798
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000799 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.p+1").convertToDouble());
800 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.p+1").convertToDouble());
801 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.p+1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000802
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000803 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.p-1").convertToDouble());
804 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.p-1").convertToDouble());
805 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.p-1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000806
807
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000808 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x.0p1").convertToDouble());
809 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x.0p1").convertToDouble());
810 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x.0p1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000811
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000812 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x.0p+1").convertToDouble());
813 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x.0p+1").convertToDouble());
814 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x.0p+1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000815
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000816 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x.0p-1").convertToDouble());
817 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x.0p-1").convertToDouble());
818 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x.0p-1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000819
820
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000821 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.0p1").convertToDouble());
822 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.0p1").convertToDouble());
823 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.0p1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000824
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000825 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.0p+1").convertToDouble());
826 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.0p+1").convertToDouble());
827 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.0p+1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000828
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000829 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.0p-1").convertToDouble());
830 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.0p-1").convertToDouble());
831 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.0p-1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000832
833
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000834 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x00000.p1").convertToDouble());
835 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0000.00000p1").convertToDouble());
836 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x.00000p1").convertToDouble());
837 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.p1").convertToDouble());
838 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0p1234").convertToDouble());
839 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0p1234").convertToDouble());
840 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x00000.p1234").convertToDouble());
841 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0000.00000p1234").convertToDouble());
842 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x.00000p1234").convertToDouble());
843 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.p1234").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000844}
845
846TEST(APFloatTest, fromDecimalString) {
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000847 EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1").convertToDouble());
848 EXPECT_EQ(2.0, APFloat(APFloat::IEEEdouble(), "2.").convertToDouble());
849 EXPECT_EQ(0.5, APFloat(APFloat::IEEEdouble(), ".5").convertToDouble());
850 EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1.0").convertToDouble());
851 EXPECT_EQ(-2.0, APFloat(APFloat::IEEEdouble(), "-2").convertToDouble());
852 EXPECT_EQ(-4.0, APFloat(APFloat::IEEEdouble(), "-4.").convertToDouble());
853 EXPECT_EQ(-0.5, APFloat(APFloat::IEEEdouble(), "-.5").convertToDouble());
854 EXPECT_EQ(-1.5, APFloat(APFloat::IEEEdouble(), "-1.5").convertToDouble());
855 EXPECT_EQ(1.25e12, APFloat(APFloat::IEEEdouble(), "1.25e12").convertToDouble());
856 EXPECT_EQ(1.25e+12, APFloat(APFloat::IEEEdouble(), "1.25e+12").convertToDouble());
857 EXPECT_EQ(1.25e-12, APFloat(APFloat::IEEEdouble(), "1.25e-12").convertToDouble());
858 EXPECT_EQ(1024.0, APFloat(APFloat::IEEEdouble(), "1024.").convertToDouble());
859 EXPECT_EQ(1024.05, APFloat(APFloat::IEEEdouble(), "1024.05000").convertToDouble());
860 EXPECT_EQ(0.05, APFloat(APFloat::IEEEdouble(), ".05000").convertToDouble());
861 EXPECT_EQ(2.0, APFloat(APFloat::IEEEdouble(), "2.").convertToDouble());
862 EXPECT_EQ(2.0e2, APFloat(APFloat::IEEEdouble(), "2.e2").convertToDouble());
863 EXPECT_EQ(2.0e+2, APFloat(APFloat::IEEEdouble(), "2.e+2").convertToDouble());
864 EXPECT_EQ(2.0e-2, APFloat(APFloat::IEEEdouble(), "2.e-2").convertToDouble());
865 EXPECT_EQ(2.05e2, APFloat(APFloat::IEEEdouble(), "002.05000e2").convertToDouble());
866 EXPECT_EQ(2.05e+2, APFloat(APFloat::IEEEdouble(), "002.05000e+2").convertToDouble());
867 EXPECT_EQ(2.05e-2, APFloat(APFloat::IEEEdouble(), "002.05000e-2").convertToDouble());
868 EXPECT_EQ(2.05e12, APFloat(APFloat::IEEEdouble(), "002.05000e12").convertToDouble());
869 EXPECT_EQ(2.05e+12, APFloat(APFloat::IEEEdouble(), "002.05000e+12").convertToDouble());
870 EXPECT_EQ(2.05e-12, APFloat(APFloat::IEEEdouble(), "002.05000e-12").convertToDouble());
John McCall8b3f3302010-02-26 22:20:41 +0000871
872 // These are "carefully selected" to overflow the fast log-base
873 // calculations in APFloat.cpp
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000874 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "99e99999").isInfinity());
875 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-99e99999").isInfinity());
876 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "1e-99999").isPosZero());
877 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-1e-99999").isNegZero());
Eli Friedman763c0662013-07-17 22:17:29 +0000878
879 EXPECT_EQ(2.71828, convertToDoubleFromString("2.71828"));
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000880}
881
Serguei Katkov643edab2017-12-19 04:27:39 +0000882TEST(APFloatTest, fromToStringSpecials) {
883 auto expects = [] (const char *first, const char *second) {
884 std::string roundtrip = convertToString(convertToDoubleFromString(second), 0, 3);
885 EXPECT_STREQ(first, roundtrip.c_str());
886 };
887 expects("+Inf", "+Inf");
888 expects("+Inf", "INFINITY");
889 expects("+Inf", "inf");
890 expects("-Inf", "-Inf");
891 expects("-Inf", "-INFINITY");
892 expects("-Inf", "-inf");
893 expects("NaN", "NaN");
894 expects("NaN", "nan");
895 expects("NaN", "-NaN");
896 expects("NaN", "-nan");
897}
898
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000899TEST(APFloatTest, fromHexadecimalString) {
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000900 EXPECT_EQ( 1.0, APFloat(APFloat::IEEEdouble(), "0x1p0").convertToDouble());
901 EXPECT_EQ(+1.0, APFloat(APFloat::IEEEdouble(), "+0x1p0").convertToDouble());
902 EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble(), "-0x1p0").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000903
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000904 EXPECT_EQ( 1.0, APFloat(APFloat::IEEEdouble(), "0x1p+0").convertToDouble());
905 EXPECT_EQ(+1.0, APFloat(APFloat::IEEEdouble(), "+0x1p+0").convertToDouble());
906 EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble(), "-0x1p+0").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000907
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000908 EXPECT_EQ( 1.0, APFloat(APFloat::IEEEdouble(), "0x1p-0").convertToDouble());
909 EXPECT_EQ(+1.0, APFloat(APFloat::IEEEdouble(), "+0x1p-0").convertToDouble());
910 EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble(), "-0x1p-0").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000911
912
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000913 EXPECT_EQ( 2.0, APFloat(APFloat::IEEEdouble(), "0x1p1").convertToDouble());
914 EXPECT_EQ(+2.0, APFloat(APFloat::IEEEdouble(), "+0x1p1").convertToDouble());
915 EXPECT_EQ(-2.0, APFloat(APFloat::IEEEdouble(), "-0x1p1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000916
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000917 EXPECT_EQ( 2.0, APFloat(APFloat::IEEEdouble(), "0x1p+1").convertToDouble());
918 EXPECT_EQ(+2.0, APFloat(APFloat::IEEEdouble(), "+0x1p+1").convertToDouble());
919 EXPECT_EQ(-2.0, APFloat(APFloat::IEEEdouble(), "-0x1p+1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000920
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000921 EXPECT_EQ( 0.5, APFloat(APFloat::IEEEdouble(), "0x1p-1").convertToDouble());
922 EXPECT_EQ(+0.5, APFloat(APFloat::IEEEdouble(), "+0x1p-1").convertToDouble());
923 EXPECT_EQ(-0.5, APFloat(APFloat::IEEEdouble(), "-0x1p-1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000924
925
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000926 EXPECT_EQ( 3.0, APFloat(APFloat::IEEEdouble(), "0x1.8p1").convertToDouble());
927 EXPECT_EQ(+3.0, APFloat(APFloat::IEEEdouble(), "+0x1.8p1").convertToDouble());
928 EXPECT_EQ(-3.0, APFloat(APFloat::IEEEdouble(), "-0x1.8p1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000929
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000930 EXPECT_EQ( 3.0, APFloat(APFloat::IEEEdouble(), "0x1.8p+1").convertToDouble());
931 EXPECT_EQ(+3.0, APFloat(APFloat::IEEEdouble(), "+0x1.8p+1").convertToDouble());
932 EXPECT_EQ(-3.0, APFloat(APFloat::IEEEdouble(), "-0x1.8p+1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000933
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000934 EXPECT_EQ( 0.75, APFloat(APFloat::IEEEdouble(), "0x1.8p-1").convertToDouble());
935 EXPECT_EQ(+0.75, APFloat(APFloat::IEEEdouble(), "+0x1.8p-1").convertToDouble());
936 EXPECT_EQ(-0.75, APFloat(APFloat::IEEEdouble(), "-0x1.8p-1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000937
938
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000939 EXPECT_EQ( 8192.0, APFloat(APFloat::IEEEdouble(), "0x1000.000p1").convertToDouble());
940 EXPECT_EQ(+8192.0, APFloat(APFloat::IEEEdouble(), "+0x1000.000p1").convertToDouble());
941 EXPECT_EQ(-8192.0, APFloat(APFloat::IEEEdouble(), "-0x1000.000p1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000942
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000943 EXPECT_EQ( 8192.0, APFloat(APFloat::IEEEdouble(), "0x1000.000p+1").convertToDouble());
944 EXPECT_EQ(+8192.0, APFloat(APFloat::IEEEdouble(), "+0x1000.000p+1").convertToDouble());
945 EXPECT_EQ(-8192.0, APFloat(APFloat::IEEEdouble(), "-0x1000.000p+1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000946
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000947 EXPECT_EQ( 2048.0, APFloat(APFloat::IEEEdouble(), "0x1000.000p-1").convertToDouble());
948 EXPECT_EQ(+2048.0, APFloat(APFloat::IEEEdouble(), "+0x1000.000p-1").convertToDouble());
949 EXPECT_EQ(-2048.0, APFloat(APFloat::IEEEdouble(), "-0x1000.000p-1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000950
951
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000952 EXPECT_EQ( 8192.0, APFloat(APFloat::IEEEdouble(), "0x1000p1").convertToDouble());
953 EXPECT_EQ(+8192.0, APFloat(APFloat::IEEEdouble(), "+0x1000p1").convertToDouble());
954 EXPECT_EQ(-8192.0, APFloat(APFloat::IEEEdouble(), "-0x1000p1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000955
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000956 EXPECT_EQ( 8192.0, APFloat(APFloat::IEEEdouble(), "0x1000p+1").convertToDouble());
957 EXPECT_EQ(+8192.0, APFloat(APFloat::IEEEdouble(), "+0x1000p+1").convertToDouble());
958 EXPECT_EQ(-8192.0, APFloat(APFloat::IEEEdouble(), "-0x1000p+1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000959
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000960 EXPECT_EQ( 2048.0, APFloat(APFloat::IEEEdouble(), "0x1000p-1").convertToDouble());
961 EXPECT_EQ(+2048.0, APFloat(APFloat::IEEEdouble(), "+0x1000p-1").convertToDouble());
962 EXPECT_EQ(-2048.0, APFloat(APFloat::IEEEdouble(), "-0x1000p-1").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000963
964
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000965 EXPECT_EQ( 16384.0, APFloat(APFloat::IEEEdouble(), "0x10p10").convertToDouble());
966 EXPECT_EQ(+16384.0, APFloat(APFloat::IEEEdouble(), "+0x10p10").convertToDouble());
967 EXPECT_EQ(-16384.0, APFloat(APFloat::IEEEdouble(), "-0x10p10").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000968
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000969 EXPECT_EQ( 16384.0, APFloat(APFloat::IEEEdouble(), "0x10p+10").convertToDouble());
970 EXPECT_EQ(+16384.0, APFloat(APFloat::IEEEdouble(), "+0x10p+10").convertToDouble());
971 EXPECT_EQ(-16384.0, APFloat(APFloat::IEEEdouble(), "-0x10p+10").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000972
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000973 EXPECT_EQ( 0.015625, APFloat(APFloat::IEEEdouble(), "0x10p-10").convertToDouble());
974 EXPECT_EQ(+0.015625, APFloat(APFloat::IEEEdouble(), "+0x10p-10").convertToDouble());
975 EXPECT_EQ(-0.015625, APFloat(APFloat::IEEEdouble(), "-0x10p-10").convertToDouble());
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +0000976
Stephan Bergmann20a600c2016-12-14 11:57:17 +0000977 EXPECT_EQ(1.0625, APFloat(APFloat::IEEEdouble(), "0x1.1p0").convertToDouble());
978 EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "0x1p0").convertToDouble());
Daniel Dunbar83fecfa2009-09-03 22:57:02 +0000979
Eli Friedman763c0662013-07-17 22:17:29 +0000980 EXPECT_EQ(convertToDoubleFromString("0x1p-150"),
981 convertToDoubleFromString("+0x800000000000000001.p-221"));
982 EXPECT_EQ(2251799813685248.5,
983 convertToDoubleFromString("0x80000000000004000000.010p-28"));
Erick Tryzelaara15d8902009-08-16 23:36:19 +0000984}
985
John McCall00e65de2009-12-24 08:56:26 +0000986TEST(APFloatTest, toString) {
987 ASSERT_EQ("10", convertToString(10.0, 6, 3));
988 ASSERT_EQ("1.0E+1", convertToString(10.0, 6, 0));
989 ASSERT_EQ("10100", convertToString(1.01E+4, 5, 2));
990 ASSERT_EQ("1.01E+4", convertToString(1.01E+4, 4, 2));
991 ASSERT_EQ("1.01E+4", convertToString(1.01E+4, 5, 1));
992 ASSERT_EQ("0.0101", convertToString(1.01E-2, 5, 2));
John McCall6a09aff2009-12-24 23:18:09 +0000993 ASSERT_EQ("0.0101", convertToString(1.01E-2, 4, 2));
John McCall00e65de2009-12-24 08:56:26 +0000994 ASSERT_EQ("1.01E-2", convertToString(1.01E-2, 5, 1));
Eli Friedman1053a0b2013-08-29 23:44:34 +0000995 ASSERT_EQ("0.78539816339744828", convertToString(0.78539816339744830961, 0, 3));
996 ASSERT_EQ("4.9406564584124654E-324", convertToString(4.9406564584124654e-324, 0, 3));
997 ASSERT_EQ("873.18340000000001", convertToString(873.1834, 0, 1));
998 ASSERT_EQ("8.7318340000000001E+2", convertToString(873.1834, 0, 0));
999 ASSERT_EQ("1.7976931348623157E+308", convertToString(1.7976931348623157E+308, 0, 0));
Serguei Katkovc849a0c2017-04-21 02:52:17 +00001000 ASSERT_EQ("10", convertToString(10.0, 6, 3, false));
1001 ASSERT_EQ("1.000000e+01", convertToString(10.0, 6, 0, false));
1002 ASSERT_EQ("10100", convertToString(1.01E+4, 5, 2, false));
1003 ASSERT_EQ("1.0100e+04", convertToString(1.01E+4, 4, 2, false));
1004 ASSERT_EQ("1.01000e+04", convertToString(1.01E+4, 5, 1, false));
1005 ASSERT_EQ("0.0101", convertToString(1.01E-2, 5, 2, false));
1006 ASSERT_EQ("0.0101", convertToString(1.01E-2, 4, 2, false));
1007 ASSERT_EQ("1.01000e-02", convertToString(1.01E-2, 5, 1, false));
1008 ASSERT_EQ("0.78539816339744828",
1009 convertToString(0.78539816339744830961, 0, 3, false));
1010 ASSERT_EQ("4.94065645841246540e-324",
1011 convertToString(4.9406564584124654e-324, 0, 3, false));
1012 ASSERT_EQ("873.18340000000001", convertToString(873.1834, 0, 1, false));
1013 ASSERT_EQ("8.73183400000000010e+02", convertToString(873.1834, 0, 0, false));
1014 ASSERT_EQ("1.79769313486231570e+308",
1015 convertToString(1.7976931348623157E+308, 0, 0, false));
Pavel Labath277cedd2018-05-09 15:13:45 +00001016
1017 {
1018 SmallString<64> Str;
1019 APFloat UnnormalZero(APFloat::x87DoubleExtended(), APInt(80, {0, 1}));
1020 UnnormalZero.toString(Str);
1021 ASSERT_EQ("NaN", Str);
1022 }
John McCall00e65de2009-12-24 08:56:26 +00001023}
1024
Jeffrey Yasskin3d42bfb2011-07-15 07:04:56 +00001025TEST(APFloatTest, toInteger) {
1026 bool isExact = false;
1027 APSInt result(5, /*isUnsigned=*/true);
1028
1029 EXPECT_EQ(APFloat::opOK,
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001030 APFloat(APFloat::IEEEdouble(), "10")
Jeffrey Yasskin3d42bfb2011-07-15 07:04:56 +00001031 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
1032 EXPECT_TRUE(isExact);
1033 EXPECT_EQ(APSInt(APInt(5, 10), true), result);
1034
1035 EXPECT_EQ(APFloat::opInvalidOp,
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001036 APFloat(APFloat::IEEEdouble(), "-10")
Jeffrey Yasskin3d42bfb2011-07-15 07:04:56 +00001037 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
1038 EXPECT_FALSE(isExact);
1039 EXPECT_EQ(APSInt::getMinValue(5, true), result);
1040
1041 EXPECT_EQ(APFloat::opInvalidOp,
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001042 APFloat(APFloat::IEEEdouble(), "32")
Jeffrey Yasskin3d42bfb2011-07-15 07:04:56 +00001043 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
1044 EXPECT_FALSE(isExact);
1045 EXPECT_EQ(APSInt::getMaxValue(5, true), result);
1046
1047 EXPECT_EQ(APFloat::opInexact,
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001048 APFloat(APFloat::IEEEdouble(), "7.9")
Jeffrey Yasskin3d42bfb2011-07-15 07:04:56 +00001049 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
1050 EXPECT_FALSE(isExact);
1051 EXPECT_EQ(APSInt(APInt(5, 7), true), result);
1052
1053 result.setIsUnsigned(false);
1054 EXPECT_EQ(APFloat::opOK,
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001055 APFloat(APFloat::IEEEdouble(), "-10")
Jeffrey Yasskin3d42bfb2011-07-15 07:04:56 +00001056 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
1057 EXPECT_TRUE(isExact);
1058 EXPECT_EQ(APSInt(APInt(5, -10, true), false), result);
1059
1060 EXPECT_EQ(APFloat::opInvalidOp,
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001061 APFloat(APFloat::IEEEdouble(), "-17")
Jeffrey Yasskin3d42bfb2011-07-15 07:04:56 +00001062 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
1063 EXPECT_FALSE(isExact);
1064 EXPECT_EQ(APSInt::getMinValue(5, false), result);
1065
1066 EXPECT_EQ(APFloat::opInvalidOp,
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001067 APFloat(APFloat::IEEEdouble(), "16")
Jeffrey Yasskin3d42bfb2011-07-15 07:04:56 +00001068 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
1069 EXPECT_FALSE(isExact);
1070 EXPECT_EQ(APSInt::getMaxValue(5, false), result);
1071}
1072
JF Bastiene3796d32018-12-10 19:27:38 +00001073static APInt nanbitsFromAPInt(const fltSemantics &Sem, bool SNaN, bool Negative,
1074 uint64_t payload) {
1075 APInt appayload(64, payload);
John McCalle12b7382010-02-28 02:51:25 +00001076 if (SNaN)
JF Bastiene3796d32018-12-10 19:27:38 +00001077 return APFloat::getSNaN(Sem, Negative, &appayload).bitcastToAPInt();
John McCalle12b7382010-02-28 02:51:25 +00001078 else
JF Bastiene3796d32018-12-10 19:27:38 +00001079 return APFloat::getQNaN(Sem, Negative, &appayload).bitcastToAPInt();
John McCalle12b7382010-02-28 02:51:25 +00001080}
1081
1082TEST(APFloatTest, makeNaN) {
JF Bastiene3796d32018-12-10 19:27:38 +00001083 const struct {
1084 uint64_t expected;
1085 const fltSemantics &semantics;
1086 bool SNaN;
1087 bool Negative;
1088 uint64_t payload;
1089 } tests[] = {
1090 /* expected semantics SNaN Neg payload */
1091 { 0x7fc00000ULL, APFloat::IEEEsingle(), false, false, 0x00000000ULL },
1092 { 0xffc00000ULL, APFloat::IEEEsingle(), false, true, 0x00000000ULL },
1093 { 0x7fc0ae72ULL, APFloat::IEEEsingle(), false, false, 0x0000ae72ULL },
1094 { 0x7fffae72ULL, APFloat::IEEEsingle(), false, false, 0xffffae72ULL },
1095 { 0x7fdaae72ULL, APFloat::IEEEsingle(), false, false, 0x00daae72ULL },
1096 { 0x7fa00000ULL, APFloat::IEEEsingle(), true, false, 0x00000000ULL },
1097 { 0xffa00000ULL, APFloat::IEEEsingle(), true, true, 0x00000000ULL },
1098 { 0x7f80ae72ULL, APFloat::IEEEsingle(), true, false, 0x0000ae72ULL },
1099 { 0x7fbfae72ULL, APFloat::IEEEsingle(), true, false, 0xffffae72ULL },
1100 { 0x7f9aae72ULL, APFloat::IEEEsingle(), true, false, 0x001aae72ULL },
1101 { 0x7ff8000000000000ULL, APFloat::IEEEdouble(), false, false, 0x0000000000000000ULL },
1102 { 0xfff8000000000000ULL, APFloat::IEEEdouble(), false, true, 0x0000000000000000ULL },
1103 { 0x7ff800000000ae72ULL, APFloat::IEEEdouble(), false, false, 0x000000000000ae72ULL },
1104 { 0x7fffffffffffae72ULL, APFloat::IEEEdouble(), false, false, 0xffffffffffffae72ULL },
1105 { 0x7ffdaaaaaaaaae72ULL, APFloat::IEEEdouble(), false, false, 0x000daaaaaaaaae72ULL },
1106 { 0x7ff4000000000000ULL, APFloat::IEEEdouble(), true, false, 0x0000000000000000ULL },
1107 { 0xfff4000000000000ULL, APFloat::IEEEdouble(), true, true, 0x0000000000000000ULL },
1108 { 0x7ff000000000ae72ULL, APFloat::IEEEdouble(), true, false, 0x000000000000ae72ULL },
1109 { 0x7ff7ffffffffae72ULL, APFloat::IEEEdouble(), true, false, 0xffffffffffffae72ULL },
1110 { 0x7ff1aaaaaaaaae72ULL, APFloat::IEEEdouble(), true, false, 0x0001aaaaaaaaae72ULL },
1111 };
John McCalle12b7382010-02-28 02:51:25 +00001112
JF Bastiene3796d32018-12-10 19:27:38 +00001113 for (const auto &t : tests) {
1114 ASSERT_EQ(t.expected, nanbitsFromAPInt(t.semantics, t.SNaN, t.Negative, t.payload));
1115 }
John McCalle12b7382010-02-28 02:51:25 +00001116}
1117
Erick Tryzelaar2ad40a32009-08-17 00:55:33 +00001118#ifdef GTEST_HAS_DEATH_TEST
Jeffrey Yasskinb5f59f52010-03-17 01:18:45 +00001119#ifndef NDEBUG
Erick Tryzelaar2ad40a32009-08-17 00:55:33 +00001120TEST(APFloatTest, SemanticsDeath) {
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001121 EXPECT_DEATH(APFloat(APFloat::IEEEsingle(), 0.0f).convertToDouble(), "Float semantics are not IEEEdouble");
1122 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), 0.0 ).convertToFloat(), "Float semantics are not IEEEsingle");
Erick Tryzelaar2ad40a32009-08-17 00:55:33 +00001123}
1124
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001125TEST(APFloatTest, StringDecimalDeath) {
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001126 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ""), "Invalid string length");
1127 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+"), "String has no digits");
1128 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-"), "String has no digits");
Erick Tryzelaara15d8902009-08-16 23:36:19 +00001129
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001130 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("\0", 1)), "Invalid character in significand");
1131 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("1\0", 2)), "Invalid character in significand");
Chandler Carruthcf8b5602017-07-09 07:37:47 +00001132 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("1" "\0" "2", 3)), "Invalid character in significand");
1133 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("1" "\0" "2e1", 5)), "Invalid character in significand");
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001134 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("1e\0", 3)), "Invalid character in exponent");
1135 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("1e1\0", 4)), "Invalid character in exponent");
Chandler Carruthcf8b5602017-07-09 07:37:47 +00001136 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("1e1" "\0" "2", 5)), "Invalid character in exponent");
Erick Tryzelaara15d8902009-08-16 23:36:19 +00001137
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001138 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.0f"), "Invalid character in significand");
Erick Tryzelaara15d8902009-08-16 23:36:19 +00001139
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001140 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".."), "String contains multiple dots");
1141 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "..0"), "String contains multiple dots");
1142 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.0.0"), "String contains multiple dots");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001143}
1144
1145TEST(APFloatTest, StringDecimalSignificandDeath) {
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001146 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "."), "Significand has no digits");
1147 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+."), "Significand has no digits");
1148 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-."), "Significand has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001149
1150
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001151 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "e"), "Significand has no digits");
1152 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+e"), "Significand has no digits");
1153 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-e"), "Significand has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001154
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001155 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "e1"), "Significand has no digits");
1156 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+e1"), "Significand has no digits");
1157 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-e1"), "Significand has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001158
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001159 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".e1"), "Significand has no digits");
1160 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+.e1"), "Significand has no digits");
1161 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-.e1"), "Significand has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001162
1163
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001164 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".e"), "Significand has no digits");
1165 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+.e"), "Significand has no digits");
1166 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-.e"), "Significand has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001167}
1168
1169TEST(APFloatTest, StringDecimalExponentDeath) {
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001170 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1e"), "Exponent has no digits");
1171 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+1e"), "Exponent has no digits");
1172 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-1e"), "Exponent has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001173
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001174 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.e"), "Exponent has no digits");
1175 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+1.e"), "Exponent has no digits");
1176 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-1.e"), "Exponent has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001177
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001178 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".1e"), "Exponent has no digits");
1179 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+.1e"), "Exponent has no digits");
1180 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-.1e"), "Exponent has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001181
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001182 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.1e"), "Exponent has no digits");
1183 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+1.1e"), "Exponent has no digits");
1184 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-1.1e"), "Exponent has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001185
1186
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001187 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1e+"), "Exponent has no digits");
1188 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1e-"), "Exponent has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001189
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001190 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".1e"), "Exponent has no digits");
1191 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".1e+"), "Exponent has no digits");
1192 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".1e-"), "Exponent has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001193
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001194 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.0e"), "Exponent has no digits");
1195 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.0e+"), "Exponent has no digits");
1196 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.0e-"), "Exponent has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001197}
1198
1199TEST(APFloatTest, StringHexadecimalDeath) {
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001200 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x"), "Invalid string");
1201 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x"), "Invalid string");
1202 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x"), "Invalid string");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001203
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001204 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x0"), "Hex strings require an exponent");
1205 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x0"), "Hex strings require an exponent");
1206 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x0"), "Hex strings require an exponent");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001207
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001208 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x0."), "Hex strings require an exponent");
1209 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x0."), "Hex strings require an exponent");
1210 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x0."), "Hex strings require an exponent");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001211
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001212 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x.0"), "Hex strings require an exponent");
1213 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x.0"), "Hex strings require an exponent");
1214 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x.0"), "Hex strings require an exponent");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001215
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001216 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x0.0"), "Hex strings require an exponent");
1217 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x0.0"), "Hex strings require an exponent");
1218 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x0.0"), "Hex strings require an exponent");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001219
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001220 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("0x\0", 3)), "Invalid character in significand");
1221 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("0x1\0", 4)), "Invalid character in significand");
Chandler Carruthcf8b5602017-07-09 07:37:47 +00001222 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("0x1" "\0" "2", 5)), "Invalid character in significand");
1223 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("0x1" "\0" "2p1", 7)), "Invalid character in significand");
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001224 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("0x1p\0", 5)), "Invalid character in exponent");
1225 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("0x1p1\0", 6)), "Invalid character in exponent");
Chandler Carruthcf8b5602017-07-09 07:37:47 +00001226 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("0x1p1" "\0" "2", 7)), "Invalid character in exponent");
Erick Tryzelaara15d8902009-08-16 23:36:19 +00001227
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001228 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1p0f"), "Invalid character in exponent");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001229
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001230 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x..p1"), "String contains multiple dots");
1231 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x..0p1"), "String contains multiple dots");
1232 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1.0.0p1"), "String contains multiple dots");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001233}
1234
1235TEST(APFloatTest, StringHexadecimalSignificandDeath) {
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001236 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x."), "Significand has no digits");
1237 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x."), "Significand has no digits");
1238 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x."), "Significand has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001239
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001240 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0xp"), "Significand has no digits");
1241 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0xp"), "Significand has no digits");
1242 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0xp"), "Significand has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001243
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001244 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0xp+"), "Significand has no digits");
1245 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0xp+"), "Significand has no digits");
1246 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0xp+"), "Significand has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001247
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001248 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0xp-"), "Significand has no digits");
1249 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0xp-"), "Significand has no digits");
1250 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0xp-"), "Significand has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001251
1252
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001253 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x.p"), "Significand has no digits");
1254 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x.p"), "Significand has no digits");
1255 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x.p"), "Significand has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001256
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001257 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x.p+"), "Significand has no digits");
1258 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x.p+"), "Significand has no digits");
1259 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x.p+"), "Significand has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001260
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001261 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x.p-"), "Significand has no digits");
1262 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x.p-"), "Significand has no digits");
1263 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x.p-"), "Significand has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001264}
1265
1266TEST(APFloatTest, StringHexadecimalExponentDeath) {
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001267 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1p"), "Exponent has no digits");
1268 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1p"), "Exponent has no digits");
1269 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1p"), "Exponent has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001270
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001271 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1p+"), "Exponent has no digits");
1272 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1p+"), "Exponent has no digits");
1273 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1p+"), "Exponent has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001274
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001275 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1p-"), "Exponent has no digits");
1276 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1p-"), "Exponent has no digits");
1277 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1p-"), "Exponent has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001278
1279
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001280 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1.p"), "Exponent has no digits");
1281 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1.p"), "Exponent has no digits");
1282 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1.p"), "Exponent has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001283
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001284 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1.p+"), "Exponent has no digits");
1285 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1.p+"), "Exponent has no digits");
1286 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1.p+"), "Exponent has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001287
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001288 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1.p-"), "Exponent has no digits");
1289 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1.p-"), "Exponent has no digits");
1290 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1.p-"), "Exponent has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001291
1292
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001293 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x.1p"), "Exponent has no digits");
1294 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x.1p"), "Exponent has no digits");
1295 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x.1p"), "Exponent has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001296
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001297 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x.1p+"), "Exponent has no digits");
1298 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x.1p+"), "Exponent has no digits");
1299 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x.1p+"), "Exponent has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001300
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001301 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x.1p-"), "Exponent has no digits");
1302 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x.1p-"), "Exponent has no digits");
1303 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x.1p-"), "Exponent has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001304
1305
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001306 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1.1p"), "Exponent has no digits");
1307 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1.1p"), "Exponent has no digits");
1308 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1.1p"), "Exponent has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001309
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001310 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1.1p+"), "Exponent has no digits");
1311 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1.1p+"), "Exponent has no digits");
1312 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1.1p+"), "Exponent has no digits");
Erick Tryzelaarc78b33b2009-08-20 23:30:43 +00001313
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001314 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1.1p-"), "Exponent has no digits");
1315 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1.1p-"), "Exponent has no digits");
1316 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1.1p-"), "Exponent has no digits");
Erick Tryzelaara15d8902009-08-16 23:36:19 +00001317}
Erick Tryzelaar2ad40a32009-08-17 00:55:33 +00001318#endif
Jeffrey Yasskinb5f59f52010-03-17 01:18:45 +00001319#endif
Erick Tryzelaara15d8902009-08-16 23:36:19 +00001320
Benjamin Kramer27460002011-03-30 15:42:27 +00001321TEST(APFloatTest, exactInverse) {
1322 APFloat inv(0.0f);
1323
1324 // Trivial operation.
1325 EXPECT_TRUE(APFloat(2.0).getExactInverse(&inv));
1326 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(0.5)));
1327 EXPECT_TRUE(APFloat(2.0f).getExactInverse(&inv));
1328 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(0.5f)));
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001329 EXPECT_TRUE(APFloat(APFloat::IEEEquad(), "2.0").getExactInverse(&inv));
1330 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(APFloat::IEEEquad(), "0.5")));
1331 EXPECT_TRUE(APFloat(APFloat::PPCDoubleDouble(), "2.0").getExactInverse(&inv));
1332 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(APFloat::PPCDoubleDouble(), "0.5")));
1333 EXPECT_TRUE(APFloat(APFloat::x87DoubleExtended(), "2.0").getExactInverse(&inv));
1334 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(APFloat::x87DoubleExtended(), "0.5")));
Benjamin Kramer27460002011-03-30 15:42:27 +00001335
1336 // FLT_MIN
1337 EXPECT_TRUE(APFloat(1.17549435e-38f).getExactInverse(&inv));
1338 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(8.5070592e+37f)));
1339
Benjamin Kramer83985122011-03-30 17:02:54 +00001340 // Large float, inverse is a denormal.
Craig Topperb1770412014-06-08 22:29:17 +00001341 EXPECT_FALSE(APFloat(1.7014118e38f).getExactInverse(nullptr));
Benjamin Kramer27460002011-03-30 15:42:27 +00001342 // Zero
Craig Topperb1770412014-06-08 22:29:17 +00001343 EXPECT_FALSE(APFloat(0.0).getExactInverse(nullptr));
Benjamin Kramer27460002011-03-30 15:42:27 +00001344 // Denormalized float
Craig Topperb1770412014-06-08 22:29:17 +00001345 EXPECT_FALSE(APFloat(1.40129846e-45f).getExactInverse(nullptr));
Benjamin Kramer27460002011-03-30 15:42:27 +00001346}
1347
Owen Andersonf7a5dfc2012-08-15 05:39:46 +00001348TEST(APFloatTest, roundToIntegral) {
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001349 APFloat T(-0.5), S(3.14), R(APFloat::getLargest(APFloat::IEEEdouble())), P(0.0);
Owen Andersonf7a5dfc2012-08-15 05:39:46 +00001350
1351 P = T;
1352 P.roundToIntegral(APFloat::rmTowardZero);
1353 EXPECT_EQ(-0.0, P.convertToDouble());
1354 P = T;
1355 P.roundToIntegral(APFloat::rmTowardNegative);
1356 EXPECT_EQ(-1.0, P.convertToDouble());
1357 P = T;
1358 P.roundToIntegral(APFloat::rmTowardPositive);
1359 EXPECT_EQ(-0.0, P.convertToDouble());
1360 P = T;
1361 P.roundToIntegral(APFloat::rmNearestTiesToEven);
1362 EXPECT_EQ(-0.0, P.convertToDouble());
1363
1364 P = S;
1365 P.roundToIntegral(APFloat::rmTowardZero);
1366 EXPECT_EQ(3.0, P.convertToDouble());
1367 P = S;
1368 P.roundToIntegral(APFloat::rmTowardNegative);
1369 EXPECT_EQ(3.0, P.convertToDouble());
1370 P = S;
1371 P.roundToIntegral(APFloat::rmTowardPositive);
1372 EXPECT_EQ(4.0, P.convertToDouble());
1373 P = S;
1374 P.roundToIntegral(APFloat::rmNearestTiesToEven);
1375 EXPECT_EQ(3.0, P.convertToDouble());
Owen Andersonc82cc582012-08-15 18:28:45 +00001376
1377 P = R;
1378 P.roundToIntegral(APFloat::rmTowardZero);
1379 EXPECT_EQ(R.convertToDouble(), P.convertToDouble());
1380 P = R;
1381 P.roundToIntegral(APFloat::rmTowardNegative);
1382 EXPECT_EQ(R.convertToDouble(), P.convertToDouble());
1383 P = R;
1384 P.roundToIntegral(APFloat::rmTowardPositive);
1385 EXPECT_EQ(R.convertToDouble(), P.convertToDouble());
1386 P = R;
1387 P.roundToIntegral(APFloat::rmNearestTiesToEven);
1388 EXPECT_EQ(R.convertToDouble(), P.convertToDouble());
Benjamin Kramer3e7735f2012-09-26 14:06:58 +00001389
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001390 P = APFloat::getZero(APFloat::IEEEdouble());
Benjamin Kramer3e7735f2012-09-26 14:06:58 +00001391 P.roundToIntegral(APFloat::rmTowardZero);
1392 EXPECT_EQ(0.0, P.convertToDouble());
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001393 P = APFloat::getZero(APFloat::IEEEdouble(), true);
Benjamin Kramer3e7735f2012-09-26 14:06:58 +00001394 P.roundToIntegral(APFloat::rmTowardZero);
1395 EXPECT_EQ(-0.0, P.convertToDouble());
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001396 P = APFloat::getNaN(APFloat::IEEEdouble());
Benjamin Kramer3e7735f2012-09-26 14:06:58 +00001397 P.roundToIntegral(APFloat::rmTowardZero);
Benjamin Kramer0df66b82015-03-09 18:35:18 +00001398 EXPECT_TRUE(std::isnan(P.convertToDouble()));
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001399 P = APFloat::getInf(APFloat::IEEEdouble());
Benjamin Kramer3e7735f2012-09-26 14:06:58 +00001400 P.roundToIntegral(APFloat::rmTowardZero);
Benjamin Kramer0df66b82015-03-09 18:35:18 +00001401 EXPECT_TRUE(std::isinf(P.convertToDouble()) && P.convertToDouble() > 0.0);
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001402 P = APFloat::getInf(APFloat::IEEEdouble(), true);
Benjamin Kramer3e7735f2012-09-26 14:06:58 +00001403 P.roundToIntegral(APFloat::rmTowardZero);
Benjamin Kramer0df66b82015-03-09 18:35:18 +00001404 EXPECT_TRUE(std::isinf(P.convertToDouble()) && P.convertToDouble() < 0.0);
Stephen Canon0136ee92015-11-16 21:52:48 +00001405}
Matt Arsenault7c9226f2016-03-21 16:49:16 +00001406
Stephen Canon0136ee92015-11-16 21:52:48 +00001407TEST(APFloatTest, isInteger) {
1408 APFloat T(-0.0);
1409 EXPECT_TRUE(T.isInteger());
1410 T = APFloat(3.14159);
1411 EXPECT_FALSE(T.isInteger());
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001412 T = APFloat::getNaN(APFloat::IEEEdouble());
Stephen Canon0136ee92015-11-16 21:52:48 +00001413 EXPECT_FALSE(T.isInteger());
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001414 T = APFloat::getInf(APFloat::IEEEdouble());
Stephen Canon0136ee92015-11-16 21:52:48 +00001415 EXPECT_FALSE(T.isInteger());
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001416 T = APFloat::getInf(APFloat::IEEEdouble(), true);
Stephen Canon0136ee92015-11-16 21:52:48 +00001417 EXPECT_FALSE(T.isInteger());
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001418 T = APFloat::getLargest(APFloat::IEEEdouble());
Stephen Canon0136ee92015-11-16 21:52:48 +00001419 EXPECT_TRUE(T.isInteger());
Owen Andersonf7a5dfc2012-08-15 05:39:46 +00001420}
1421
Davide Italiano6d970032017-08-21 16:51:54 +00001422TEST(DoubleAPFloatTest, isInteger) {
1423 APFloat F1(-0.0);
1424 APFloat F2(-0.0);
1425 llvm::detail::DoubleAPFloat T(APFloat::PPCDoubleDouble(), std::move(F1),
1426 std::move(F2));
1427 EXPECT_TRUE(T.isInteger());
1428 APFloat F3(3.14159);
1429 APFloat F4(-0.0);
1430 llvm::detail::DoubleAPFloat T2(APFloat::PPCDoubleDouble(), std::move(F3),
1431 std::move(F4));
1432 EXPECT_FALSE(T2.isInteger());
1433 APFloat F5(-0.0);
1434 APFloat F6(3.14159);
1435 llvm::detail::DoubleAPFloat T3(APFloat::PPCDoubleDouble(), std::move(F5),
1436 std::move(F6));
1437 EXPECT_FALSE(T3.isInteger());
1438}
1439
Eli Friedman7247a5f2011-10-12 21:51:36 +00001440TEST(APFloatTest, getLargest) {
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001441 EXPECT_EQ(3.402823466e+38f, APFloat::getLargest(APFloat::IEEEsingle()).convertToFloat());
1442 EXPECT_EQ(1.7976931348623158e+308, APFloat::getLargest(APFloat::IEEEdouble()).convertToDouble());
Eli Friedman7247a5f2011-10-12 21:51:36 +00001443}
1444
Michael Gottesman3e8d3562013-05-29 23:58:29 +00001445TEST(APFloatTest, getSmallest) {
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001446 APFloat test = APFloat::getSmallest(APFloat::IEEEsingle(), false);
1447 APFloat expected = APFloat(APFloat::IEEEsingle(), "0x0.000002p-126");
Michael Gottesman7d13d522013-05-30 00:18:44 +00001448 EXPECT_FALSE(test.isNegative());
Michael Gottesman4f71c1b2013-06-19 21:53:45 +00001449 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman7d13d522013-05-30 00:18:44 +00001450 EXPECT_TRUE(test.isDenormal());
Michael Gottesman3e8d3562013-05-29 23:58:29 +00001451 EXPECT_TRUE(test.bitwiseIsEqual(expected));
1452
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001453 test = APFloat::getSmallest(APFloat::IEEEsingle(), true);
1454 expected = APFloat(APFloat::IEEEsingle(), "-0x0.000002p-126");
Michael Gottesman3e8d3562013-05-29 23:58:29 +00001455 EXPECT_TRUE(test.isNegative());
Michael Gottesman4f71c1b2013-06-19 21:53:45 +00001456 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman7d13d522013-05-30 00:18:44 +00001457 EXPECT_TRUE(test.isDenormal());
Michael Gottesman3e8d3562013-05-29 23:58:29 +00001458 EXPECT_TRUE(test.bitwiseIsEqual(expected));
1459
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001460 test = APFloat::getSmallest(APFloat::IEEEquad(), false);
1461 expected = APFloat(APFloat::IEEEquad(), "0x0.0000000000000000000000000001p-16382");
Michael Gottesman7d13d522013-05-30 00:18:44 +00001462 EXPECT_FALSE(test.isNegative());
Michael Gottesman4f71c1b2013-06-19 21:53:45 +00001463 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman7d13d522013-05-30 00:18:44 +00001464 EXPECT_TRUE(test.isDenormal());
Michael Gottesman3e8d3562013-05-29 23:58:29 +00001465 EXPECT_TRUE(test.bitwiseIsEqual(expected));
1466
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001467 test = APFloat::getSmallest(APFloat::IEEEquad(), true);
1468 expected = APFloat(APFloat::IEEEquad(), "-0x0.0000000000000000000000000001p-16382");
Michael Gottesman3e8d3562013-05-29 23:58:29 +00001469 EXPECT_TRUE(test.isNegative());
Michael Gottesman4f71c1b2013-06-19 21:53:45 +00001470 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman7d13d522013-05-30 00:18:44 +00001471 EXPECT_TRUE(test.isDenormal());
Michael Gottesman567a1122013-06-24 09:58:09 +00001472 EXPECT_TRUE(test.bitwiseIsEqual(expected));
Michael Gottesman3e8d3562013-05-29 23:58:29 +00001473}
1474
Michael Gottesman999c6932013-05-30 00:18:47 +00001475TEST(APFloatTest, getSmallestNormalized) {
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001476 APFloat test = APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);
1477 APFloat expected = APFloat(APFloat::IEEEsingle(), "0x1p-126");
Michael Gottesman999c6932013-05-30 00:18:47 +00001478 EXPECT_FALSE(test.isNegative());
Michael Gottesman4f71c1b2013-06-19 21:53:45 +00001479 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman999c6932013-05-30 00:18:47 +00001480 EXPECT_FALSE(test.isDenormal());
1481 EXPECT_TRUE(test.bitwiseIsEqual(expected));
1482
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001483 test = APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);
1484 expected = APFloat(APFloat::IEEEsingle(), "-0x1p-126");
Michael Gottesman999c6932013-05-30 00:18:47 +00001485 EXPECT_TRUE(test.isNegative());
Michael Gottesman4f71c1b2013-06-19 21:53:45 +00001486 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman999c6932013-05-30 00:18:47 +00001487 EXPECT_FALSE(test.isDenormal());
1488 EXPECT_TRUE(test.bitwiseIsEqual(expected));
1489
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001490 test = APFloat::getSmallestNormalized(APFloat::IEEEquad(), false);
1491 expected = APFloat(APFloat::IEEEquad(), "0x1p-16382");
Michael Gottesman999c6932013-05-30 00:18:47 +00001492 EXPECT_FALSE(test.isNegative());
Michael Gottesman4f71c1b2013-06-19 21:53:45 +00001493 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman999c6932013-05-30 00:18:47 +00001494 EXPECT_FALSE(test.isDenormal());
1495 EXPECT_TRUE(test.bitwiseIsEqual(expected));
1496
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001497 test = APFloat::getSmallestNormalized(APFloat::IEEEquad(), true);
1498 expected = APFloat(APFloat::IEEEquad(), "-0x1p-16382");
Michael Gottesman999c6932013-05-30 00:18:47 +00001499 EXPECT_TRUE(test.isNegative());
Michael Gottesman4f71c1b2013-06-19 21:53:45 +00001500 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman999c6932013-05-30 00:18:47 +00001501 EXPECT_FALSE(test.isDenormal());
Michael Gottesman567a1122013-06-24 09:58:09 +00001502 EXPECT_TRUE(test.bitwiseIsEqual(expected));
Michael Gottesman999c6932013-05-30 00:18:47 +00001503}
1504
Michael Gottesman504e2da2013-05-31 18:43:34 +00001505TEST(APFloatTest, getZero) {
1506 struct {
1507 const fltSemantics *semantics;
1508 const bool sign;
1509 const unsigned long long bitPattern[2];
1510 const unsigned bitPatternLength;
Benjamin Kramer44dbb742013-06-01 22:29:41 +00001511 } const GetZeroTest[] = {
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001512 { &APFloat::IEEEhalf(), false, {0, 0}, 1},
1513 { &APFloat::IEEEhalf(), true, {0x8000ULL, 0}, 1},
1514 { &APFloat::IEEEsingle(), false, {0, 0}, 1},
1515 { &APFloat::IEEEsingle(), true, {0x80000000ULL, 0}, 1},
1516 { &APFloat::IEEEdouble(), false, {0, 0}, 1},
1517 { &APFloat::IEEEdouble(), true, {0x8000000000000000ULL, 0}, 1},
1518 { &APFloat::IEEEquad(), false, {0, 0}, 2},
1519 { &APFloat::IEEEquad(), true, {0, 0x8000000000000000ULL}, 2},
1520 { &APFloat::PPCDoubleDouble(), false, {0, 0}, 2},
1521 { &APFloat::PPCDoubleDouble(), true, {0x8000000000000000ULL, 0}, 2},
1522 { &APFloat::x87DoubleExtended(), false, {0, 0}, 2},
1523 { &APFloat::x87DoubleExtended(), true, {0, 0x8000ULL}, 2},
Michael Gottesman504e2da2013-05-31 18:43:34 +00001524 };
1525 const unsigned NumGetZeroTests = 12;
1526 for (unsigned i = 0; i < NumGetZeroTests; ++i) {
1527 APFloat test = APFloat::getZero(*GetZeroTest[i].semantics,
NAKAMURA Takumid8ff2f42017-10-18 13:31:28 +00001528 GetZeroTest[i].sign);
Michael Gottesman504e2da2013-05-31 18:43:34 +00001529 const char *pattern = GetZeroTest[i].sign? "-0x0p+0" : "0x0p+0";
1530 APFloat expected = APFloat(*GetZeroTest[i].semantics,
NAKAMURA Takumid8ff2f42017-10-18 13:31:28 +00001531 pattern);
Michael Gottesman504e2da2013-05-31 18:43:34 +00001532 EXPECT_TRUE(test.isZero());
1533 EXPECT_TRUE(GetZeroTest[i].sign? test.isNegative() : !test.isNegative());
1534 EXPECT_TRUE(test.bitwiseIsEqual(expected));
1535 for (unsigned j = 0, je = GetZeroTest[i].bitPatternLength; j < je; ++j) {
1536 EXPECT_EQ(GetZeroTest[i].bitPattern[j],
NAKAMURA Takumief15f2c2017-08-28 06:47:47 +00001537 test.bitcastToAPInt().getRawData()[j]);
Michael Gottesman504e2da2013-05-31 18:43:34 +00001538 }
1539 }
1540}
1541
Chandler Carruth0ffdb312014-10-09 23:26:15 +00001542TEST(APFloatTest, copySign) {
1543 EXPECT_TRUE(APFloat(-42.0).bitwiseIsEqual(
1544 APFloat::copySign(APFloat(42.0), APFloat(-1.0))));
1545 EXPECT_TRUE(APFloat(42.0).bitwiseIsEqual(
1546 APFloat::copySign(APFloat(-42.0), APFloat(1.0))));
1547 EXPECT_TRUE(APFloat(-42.0).bitwiseIsEqual(
1548 APFloat::copySign(APFloat(-42.0), APFloat(-1.0))));
1549 EXPECT_TRUE(APFloat(42.0).bitwiseIsEqual(
1550 APFloat::copySign(APFloat(42.0), APFloat(1.0))));
1551}
1552
Eli Friedman44551422011-11-26 03:38:02 +00001553TEST(APFloatTest, convert) {
1554 bool losesInfo;
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001555 APFloat test(APFloat::IEEEdouble(), "1.0");
1556 test.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &losesInfo);
Eli Friedman44551422011-11-26 03:38:02 +00001557 EXPECT_EQ(1.0f, test.convertToFloat());
1558 EXPECT_FALSE(losesInfo);
1559
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001560 test = APFloat(APFloat::x87DoubleExtended(), "0x1p-53");
1561 test.add(APFloat(APFloat::x87DoubleExtended(), "1.0"), APFloat::rmNearestTiesToEven);
1562 test.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &losesInfo);
Eli Friedman44551422011-11-26 03:38:02 +00001563 EXPECT_EQ(1.0, test.convertToDouble());
1564 EXPECT_TRUE(losesInfo);
1565
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001566 test = APFloat(APFloat::IEEEquad(), "0x1p-53");
1567 test.add(APFloat(APFloat::IEEEquad(), "1.0"), APFloat::rmNearestTiesToEven);
1568 test.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &losesInfo);
Eli Friedman44551422011-11-26 03:38:02 +00001569 EXPECT_EQ(1.0, test.convertToDouble());
1570 EXPECT_TRUE(losesInfo);
1571
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001572 test = APFloat(APFloat::x87DoubleExtended(), "0xf.fffffffp+28");
1573 test.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &losesInfo);
Eli Friedman44551422011-11-26 03:38:02 +00001574 EXPECT_EQ(4294967295.0, test.convertToDouble());
1575 EXPECT_FALSE(losesInfo);
Benjamin Kramerbd7561e2013-01-25 17:01:00 +00001576
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001577 test = APFloat::getSNaN(APFloat::IEEEsingle());
1578 APFloat X87SNaN = APFloat::getSNaN(APFloat::x87DoubleExtended());
1579 test.convert(APFloat::x87DoubleExtended(), APFloat::rmNearestTiesToEven,
Benjamin Kramerbd7561e2013-01-25 17:01:00 +00001580 &losesInfo);
1581 EXPECT_TRUE(test.bitwiseIsEqual(X87SNaN));
1582 EXPECT_FALSE(losesInfo);
1583
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001584 test = APFloat::getQNaN(APFloat::IEEEsingle());
1585 APFloat X87QNaN = APFloat::getQNaN(APFloat::x87DoubleExtended());
1586 test.convert(APFloat::x87DoubleExtended(), APFloat::rmNearestTiesToEven,
Benjamin Kramerbd7561e2013-01-25 17:01:00 +00001587 &losesInfo);
1588 EXPECT_TRUE(test.bitwiseIsEqual(X87QNaN));
1589 EXPECT_FALSE(losesInfo);
1590
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001591 test = APFloat::getSNaN(APFloat::x87DoubleExtended());
1592 test.convert(APFloat::x87DoubleExtended(), APFloat::rmNearestTiesToEven,
Benjamin Kramerbd7561e2013-01-25 17:01:00 +00001593 &losesInfo);
1594 EXPECT_TRUE(test.bitwiseIsEqual(X87SNaN));
1595 EXPECT_FALSE(losesInfo);
1596
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001597 test = APFloat::getQNaN(APFloat::x87DoubleExtended());
1598 test.convert(APFloat::x87DoubleExtended(), APFloat::rmNearestTiesToEven,
Benjamin Kramerbd7561e2013-01-25 17:01:00 +00001599 &losesInfo);
1600 EXPECT_TRUE(test.bitwiseIsEqual(X87QNaN));
1601 EXPECT_FALSE(losesInfo);
Eli Friedman44551422011-11-26 03:38:02 +00001602}
Ulrich Weigand69c9c8c2012-10-29 18:09:01 +00001603
1604TEST(APFloatTest, PPCDoubleDouble) {
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001605 APFloat test(APFloat::PPCDoubleDouble(), "1.0");
Ulrich Weigand69c9c8c2012-10-29 18:09:01 +00001606 EXPECT_EQ(0x3ff0000000000000ull, test.bitcastToAPInt().getRawData()[0]);
1607 EXPECT_EQ(0x0000000000000000ull, test.bitcastToAPInt().getRawData()[1]);
1608
Ulrich Weigand69c9c8c2012-10-29 18:09:01 +00001609 // LDBL_MAX
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001610 test = APFloat(APFloat::PPCDoubleDouble(), "1.79769313486231580793728971405301e+308");
Ulrich Weigand69c9c8c2012-10-29 18:09:01 +00001611 EXPECT_EQ(0x7fefffffffffffffull, test.bitcastToAPInt().getRawData()[0]);
1612 EXPECT_EQ(0x7c8ffffffffffffeull, test.bitcastToAPInt().getRawData()[1]);
1613
1614 // LDBL_MIN
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001615 test = APFloat(APFloat::PPCDoubleDouble(), "2.00416836000897277799610805135016e-292");
Ulrich Weigand69c9c8c2012-10-29 18:09:01 +00001616 EXPECT_EQ(0x0360000000000000ull, test.bitcastToAPInt().getRawData()[0]);
1617 EXPECT_EQ(0x0000000000000000ull, test.bitcastToAPInt().getRawData()[1]);
1618
Tim Shenc7524ad2016-11-06 07:38:37 +00001619 // PR30869
1620 {
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001621 auto Result = APFloat(APFloat::PPCDoubleDouble(), "1.0") +
1622 APFloat(APFloat::PPCDoubleDouble(), "1.0");
1623 EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics());
Tim Shenc7524ad2016-11-06 07:38:37 +00001624
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001625 Result = APFloat(APFloat::PPCDoubleDouble(), "1.0") -
1626 APFloat(APFloat::PPCDoubleDouble(), "1.0");
1627 EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics());
Tim Shenc7524ad2016-11-06 07:38:37 +00001628
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001629 Result = APFloat(APFloat::PPCDoubleDouble(), "1.0") *
1630 APFloat(APFloat::PPCDoubleDouble(), "1.0");
1631 EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics());
Tim Shenc7524ad2016-11-06 07:38:37 +00001632
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001633 Result = APFloat(APFloat::PPCDoubleDouble(), "1.0") /
1634 APFloat(APFloat::PPCDoubleDouble(), "1.0");
1635 EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics());
Tim Shenc7524ad2016-11-06 07:38:37 +00001636
1637 int Exp;
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001638 Result = frexp(APFloat(APFloat::PPCDoubleDouble(), "1.0"), Exp,
Tim Shenc7524ad2016-11-06 07:38:37 +00001639 APFloat::rmNearestTiesToEven);
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001640 EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics());
Tim Shenc7524ad2016-11-06 07:38:37 +00001641
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001642 Result = scalbn(APFloat(APFloat::PPCDoubleDouble(), "1.0"), 1,
Tim Shenc7524ad2016-11-06 07:38:37 +00001643 APFloat::rmNearestTiesToEven);
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001644 EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics());
Tim Shenc7524ad2016-11-06 07:38:37 +00001645 }
Ulrich Weigand69c9c8c2012-10-29 18:09:01 +00001646}
Michael Gottesmanb30718a2013-06-04 03:46:25 +00001647
1648TEST(APFloatTest, isNegative) {
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001649 APFloat t(APFloat::IEEEsingle(), "0x1p+0");
Michael Gottesmanb30718a2013-06-04 03:46:25 +00001650 EXPECT_FALSE(t.isNegative());
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001651 t = APFloat(APFloat::IEEEsingle(), "-0x1p+0");
Michael Gottesmanb30718a2013-06-04 03:46:25 +00001652 EXPECT_TRUE(t.isNegative());
Michael Gottesman567a1122013-06-24 09:58:09 +00001653
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001654 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), false).isNegative());
1655 EXPECT_TRUE(APFloat::getInf(APFloat::IEEEsingle(), true).isNegative());
Michael Gottesman567a1122013-06-24 09:58:09 +00001656
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001657 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), false).isNegative());
1658 EXPECT_TRUE(APFloat::getZero(APFloat::IEEEsingle(), true).isNegative());
Michael Gottesmanb30718a2013-06-04 03:46:25 +00001659
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001660 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), false).isNegative());
1661 EXPECT_TRUE(APFloat::getNaN(APFloat::IEEEsingle(), true).isNegative());
Michael Gottesmanb30718a2013-06-04 03:46:25 +00001662
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001663 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isNegative());
1664 EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle(), true).isNegative());
Michael Gottesmanb30718a2013-06-04 03:46:25 +00001665}
1666
Michael Gottesmana1694e52013-06-20 18:34:38 +00001667TEST(APFloatTest, isNormal) {
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001668 APFloat t(APFloat::IEEEsingle(), "0x1p+0");
Michael Gottesmana1694e52013-06-20 18:34:38 +00001669 EXPECT_TRUE(t.isNormal());
Michael Gottesman567a1122013-06-24 09:58:09 +00001670
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001671 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), false).isNormal());
1672 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), false).isNormal());
1673 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), false).isNormal());
1674 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isNormal());
1675 EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), "0x1p-149").isNormal());
Michael Gottesmanb30718a2013-06-04 03:46:25 +00001676}
1677
1678TEST(APFloatTest, isFinite) {
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001679 APFloat t(APFloat::IEEEsingle(), "0x1p+0");
Michael Gottesman567a1122013-06-24 09:58:09 +00001680 EXPECT_TRUE(t.isFinite());
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001681 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), false).isFinite());
1682 EXPECT_TRUE(APFloat::getZero(APFloat::IEEEsingle(), false).isFinite());
1683 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), false).isFinite());
1684 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isFinite());
1685 EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "0x1p-149").isFinite());
Michael Gottesmanb30718a2013-06-04 03:46:25 +00001686}
1687
1688TEST(APFloatTest, isInfinity) {
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001689 APFloat t(APFloat::IEEEsingle(), "0x1p+0");
Michael Gottesmanb30718a2013-06-04 03:46:25 +00001690 EXPECT_FALSE(t.isInfinity());
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001691 EXPECT_TRUE(APFloat::getInf(APFloat::IEEEsingle(), false).isInfinity());
1692 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), false).isInfinity());
1693 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), false).isInfinity());
1694 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isInfinity());
1695 EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), "0x1p-149").isInfinity());
Michael Gottesmanb30718a2013-06-04 03:46:25 +00001696}
1697
1698TEST(APFloatTest, isNaN) {
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001699 APFloat t(APFloat::IEEEsingle(), "0x1p+0");
Michael Gottesman567a1122013-06-24 09:58:09 +00001700 EXPECT_FALSE(t.isNaN());
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001701 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), false).isNaN());
1702 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), false).isNaN());
1703 EXPECT_TRUE(APFloat::getNaN(APFloat::IEEEsingle(), false).isNaN());
1704 EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isNaN());
1705 EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), "0x1p-149").isNaN());
Michael Gottesmanb30718a2013-06-04 03:46:25 +00001706}
1707
Michael Gottesman7032c882013-06-19 21:00:17 +00001708TEST(APFloatTest, isFiniteNonZero) {
1709 // Test positive/negative normal value.
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001710 EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "0x1p+0").isFiniteNonZero());
1711 EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "-0x1p+0").isFiniteNonZero());
Michael Gottesman7032c882013-06-19 21:00:17 +00001712
1713 // Test positive/negative denormal value.
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001714 EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "0x1p-149").isFiniteNonZero());
1715 EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "-0x1p-149").isFiniteNonZero());
Michael Gottesman7032c882013-06-19 21:00:17 +00001716
1717 // Test +/- Infinity.
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001718 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), false).isFiniteNonZero());
1719 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), true).isFiniteNonZero());
Michael Gottesman7032c882013-06-19 21:00:17 +00001720
1721 // Test +/- Zero.
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001722 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), false).isFiniteNonZero());
1723 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), true).isFiniteNonZero());
Michael Gottesman7032c882013-06-19 21:00:17 +00001724
1725 // Test +/- qNaN. +/- dont mean anything with qNaN but paranoia can't hurt in
1726 // this instance.
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001727 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), false).isFiniteNonZero());
1728 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), true).isFiniteNonZero());
Michael Gottesman7032c882013-06-19 21:00:17 +00001729
1730 // Test +/- sNaN. +/- dont mean anything with sNaN but paranoia can't hurt in
1731 // this instance.
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001732 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isFiniteNonZero());
1733 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), true).isFiniteNonZero());
Michael Gottesman7032c882013-06-19 21:00:17 +00001734}
1735
Michael Gottesman683069f2013-06-24 09:58:07 +00001736TEST(APFloatTest, add) {
1737 // Test Special Cases against each other and normal values.
1738
1739 // TODOS/NOTES:
1740 // 1. Since we perform only default exception handling all operations with
1741 // signaling NaNs should have a result that is a quiet NaN. Currently they
1742 // return sNaN.
Michael Gottesman683069f2013-06-24 09:58:07 +00001743
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001744 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle(), false);
1745 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle(), true);
1746 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle(), false);
1747 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle(), true);
1748 APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);
1749 APFloat SNaN = APFloat::getSNaN(APFloat::IEEEsingle(), false);
1750 APFloat PNormalValue = APFloat(APFloat::IEEEsingle(), "0x1p+0");
1751 APFloat MNormalValue = APFloat(APFloat::IEEEsingle(), "-0x1p+0");
1752 APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), false);
1753 APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), true);
1754 APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), false);
1755 APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), true);
Michael Gottesman683069f2013-06-24 09:58:07 +00001756 APFloat PSmallestNormalized =
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001757 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);
Michael Gottesman683069f2013-06-24 09:58:07 +00001758 APFloat MSmallestNormalized =
Stephan Bergmann20a600c2016-12-14 11:57:17 +00001759 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);
Michael Gottesman683069f2013-06-24 09:58:07 +00001760
1761 const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact;
1762
1763 const unsigned NumTests = 169;
1764 struct {
1765 APFloat x;
1766 APFloat y;
1767 const char *result;
1768 int status;
1769 int category;
1770 } SpecialCaseTests[NumTests] = {
1771 { PInf, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1772 { PInf, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1773 { PInf, PZero, "inf", APFloat::opOK, APFloat::fcInfinity },
1774 { PInf, MZero, "inf", APFloat::opOK, APFloat::fcInfinity },
1775 { PInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
1776#if 0
1777 // See Note 1.
1778 { PInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1779#endif
1780 { PInf, PNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1781 { PInf, MNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1782 { PInf, PLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1783 { PInf, MLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1784 { PInf, PSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1785 { PInf, MSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1786 { PInf, PSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
1787 { PInf, MSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
1788 { MInf, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1789 { MInf, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1790 { MInf, PZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
1791 { MInf, MZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00001792 { MInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman683069f2013-06-24 09:58:07 +00001793#if 0
1794 // See Note 1.
1795 { MInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1796#endif
1797 { MInf, PNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1798 { MInf, MNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1799 { MInf, PLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1800 { MInf, MLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1801 { MInf, PSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1802 { MInf, MSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1803 { MInf, PSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
1804 { MInf, MSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
1805 { PZero, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1806 { PZero, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1807 { PZero, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1808 { PZero, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1809 { PZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
1810#if 0
1811 // See Note 1.
1812 { PZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1813#endif
1814 { PZero, PNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
1815 { PZero, MNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
1816 { PZero, PLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1817 { PZero, MLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1818 { PZero, PSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
1819 { PZero, MSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
1820 { PZero, PSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
1821 { PZero, MSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
1822 { MZero, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1823 { MZero, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1824 { MZero, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1825 { MZero, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00001826 { MZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman683069f2013-06-24 09:58:07 +00001827#if 0
1828 // See Note 1.
1829 { MZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1830#endif
1831 { MZero, PNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
1832 { MZero, MNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
1833 { MZero, PLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1834 { MZero, MLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1835 { MZero, PSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
1836 { MZero, MSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
1837 { MZero, PSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
1838 { MZero, MSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
1839 { QNaN, PInf, "nan", APFloat::opOK, APFloat::fcNaN },
1840 { QNaN, MInf, "nan", APFloat::opOK, APFloat::fcNaN },
1841 { QNaN, PZero, "nan", APFloat::opOK, APFloat::fcNaN },
1842 { QNaN, MZero, "nan", APFloat::opOK, APFloat::fcNaN },
1843 { QNaN, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
1844#if 0
1845 // See Note 1.
1846 { QNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1847#endif
1848 { QNaN, PNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
1849 { QNaN, MNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
1850 { QNaN, PLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
1851 { QNaN, MLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
1852 { QNaN, PSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
1853 { QNaN, MSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
1854 { QNaN, PSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
1855 { QNaN, MSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
1856#if 0
1857 // See Note 1.
1858 { SNaN, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1859 { SNaN, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1860 { SNaN, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1861 { SNaN, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1862 { SNaN, QNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1863 { SNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1864 { SNaN, PNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1865 { SNaN, MNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1866 { SNaN, PLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1867 { SNaN, MLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1868 { SNaN, PSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1869 { SNaN, MSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1870 { SNaN, PSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1871 { SNaN, MSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1872#endif
1873 { PNormalValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1874 { PNormalValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1875 { PNormalValue, PZero, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
1876 { PNormalValue, MZero, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
1877 { PNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
1878#if 0
1879 // See Note 1.
1880 { PNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1881#endif
1882 { PNormalValue, PNormalValue, "0x1p+1", APFloat::opOK, APFloat::fcNormal },
1883 { PNormalValue, MNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1884 { PNormalValue, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1885 { PNormalValue, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1886 { PNormalValue, PSmallestValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1887 { PNormalValue, MSmallestValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1888 { PNormalValue, PSmallestNormalized, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1889 { PNormalValue, MSmallestNormalized, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1890 { MNormalValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1891 { MNormalValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1892 { MNormalValue, PZero, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
1893 { MNormalValue, MZero, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00001894 { MNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman683069f2013-06-24 09:58:07 +00001895#if 0
1896 // See Note 1.
1897 { MNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1898#endif
1899 { MNormalValue, PNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1900 { MNormalValue, MNormalValue, "-0x1p+1", APFloat::opOK, APFloat::fcNormal },
1901 { MNormalValue, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1902 { MNormalValue, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1903 { MNormalValue, PSmallestValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1904 { MNormalValue, MSmallestValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1905 { MNormalValue, PSmallestNormalized, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1906 { MNormalValue, MSmallestNormalized, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1907 { PLargestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1908 { PLargestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1909 { PLargestValue, PZero, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1910 { PLargestValue, MZero, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1911 { PLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
1912#if 0
1913 // See Note 1.
1914 { PLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1915#endif
1916 { PLargestValue, PNormalValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1917 { PLargestValue, MNormalValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1918 { PLargestValue, PLargestValue, "inf", OverflowStatus, APFloat::fcInfinity },
1919 { PLargestValue, MLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1920 { PLargestValue, PSmallestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1921 { PLargestValue, MSmallestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1922 { PLargestValue, PSmallestNormalized, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1923 { PLargestValue, MSmallestNormalized, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1924 { MLargestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1925 { MLargestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1926 { MLargestValue, PZero, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1927 { MLargestValue, MZero, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00001928 { MLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman683069f2013-06-24 09:58:07 +00001929#if 0
1930 // See Note 1.
1931 { MLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1932#endif
1933 { MLargestValue, PNormalValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1934 { MLargestValue, MNormalValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1935 { MLargestValue, PLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1936 { MLargestValue, MLargestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
1937 { MLargestValue, PSmallestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1938 { MLargestValue, MSmallestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1939 { MLargestValue, PSmallestNormalized, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1940 { MLargestValue, MSmallestNormalized, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1941 { PSmallestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1942 { PSmallestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1943 { PSmallestValue, PZero, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
1944 { PSmallestValue, MZero, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
1945 { PSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
1946#if 0
1947 // See Note 1.
1948 { PSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1949#endif
1950 { PSmallestValue, PNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1951 { PSmallestValue, MNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1952 { PSmallestValue, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1953 { PSmallestValue, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1954 { PSmallestValue, PSmallestValue, "0x1p-148", APFloat::opOK, APFloat::fcNormal },
1955 { PSmallestValue, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1956 { PSmallestValue, PSmallestNormalized, "0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
1957 { PSmallestValue, MSmallestNormalized, "-0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
1958 { MSmallestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1959 { MSmallestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1960 { MSmallestValue, PZero, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
1961 { MSmallestValue, MZero, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00001962 { MSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman683069f2013-06-24 09:58:07 +00001963#if 0
1964 // See Note 1.
1965 { MSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1966#endif
1967 { MSmallestValue, PNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1968 { MSmallestValue, MNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1969 { MSmallestValue, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1970 { MSmallestValue, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1971 { MSmallestValue, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1972 { MSmallestValue, MSmallestValue, "-0x1p-148", APFloat::opOK, APFloat::fcNormal },
1973 { MSmallestValue, PSmallestNormalized, "0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
1974 { MSmallestValue, MSmallestNormalized, "-0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
1975 { PSmallestNormalized, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1976 { PSmallestNormalized, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1977 { PSmallestNormalized, PZero, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
1978 { PSmallestNormalized, MZero, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
1979 { PSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
1980#if 0
1981// See Note 1.
1982 { PSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1983#endif
1984 { PSmallestNormalized, PNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1985 { PSmallestNormalized, MNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1986 { PSmallestNormalized, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1987 { PSmallestNormalized, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1988 { PSmallestNormalized, PSmallestValue, "0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
1989 { PSmallestNormalized, MSmallestValue, "0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
1990 { PSmallestNormalized, PSmallestNormalized, "0x1p-125", APFloat::opOK, APFloat::fcNormal },
1991 { PSmallestNormalized, MSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1992 { MSmallestNormalized, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1993 { MSmallestNormalized, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1994 { MSmallestNormalized, PZero, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
1995 { MSmallestNormalized, MZero, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00001996 { MSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman683069f2013-06-24 09:58:07 +00001997#if 0
1998 // See Note 1.
1999 { MSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2000#endif
2001 { MSmallestNormalized, PNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2002 { MSmallestNormalized, MNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2003 { MSmallestNormalized, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2004 { MSmallestNormalized, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2005 { MSmallestNormalized, PSmallestValue, "-0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
2006 { MSmallestNormalized, MSmallestValue, "-0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
2007 { MSmallestNormalized, PSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2008 { MSmallestNormalized, MSmallestNormalized, "-0x1p-125", APFloat::opOK, APFloat::fcNormal }
2009 };
2010
2011 for (size_t i = 0; i < NumTests; ++i) {
2012 APFloat x(SpecialCaseTests[i].x);
2013 APFloat y(SpecialCaseTests[i].y);
2014 APFloat::opStatus status = x.add(y, APFloat::rmNearestTiesToEven);
2015
Stephan Bergmann20a600c2016-12-14 11:57:17 +00002016 APFloat result(APFloat::IEEEsingle(), SpecialCaseTests[i].result);
Michael Gottesman683069f2013-06-24 09:58:07 +00002017
Michael Gottesman683069f2013-06-24 09:58:07 +00002018 EXPECT_TRUE(result.bitwiseIsEqual(x));
2019 EXPECT_TRUE((int)status == SpecialCaseTests[i].status);
2020 EXPECT_TRUE((int)x.getCategory() == SpecialCaseTests[i].category);
2021 }
2022}
2023
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002024TEST(APFloatTest, subtract) {
2025 // Test Special Cases against each other and normal values.
2026
2027 // TODOS/NOTES:
2028 // 1. Since we perform only default exception handling all operations with
2029 // signaling NaNs should have a result that is a quiet NaN. Currently they
2030 // return sNaN.
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002031
Stephan Bergmann20a600c2016-12-14 11:57:17 +00002032 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle(), false);
2033 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle(), true);
2034 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle(), false);
2035 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle(), true);
2036 APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);
2037 APFloat SNaN = APFloat::getSNaN(APFloat::IEEEsingle(), false);
2038 APFloat PNormalValue = APFloat(APFloat::IEEEsingle(), "0x1p+0");
2039 APFloat MNormalValue = APFloat(APFloat::IEEEsingle(), "-0x1p+0");
2040 APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), false);
2041 APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), true);
2042 APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), false);
2043 APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), true);
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002044 APFloat PSmallestNormalized =
Stephan Bergmann20a600c2016-12-14 11:57:17 +00002045 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002046 APFloat MSmallestNormalized =
Stephan Bergmann20a600c2016-12-14 11:57:17 +00002047 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002048
2049 const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact;
2050
2051 const unsigned NumTests = 169;
2052 struct {
2053 APFloat x;
2054 APFloat y;
2055 const char *result;
2056 int status;
2057 int category;
2058 } SpecialCaseTests[NumTests] = {
2059 { PInf, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2060 { PInf, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2061 { PInf, PZero, "inf", APFloat::opOK, APFloat::fcInfinity },
2062 { PInf, MZero, "inf", APFloat::opOK, APFloat::fcInfinity },
Stephen Canonbef256f2014-06-08 16:53:31 +00002063 { PInf, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002064#if 0
2065// See Note 1.
Stephen Canonbef256f2014-06-08 16:53:31 +00002066 { PInf, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002067#endif
2068 { PInf, PNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2069 { PInf, MNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2070 { PInf, PLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2071 { PInf, MLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2072 { PInf, PSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2073 { PInf, MSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2074 { PInf, PSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
2075 { PInf, MSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
2076 { MInf, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2077 { MInf, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2078 { MInf, PZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
2079 { MInf, MZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
Stephen Canonbef256f2014-06-08 16:53:31 +00002080 { MInf, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002081#if 0
2082// See Note 1.
Stephen Canonbef256f2014-06-08 16:53:31 +00002083 { MInf, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002084#endif
2085 { MInf, PNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2086 { MInf, MNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2087 { MInf, PLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2088 { MInf, MLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2089 { MInf, PSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2090 { MInf, MSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2091 { MInf, PSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
2092 { MInf, MSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
2093 { PZero, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2094 { PZero, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2095 { PZero, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2096 { PZero, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
Stephen Canonbef256f2014-06-08 16:53:31 +00002097 { PZero, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002098#if 0
2099// See Note 1.
Stephen Canonbef256f2014-06-08 16:53:31 +00002100 { PZero, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002101#endif
2102 { PZero, PNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2103 { PZero, MNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2104 { PZero, PLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2105 { PZero, MLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2106 { PZero, PSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2107 { PZero, MSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2108 { PZero, PSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2109 { PZero, MSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2110 { MZero, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2111 { MZero, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2112 { MZero, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2113 { MZero, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
Stephen Canonbef256f2014-06-08 16:53:31 +00002114 { MZero, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002115#if 0
2116// See Note 1.
Stephen Canonbef256f2014-06-08 16:53:31 +00002117 { MZero, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002118#endif
2119 { MZero, PNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2120 { MZero, MNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2121 { MZero, PLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2122 { MZero, MLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2123 { MZero, PSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2124 { MZero, MSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2125 { MZero, PSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2126 { MZero, MSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2127 { QNaN, PInf, "nan", APFloat::opOK, APFloat::fcNaN },
2128 { QNaN, MInf, "nan", APFloat::opOK, APFloat::fcNaN },
2129 { QNaN, PZero, "nan", APFloat::opOK, APFloat::fcNaN },
2130 { QNaN, MZero, "nan", APFloat::opOK, APFloat::fcNaN },
2131 { QNaN, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2132#if 0
2133// See Note 1.
2134 { QNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2135#endif
2136 { QNaN, PNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
2137 { QNaN, MNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
2138 { QNaN, PLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
2139 { QNaN, MLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
2140 { QNaN, PSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
2141 { QNaN, MSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
2142 { QNaN, PSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
2143 { QNaN, MSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
2144#if 0
2145// See Note 1.
2146 { SNaN, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2147 { SNaN, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2148 { SNaN, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2149 { SNaN, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2150 { SNaN, QNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2151 { SNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2152 { SNaN, PNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2153 { SNaN, MNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2154 { SNaN, PLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2155 { SNaN, MLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2156 { SNaN, PSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2157 { SNaN, MSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2158 { SNaN, PSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2159 { SNaN, MSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2160#endif
2161 { PNormalValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2162 { PNormalValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2163 { PNormalValue, PZero, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2164 { PNormalValue, MZero, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
Stephen Canonbef256f2014-06-08 16:53:31 +00002165 { PNormalValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002166#if 0
2167// See Note 1.
Stephen Canonbef256f2014-06-08 16:53:31 +00002168 { PNormalValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002169#endif
2170 { PNormalValue, PNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2171 { PNormalValue, MNormalValue, "0x1p+1", APFloat::opOK, APFloat::fcNormal },
2172 { PNormalValue, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2173 { PNormalValue, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2174 { PNormalValue, PSmallestValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2175 { PNormalValue, MSmallestValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2176 { PNormalValue, PSmallestNormalized, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2177 { PNormalValue, MSmallestNormalized, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2178 { MNormalValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2179 { MNormalValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2180 { MNormalValue, PZero, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2181 { MNormalValue, MZero, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
Stephen Canonbef256f2014-06-08 16:53:31 +00002182 { MNormalValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002183#if 0
2184// See Note 1.
Stephen Canonbef256f2014-06-08 16:53:31 +00002185 { MNormalValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002186#endif
2187 { MNormalValue, PNormalValue, "-0x1p+1", APFloat::opOK, APFloat::fcNormal },
2188 { MNormalValue, MNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2189 { MNormalValue, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2190 { MNormalValue, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2191 { MNormalValue, PSmallestValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2192 { MNormalValue, MSmallestValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2193 { MNormalValue, PSmallestNormalized, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2194 { MNormalValue, MSmallestNormalized, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2195 { PLargestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2196 { PLargestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2197 { PLargestValue, PZero, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2198 { PLargestValue, MZero, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
Stephen Canonbef256f2014-06-08 16:53:31 +00002199 { PLargestValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002200#if 0
2201// See Note 1.
Stephen Canonbef256f2014-06-08 16:53:31 +00002202 { PLargestValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002203#endif
2204 { PLargestValue, PNormalValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2205 { PLargestValue, MNormalValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2206 { PLargestValue, PLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2207 { PLargestValue, MLargestValue, "inf", OverflowStatus, APFloat::fcInfinity },
2208 { PLargestValue, PSmallestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2209 { PLargestValue, MSmallestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2210 { PLargestValue, PSmallestNormalized, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2211 { PLargestValue, MSmallestNormalized, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2212 { MLargestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2213 { MLargestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2214 { MLargestValue, PZero, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2215 { MLargestValue, MZero, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
Stephen Canonbef256f2014-06-08 16:53:31 +00002216 { MLargestValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002217#if 0
2218// See Note 1.
Stephen Canonbef256f2014-06-08 16:53:31 +00002219 { MLargestValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002220#endif
2221 { MLargestValue, PNormalValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2222 { MLargestValue, MNormalValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2223 { MLargestValue, PLargestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
2224 { MLargestValue, MLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2225 { MLargestValue, PSmallestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2226 { MLargestValue, MSmallestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2227 { MLargestValue, PSmallestNormalized, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2228 { MLargestValue, MSmallestNormalized, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2229 { PSmallestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2230 { PSmallestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2231 { PSmallestValue, PZero, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2232 { PSmallestValue, MZero, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
Stephen Canonbef256f2014-06-08 16:53:31 +00002233 { PSmallestValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002234#if 0
2235// See Note 1.
Stephen Canonbef256f2014-06-08 16:53:31 +00002236 { PSmallestValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002237#endif
2238 { PSmallestValue, PNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2239 { PSmallestValue, MNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2240 { PSmallestValue, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2241 { PSmallestValue, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2242 { PSmallestValue, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2243 { PSmallestValue, MSmallestValue, "0x1p-148", APFloat::opOK, APFloat::fcNormal },
2244 { PSmallestValue, PSmallestNormalized, "-0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
2245 { PSmallestValue, MSmallestNormalized, "0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
2246 { MSmallestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2247 { MSmallestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2248 { MSmallestValue, PZero, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2249 { MSmallestValue, MZero, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
Stephen Canonbef256f2014-06-08 16:53:31 +00002250 { MSmallestValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002251#if 0
2252// See Note 1.
Stephen Canonbef256f2014-06-08 16:53:31 +00002253 { MSmallestValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002254#endif
2255 { MSmallestValue, PNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2256 { MSmallestValue, MNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2257 { MSmallestValue, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2258 { MSmallestValue, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2259 { MSmallestValue, PSmallestValue, "-0x1p-148", APFloat::opOK, APFloat::fcNormal },
2260 { MSmallestValue, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2261 { MSmallestValue, PSmallestNormalized, "-0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
2262 { MSmallestValue, MSmallestNormalized, "0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
2263 { PSmallestNormalized, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2264 { PSmallestNormalized, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2265 { PSmallestNormalized, PZero, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2266 { PSmallestNormalized, MZero, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
Stephen Canonbef256f2014-06-08 16:53:31 +00002267 { PSmallestNormalized, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002268#if 0
2269// See Note 1.
Stephen Canonbef256f2014-06-08 16:53:31 +00002270 { PSmallestNormalized, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002271#endif
2272 { PSmallestNormalized, PNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2273 { PSmallestNormalized, MNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2274 { PSmallestNormalized, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2275 { PSmallestNormalized, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2276 { PSmallestNormalized, PSmallestValue, "0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
2277 { PSmallestNormalized, MSmallestValue, "0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
2278 { PSmallestNormalized, PSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2279 { PSmallestNormalized, MSmallestNormalized, "0x1p-125", APFloat::opOK, APFloat::fcNormal },
2280 { MSmallestNormalized, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2281 { MSmallestNormalized, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2282 { MSmallestNormalized, PZero, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2283 { MSmallestNormalized, MZero, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
Stephen Canonbef256f2014-06-08 16:53:31 +00002284 { MSmallestNormalized, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002285#if 0
2286// See Note 1.
Stephen Canonbef256f2014-06-08 16:53:31 +00002287 { MSmallestNormalized, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002288#endif
2289 { MSmallestNormalized, PNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2290 { MSmallestNormalized, MNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2291 { MSmallestNormalized, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2292 { MSmallestNormalized, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2293 { MSmallestNormalized, PSmallestValue, "-0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
2294 { MSmallestNormalized, MSmallestValue, "-0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
2295 { MSmallestNormalized, PSmallestNormalized, "-0x1p-125", APFloat::opOK, APFloat::fcNormal },
2296 { MSmallestNormalized, MSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero }
2297 };
2298
2299 for (size_t i = 0; i < NumTests; ++i) {
2300 APFloat x(SpecialCaseTests[i].x);
2301 APFloat y(SpecialCaseTests[i].y);
2302 APFloat::opStatus status = x.subtract(y, APFloat::rmNearestTiesToEven);
2303
Stephan Bergmann20a600c2016-12-14 11:57:17 +00002304 APFloat result(APFloat::IEEEsingle(), SpecialCaseTests[i].result);
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002305
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002306 EXPECT_TRUE(result.bitwiseIsEqual(x));
2307 EXPECT_TRUE((int)status == SpecialCaseTests[i].status);
2308 EXPECT_TRUE((int)x.getCategory() == SpecialCaseTests[i].category);
2309 }
2310}
2311
Michael Gottesman2eda8972013-06-26 23:55:26 +00002312TEST(APFloatTest, multiply) {
2313 // Test Special Cases against each other and normal values.
2314
2315 // TODOS/NOTES:
2316 // 1. Since we perform only default exception handling all operations with
2317 // signaling NaNs should have a result that is a quiet NaN. Currently they
2318 // return sNaN.
Michael Gottesman2eda8972013-06-26 23:55:26 +00002319
Stephan Bergmann20a600c2016-12-14 11:57:17 +00002320 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle(), false);
2321 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle(), true);
2322 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle(), false);
2323 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle(), true);
2324 APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);
2325 APFloat SNaN = APFloat::getSNaN(APFloat::IEEEsingle(), false);
2326 APFloat PNormalValue = APFloat(APFloat::IEEEsingle(), "0x1p+0");
2327 APFloat MNormalValue = APFloat(APFloat::IEEEsingle(), "-0x1p+0");
2328 APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), false);
2329 APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), true);
2330 APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), false);
2331 APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), true);
Michael Gottesman2eda8972013-06-26 23:55:26 +00002332 APFloat PSmallestNormalized =
Stephan Bergmann20a600c2016-12-14 11:57:17 +00002333 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);
Michael Gottesman2eda8972013-06-26 23:55:26 +00002334 APFloat MSmallestNormalized =
Stephan Bergmann20a600c2016-12-14 11:57:17 +00002335 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);
Michael Gottesman2eda8972013-06-26 23:55:26 +00002336
2337 const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact;
2338 const int UnderflowStatus = APFloat::opUnderflow | APFloat::opInexact;
2339
2340 const unsigned NumTests = 169;
2341 struct {
2342 APFloat x;
2343 APFloat y;
2344 const char *result;
2345 int status;
2346 int category;
2347 } SpecialCaseTests[NumTests] = {
2348 { PInf, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2349 { PInf, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2350 { PInf, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2351 { PInf, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2352 { PInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2353#if 0
2354// See Note 1.
2355 { PInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2356#endif
2357 { PInf, PNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2358 { PInf, MNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2359 { PInf, PLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2360 { PInf, MLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2361 { PInf, PSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2362 { PInf, MSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2363 { PInf, PSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
2364 { PInf, MSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
2365 { MInf, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2366 { MInf, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2367 { MInf, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2368 { MInf, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00002369 { MInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman2eda8972013-06-26 23:55:26 +00002370#if 0
2371// See Note 1.
2372 { MInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2373#endif
2374 { MInf, PNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2375 { MInf, MNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2376 { MInf, PLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2377 { MInf, MLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2378 { MInf, PSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2379 { MInf, MSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2380 { MInf, PSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
2381 { MInf, MSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
2382 { PZero, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2383 { PZero, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2384 { PZero, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2385 { PZero, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2386 { PZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2387#if 0
2388// See Note 1.
2389 { PZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2390#endif
2391 { PZero, PNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2392 { PZero, MNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2393 { PZero, PLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2394 { PZero, MLargestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2395 { PZero, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2396 { PZero, MSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2397 { PZero, PSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2398 { PZero, MSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2399 { MZero, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2400 { MZero, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2401 { MZero, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2402 { MZero, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00002403 { MZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman2eda8972013-06-26 23:55:26 +00002404#if 0
2405// See Note 1.
2406 { MZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2407#endif
2408 { MZero, PNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2409 { MZero, MNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2410 { MZero, PLargestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2411 { MZero, MLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2412 { MZero, PSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2413 { MZero, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2414 { MZero, PSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2415 { MZero, MSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2416 { QNaN, PInf, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00002417 { QNaN, MInf, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman2eda8972013-06-26 23:55:26 +00002418 { QNaN, PZero, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00002419 { QNaN, MZero, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman2eda8972013-06-26 23:55:26 +00002420 { QNaN, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2421#if 0
2422// See Note 1.
2423 { QNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2424#endif
2425 { QNaN, PNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00002426 { QNaN, MNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman2eda8972013-06-26 23:55:26 +00002427 { QNaN, PLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00002428 { QNaN, MLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman2eda8972013-06-26 23:55:26 +00002429 { QNaN, PSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00002430 { QNaN, MSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman2eda8972013-06-26 23:55:26 +00002431 { QNaN, PSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00002432 { QNaN, MSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman2eda8972013-06-26 23:55:26 +00002433#if 0
2434// See Note 1.
2435 { SNaN, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2436 { SNaN, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2437 { SNaN, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2438 { SNaN, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2439 { SNaN, QNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2440 { SNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2441 { SNaN, PNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2442 { SNaN, MNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2443 { SNaN, PLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2444 { SNaN, MLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2445 { SNaN, PSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2446 { SNaN, MSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2447 { SNaN, PSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2448 { SNaN, MSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2449#endif
2450 { PNormalValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2451 { PNormalValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2452 { PNormalValue, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2453 { PNormalValue, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2454 { PNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2455#if 0
2456// See Note 1.
2457 { PNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2458#endif
2459 { PNormalValue, PNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2460 { PNormalValue, MNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2461 { PNormalValue, PLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2462 { PNormalValue, MLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2463 { PNormalValue, PSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2464 { PNormalValue, MSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2465 { PNormalValue, PSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2466 { PNormalValue, MSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2467 { MNormalValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2468 { MNormalValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2469 { MNormalValue, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2470 { MNormalValue, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00002471 { MNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman2eda8972013-06-26 23:55:26 +00002472#if 0
2473// See Note 1.
2474 { MNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2475#endif
2476 { MNormalValue, PNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2477 { MNormalValue, MNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2478 { MNormalValue, PLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2479 { MNormalValue, MLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2480 { MNormalValue, PSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2481 { MNormalValue, MSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2482 { MNormalValue, PSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2483 { MNormalValue, MSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2484 { PLargestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2485 { PLargestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2486 { PLargestValue, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2487 { PLargestValue, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2488 { PLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2489#if 0
2490// See Note 1.
2491 { PLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2492#endif
2493 { PLargestValue, PNormalValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2494 { PLargestValue, MNormalValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2495 { PLargestValue, PLargestValue, "inf", OverflowStatus, APFloat::fcInfinity },
2496 { PLargestValue, MLargestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
2497 { PLargestValue, PSmallestValue, "0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2498 { PLargestValue, MSmallestValue, "-0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2499 { PLargestValue, PSmallestNormalized, "0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2500 { PLargestValue, MSmallestNormalized, "-0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2501 { MLargestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2502 { MLargestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2503 { MLargestValue, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2504 { MLargestValue, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00002505 { MLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman2eda8972013-06-26 23:55:26 +00002506#if 0
2507// See Note 1.
2508 { MLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2509#endif
2510 { MLargestValue, PNormalValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2511 { MLargestValue, MNormalValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2512 { MLargestValue, PLargestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
2513 { MLargestValue, MLargestValue, "inf", OverflowStatus, APFloat::fcInfinity },
2514 { MLargestValue, PSmallestValue, "-0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2515 { MLargestValue, MSmallestValue, "0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2516 { MLargestValue, PSmallestNormalized, "-0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2517 { MLargestValue, MSmallestNormalized, "0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2518 { PSmallestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2519 { PSmallestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2520 { PSmallestValue, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2521 { PSmallestValue, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2522 { PSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2523#if 0
2524// See Note 1.
2525 { PSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2526#endif
2527 { PSmallestValue, PNormalValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2528 { PSmallestValue, MNormalValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2529 { PSmallestValue, PLargestValue, "0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2530 { PSmallestValue, MLargestValue, "-0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2531 { PSmallestValue, PSmallestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2532 { PSmallestValue, MSmallestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2533 { PSmallestValue, PSmallestNormalized, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2534 { PSmallestValue, MSmallestNormalized, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2535 { MSmallestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2536 { MSmallestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2537 { MSmallestValue, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2538 { MSmallestValue, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00002539 { MSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman2eda8972013-06-26 23:55:26 +00002540#if 0
2541// See Note 1.
2542 { MSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2543#endif
2544 { MSmallestValue, PNormalValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2545 { MSmallestValue, MNormalValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2546 { MSmallestValue, PLargestValue, "-0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2547 { MSmallestValue, MLargestValue, "0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2548 { MSmallestValue, PSmallestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2549 { MSmallestValue, MSmallestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2550 { MSmallestValue, PSmallestNormalized, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2551 { MSmallestValue, MSmallestNormalized, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2552 { PSmallestNormalized, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2553 { PSmallestNormalized, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2554 { PSmallestNormalized, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2555 { PSmallestNormalized, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2556 { PSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2557#if 0
2558// See Note 1.
2559 { PSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2560#endif
2561 { PSmallestNormalized, PNormalValue, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2562 { PSmallestNormalized, MNormalValue, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2563 { PSmallestNormalized, PLargestValue, "0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2564 { PSmallestNormalized, MLargestValue, "-0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2565 { PSmallestNormalized, PSmallestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2566 { PSmallestNormalized, MSmallestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2567 { PSmallestNormalized, PSmallestNormalized, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2568 { PSmallestNormalized, MSmallestNormalized, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2569 { MSmallestNormalized, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2570 { MSmallestNormalized, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2571 { MSmallestNormalized, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2572 { MSmallestNormalized, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00002573 { MSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman2eda8972013-06-26 23:55:26 +00002574#if 0
2575// See Note 1.
2576 { MSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2577#endif
2578 { MSmallestNormalized, PNormalValue, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2579 { MSmallestNormalized, MNormalValue, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2580 { MSmallestNormalized, PLargestValue, "-0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2581 { MSmallestNormalized, MLargestValue, "0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2582 { MSmallestNormalized, PSmallestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2583 { MSmallestNormalized, MSmallestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2584 { MSmallestNormalized, PSmallestNormalized, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2585 { MSmallestNormalized, MSmallestNormalized, "0x0p+0", UnderflowStatus, APFloat::fcZero }
2586 };
2587
2588 for (size_t i = 0; i < NumTests; ++i) {
2589 APFloat x(SpecialCaseTests[i].x);
2590 APFloat y(SpecialCaseTests[i].y);
2591 APFloat::opStatus status = x.multiply(y, APFloat::rmNearestTiesToEven);
2592
Stephan Bergmann20a600c2016-12-14 11:57:17 +00002593 APFloat result(APFloat::IEEEsingle(), SpecialCaseTests[i].result);
Michael Gottesman2eda8972013-06-26 23:55:26 +00002594
Michael Gottesman2eda8972013-06-26 23:55:26 +00002595 EXPECT_TRUE(result.bitwiseIsEqual(x));
2596 EXPECT_TRUE((int)status == SpecialCaseTests[i].status);
2597 EXPECT_TRUE((int)x.getCategory() == SpecialCaseTests[i].category);
2598 }
2599}
Michael Gottesmand7d88d92013-06-26 23:55:23 +00002600
Michael Gottesmanfb76ffd2013-06-27 00:42:00 +00002601TEST(APFloatTest, divide) {
2602 // Test Special Cases against each other and normal values.
2603
2604 // TODOS/NOTES:
2605 // 1. Since we perform only default exception handling all operations with
2606 // signaling NaNs should have a result that is a quiet NaN. Currently they
2607 // return sNaN.
Michael Gottesmanfb76ffd2013-06-27 00:42:00 +00002608
Stephan Bergmann20a600c2016-12-14 11:57:17 +00002609 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle(), false);
2610 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle(), true);
2611 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle(), false);
2612 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle(), true);
2613 APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);
2614 APFloat SNaN = APFloat::getSNaN(APFloat::IEEEsingle(), false);
2615 APFloat PNormalValue = APFloat(APFloat::IEEEsingle(), "0x1p+0");
2616 APFloat MNormalValue = APFloat(APFloat::IEEEsingle(), "-0x1p+0");
2617 APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), false);
2618 APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), true);
2619 APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), false);
2620 APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), true);
Michael Gottesmanfb76ffd2013-06-27 00:42:00 +00002621 APFloat PSmallestNormalized =
Stephan Bergmann20a600c2016-12-14 11:57:17 +00002622 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);
Michael Gottesmanfb76ffd2013-06-27 00:42:00 +00002623 APFloat MSmallestNormalized =
Stephan Bergmann20a600c2016-12-14 11:57:17 +00002624 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);
Michael Gottesmanfb76ffd2013-06-27 00:42:00 +00002625
2626 const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact;
2627 const int UnderflowStatus = APFloat::opUnderflow | APFloat::opInexact;
2628
2629 const unsigned NumTests = 169;
2630 struct {
2631 APFloat x;
2632 APFloat y;
2633 const char *result;
2634 int status;
2635 int category;
2636 } SpecialCaseTests[NumTests] = {
2637 { PInf, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2638 { PInf, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2639 { PInf, PZero, "inf", APFloat::opOK, APFloat::fcInfinity },
2640 { PInf, MZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
2641 { PInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2642#if 0
2643// See Note 1.
2644 { PInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2645#endif
2646 { PInf, PNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2647 { PInf, MNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2648 { PInf, PLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2649 { PInf, MLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2650 { PInf, PSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2651 { PInf, MSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2652 { PInf, PSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
2653 { PInf, MSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
2654 { MInf, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2655 { MInf, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2656 { MInf, PZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
2657 { MInf, MZero, "inf", APFloat::opOK, APFloat::fcInfinity },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00002658 { MInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanfb76ffd2013-06-27 00:42:00 +00002659#if 0
2660// See Note 1.
2661 { MInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2662#endif
2663 { MInf, PNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2664 { MInf, MNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2665 { MInf, PLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2666 { MInf, MLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2667 { MInf, PSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2668 { MInf, MSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2669 { MInf, PSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
2670 { MInf, MSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
2671 { PZero, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2672 { PZero, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2673 { PZero, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2674 { PZero, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2675 { PZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2676#if 0
2677// See Note 1.
2678 { PZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2679#endif
2680 { PZero, PNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2681 { PZero, MNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2682 { PZero, PLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2683 { PZero, MLargestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2684 { PZero, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2685 { PZero, MSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2686 { PZero, PSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2687 { PZero, MSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2688 { MZero, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2689 { MZero, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2690 { MZero, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2691 { MZero, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00002692 { MZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanfb76ffd2013-06-27 00:42:00 +00002693#if 0
2694// See Note 1.
2695 { MZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2696#endif
2697 { MZero, PNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2698 { MZero, MNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2699 { MZero, PLargestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2700 { MZero, MLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2701 { MZero, PSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2702 { MZero, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2703 { MZero, PSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2704 { MZero, MSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2705 { QNaN, PInf, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00002706 { QNaN, MInf, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanfb76ffd2013-06-27 00:42:00 +00002707 { QNaN, PZero, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00002708 { QNaN, MZero, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanfb76ffd2013-06-27 00:42:00 +00002709 { QNaN, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2710#if 0
2711// See Note 1.
2712 { QNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2713#endif
2714 { QNaN, PNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00002715 { QNaN, MNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanfb76ffd2013-06-27 00:42:00 +00002716 { QNaN, PLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00002717 { QNaN, MLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanfb76ffd2013-06-27 00:42:00 +00002718 { QNaN, PSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00002719 { QNaN, MSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanfb76ffd2013-06-27 00:42:00 +00002720 { QNaN, PSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00002721 { QNaN, MSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanfb76ffd2013-06-27 00:42:00 +00002722#if 0
2723// See Note 1.
2724 { SNaN, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2725 { SNaN, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2726 { SNaN, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2727 { SNaN, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2728 { SNaN, QNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2729 { SNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2730 { SNaN, PNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2731 { SNaN, MNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2732 { SNaN, PLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2733 { SNaN, MLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2734 { SNaN, PSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2735 { SNaN, MSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2736 { SNaN, PSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2737 { SNaN, MSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2738#endif
2739 { PNormalValue, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2740 { PNormalValue, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2741 { PNormalValue, PZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
2742 { PNormalValue, MZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2743 { PNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2744#if 0
2745// See Note 1.
2746 { PNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2747#endif
2748 { PNormalValue, PNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2749 { PNormalValue, MNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2750 { PNormalValue, PLargestValue, "0x1p-128", UnderflowStatus, APFloat::fcNormal },
2751 { PNormalValue, MLargestValue, "-0x1p-128", UnderflowStatus, APFloat::fcNormal },
2752 { PNormalValue, PSmallestValue, "inf", OverflowStatus, APFloat::fcInfinity },
2753 { PNormalValue, MSmallestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
2754 { PNormalValue, PSmallestNormalized, "0x1p+126", APFloat::opOK, APFloat::fcNormal },
2755 { PNormalValue, MSmallestNormalized, "-0x1p+126", APFloat::opOK, APFloat::fcNormal },
2756 { MNormalValue, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2757 { MNormalValue, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2758 { MNormalValue, PZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2759 { MNormalValue, MZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00002760 { MNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanfb76ffd2013-06-27 00:42:00 +00002761#if 0
2762// See Note 1.
2763 { MNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2764#endif
2765 { MNormalValue, PNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2766 { MNormalValue, MNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2767 { MNormalValue, PLargestValue, "-0x1p-128", UnderflowStatus, APFloat::fcNormal },
2768 { MNormalValue, MLargestValue, "0x1p-128", UnderflowStatus, APFloat::fcNormal },
2769 { MNormalValue, PSmallestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
2770 { MNormalValue, MSmallestValue, "inf", OverflowStatus, APFloat::fcInfinity },
2771 { MNormalValue, PSmallestNormalized, "-0x1p+126", APFloat::opOK, APFloat::fcNormal },
2772 { MNormalValue, MSmallestNormalized, "0x1p+126", APFloat::opOK, APFloat::fcNormal },
2773 { PLargestValue, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2774 { PLargestValue, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2775 { PLargestValue, PZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
2776 { PLargestValue, MZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2777 { PLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2778#if 0
2779// See Note 1.
2780 { PLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2781#endif
2782 { PLargestValue, PNormalValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2783 { PLargestValue, MNormalValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2784 { PLargestValue, PLargestValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2785 { PLargestValue, MLargestValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2786 { PLargestValue, PSmallestValue, "inf", OverflowStatus, APFloat::fcInfinity },
2787 { PLargestValue, MSmallestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
2788 { PLargestValue, PSmallestNormalized, "inf", OverflowStatus, APFloat::fcInfinity },
2789 { PLargestValue, MSmallestNormalized, "-inf", OverflowStatus, APFloat::fcInfinity },
2790 { MLargestValue, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2791 { MLargestValue, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2792 { MLargestValue, PZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2793 { MLargestValue, MZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00002794 { MLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanfb76ffd2013-06-27 00:42:00 +00002795#if 0
2796// See Note 1.
2797 { MLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2798#endif
2799 { MLargestValue, PNormalValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2800 { MLargestValue, MNormalValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2801 { MLargestValue, PLargestValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2802 { MLargestValue, MLargestValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2803 { MLargestValue, PSmallestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
2804 { MLargestValue, MSmallestValue, "inf", OverflowStatus, APFloat::fcInfinity },
2805 { MLargestValue, PSmallestNormalized, "-inf", OverflowStatus, APFloat::fcInfinity },
2806 { MLargestValue, MSmallestNormalized, "inf", OverflowStatus, APFloat::fcInfinity },
2807 { PSmallestValue, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2808 { PSmallestValue, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2809 { PSmallestValue, PZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
2810 { PSmallestValue, MZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2811 { PSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2812#if 0
2813// See Note 1.
2814 { PSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2815#endif
2816 { PSmallestValue, PNormalValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2817 { PSmallestValue, MNormalValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2818 { PSmallestValue, PLargestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2819 { PSmallestValue, MLargestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2820 { PSmallestValue, PSmallestValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2821 { PSmallestValue, MSmallestValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2822 { PSmallestValue, PSmallestNormalized, "0x1p-23", APFloat::opOK, APFloat::fcNormal },
2823 { PSmallestValue, MSmallestNormalized, "-0x1p-23", APFloat::opOK, APFloat::fcNormal },
2824 { MSmallestValue, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2825 { MSmallestValue, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2826 { MSmallestValue, PZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2827 { MSmallestValue, MZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00002828 { MSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanfb76ffd2013-06-27 00:42:00 +00002829#if 0
2830// See Note 1.
2831 { MSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2832#endif
2833 { MSmallestValue, PNormalValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2834 { MSmallestValue, MNormalValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2835 { MSmallestValue, PLargestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2836 { MSmallestValue, MLargestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2837 { MSmallestValue, PSmallestValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2838 { MSmallestValue, MSmallestValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2839 { MSmallestValue, PSmallestNormalized, "-0x1p-23", APFloat::opOK, APFloat::fcNormal },
2840 { MSmallestValue, MSmallestNormalized, "0x1p-23", APFloat::opOK, APFloat::fcNormal },
2841 { PSmallestNormalized, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2842 { PSmallestNormalized, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2843 { PSmallestNormalized, PZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
2844 { PSmallestNormalized, MZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2845 { PSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2846#if 0
2847// See Note 1.
2848 { PSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2849#endif
2850 { PSmallestNormalized, PNormalValue, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2851 { PSmallestNormalized, MNormalValue, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2852 { PSmallestNormalized, PLargestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2853 { PSmallestNormalized, MLargestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2854 { PSmallestNormalized, PSmallestValue, "0x1p+23", APFloat::opOK, APFloat::fcNormal },
2855 { PSmallestNormalized, MSmallestValue, "-0x1p+23", APFloat::opOK, APFloat::fcNormal },
2856 { PSmallestNormalized, PSmallestNormalized, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2857 { PSmallestNormalized, MSmallestNormalized, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2858 { MSmallestNormalized, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2859 { MSmallestNormalized, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2860 { MSmallestNormalized, PZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2861 { MSmallestNormalized, MZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
Michael Gottesmanca4d2e62013-07-27 21:49:25 +00002862 { MSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanfb76ffd2013-06-27 00:42:00 +00002863#if 0
2864// See Note 1.
2865 { MSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2866#endif
2867 { MSmallestNormalized, PNormalValue, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2868 { MSmallestNormalized, MNormalValue, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2869 { MSmallestNormalized, PLargestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2870 { MSmallestNormalized, MLargestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2871 { MSmallestNormalized, PSmallestValue, "-0x1p+23", APFloat::opOK, APFloat::fcNormal },
2872 { MSmallestNormalized, MSmallestValue, "0x1p+23", APFloat::opOK, APFloat::fcNormal },
2873 { MSmallestNormalized, PSmallestNormalized, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2874 { MSmallestNormalized, MSmallestNormalized, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2875 };
2876
2877 for (size_t i = 0; i < NumTests; ++i) {
2878 APFloat x(SpecialCaseTests[i].x);
2879 APFloat y(SpecialCaseTests[i].y);
2880 APFloat::opStatus status = x.divide(y, APFloat::rmNearestTiesToEven);
2881
Stephan Bergmann20a600c2016-12-14 11:57:17 +00002882 APFloat result(APFloat::IEEEsingle(), SpecialCaseTests[i].result);
Michael Gottesmanfb76ffd2013-06-27 00:42:00 +00002883
2884 EXPECT_TRUE(result.bitwiseIsEqual(x));
2885 EXPECT_TRUE((int)status == SpecialCaseTests[i].status);
2886 EXPECT_TRUE((int)x.getCategory() == SpecialCaseTests[i].category);
2887 }
2888}
2889
Chandler Carruth0ffdb312014-10-09 23:26:15 +00002890TEST(APFloatTest, operatorOverloads) {
2891 // This is mostly testing that these operator overloads compile.
Stephan Bergmann20a600c2016-12-14 11:57:17 +00002892 APFloat One = APFloat(APFloat::IEEEsingle(), "0x1p+0");
2893 APFloat Two = APFloat(APFloat::IEEEsingle(), "0x2p+0");
Chandler Carruth0ffdb312014-10-09 23:26:15 +00002894 EXPECT_TRUE(Two.bitwiseIsEqual(One + One));
2895 EXPECT_TRUE(One.bitwiseIsEqual(Two - One));
2896 EXPECT_TRUE(Two.bitwiseIsEqual(One * Two));
2897 EXPECT_TRUE(One.bitwiseIsEqual(Two / Two));
2898}
Chandler Carruth9ea4dd22014-10-10 04:17:04 +00002899
Chandler Carruth082e6672014-10-10 08:27:22 +00002900TEST(APFloatTest, abs) {
Stephan Bergmann20a600c2016-12-14 11:57:17 +00002901 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle(), false);
2902 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle(), true);
2903 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle(), false);
2904 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle(), true);
2905 APFloat PQNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);
2906 APFloat MQNaN = APFloat::getNaN(APFloat::IEEEsingle(), true);
2907 APFloat PSNaN = APFloat::getSNaN(APFloat::IEEEsingle(), false);
2908 APFloat MSNaN = APFloat::getSNaN(APFloat::IEEEsingle(), true);
2909 APFloat PNormalValue = APFloat(APFloat::IEEEsingle(), "0x1p+0");
2910 APFloat MNormalValue = APFloat(APFloat::IEEEsingle(), "-0x1p+0");
2911 APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), false);
2912 APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), true);
2913 APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), false);
2914 APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), true);
Chandler Carruth082e6672014-10-10 08:27:22 +00002915 APFloat PSmallestNormalized =
Stephan Bergmann20a600c2016-12-14 11:57:17 +00002916 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);
Chandler Carruth082e6672014-10-10 08:27:22 +00002917 APFloat MSmallestNormalized =
Stephan Bergmann20a600c2016-12-14 11:57:17 +00002918 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);
Chandler Carruth082e6672014-10-10 08:27:22 +00002919
2920 EXPECT_TRUE(PInf.bitwiseIsEqual(abs(PInf)));
2921 EXPECT_TRUE(PInf.bitwiseIsEqual(abs(MInf)));
2922 EXPECT_TRUE(PZero.bitwiseIsEqual(abs(PZero)));
2923 EXPECT_TRUE(PZero.bitwiseIsEqual(abs(MZero)));
2924 EXPECT_TRUE(PQNaN.bitwiseIsEqual(abs(PQNaN)));
2925 EXPECT_TRUE(PQNaN.bitwiseIsEqual(abs(MQNaN)));
2926 EXPECT_TRUE(PSNaN.bitwiseIsEqual(abs(PSNaN)));
2927 EXPECT_TRUE(PSNaN.bitwiseIsEqual(abs(MSNaN)));
2928 EXPECT_TRUE(PNormalValue.bitwiseIsEqual(abs(PNormalValue)));
2929 EXPECT_TRUE(PNormalValue.bitwiseIsEqual(abs(MNormalValue)));
2930 EXPECT_TRUE(PLargestValue.bitwiseIsEqual(abs(PLargestValue)));
2931 EXPECT_TRUE(PLargestValue.bitwiseIsEqual(abs(MLargestValue)));
2932 EXPECT_TRUE(PSmallestValue.bitwiseIsEqual(abs(PSmallestValue)));
2933 EXPECT_TRUE(PSmallestValue.bitwiseIsEqual(abs(MSmallestValue)));
2934 EXPECT_TRUE(PSmallestNormalized.bitwiseIsEqual(abs(PSmallestNormalized)));
2935 EXPECT_TRUE(PSmallestNormalized.bitwiseIsEqual(abs(MSmallestNormalized)));
2936}
2937
Matt Arsenaultf3379522017-01-25 04:54:34 +00002938TEST(APFloatTest, neg) {
2939 APFloat One = APFloat(APFloat::IEEEsingle(), "1.0");
2940 APFloat NegOne = APFloat(APFloat::IEEEsingle(), "-1.0");
2941 APFloat Zero = APFloat::getZero(APFloat::IEEEsingle(), false);
2942 APFloat NegZero = APFloat::getZero(APFloat::IEEEsingle(), true);
2943 APFloat Inf = APFloat::getInf(APFloat::IEEEsingle(), false);
2944 APFloat NegInf = APFloat::getInf(APFloat::IEEEsingle(), true);
2945 APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);
2946 APFloat NegQNaN = APFloat::getNaN(APFloat::IEEEsingle(), true);
2947
2948 EXPECT_TRUE(NegOne.bitwiseIsEqual(neg(One)));
2949 EXPECT_TRUE(One.bitwiseIsEqual(neg(NegOne)));
2950 EXPECT_TRUE(NegZero.bitwiseIsEqual(neg(Zero)));
2951 EXPECT_TRUE(Zero.bitwiseIsEqual(neg(NegZero)));
2952 EXPECT_TRUE(NegInf.bitwiseIsEqual(neg(Inf)));
2953 EXPECT_TRUE(Inf.bitwiseIsEqual(neg(NegInf)));
2954 EXPECT_TRUE(NegInf.bitwiseIsEqual(neg(Inf)));
2955 EXPECT_TRUE(Inf.bitwiseIsEqual(neg(NegInf)));
2956 EXPECT_TRUE(NegQNaN.bitwiseIsEqual(neg(QNaN)));
2957 EXPECT_TRUE(QNaN.bitwiseIsEqual(neg(NegQNaN)));
2958}
2959
Chandler Carruthf4ec6692014-10-10 05:14:12 +00002960TEST(APFloatTest, ilogb) {
Stephan Bergmann20a600c2016-12-14 11:57:17 +00002961 EXPECT_EQ(-1074, ilogb(APFloat::getSmallest(APFloat::IEEEdouble(), false)));
2962 EXPECT_EQ(-1074, ilogb(APFloat::getSmallest(APFloat::IEEEdouble(), true)));
2963 EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1024")));
2964 EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1023")));
2965 EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble(), "-0x1.ffffffffffffep-1023")));
2966 EXPECT_EQ(-51, ilogb(APFloat(APFloat::IEEEdouble(), "0x1p-51")));
2967 EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp-1023")));
2968 EXPECT_EQ(-2, ilogb(APFloat(APFloat::IEEEdouble(), "0x0.ffffp-1")));
2969 EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble(), "0x1.fffep-1023")));
2970 EXPECT_EQ(1023, ilogb(APFloat::getLargest(APFloat::IEEEdouble(), false)));
2971 EXPECT_EQ(1023, ilogb(APFloat::getLargest(APFloat::IEEEdouble(), true)));
Matt Arsenault499f78c2016-03-13 05:12:32 +00002972
2973
Stephan Bergmann20a600c2016-12-14 11:57:17 +00002974 EXPECT_EQ(0, ilogb(APFloat(APFloat::IEEEsingle(), "0x1p+0")));
2975 EXPECT_EQ(0, ilogb(APFloat(APFloat::IEEEsingle(), "-0x1p+0")));
2976 EXPECT_EQ(42, ilogb(APFloat(APFloat::IEEEsingle(), "0x1p+42")));
2977 EXPECT_EQ(-42, ilogb(APFloat(APFloat::IEEEsingle(), "0x1p-42")));
Chandler Carruth9ea4dd22014-10-10 04:17:04 +00002978
Chandler Carruthf4ec6692014-10-10 05:14:12 +00002979 EXPECT_EQ(APFloat::IEK_Inf,
Stephan Bergmann20a600c2016-12-14 11:57:17 +00002980 ilogb(APFloat::getInf(APFloat::IEEEsingle(), false)));
Chandler Carruthf4ec6692014-10-10 05:14:12 +00002981 EXPECT_EQ(APFloat::IEK_Inf,
Stephan Bergmann20a600c2016-12-14 11:57:17 +00002982 ilogb(APFloat::getInf(APFloat::IEEEsingle(), true)));
Chandler Carruthf4ec6692014-10-10 05:14:12 +00002983 EXPECT_EQ(APFloat::IEK_Zero,
Stephan Bergmann20a600c2016-12-14 11:57:17 +00002984 ilogb(APFloat::getZero(APFloat::IEEEsingle(), false)));
Chandler Carruthf4ec6692014-10-10 05:14:12 +00002985 EXPECT_EQ(APFloat::IEK_Zero,
Stephan Bergmann20a600c2016-12-14 11:57:17 +00002986 ilogb(APFloat::getZero(APFloat::IEEEsingle(), true)));
Chandler Carruthf4ec6692014-10-10 05:14:12 +00002987 EXPECT_EQ(APFloat::IEK_NaN,
Stephan Bergmann20a600c2016-12-14 11:57:17 +00002988 ilogb(APFloat::getNaN(APFloat::IEEEsingle(), false)));
Chandler Carruthf4ec6692014-10-10 05:14:12 +00002989 EXPECT_EQ(APFloat::IEK_NaN,
Stephan Bergmann20a600c2016-12-14 11:57:17 +00002990 ilogb(APFloat::getSNaN(APFloat::IEEEsingle(), false)));
Chandler Carruth9ea4dd22014-10-10 04:17:04 +00002991
Stephan Bergmann20a600c2016-12-14 11:57:17 +00002992 EXPECT_EQ(127, ilogb(APFloat::getLargest(APFloat::IEEEsingle(), false)));
2993 EXPECT_EQ(127, ilogb(APFloat::getLargest(APFloat::IEEEsingle(), true)));
Matt Arsenault499f78c2016-03-13 05:12:32 +00002994
Stephan Bergmann20a600c2016-12-14 11:57:17 +00002995 EXPECT_EQ(-149, ilogb(APFloat::getSmallest(APFloat::IEEEsingle(), false)));
2996 EXPECT_EQ(-149, ilogb(APFloat::getSmallest(APFloat::IEEEsingle(), true)));
Chandler Carruthf4ec6692014-10-10 05:14:12 +00002997 EXPECT_EQ(-126,
Stephan Bergmann20a600c2016-12-14 11:57:17 +00002998 ilogb(APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false)));
Chandler Carruthf4ec6692014-10-10 05:14:12 +00002999 EXPECT_EQ(-126,
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003000 ilogb(APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true)));
Chandler Carruth9ea4dd22014-10-10 04:17:04 +00003001}
Chandler Carruthcb84b212014-10-10 04:54:30 +00003002
3003TEST(APFloatTest, scalbn) {
Matt Arsenault2ef94692016-03-13 05:11:51 +00003004
3005 const APFloat::roundingMode RM = APFloat::rmNearestTiesToEven;
Chandler Carruthcb84b212014-10-10 04:54:30 +00003006 EXPECT_TRUE(
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003007 APFloat(APFloat::IEEEsingle(), "0x1p+0")
3008 .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEsingle(), "0x1p+0"), 0, RM)));
Chandler Carruthcb84b212014-10-10 04:54:30 +00003009 EXPECT_TRUE(
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003010 APFloat(APFloat::IEEEsingle(), "0x1p+42")
3011 .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEsingle(), "0x1p+0"), 42, RM)));
Chandler Carruthcb84b212014-10-10 04:54:30 +00003012 EXPECT_TRUE(
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003013 APFloat(APFloat::IEEEsingle(), "0x1p-42")
3014 .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEsingle(), "0x1p+0"), -42, RM)));
Chandler Carruthcb84b212014-10-10 04:54:30 +00003015
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003016 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle(), false);
3017 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle(), true);
3018 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle(), false);
3019 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle(), true);
3020 APFloat QPNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);
3021 APFloat QMNaN = APFloat::getNaN(APFloat::IEEEsingle(), true);
3022 APFloat SNaN = APFloat::getSNaN(APFloat::IEEEsingle(), false);
Chandler Carruthcb84b212014-10-10 04:54:30 +00003023
Matt Arsenault2ef94692016-03-13 05:11:51 +00003024 EXPECT_TRUE(PInf.bitwiseIsEqual(scalbn(PInf, 0, RM)));
3025 EXPECT_TRUE(MInf.bitwiseIsEqual(scalbn(MInf, 0, RM)));
3026 EXPECT_TRUE(PZero.bitwiseIsEqual(scalbn(PZero, 0, RM)));
3027 EXPECT_TRUE(MZero.bitwiseIsEqual(scalbn(MZero, 0, RM)));
3028 EXPECT_TRUE(QPNaN.bitwiseIsEqual(scalbn(QPNaN, 0, RM)));
3029 EXPECT_TRUE(QMNaN.bitwiseIsEqual(scalbn(QMNaN, 0, RM)));
Matt Arsenaultb8833722016-03-23 23:51:45 +00003030 EXPECT_FALSE(scalbn(SNaN, 0, RM).isSignaling());
3031
3032 APFloat ScalbnSNaN = scalbn(SNaN, 1, RM);
3033 EXPECT_TRUE(ScalbnSNaN.isNaN() && !ScalbnSNaN.isSignaling());
3034
3035 // Make sure highest bit of payload is preserved.
3036 const APInt Payload(64, (UINT64_C(1) << 50) |
3037 (UINT64_C(1) << 49) |
3038 (UINT64_C(1234) << 32) |
3039 1);
3040
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003041 APFloat SNaNWithPayload = APFloat::getSNaN(APFloat::IEEEdouble(), false,
Matt Arsenaultb8833722016-03-23 23:51:45 +00003042 &Payload);
3043 APFloat QuietPayload = scalbn(SNaNWithPayload, 1, RM);
3044 EXPECT_TRUE(QuietPayload.isNaN() && !QuietPayload.isSignaling());
3045 EXPECT_EQ(Payload, QuietPayload.bitcastToAPInt().getLoBits(51));
Matt Arsenault2ef94692016-03-13 05:11:51 +00003046
3047 EXPECT_TRUE(PInf.bitwiseIsEqual(
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003048 scalbn(APFloat(APFloat::IEEEsingle(), "0x1p+0"), 128, RM)));
Matt Arsenault2ef94692016-03-13 05:11:51 +00003049 EXPECT_TRUE(MInf.bitwiseIsEqual(
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003050 scalbn(APFloat(APFloat::IEEEsingle(), "-0x1p+0"), 128, RM)));
Matt Arsenault2ef94692016-03-13 05:11:51 +00003051 EXPECT_TRUE(PInf.bitwiseIsEqual(
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003052 scalbn(APFloat(APFloat::IEEEsingle(), "0x1p+127"), 1, RM)));
Matt Arsenault2ef94692016-03-13 05:11:51 +00003053 EXPECT_TRUE(PZero.bitwiseIsEqual(
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003054 scalbn(APFloat(APFloat::IEEEsingle(), "0x1p-127"), -127, RM)));
Matt Arsenault2ef94692016-03-13 05:11:51 +00003055 EXPECT_TRUE(MZero.bitwiseIsEqual(
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003056 scalbn(APFloat(APFloat::IEEEsingle(), "-0x1p-127"), -127, RM)));
3057 EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "-0x1p-149").bitwiseIsEqual(
3058 scalbn(APFloat(APFloat::IEEEsingle(), "-0x1p-127"), -22, RM)));
Matt Arsenault2ef94692016-03-13 05:11:51 +00003059 EXPECT_TRUE(PZero.bitwiseIsEqual(
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003060 scalbn(APFloat(APFloat::IEEEsingle(), "0x1p-126"), -24, RM)));
Matt Arsenault2ef94692016-03-13 05:11:51 +00003061
3062
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003063 APFloat SmallestF64 = APFloat::getSmallest(APFloat::IEEEdouble(), false);
3064 APFloat NegSmallestF64 = APFloat::getSmallest(APFloat::IEEEdouble(), true);
Matt Arsenault2ef94692016-03-13 05:11:51 +00003065
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003066 APFloat LargestF64 = APFloat::getLargest(APFloat::IEEEdouble(), false);
3067 APFloat NegLargestF64 = APFloat::getLargest(APFloat::IEEEdouble(), true);
Matt Arsenault2ef94692016-03-13 05:11:51 +00003068
3069 APFloat SmallestNormalizedF64
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003070 = APFloat::getSmallestNormalized(APFloat::IEEEdouble(), false);
Matt Arsenault2ef94692016-03-13 05:11:51 +00003071 APFloat NegSmallestNormalizedF64
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003072 = APFloat::getSmallestNormalized(APFloat::IEEEdouble(), true);
Matt Arsenault2ef94692016-03-13 05:11:51 +00003073
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003074 APFloat LargestDenormalF64(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1023");
3075 APFloat NegLargestDenormalF64(APFloat::IEEEdouble(), "-0x1.ffffffffffffep-1023");
Matt Arsenault2ef94692016-03-13 05:11:51 +00003076
3077
3078 EXPECT_TRUE(SmallestF64.bitwiseIsEqual(
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003079 scalbn(APFloat(APFloat::IEEEdouble(), "0x1p-1074"), 0, RM)));
Matt Arsenault2ef94692016-03-13 05:11:51 +00003080 EXPECT_TRUE(NegSmallestF64.bitwiseIsEqual(
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003081 scalbn(APFloat(APFloat::IEEEdouble(), "-0x1p-1074"), 0, RM)));
Matt Arsenault2ef94692016-03-13 05:11:51 +00003082
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003083 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p+1023")
Matt Arsenault2ef94692016-03-13 05:11:51 +00003084 .bitwiseIsEqual(scalbn(SmallestF64, 2097, RM)));
3085
3086 EXPECT_TRUE(scalbn(SmallestF64, -2097, RM).isPosZero());
3087 EXPECT_TRUE(scalbn(SmallestF64, -2098, RM).isPosZero());
3088 EXPECT_TRUE(scalbn(SmallestF64, -2099, RM).isPosZero());
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003089 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p+1022")
Matt Arsenault2ef94692016-03-13 05:11:51 +00003090 .bitwiseIsEqual(scalbn(SmallestF64, 2096, RM)));
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003091 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p+1023")
Matt Arsenault2ef94692016-03-13 05:11:51 +00003092 .bitwiseIsEqual(scalbn(SmallestF64, 2097, RM)));
3093 EXPECT_TRUE(scalbn(SmallestF64, 2098, RM).isInfinity());
3094 EXPECT_TRUE(scalbn(SmallestF64, 2099, RM).isInfinity());
3095
3096 // Test for integer overflows when adding to exponent.
3097 EXPECT_TRUE(scalbn(SmallestF64, -INT_MAX, RM).isPosZero());
3098 EXPECT_TRUE(scalbn(LargestF64, INT_MAX, RM).isInfinity());
3099
3100 EXPECT_TRUE(LargestDenormalF64
3101 .bitwiseIsEqual(scalbn(LargestDenormalF64, 0, RM)));
3102 EXPECT_TRUE(NegLargestDenormalF64
3103 .bitwiseIsEqual(scalbn(NegLargestDenormalF64, 0, RM)));
3104
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003105 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1022")
Matt Arsenault2ef94692016-03-13 05:11:51 +00003106 .bitwiseIsEqual(scalbn(LargestDenormalF64, 1, RM)));
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003107 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1.ffffffffffffep-1021")
Matt Arsenault2ef94692016-03-13 05:11:51 +00003108 .bitwiseIsEqual(scalbn(NegLargestDenormalF64, 2, RM)));
3109
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003110 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep+1")
Matt Arsenault2ef94692016-03-13 05:11:51 +00003111 .bitwiseIsEqual(scalbn(LargestDenormalF64, 1024, RM)));
3112 EXPECT_TRUE(scalbn(LargestDenormalF64, -1023, RM).isPosZero());
3113 EXPECT_TRUE(scalbn(LargestDenormalF64, -1024, RM).isPosZero());
3114 EXPECT_TRUE(scalbn(LargestDenormalF64, -2048, RM).isPosZero());
3115 EXPECT_TRUE(scalbn(LargestDenormalF64, 2047, RM).isInfinity());
3116 EXPECT_TRUE(scalbn(LargestDenormalF64, 2098, RM).isInfinity());
3117 EXPECT_TRUE(scalbn(LargestDenormalF64, 2099, RM).isInfinity());
3118
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003119 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-2")
Matt Arsenault2ef94692016-03-13 05:11:51 +00003120 .bitwiseIsEqual(scalbn(LargestDenormalF64, 1021, RM)));
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003121 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1")
Matt Arsenault2ef94692016-03-13 05:11:51 +00003122 .bitwiseIsEqual(scalbn(LargestDenormalF64, 1022, RM)));
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003123 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep+0")
Matt Arsenault2ef94692016-03-13 05:11:51 +00003124 .bitwiseIsEqual(scalbn(LargestDenormalF64, 1023, RM)));
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003125 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep+1023")
Matt Arsenault2ef94692016-03-13 05:11:51 +00003126 .bitwiseIsEqual(scalbn(LargestDenormalF64, 2046, RM)));
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003127 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p+974")
Matt Arsenault2ef94692016-03-13 05:11:51 +00003128 .bitwiseIsEqual(scalbn(SmallestF64, 2048, RM)));
3129
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003130 APFloat RandomDenormalF64(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp+51");
3131 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp-972")
Matt Arsenault2ef94692016-03-13 05:11:51 +00003132 .bitwiseIsEqual(scalbn(RandomDenormalF64, -1023, RM)));
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003133 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp-1")
Matt Arsenault2ef94692016-03-13 05:11:51 +00003134 .bitwiseIsEqual(scalbn(RandomDenormalF64, -52, RM)));
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003135 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp-2")
Matt Arsenault2ef94692016-03-13 05:11:51 +00003136 .bitwiseIsEqual(scalbn(RandomDenormalF64, -53, RM)));
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003137 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp+0")
Matt Arsenault2ef94692016-03-13 05:11:51 +00003138 .bitwiseIsEqual(scalbn(RandomDenormalF64, -51, RM)));
3139
3140 EXPECT_TRUE(scalbn(RandomDenormalF64, -2097, RM).isPosZero());
3141 EXPECT_TRUE(scalbn(RandomDenormalF64, -2090, RM).isPosZero());
3142
Chandler Carruthcb84b212014-10-10 04:54:30 +00003143
3144 EXPECT_TRUE(
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003145 APFloat(APFloat::IEEEdouble(), "-0x1p-1073")
Matt Arsenault2ef94692016-03-13 05:11:51 +00003146 .bitwiseIsEqual(scalbn(NegLargestF64, -2097, RM)));
3147
Chandler Carruthcb84b212014-10-10 04:54:30 +00003148 EXPECT_TRUE(
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003149 APFloat(APFloat::IEEEdouble(), "-0x1p-1024")
Matt Arsenault2ef94692016-03-13 05:11:51 +00003150 .bitwiseIsEqual(scalbn(NegLargestF64, -2048, RM)));
3151
3152 EXPECT_TRUE(
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003153 APFloat(APFloat::IEEEdouble(), "0x1p-1073")
Matt Arsenault2ef94692016-03-13 05:11:51 +00003154 .bitwiseIsEqual(scalbn(LargestF64, -2097, RM)));
3155
3156 EXPECT_TRUE(
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003157 APFloat(APFloat::IEEEdouble(), "0x1p-1074")
Matt Arsenault2ef94692016-03-13 05:11:51 +00003158 .bitwiseIsEqual(scalbn(LargestF64, -2098, RM)));
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003159 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1p-1074")
Matt Arsenault2ef94692016-03-13 05:11:51 +00003160 .bitwiseIsEqual(scalbn(NegLargestF64, -2098, RM)));
3161 EXPECT_TRUE(scalbn(NegLargestF64, -2099, RM).isNegZero());
3162 EXPECT_TRUE(scalbn(LargestF64, 1, RM).isInfinity());
3163
3164
3165 EXPECT_TRUE(
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003166 APFloat(APFloat::IEEEdouble(), "0x1p+0")
3167 .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEdouble(), "0x1p+52"), -52, RM)));
Matt Arsenault2ef94692016-03-13 05:11:51 +00003168
3169 EXPECT_TRUE(
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003170 APFloat(APFloat::IEEEdouble(), "0x1p-103")
3171 .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEdouble(), "0x1p-51"), -52, RM)));
Chandler Carruthcb84b212014-10-10 04:54:30 +00003172}
Matt Arsenault7c9226f2016-03-21 16:49:16 +00003173
3174TEST(APFloatTest, frexp) {
3175 const APFloat::roundingMode RM = APFloat::rmNearestTiesToEven;
3176
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003177 APFloat PZero = APFloat::getZero(APFloat::IEEEdouble(), false);
3178 APFloat MZero = APFloat::getZero(APFloat::IEEEdouble(), true);
Matt Arsenault7c9226f2016-03-21 16:49:16 +00003179 APFloat One(1.0);
3180 APFloat MOne(-1.0);
3181 APFloat Two(2.0);
3182 APFloat MTwo(-2.0);
3183
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003184 APFloat LargestDenormal(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1023");
3185 APFloat NegLargestDenormal(APFloat::IEEEdouble(), "-0x1.ffffffffffffep-1023");
Matt Arsenault7c9226f2016-03-21 16:49:16 +00003186
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003187 APFloat Smallest = APFloat::getSmallest(APFloat::IEEEdouble(), false);
3188 APFloat NegSmallest = APFloat::getSmallest(APFloat::IEEEdouble(), true);
Matt Arsenault7c9226f2016-03-21 16:49:16 +00003189
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003190 APFloat Largest = APFloat::getLargest(APFloat::IEEEdouble(), false);
3191 APFloat NegLargest = APFloat::getLargest(APFloat::IEEEdouble(), true);
Matt Arsenault7c9226f2016-03-21 16:49:16 +00003192
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003193 APFloat PInf = APFloat::getInf(APFloat::IEEEdouble(), false);
3194 APFloat MInf = APFloat::getInf(APFloat::IEEEdouble(), true);
Matt Arsenault7c9226f2016-03-21 16:49:16 +00003195
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003196 APFloat QPNaN = APFloat::getNaN(APFloat::IEEEdouble(), false);
3197 APFloat QMNaN = APFloat::getNaN(APFloat::IEEEdouble(), true);
3198 APFloat SNaN = APFloat::getSNaN(APFloat::IEEEdouble(), false);
Matt Arsenault7c9226f2016-03-21 16:49:16 +00003199
3200 // Make sure highest bit of payload is preserved.
3201 const APInt Payload(64, (UINT64_C(1) << 50) |
3202 (UINT64_C(1) << 49) |
3203 (UINT64_C(1234) << 32) |
3204 1);
3205
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003206 APFloat SNaNWithPayload = APFloat::getSNaN(APFloat::IEEEdouble(), false,
Matt Arsenault7c9226f2016-03-21 16:49:16 +00003207 &Payload);
3208
3209 APFloat SmallestNormalized
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003210 = APFloat::getSmallestNormalized(APFloat::IEEEdouble(), false);
Matt Arsenault7c9226f2016-03-21 16:49:16 +00003211 APFloat NegSmallestNormalized
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003212 = APFloat::getSmallestNormalized(APFloat::IEEEdouble(), true);
Matt Arsenault7c9226f2016-03-21 16:49:16 +00003213
3214 int Exp;
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003215 APFloat Frac(APFloat::IEEEdouble());
Matt Arsenault7c9226f2016-03-21 16:49:16 +00003216
3217
3218 Frac = frexp(PZero, Exp, RM);
3219 EXPECT_EQ(0, Exp);
3220 EXPECT_TRUE(Frac.isPosZero());
3221
3222 Frac = frexp(MZero, Exp, RM);
3223 EXPECT_EQ(0, Exp);
3224 EXPECT_TRUE(Frac.isNegZero());
3225
3226
3227 Frac = frexp(One, Exp, RM);
3228 EXPECT_EQ(1, Exp);
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003229 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p-1").bitwiseIsEqual(Frac));
Matt Arsenault7c9226f2016-03-21 16:49:16 +00003230
3231 Frac = frexp(MOne, Exp, RM);
3232 EXPECT_EQ(1, Exp);
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003233 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1p-1").bitwiseIsEqual(Frac));
Matt Arsenault7c9226f2016-03-21 16:49:16 +00003234
3235 Frac = frexp(LargestDenormal, Exp, RM);
3236 EXPECT_EQ(-1022, Exp);
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003237 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1").bitwiseIsEqual(Frac));
Matt Arsenault7c9226f2016-03-21 16:49:16 +00003238
3239 Frac = frexp(NegLargestDenormal, Exp, RM);
3240 EXPECT_EQ(-1022, Exp);
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003241 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1.ffffffffffffep-1").bitwiseIsEqual(Frac));
Matt Arsenault7c9226f2016-03-21 16:49:16 +00003242
3243
3244 Frac = frexp(Smallest, Exp, RM);
3245 EXPECT_EQ(-1073, Exp);
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003246 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p-1").bitwiseIsEqual(Frac));
Matt Arsenault7c9226f2016-03-21 16:49:16 +00003247
3248 Frac = frexp(NegSmallest, Exp, RM);
3249 EXPECT_EQ(-1073, Exp);
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003250 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1p-1").bitwiseIsEqual(Frac));
Matt Arsenault7c9226f2016-03-21 16:49:16 +00003251
3252
3253 Frac = frexp(Largest, Exp, RM);
3254 EXPECT_EQ(1024, Exp);
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003255 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.fffffffffffffp-1").bitwiseIsEqual(Frac));
Matt Arsenault7c9226f2016-03-21 16:49:16 +00003256
3257 Frac = frexp(NegLargest, Exp, RM);
3258 EXPECT_EQ(1024, Exp);
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003259 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1.fffffffffffffp-1").bitwiseIsEqual(Frac));
Matt Arsenault7c9226f2016-03-21 16:49:16 +00003260
3261
3262 Frac = frexp(PInf, Exp, RM);
3263 EXPECT_EQ(INT_MAX, Exp);
3264 EXPECT_TRUE(Frac.isInfinity() && !Frac.isNegative());
3265
3266 Frac = frexp(MInf, Exp, RM);
3267 EXPECT_EQ(INT_MAX, Exp);
3268 EXPECT_TRUE(Frac.isInfinity() && Frac.isNegative());
3269
3270 Frac = frexp(QPNaN, Exp, RM);
3271 EXPECT_EQ(INT_MIN, Exp);
3272 EXPECT_TRUE(Frac.isNaN());
3273
3274 Frac = frexp(QMNaN, Exp, RM);
3275 EXPECT_EQ(INT_MIN, Exp);
3276 EXPECT_TRUE(Frac.isNaN());
3277
3278 Frac = frexp(SNaN, Exp, RM);
3279 EXPECT_EQ(INT_MIN, Exp);
3280 EXPECT_TRUE(Frac.isNaN() && !Frac.isSignaling());
3281
3282 Frac = frexp(SNaNWithPayload, Exp, RM);
3283 EXPECT_EQ(INT_MIN, Exp);
3284 EXPECT_TRUE(Frac.isNaN() && !Frac.isSignaling());
3285 EXPECT_EQ(Payload, Frac.bitcastToAPInt().getLoBits(51));
3286
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003287 Frac = frexp(APFloat(APFloat::IEEEdouble(), "0x0.ffffp-1"), Exp, RM);
Matt Arsenault7c9226f2016-03-21 16:49:16 +00003288 EXPECT_EQ(-1, Exp);
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003289 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.fffep-1").bitwiseIsEqual(Frac));
Matt Arsenault7c9226f2016-03-21 16:49:16 +00003290
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003291 Frac = frexp(APFloat(APFloat::IEEEdouble(), "0x1p-51"), Exp, RM);
Matt Arsenault7c9226f2016-03-21 16:49:16 +00003292 EXPECT_EQ(-50, Exp);
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003293 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p-1").bitwiseIsEqual(Frac));
Matt Arsenault7c9226f2016-03-21 16:49:16 +00003294
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003295 Frac = frexp(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp+51"), Exp, RM);
Matt Arsenault7c9226f2016-03-21 16:49:16 +00003296 EXPECT_EQ(52, Exp);
Stephan Bergmann20a600c2016-12-14 11:57:17 +00003297 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp-1").bitwiseIsEqual(Frac));
Matt Arsenault7c9226f2016-03-21 16:49:16 +00003298}
Tim Shen611d8de2016-12-12 21:59:30 +00003299
Stephen Canon872b5052017-03-31 20:31:33 +00003300TEST(APFloatTest, mod) {
3301 {
3302 APFloat f1(APFloat::IEEEdouble(), "1.5");
3303 APFloat f2(APFloat::IEEEdouble(), "1.0");
3304 APFloat expected(APFloat::IEEEdouble(), "0.5");
3305 EXPECT_EQ(f1.mod(f2), APFloat::opOK);
3306 EXPECT_TRUE(f1.bitwiseIsEqual(expected));
3307 }
3308 {
3309 APFloat f1(APFloat::IEEEdouble(), "0.5");
3310 APFloat f2(APFloat::IEEEdouble(), "1.0");
3311 APFloat expected(APFloat::IEEEdouble(), "0.5");
3312 EXPECT_EQ(f1.mod(f2), APFloat::opOK);
3313 EXPECT_TRUE(f1.bitwiseIsEqual(expected));
3314 }
3315 {
3316 APFloat f1(APFloat::IEEEdouble(), "0x1.3333333333333p-2"); // 0.3
3317 APFloat f2(APFloat::IEEEdouble(), "0x1.47ae147ae147bp-7"); // 0.01
3318 APFloat expected(APFloat::IEEEdouble(),
3319 "0x1.47ae147ae1471p-7"); // 0.009999999999999983
3320 EXPECT_EQ(f1.mod(f2), APFloat::opOK);
3321 EXPECT_TRUE(f1.bitwiseIsEqual(expected));
3322 }
3323 {
3324 APFloat f1(APFloat::IEEEdouble(), "0x1p64"); // 1.8446744073709552e19
3325 APFloat f2(APFloat::IEEEdouble(), "1.5");
3326 APFloat expected(APFloat::IEEEdouble(), "1.0");
3327 EXPECT_EQ(f1.mod(f2), APFloat::opOK);
3328 EXPECT_TRUE(f1.bitwiseIsEqual(expected));
3329 }
3330 {
3331 APFloat f1(APFloat::IEEEdouble(), "0x1p1000");
3332 APFloat f2(APFloat::IEEEdouble(), "0x1p-1000");
3333 APFloat expected(APFloat::IEEEdouble(), "0.0");
3334 EXPECT_EQ(f1.mod(f2), APFloat::opOK);
3335 EXPECT_TRUE(f1.bitwiseIsEqual(expected));
3336 }
3337 {
3338 APFloat f1(APFloat::IEEEdouble(), "0.0");
3339 APFloat f2(APFloat::IEEEdouble(), "1.0");
3340 APFloat expected(APFloat::IEEEdouble(), "0.0");
3341 EXPECT_EQ(f1.mod(f2), APFloat::opOK);
3342 EXPECT_TRUE(f1.bitwiseIsEqual(expected));
3343 }
3344 {
3345 APFloat f1(APFloat::IEEEdouble(), "1.0");
3346 APFloat f2(APFloat::IEEEdouble(), "0.0");
3347 EXPECT_EQ(f1.mod(f2), APFloat::opInvalidOp);
3348 EXPECT_TRUE(f1.isNaN());
3349 }
3350 {
3351 APFloat f1(APFloat::IEEEdouble(), "0.0");
3352 APFloat f2(APFloat::IEEEdouble(), "0.0");
3353 EXPECT_EQ(f1.mod(f2), APFloat::opInvalidOp);
3354 EXPECT_TRUE(f1.isNaN());
3355 }
3356 {
3357 APFloat f1 = APFloat::getInf(APFloat::IEEEdouble(), false);
3358 APFloat f2(APFloat::IEEEdouble(), "1.0");
3359 EXPECT_EQ(f1.mod(f2), APFloat::opInvalidOp);
3360 EXPECT_TRUE(f1.isNaN());
3361 }
Serguei Katkovbfaa9ed2017-11-01 07:56:55 +00003362 {
3363 APFloat f1(APFloat::IEEEdouble(), "-4.0");
3364 APFloat f2(APFloat::IEEEdouble(), "-2.0");
3365 APFloat expected(APFloat::IEEEdouble(), "-0.0");
3366 EXPECT_EQ(f1.mod(f2), APFloat::opOK);
3367 EXPECT_TRUE(f1.bitwiseIsEqual(expected));
3368 }
3369 {
3370 APFloat f1(APFloat::IEEEdouble(), "-4.0");
3371 APFloat f2(APFloat::IEEEdouble(), "2.0");
3372 APFloat expected(APFloat::IEEEdouble(), "-0.0");
3373 EXPECT_EQ(f1.mod(f2), APFloat::opOK);
3374 EXPECT_TRUE(f1.bitwiseIsEqual(expected));
3375 }
Stephen Canon872b5052017-03-31 20:31:33 +00003376}
3377
Tim Shen611d8de2016-12-12 21:59:30 +00003378TEST(APFloatTest, PPCDoubleDoubleAddSpecial) {
3379 using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t,
Stephen Canon2215b7d2017-03-31 20:35:02 +00003380 APFloat::fltCategory, APFloat::roundingMode>;
3381 DataType Data[] = {
Tim Shen611d8de2016-12-12 21:59:30 +00003382 // (1 + 0) + (-1 + 0) = fcZero
Tim Shen2229ea12016-12-12 22:16:08 +00003383 std::make_tuple(0x3ff0000000000000ull, 0, 0xbff0000000000000ull, 0,
3384 APFloat::fcZero, APFloat::rmNearestTiesToEven),
Tim Shen611d8de2016-12-12 21:59:30 +00003385 // LDBL_MAX + (1.1 >> (1023 - 106) + 0)) = fcInfinity
Tim Shen2229ea12016-12-12 22:16:08 +00003386 std::make_tuple(0x7fefffffffffffffull, 0x7c8ffffffffffffeull,
3387 0x7948000000000000ull, 0ull, APFloat::fcInfinity,
3388 APFloat::rmNearestTiesToEven),
Tim Shen611d8de2016-12-12 21:59:30 +00003389 // TODO: change the 4th 0x75effffffffffffe to 0x75efffffffffffff when
Tim Shen207a20d2017-01-23 22:39:35 +00003390 // semPPCDoubleDoubleLegacy is gone.
Tim Shen611d8de2016-12-12 21:59:30 +00003391 // LDBL_MAX + (1.011111... >> (1023 - 106) + (1.1111111...0 >> (1023 -
3392 // 160))) = fcNormal
Tim Shen2229ea12016-12-12 22:16:08 +00003393 std::make_tuple(0x7fefffffffffffffull, 0x7c8ffffffffffffeull,
3394 0x7947ffffffffffffull, 0x75effffffffffffeull,
3395 APFloat::fcNormal, APFloat::rmNearestTiesToEven),
Tim Shen611d8de2016-12-12 21:59:30 +00003396 // LDBL_MAX + (1.1 >> (1023 - 106) + 0)) = fcInfinity
Tim Shen2229ea12016-12-12 22:16:08 +00003397 std::make_tuple(0x7fefffffffffffffull, 0x7c8ffffffffffffeull,
3398 0x7fefffffffffffffull, 0x7c8ffffffffffffeull,
3399 APFloat::fcInfinity, APFloat::rmNearestTiesToEven),
Tim Shen611d8de2016-12-12 21:59:30 +00003400 // NaN + (1 + 0) = fcNaN
Tim Shen2229ea12016-12-12 22:16:08 +00003401 std::make_tuple(0x7ff8000000000000ull, 0, 0x3ff0000000000000ull, 0,
3402 APFloat::fcNaN, APFloat::rmNearestTiesToEven),
Tim Shen611d8de2016-12-12 21:59:30 +00003403 };
3404
3405 for (auto Tp : Data) {
3406 uint64_t Op1[2], Op2[2];
3407 APFloat::fltCategory Expected;
3408 APFloat::roundingMode RM;
3409 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected, RM) = Tp;
3410
Tim Shen3796f1e2017-01-24 00:19:45 +00003411 {
3412 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1));
3413 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2));
3414 A1.add(A2, RM);
Tim Shen611d8de2016-12-12 21:59:30 +00003415
Tim Shen3796f1e2017-01-24 00:19:45 +00003416 EXPECT_EQ(Expected, A1.getCategory())
3417 << formatv("({0:x} + {1:x}) + ({2:x} + {3:x})", Op1[0], Op1[1],
3418 Op2[0], Op2[1])
3419 .str();
3420 }
3421 {
3422 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1));
3423 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2));
3424 A2.add(A1, RM);
3425
3426 EXPECT_EQ(Expected, A2.getCategory())
3427 << formatv("({0:x} + {1:x}) + ({2:x} + {3:x})", Op2[0], Op2[1],
3428 Op1[0], Op1[1])
3429 .str();
3430 }
Tim Shen611d8de2016-12-12 21:59:30 +00003431 }
3432}
3433
3434TEST(APFloatTest, PPCDoubleDoubleAdd) {
3435 using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,
3436 uint64_t, APFloat::roundingMode>;
3437 DataType Data[] = {
3438 // (1 + 0) + (1e-105 + 0) = (1 + 1e-105)
Tim Shen2229ea12016-12-12 22:16:08 +00003439 std::make_tuple(0x3ff0000000000000ull, 0, 0x3960000000000000ull, 0,
3440 0x3ff0000000000000ull, 0x3960000000000000ull,
3441 APFloat::rmNearestTiesToEven),
Tim Shen611d8de2016-12-12 21:59:30 +00003442 // (1 + 0) + (1e-106 + 0) = (1 + 1e-106)
Tim Shen2229ea12016-12-12 22:16:08 +00003443 std::make_tuple(0x3ff0000000000000ull, 0, 0x3950000000000000ull, 0,
3444 0x3ff0000000000000ull, 0x3950000000000000ull,
3445 APFloat::rmNearestTiesToEven),
Tim Shen611d8de2016-12-12 21:59:30 +00003446 // (1 + 1e-106) + (1e-106 + 0) = (1 + 1e-105)
Tim Shen2229ea12016-12-12 22:16:08 +00003447 std::make_tuple(0x3ff0000000000000ull, 0x3950000000000000ull,
3448 0x3950000000000000ull, 0, 0x3ff0000000000000ull,
3449 0x3960000000000000ull, APFloat::rmNearestTiesToEven),
Tim Shen611d8de2016-12-12 21:59:30 +00003450 // (1 + 0) + (epsilon + 0) = (1 + epsilon)
Tim Shen2229ea12016-12-12 22:16:08 +00003451 std::make_tuple(0x3ff0000000000000ull, 0, 0x0000000000000001ull, 0,
3452 0x3ff0000000000000ull, 0x0000000000000001ull,
3453 APFloat::rmNearestTiesToEven),
Tim Shen611d8de2016-12-12 21:59:30 +00003454 // TODO: change 0xf950000000000000 to 0xf940000000000000, when
Tim Shen207a20d2017-01-23 22:39:35 +00003455 // semPPCDoubleDoubleLegacy is gone.
Tim Shen611d8de2016-12-12 21:59:30 +00003456 // (DBL_MAX - 1 << (1023 - 105)) + (1 << (1023 - 53) + 0) = DBL_MAX +
3457 // 1.11111... << (1023 - 52)
Tim Shen2229ea12016-12-12 22:16:08 +00003458 std::make_tuple(0x7fefffffffffffffull, 0xf950000000000000ull,
3459 0x7c90000000000000ull, 0, 0x7fefffffffffffffull,
3460 0x7c8ffffffffffffeull, APFloat::rmNearestTiesToEven),
Tim Shen611d8de2016-12-12 21:59:30 +00003461 // TODO: change 0xf950000000000000 to 0xf940000000000000, when
Tim Shen207a20d2017-01-23 22:39:35 +00003462 // semPPCDoubleDoubleLegacy is gone.
Tim Shen611d8de2016-12-12 21:59:30 +00003463 // (1 << (1023 - 53) + 0) + (DBL_MAX - 1 << (1023 - 105)) = DBL_MAX +
3464 // 1.11111... << (1023 - 52)
Tim Shen2229ea12016-12-12 22:16:08 +00003465 std::make_tuple(0x7c90000000000000ull, 0, 0x7fefffffffffffffull,
3466 0xf950000000000000ull, 0x7fefffffffffffffull,
3467 0x7c8ffffffffffffeull, APFloat::rmNearestTiesToEven),
Tim Shen611d8de2016-12-12 21:59:30 +00003468 };
3469
3470 for (auto Tp : Data) {
3471 uint64_t Op1[2], Op2[2], Expected[2];
3472 APFloat::roundingMode RM;
3473 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected[0], Expected[1], RM) = Tp;
3474
Tim Shen3796f1e2017-01-24 00:19:45 +00003475 {
3476 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1));
3477 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2));
3478 A1.add(A2, RM);
Tim Shen611d8de2016-12-12 21:59:30 +00003479
Tim Shen3796f1e2017-01-24 00:19:45 +00003480 EXPECT_EQ(Expected[0], A1.bitcastToAPInt().getRawData()[0])
3481 << formatv("({0:x} + {1:x}) + ({2:x} + {3:x})", Op1[0], Op1[1],
3482 Op2[0], Op2[1])
3483 .str();
3484 EXPECT_EQ(Expected[1], A1.bitcastToAPInt().getRawData()[1])
3485 << formatv("({0:x} + {1:x}) + ({2:x} + {3:x})", Op1[0], Op1[1],
3486 Op2[0], Op2[1])
3487 .str();
3488 }
3489 {
3490 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1));
3491 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2));
3492 A2.add(A1, RM);
3493
3494 EXPECT_EQ(Expected[0], A2.bitcastToAPInt().getRawData()[0])
3495 << formatv("({0:x} + {1:x}) + ({2:x} + {3:x})", Op2[0], Op2[1],
3496 Op1[0], Op1[1])
3497 .str();
3498 EXPECT_EQ(Expected[1], A2.bitcastToAPInt().getRawData()[1])
3499 << formatv("({0:x} + {1:x}) + ({2:x} + {3:x})", Op2[0], Op2[1],
3500 Op1[0], Op1[1])
3501 .str();
3502 }
Tim Shen611d8de2016-12-12 21:59:30 +00003503 }
3504}
3505
3506TEST(APFloatTest, PPCDoubleDoubleSubtract) {
3507 using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,
3508 uint64_t, APFloat::roundingMode>;
3509 DataType Data[] = {
3510 // (1 + 0) - (-1e-105 + 0) = (1 + 1e-105)
Tim Shen2229ea12016-12-12 22:16:08 +00003511 std::make_tuple(0x3ff0000000000000ull, 0, 0xb960000000000000ull, 0,
3512 0x3ff0000000000000ull, 0x3960000000000000ull,
3513 APFloat::rmNearestTiesToEven),
Tim Shen611d8de2016-12-12 21:59:30 +00003514 // (1 + 0) - (-1e-106 + 0) = (1 + 1e-106)
Tim Shen2229ea12016-12-12 22:16:08 +00003515 std::make_tuple(0x3ff0000000000000ull, 0, 0xb950000000000000ull, 0,
3516 0x3ff0000000000000ull, 0x3950000000000000ull,
3517 APFloat::rmNearestTiesToEven),
Tim Shen611d8de2016-12-12 21:59:30 +00003518 };
3519
3520 for (auto Tp : Data) {
3521 uint64_t Op1[2], Op2[2], Expected[2];
3522 APFloat::roundingMode RM;
3523 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected[0], Expected[1], RM) = Tp;
3524
Stephan Bergmanndbb11ef2016-12-14 12:11:35 +00003525 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1));
3526 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2));
Tim Shen611d8de2016-12-12 21:59:30 +00003527 A1.subtract(A2, RM);
3528
Tim Shen1254a592016-12-16 00:47:17 +00003529 EXPECT_EQ(Expected[0], A1.bitcastToAPInt().getRawData()[0])
3530 << formatv("({0:x} + {1:x}) - ({2:x} + {3:x})", Op1[0], Op1[1], Op2[0],
3531 Op2[1])
3532 .str();
Tim Shen207a20d2017-01-23 22:39:35 +00003533 EXPECT_EQ(Expected[1], A1.bitcastToAPInt().getRawData()[1])
Tim Shen1254a592016-12-16 00:47:17 +00003534 << formatv("({0:x} + {1:x}) - ({2:x} + {3:x})", Op1[0], Op1[1], Op2[0],
3535 Op2[1])
3536 .str();
Tim Shen611d8de2016-12-12 21:59:30 +00003537 }
3538}
Tim Shen81d263b2017-01-05 22:57:54 +00003539
Tim Shen3796f1e2017-01-24 00:19:45 +00003540TEST(APFloatTest, PPCDoubleDoubleMultiplySpecial) {
3541 using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t,
3542 APFloat::fltCategory, APFloat::roundingMode>;
3543 DataType Data[] = {
3544 // fcNaN * fcNaN = fcNaN
3545 std::make_tuple(0x7ff8000000000000ull, 0, 0x7ff8000000000000ull, 0,
3546 APFloat::fcNaN, APFloat::rmNearestTiesToEven),
3547 // fcNaN * fcZero = fcNaN
3548 std::make_tuple(0x7ff8000000000000ull, 0, 0, 0, APFloat::fcNaN,
3549 APFloat::rmNearestTiesToEven),
3550 // fcNaN * fcInfinity = fcNaN
3551 std::make_tuple(0x7ff8000000000000ull, 0, 0x7ff0000000000000ull, 0,
3552 APFloat::fcNaN, APFloat::rmNearestTiesToEven),
3553 // fcNaN * fcNormal = fcNaN
3554 std::make_tuple(0x7ff8000000000000ull, 0, 0x3ff0000000000000ull, 0,
3555 APFloat::fcNaN, APFloat::rmNearestTiesToEven),
3556 // fcInfinity * fcInfinity = fcInfinity
3557 std::make_tuple(0x7ff0000000000000ull, 0, 0x7ff0000000000000ull, 0,
3558 APFloat::fcInfinity, APFloat::rmNearestTiesToEven),
3559 // fcInfinity * fcZero = fcNaN
3560 std::make_tuple(0x7ff0000000000000ull, 0, 0, 0, APFloat::fcNaN,
3561 APFloat::rmNearestTiesToEven),
3562 // fcInfinity * fcNormal = fcInfinity
3563 std::make_tuple(0x7ff0000000000000ull, 0, 0x3ff0000000000000ull, 0,
3564 APFloat::fcInfinity, APFloat::rmNearestTiesToEven),
3565 // fcZero * fcZero = fcZero
3566 std::make_tuple(0, 0, 0, 0, APFloat::fcZero,
3567 APFloat::rmNearestTiesToEven),
3568 // fcZero * fcNormal = fcZero
3569 std::make_tuple(0, 0, 0x3ff0000000000000ull, 0, APFloat::fcZero,
3570 APFloat::rmNearestTiesToEven),
3571 };
3572
3573 for (auto Tp : Data) {
3574 uint64_t Op1[2], Op2[2];
3575 APFloat::fltCategory Expected;
3576 APFloat::roundingMode RM;
3577 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected, RM) = Tp;
3578
3579 {
3580 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1));
3581 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2));
3582 A1.multiply(A2, RM);
3583
3584 EXPECT_EQ(Expected, A1.getCategory())
3585 << formatv("({0:x} + {1:x}) * ({2:x} + {3:x})", Op1[0], Op1[1],
3586 Op2[0], Op2[1])
3587 .str();
3588 }
3589 {
3590 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1));
3591 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2));
3592 A2.multiply(A1, RM);
3593
3594 EXPECT_EQ(Expected, A2.getCategory())
3595 << formatv("({0:x} + {1:x}) * ({2:x} + {3:x})", Op2[0], Op2[1],
3596 Op1[0], Op1[1])
3597 .str();
3598 }
3599 }
3600}
3601
Tim Shen81d263b2017-01-05 22:57:54 +00003602TEST(APFloatTest, PPCDoubleDoubleMultiply) {
3603 using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,
3604 uint64_t, APFloat::roundingMode>;
Tim Shen81d263b2017-01-05 22:57:54 +00003605 DataType Data[] = {
3606 // 1/3 * 3 = 1.0
3607 std::make_tuple(0x3fd5555555555555ull, 0x3c75555555555556ull,
3608 0x4008000000000000ull, 0, 0x3ff0000000000000ull, 0,
3609 APFloat::rmNearestTiesToEven),
Tim Shen3796f1e2017-01-24 00:19:45 +00003610 // (1 + epsilon) * (1 + 0) = fcZero
3611 std::make_tuple(0x3ff0000000000000ull, 0x0000000000000001ull,
3612 0x3ff0000000000000ull, 0, 0x3ff0000000000000ull,
3613 0x0000000000000001ull, APFloat::rmNearestTiesToEven),
3614 // (1 + epsilon) * (1 + epsilon) = 1 + 2 * epsilon
3615 std::make_tuple(0x3ff0000000000000ull, 0x0000000000000001ull,
3616 0x3ff0000000000000ull, 0x0000000000000001ull,
3617 0x3ff0000000000000ull, 0x0000000000000002ull,
3618 APFloat::rmNearestTiesToEven),
3619 // -(1 + epsilon) * (1 + epsilon) = -1
3620 std::make_tuple(0xbff0000000000000ull, 0x0000000000000001ull,
3621 0x3ff0000000000000ull, 0x0000000000000001ull,
3622 0xbff0000000000000ull, 0, APFloat::rmNearestTiesToEven),
3623 // (0.5 + 0) * (1 + 2 * epsilon) = 0.5 + epsilon
3624 std::make_tuple(0x3fe0000000000000ull, 0, 0x3ff0000000000000ull,
3625 0x0000000000000002ull, 0x3fe0000000000000ull,
3626 0x0000000000000001ull, APFloat::rmNearestTiesToEven),
3627 // (0.5 + 0) * (1 + epsilon) = 0.5
3628 std::make_tuple(0x3fe0000000000000ull, 0, 0x3ff0000000000000ull,
3629 0x0000000000000001ull, 0x3fe0000000000000ull, 0,
3630 APFloat::rmNearestTiesToEven),
3631 // __LDBL_MAX__ * (1 + 1 << 106) = inf
3632 std::make_tuple(0x7fefffffffffffffull, 0x7c8ffffffffffffeull,
3633 0x3ff0000000000000ull, 0x3950000000000000ull,
3634 0x7ff0000000000000ull, 0, APFloat::rmNearestTiesToEven),
3635 // __LDBL_MAX__ * (1 + 1 << 107) > __LDBL_MAX__, but not inf, yes =_=|||
3636 std::make_tuple(0x7fefffffffffffffull, 0x7c8ffffffffffffeull,
3637 0x3ff0000000000000ull, 0x3940000000000000ull,
3638 0x7fefffffffffffffull, 0x7c8fffffffffffffull,
3639 APFloat::rmNearestTiesToEven),
3640 // __LDBL_MAX__ * (1 + 1 << 108) = __LDBL_MAX__
3641 std::make_tuple(0x7fefffffffffffffull, 0x7c8ffffffffffffeull,
3642 0x3ff0000000000000ull, 0x3930000000000000ull,
3643 0x7fefffffffffffffull, 0x7c8ffffffffffffeull,
3644 APFloat::rmNearestTiesToEven),
Tim Shen81d263b2017-01-05 22:57:54 +00003645 };
3646
3647 for (auto Tp : Data) {
3648 uint64_t Op1[2], Op2[2], Expected[2];
3649 APFloat::roundingMode RM;
3650 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected[0], Expected[1], RM) = Tp;
3651
Tim Shen3796f1e2017-01-24 00:19:45 +00003652 {
3653 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1));
3654 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2));
3655 A1.multiply(A2, RM);
Tim Shen81d263b2017-01-05 22:57:54 +00003656
Tim Shen3796f1e2017-01-24 00:19:45 +00003657 EXPECT_EQ(Expected[0], A1.bitcastToAPInt().getRawData()[0])
3658 << formatv("({0:x} + {1:x}) * ({2:x} + {3:x})", Op1[0], Op1[1],
3659 Op2[0], Op2[1])
3660 .str();
3661 EXPECT_EQ(Expected[1], A1.bitcastToAPInt().getRawData()[1])
3662 << formatv("({0:x} + {1:x}) * ({2:x} + {3:x})", Op1[0], Op1[1],
3663 Op2[0], Op2[1])
3664 .str();
3665 }
3666 {
3667 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1));
3668 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2));
3669 A2.multiply(A1, RM);
3670
3671 EXPECT_EQ(Expected[0], A2.bitcastToAPInt().getRawData()[0])
3672 << formatv("({0:x} + {1:x}) * ({2:x} + {3:x})", Op2[0], Op2[1],
3673 Op1[0], Op1[1])
3674 .str();
3675 EXPECT_EQ(Expected[1], A2.bitcastToAPInt().getRawData()[1])
3676 << formatv("({0:x} + {1:x}) * ({2:x} + {3:x})", Op2[0], Op2[1],
3677 Op1[0], Op1[1])
3678 .str();
3679 }
Tim Shen81d263b2017-01-05 22:57:54 +00003680 }
3681}
3682
3683TEST(APFloatTest, PPCDoubleDoubleDivide) {
3684 using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,
3685 uint64_t, APFloat::roundingMode>;
3686 // TODO: Only a sanity check for now. Add more edge cases when the
3687 // double-double algorithm is implemented.
3688 DataType Data[] = {
3689 // 1 / 3 = 1/3
3690 std::make_tuple(0x3ff0000000000000ull, 0, 0x4008000000000000ull, 0,
3691 0x3fd5555555555555ull, 0x3c75555555555556ull,
3692 APFloat::rmNearestTiesToEven),
3693 };
3694
3695 for (auto Tp : Data) {
3696 uint64_t Op1[2], Op2[2], Expected[2];
3697 APFloat::roundingMode RM;
3698 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected[0], Expected[1], RM) = Tp;
3699
3700 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1));
3701 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2));
3702 A1.divide(A2, RM);
3703
3704 EXPECT_EQ(Expected[0], A1.bitcastToAPInt().getRawData()[0])
3705 << formatv("({0:x} + {1:x}) / ({2:x} + {3:x})", Op1[0], Op1[1], Op2[0],
3706 Op2[1])
3707 .str();
3708 EXPECT_EQ(Expected[1], A1.bitcastToAPInt().getRawData()[1])
3709 << formatv("({0:x} + {1:x}) / ({2:x} + {3:x})", Op1[0], Op1[1], Op2[0],
3710 Op2[1])
3711 .str();
3712 }
3713}
3714
3715TEST(APFloatTest, PPCDoubleDoubleRemainder) {
3716 using DataType =
3717 std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t>;
3718 DataType Data[] = {
3719 // remainder(3.0 + 3.0 << 53, 1.25 + 1.25 << 53) = (0.5 + 0.5 << 53)
3720 std::make_tuple(0x4008000000000000ull, 0x3cb8000000000000ull,
3721 0x3ff4000000000000ull, 0x3ca4000000000000ull,
3722 0x3fe0000000000000ull, 0x3c90000000000000ull),
3723 // remainder(3.0 + 3.0 << 53, 1.75 + 1.75 << 53) = (-0.5 - 0.5 << 53)
3724 std::make_tuple(0x4008000000000000ull, 0x3cb8000000000000ull,
3725 0x3ffc000000000000ull, 0x3cac000000000000ull,
3726 0xbfe0000000000000ull, 0xbc90000000000000ull),
3727 };
3728
3729 for (auto Tp : Data) {
3730 uint64_t Op1[2], Op2[2], Expected[2];
3731 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected[0], Expected[1]) = Tp;
3732
3733 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1));
3734 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2));
3735 A1.remainder(A2);
3736
3737 EXPECT_EQ(Expected[0], A1.bitcastToAPInt().getRawData()[0])
3738 << formatv("remainder({0:x} + {1:x}), ({2:x} + {3:x}))", Op1[0], Op1[1],
3739 Op2[0], Op2[1])
3740 .str();
3741 EXPECT_EQ(Expected[1], A1.bitcastToAPInt().getRawData()[1])
3742 << formatv("remainder(({0:x} + {1:x}), ({2:x} + {3:x}))", Op1[0],
3743 Op1[1], Op2[0], Op2[1])
3744 .str();
3745 }
3746}
3747
3748TEST(APFloatTest, PPCDoubleDoubleMod) {
3749 using DataType =
3750 std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t>;
3751 DataType Data[] = {
3752 // mod(3.0 + 3.0 << 53, 1.25 + 1.25 << 53) = (0.5 + 0.5 << 53)
3753 std::make_tuple(0x4008000000000000ull, 0x3cb8000000000000ull,
3754 0x3ff4000000000000ull, 0x3ca4000000000000ull,
3755 0x3fe0000000000000ull, 0x3c90000000000000ull),
3756 // mod(3.0 + 3.0 << 53, 1.75 + 1.75 << 53) = (1.25 + 1.25 << 53)
3757 // 0xbc98000000000000 doesn't seem right, but it's what we currently have.
3758 // TODO: investigate
3759 std::make_tuple(0x4008000000000000ull, 0x3cb8000000000000ull,
3760 0x3ffc000000000000ull, 0x3cac000000000000ull,
3761 0x3ff4000000000001ull, 0xbc98000000000000ull),
3762 };
3763
3764 for (auto Tp : Data) {
3765 uint64_t Op1[2], Op2[2], Expected[2];
3766 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected[0], Expected[1]) = Tp;
3767
3768 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1));
3769 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2));
3770 A1.mod(A2);
3771
3772 EXPECT_EQ(Expected[0], A1.bitcastToAPInt().getRawData()[0])
3773 << formatv("fmod(({0:x} + {1:x}), ({2:x} + {3:x}))", Op1[0], Op1[1],
3774 Op2[0], Op2[1])
3775 .str();
3776 EXPECT_EQ(Expected[1], A1.bitcastToAPInt().getRawData()[1])
3777 << formatv("fmod(({0:x} + {1:x}), ({2:x} + {3:x}))", Op1[0], Op1[1],
3778 Op2[0], Op2[1])
3779 .str();
3780 }
3781}
3782
3783TEST(APFloatTest, PPCDoubleDoubleFMA) {
3784 // Sanity check for now.
3785 APFloat A(APFloat::PPCDoubleDouble(), "2");
3786 A.fusedMultiplyAdd(APFloat(APFloat::PPCDoubleDouble(), "3"),
3787 APFloat(APFloat::PPCDoubleDouble(), "4"),
3788 APFloat::rmNearestTiesToEven);
3789 EXPECT_EQ(APFloat::cmpEqual,
3790 APFloat(APFloat::PPCDoubleDouble(), "10").compare(A));
3791}
3792
3793TEST(APFloatTest, PPCDoubleDoubleRoundToIntegral) {
3794 {
3795 APFloat A(APFloat::PPCDoubleDouble(), "1.5");
3796 A.roundToIntegral(APFloat::rmNearestTiesToEven);
3797 EXPECT_EQ(APFloat::cmpEqual,
3798 APFloat(APFloat::PPCDoubleDouble(), "2").compare(A));
3799 }
3800 {
3801 APFloat A(APFloat::PPCDoubleDouble(), "2.5");
3802 A.roundToIntegral(APFloat::rmNearestTiesToEven);
3803 EXPECT_EQ(APFloat::cmpEqual,
3804 APFloat(APFloat::PPCDoubleDouble(), "2").compare(A));
3805 }
3806}
3807
3808TEST(APFloatTest, PPCDoubleDoubleCompare) {
3809 using DataType =
3810 std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, APFloat::cmpResult>;
3811
3812 DataType Data[] = {
3813 // (1 + 0) = (1 + 0)
3814 std::make_tuple(0x3ff0000000000000ull, 0, 0x3ff0000000000000ull, 0,
3815 APFloat::cmpEqual),
3816 // (1 + 0) < (1.00...1 + 0)
3817 std::make_tuple(0x3ff0000000000000ull, 0, 0x3ff0000000000001ull, 0,
3818 APFloat::cmpLessThan),
3819 // (1.00...1 + 0) > (1 + 0)
3820 std::make_tuple(0x3ff0000000000001ull, 0, 0x3ff0000000000000ull, 0,
3821 APFloat::cmpGreaterThan),
3822 // (1 + 0) < (1 + epsilon)
3823 std::make_tuple(0x3ff0000000000000ull, 0, 0x3ff0000000000001ull,
3824 0x0000000000000001ull, APFloat::cmpLessThan),
3825 // NaN != NaN
3826 std::make_tuple(0x7ff8000000000000ull, 0, 0x7ff8000000000000ull, 0,
3827 APFloat::cmpUnordered),
3828 // (1 + 0) != NaN
3829 std::make_tuple(0x3ff0000000000000ull, 0, 0x7ff8000000000000ull, 0,
3830 APFloat::cmpUnordered),
3831 // Inf = Inf
3832 std::make_tuple(0x7ff0000000000000ull, 0, 0x7ff0000000000000ull, 0,
3833 APFloat::cmpEqual),
3834 };
3835
3836 for (auto Tp : Data) {
3837 uint64_t Op1[2], Op2[2];
3838 APFloat::cmpResult Expected;
3839 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected) = Tp;
3840
3841 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1));
3842 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2));
3843 EXPECT_EQ(Expected, A1.compare(A2))
Tim Shen207a20d2017-01-23 22:39:35 +00003844 << formatv("compare(({0:x} + {1:x}), ({2:x} + {3:x}))", Op1[0], Op1[1],
3845 Op2[0], Op2[1])
3846 .str();
3847 }
3848}
3849
3850TEST(APFloatTest, PPCDoubleDoubleBitwiseIsEqual) {
3851 using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, bool>;
3852
3853 DataType Data[] = {
3854 // (1 + 0) = (1 + 0)
3855 std::make_tuple(0x3ff0000000000000ull, 0, 0x3ff0000000000000ull, 0, true),
3856 // (1 + 0) != (1.00...1 + 0)
3857 std::make_tuple(0x3ff0000000000000ull, 0, 0x3ff0000000000001ull, 0,
3858 false),
3859 // NaN = NaN
3860 std::make_tuple(0x7ff8000000000000ull, 0, 0x7ff8000000000000ull, 0, true),
3861 // NaN != NaN with a different bit pattern
3862 std::make_tuple(0x7ff8000000000000ull, 0, 0x7ff8000000000000ull,
3863 0x3ff0000000000000ull, false),
3864 // Inf = Inf
3865 std::make_tuple(0x7ff0000000000000ull, 0, 0x7ff0000000000000ull, 0, true),
3866 };
3867
3868 for (auto Tp : Data) {
3869 uint64_t Op1[2], Op2[2];
3870 bool Expected;
3871 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected) = Tp;
3872
3873 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1));
3874 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2));
3875 EXPECT_EQ(Expected, A1.bitwiseIsEqual(A2))
3876 << formatv("({0:x} + {1:x}) = ({2:x} + {3:x})", Op1[0], Op1[1], Op2[0],
Tim Shen81d263b2017-01-05 22:57:54 +00003877 Op2[1])
3878 .str();
3879 }
3880}
3881
Tim Shen207a20d2017-01-23 22:39:35 +00003882TEST(APFloatTest, PPCDoubleDoubleHashValue) {
3883 uint64_t Data1[] = {0x3ff0000000000001ull, 0x0000000000000001ull};
3884 uint64_t Data2[] = {0x3ff0000000000001ull, 0};
3885 // The hash values are *hopefully* different.
3886 EXPECT_NE(
3887 hash_value(APFloat(APFloat::PPCDoubleDouble(), APInt(128, 2, Data1))),
3888 hash_value(APFloat(APFloat::PPCDoubleDouble(), APInt(128, 2, Data2))));
3889}
3890
Tim Shen81d263b2017-01-05 22:57:54 +00003891TEST(APFloatTest, PPCDoubleDoubleChangeSign) {
3892 uint64_t Data[] = {
3893 0x400f000000000000ull, 0xbcb0000000000000ull,
3894 };
3895 APFloat Float(APFloat::PPCDoubleDouble(), APInt(128, 2, Data));
3896 {
3897 APFloat Actual =
3898 APFloat::copySign(Float, APFloat(APFloat::IEEEdouble(), "1"));
3899 EXPECT_EQ(0x400f000000000000ull, Actual.bitcastToAPInt().getRawData()[0]);
3900 EXPECT_EQ(0xbcb0000000000000ull, Actual.bitcastToAPInt().getRawData()[1]);
3901 }
3902 {
3903 APFloat Actual =
3904 APFloat::copySign(Float, APFloat(APFloat::IEEEdouble(), "-1"));
3905 EXPECT_EQ(0xc00f000000000000ull, Actual.bitcastToAPInt().getRawData()[0]);
3906 EXPECT_EQ(0x3cb0000000000000ull, Actual.bitcastToAPInt().getRawData()[1]);
3907 }
3908}
3909
3910TEST(APFloatTest, PPCDoubleDoubleFactories) {
3911 {
3912 uint64_t Data[] = {
3913 0, 0,
3914 };
3915 EXPECT_EQ(APInt(128, 2, Data),
3916 APFloat::getZero(APFloat::PPCDoubleDouble()).bitcastToAPInt());
3917 }
3918 {
3919 uint64_t Data[] = {
Tim Shen207a20d2017-01-23 22:39:35 +00003920 0x7fefffffffffffffull, 0x7c8ffffffffffffeull,
3921 };
3922 EXPECT_EQ(APInt(128, 2, Data),
3923 APFloat::getLargest(APFloat::PPCDoubleDouble()).bitcastToAPInt());
3924 }
3925 {
3926 uint64_t Data[] = {
Tim Shen81d263b2017-01-05 22:57:54 +00003927 0x0000000000000001ull, 0,
3928 };
3929 EXPECT_EQ(
3930 APInt(128, 2, Data),
3931 APFloat::getSmallest(APFloat::PPCDoubleDouble()).bitcastToAPInt());
3932 }
3933 {
3934 uint64_t Data[] = {0x0360000000000000ull, 0};
3935 EXPECT_EQ(APInt(128, 2, Data),
3936 APFloat::getSmallestNormalized(APFloat::PPCDoubleDouble())
3937 .bitcastToAPInt());
3938 }
3939 {
3940 uint64_t Data[] = {
3941 0x8000000000000000ull, 0x0000000000000000ull,
3942 };
3943 EXPECT_EQ(
3944 APInt(128, 2, Data),
3945 APFloat::getZero(APFloat::PPCDoubleDouble(), true).bitcastToAPInt());
3946 }
3947 {
3948 uint64_t Data[] = {
Tim Shen207a20d2017-01-23 22:39:35 +00003949 0xffefffffffffffffull, 0xfc8ffffffffffffeull,
3950 };
3951 EXPECT_EQ(
3952 APInt(128, 2, Data),
3953 APFloat::getLargest(APFloat::PPCDoubleDouble(), true).bitcastToAPInt());
3954 }
3955 {
3956 uint64_t Data[] = {
Tim Shen81d263b2017-01-05 22:57:54 +00003957 0x8000000000000001ull, 0x0000000000000000ull,
3958 };
3959 EXPECT_EQ(APInt(128, 2, Data),
3960 APFloat::getSmallest(APFloat::PPCDoubleDouble(), true)
3961 .bitcastToAPInt());
3962 }
Tim Shen207a20d2017-01-23 22:39:35 +00003963 {
3964 uint64_t Data[] = {
3965 0x8360000000000000ull, 0x0000000000000000ull,
3966 };
3967 EXPECT_EQ(APInt(128, 2, Data),
3968 APFloat::getSmallestNormalized(APFloat::PPCDoubleDouble(), true)
3969 .bitcastToAPInt());
3970 }
Tim Shen81d263b2017-01-05 22:57:54 +00003971 EXPECT_TRUE(APFloat::getSmallest(APFloat::PPCDoubleDouble()).isSmallest());
3972 EXPECT_TRUE(APFloat::getLargest(APFloat::PPCDoubleDouble()).isLargest());
3973}
Tim Shen207a20d2017-01-23 22:39:35 +00003974
3975TEST(APFloatTest, PPCDoubleDoubleIsDenormal) {
3976 EXPECT_TRUE(APFloat::getSmallest(APFloat::PPCDoubleDouble()).isDenormal());
3977 EXPECT_FALSE(APFloat::getLargest(APFloat::PPCDoubleDouble()).isDenormal());
3978 EXPECT_FALSE(
3979 APFloat::getSmallestNormalized(APFloat::PPCDoubleDouble()).isDenormal());
3980 {
3981 // (4 + 3) is not normalized
3982 uint64_t Data[] = {
3983 0x4010000000000000ull, 0x4008000000000000ull,
3984 };
3985 EXPECT_TRUE(
3986 APFloat(APFloat::PPCDoubleDouble(), APInt(128, 2, Data)).isDenormal());
3987 }
3988}
3989
3990TEST(APFloatTest, PPCDoubleDoubleScalbn) {
3991 // 3.0 + 3.0 << 53
3992 uint64_t Input[] = {
3993 0x4008000000000000ull, 0x3cb8000000000000ull,
3994 };
3995 APFloat Result =
3996 scalbn(APFloat(APFloat::PPCDoubleDouble(), APInt(128, 2, Input)), 1,
3997 APFloat::rmNearestTiesToEven);
3998 // 6.0 + 6.0 << 53
3999 EXPECT_EQ(0x4018000000000000ull, Result.bitcastToAPInt().getRawData()[0]);
4000 EXPECT_EQ(0x3cc8000000000000ull, Result.bitcastToAPInt().getRawData()[1]);
4001}
4002
4003TEST(APFloatTest, PPCDoubleDoubleFrexp) {
4004 // 3.0 + 3.0 << 53
4005 uint64_t Input[] = {
4006 0x4008000000000000ull, 0x3cb8000000000000ull,
4007 };
4008 int Exp;
4009 // 0.75 + 0.75 << 53
4010 APFloat Result =
4011 frexp(APFloat(APFloat::PPCDoubleDouble(), APInt(128, 2, Input)), Exp,
4012 APFloat::rmNearestTiesToEven);
4013 EXPECT_EQ(2, Exp);
4014 EXPECT_EQ(0x3fe8000000000000ull, Result.bitcastToAPInt().getRawData()[0]);
4015 EXPECT_EQ(0x3c98000000000000ull, Result.bitcastToAPInt().getRawData()[1]);
4016}
Erick Tryzelaara15d8902009-08-16 23:36:19 +00004017}