blob: 1212b45fb575d6dd0b8b2b92e6b63bb66f16adc1 [file] [log] [blame]
Erick Tryzelaar19f63b22009-08-16 23:36:19 +00001//===- llvm/unittest/ADT/APFloat.cpp - APFloat unit tests ---------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Erick Tryzelaar19f63b22009-08-16 23:36:19 +000010#include "llvm/ADT/APFloat.h"
Jeffrey Yasskin03b81a22011-07-15 07:04:56 +000011#include "llvm/ADT/APSInt.h"
Tim Shenfd1e5aa2017-01-23 22:39:35 +000012#include "llvm/ADT/Hashing.h"
John McCall29b5c282009-12-24 08:56:26 +000013#include "llvm/ADT/SmallVector.h"
Tim Shen53f14c72016-12-16 00:47:17 +000014#include "llvm/Support/FormatVariadic.h"
Chandler Carruth130cec22012-12-04 10:23:08 +000015#include "llvm/Support/raw_ostream.h"
16#include "gtest/gtest.h"
Benjamin Kramer37dce442015-03-09 18:35:18 +000017#include <cmath>
Chandler Carruth130cec22012-12-04 10:23:08 +000018#include <ostream>
19#include <string>
Tim Shen18e7ae62016-12-12 22:16:08 +000020#include <tuple>
Erick Tryzelaar19f63b22009-08-16 23:36:19 +000021
22using namespace llvm;
23
Daniel Dunbarbc52e4f2009-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 Katkov3a46eb42017-04-21 02:52:17 +000030static std::string convertToString(double d, unsigned Prec, unsigned Pad,
31 bool Tr = true) {
John McCall29b5c282009-12-24 08:56:26 +000032 llvm::SmallVector<char, 100> Buffer;
33 llvm::APFloat F(d);
Serguei Katkov3a46eb42017-04-21 02:52:17 +000034 F.toString(Buffer, Prec, Pad, Tr);
John McCall29b5c282009-12-24 08:56:26 +000035 return std::string(Buffer.data(), Buffer.size());
36}
37
Erick Tryzelaar19f63b22009-08-16 23:36:19 +000038namespace {
39
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-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 Gottesman0c622ea2013-05-30 18:07:13 +000053}
54
55TEST(APFloatTest, next) {
56
Stephan Bergmann17c7f702016-12-14 11:57:17 +000057 APFloat test(APFloat::IEEEquad(), APFloat::uninitialized);
58 APFloat expected(APFloat::IEEEquad(), APFloat::uninitialized);
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +000076 test = APFloat::getInf(APFloat::IEEEquad(), false);
77 expected = APFloat::getInf(APFloat::IEEEquad(), false);
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +000084 test = APFloat::getInf(APFloat::IEEEquad(), false);
85 expected = APFloat::getLargest(APFloat::IEEEquad(), false);
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +000091 test = APFloat::getInf(APFloat::IEEEquad(), true);
92 expected = APFloat::getLargest(APFloat::IEEEquad(), true);
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +000098 test = APFloat::getInf(APFloat::IEEEquad(), true);
99 expected = APFloat::getInf(APFloat::IEEEquad(), true);
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000105 test = APFloat::getLargest(APFloat::IEEEquad(), false);
106 expected = APFloat::getInf(APFloat::IEEEquad(), false);
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000114 test = APFloat::getLargest(APFloat::IEEEquad(), false);
115 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000122 test = APFloat::getLargest(APFloat::IEEEquad(), true);
123 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000129 test = APFloat::getLargest(APFloat::IEEEquad(), true);
130 expected = APFloat::getInf(APFloat::IEEEquad(), true);
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000136 test = APFloat(APFloat::IEEEquad(), "0x0.0000000000000000000000000001p-16382");
137 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000143 test = APFloat(APFloat::IEEEquad(), "0x0.0000000000000000000000000001p-16382");
144 expected = APFloat::getZero(APFloat::IEEEquad(), false);
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000145 EXPECT_EQ(test.next(true), APFloat::opOK);
Matt Arsenaultafa31cf2016-03-13 05:11:51 +0000146 EXPECT_TRUE(test.isPosZero());
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000147 EXPECT_TRUE(test.bitwiseIsEqual(expected));
148
149 // nextUp(-getSmallest()) = -0.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000150 test = APFloat(APFloat::IEEEquad(), "-0x0.0000000000000000000000000001p-16382");
151 expected = APFloat::getZero(APFloat::IEEEquad(), true);
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000152 EXPECT_EQ(test.next(false), APFloat::opOK);
Matt Arsenaultafa31cf2016-03-13 05:11:51 +0000153 EXPECT_TRUE(test.isNegZero());
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000154 EXPECT_TRUE(test.bitwiseIsEqual(expected));
155
156 // nextDown(-getSmallest()) = -nextUp(getSmallest()) = -getSmallest() - inc.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000157 test = APFloat(APFloat::IEEEquad(), "-0x0.0000000000000000000000000001p-16382");
158 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000164 test = APFloat::getQNaN(APFloat::IEEEquad(), false);
165 expected = APFloat::getQNaN(APFloat::IEEEquad(), false);
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000170 test = APFloat::getQNaN(APFloat::IEEEquad(), false);
171 expected = APFloat::getQNaN(APFloat::IEEEquad(), false);
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000176 test = APFloat::getSNaN(APFloat::IEEEquad(), false);
177 expected = APFloat::getQNaN(APFloat::IEEEquad(), false);
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000182 test = APFloat::getSNaN(APFloat::IEEEquad(), false);
183 expected = APFloat::getQNaN(APFloat::IEEEquad(), false);
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000188 test = APFloat::getZero(APFloat::IEEEquad(), false);
189 expected = APFloat::getSmallest(APFloat::IEEEquad(), false);
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000194 test = APFloat::getZero(APFloat::IEEEquad(), false);
195 expected = APFloat::getSmallest(APFloat::IEEEquad(), true);
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000200 test = APFloat::getZero(APFloat::IEEEquad(), true);
201 expected = APFloat::getSmallest(APFloat::IEEEquad(), false);
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000206 test = APFloat::getZero(APFloat::IEEEquad(), true);
207 expected = APFloat::getSmallest(APFloat::IEEEquad(), true);
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000220 test = APFloat(APFloat::IEEEquad(), "0x0.ffffffffffffffffffffffffffffp-16382");
221 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000228 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000229 "-0x0.ffffffffffffffffffffffffffffp-16382");
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000230 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000237 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000238 "-0x1.0000000000000000000000000000p-16382");
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000239 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000246 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000247 "+0x1.0000000000000000000000000000p-16382");
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000248 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000261 test = APFloat(APFloat::IEEEquad(), "-0x1p+1");
262 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000268 test = APFloat(APFloat::IEEEquad(), "0x1p+1");
269 expected = APFloat(APFloat::IEEEquad(), "0x1.ffffffffffffffffffffffffffffp+0");
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000274 test = APFloat(APFloat::IEEEquad(), "0x1.ffffffffffffffffffffffffffffp+0");
275 expected = APFloat(APFloat::IEEEquad(), "0x1p+1");
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000280 test = APFloat(APFloat::IEEEquad(), "-0x1.ffffffffffffffffffffffffffffp+0");
281 expected = APFloat(APFloat::IEEEquad(), "-0x1p+1");
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000297 test = APFloat(APFloat::IEEEquad(), "-0x0.ffffffffffffffffffffffffffffp-16382");
298 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000306 test = APFloat(APFloat::IEEEquad(), "0x0.ffffffffffffffffffffffffffffp-16382");
307 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000315 test = APFloat(APFloat::IEEEquad(), "0x1.0000000000000000000000000000p-16382");
316 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000324 test = APFloat(APFloat::IEEEquad(), "-0x1.0000000000000000000000000000p-16382");
325 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000342 test = APFloat(APFloat::IEEEquad(), "-0x1p-16381");
343 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000350 test = APFloat(APFloat::IEEEquad(), "-0x1.ffffffffffffffffffffffffffffp-16382");
351 expected = APFloat(APFloat::IEEEquad(), "-0x1p-16381");
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000356 test = APFloat(APFloat::IEEEquad(), "0x1.ffffffffffffffffffffffffffffp-16382");
357 expected = APFloat(APFloat::IEEEquad(), "0x1p-16381");
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000362 test = APFloat(APFloat::IEEEquad(), "0x1p-16381");
363 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000380 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000381 "0x0.ffffffffffffffffffffffff000cp-16382");
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000382 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000390 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000391 "0x0.ffffffffffffffffffffffff000cp-16382");
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000392 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000400 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000401 "-0x0.ffffffffffffffffffffffff000cp-16382");
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000402 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000410 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000411 "-0x0.ffffffffffffffffffffffff000cp-16382");
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000412 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000420 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000421 "0x1.ffffffffffffffffffffffff000cp-16000");
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000422 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000430 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000431 "0x1.ffffffffffffffffffffffff000cp-16000");
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000432 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000440 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000441 "-0x1.ffffffffffffffffffffffff000cp-16000");
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000442 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-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 Bergmann17c7f702016-12-14 11:57:17 +0000450 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000451 "-0x1.ffffffffffffffffffffffff000cp-16000");
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000452 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-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 Yangbbddbac2013-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 Hames56c0eb22014-11-19 19:15:41 +0000481
Lang Hames12b12e82015-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 Bergmann17c7f702016-12-14 11:57:17 +0000515 APFloat f1(APFloat::IEEEdouble(), "-0x1p-1074");
516 APFloat f2(APFloat::IEEEdouble(), "+0x1p-1074");
Lang Hames12b12e82015-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 Hames56c0eb22014-11-19 19:15:41 +0000523 {
Stephan Bergmann17c7f702016-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 Hames56c0eb22014-11-19 19:15:41 +0000527
528 bool losesInfo = false;
529 M1.fusedMultiplyAdd(M1, A, APFloat::rmNearestTiesToEven);
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000530 M1.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &losesInfo);
Lang Hames56c0eb22014-11-19 19:15:41 +0000531 EXPECT_FALSE(losesInfo);
532 EXPECT_EQ(4.0f, M1.convertToFloat());
533 }
Shuxin Yangbbddbac2013-05-13 18:03:12 +0000534}
535
Matt Arsenault5ccdb982014-10-10 05:21:32 +0000536TEST(APFloatTest, MinNum) {
537 APFloat f1(1.0);
538 APFloat f2(2.0);
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000539 APFloat nan = APFloat::getNaN(APFloat::IEEEdouble());
Matt Arsenault5ccdb982014-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 Bergmann17c7f702016-12-14 11:57:17 +0000550 APFloat nan = APFloat::getNaN(APFloat::IEEEdouble());
Matt Arsenault5ccdb982014-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 Carruthf3598e82017-07-10 05:41:14 +0000555 EXPECT_EQ(1.0, maxnum(nan, f1).convertToDouble());
Matt Arsenault5ccdb982014-10-10 05:21:32 +0000556}
557
Shuxin Yang4fb504f2013-01-07 18:59:35 +0000558TEST(APFloatTest, Denormal) {
559 APFloat::roundingMode rdmd = APFloat::rmNearestTiesToEven;
560
561 // Test single precision
562 {
563 const char *MinNormalStr = "1.17549435082228750797e-38";
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000564 EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), MinNormalStr).isDenormal());
565 EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), 0.0).isDenormal());
Shuxin Yang4fb504f2013-01-07 18:59:35 +0000566
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000567 APFloat Val2(APFloat::IEEEsingle(), 2.0e0);
568 APFloat T(APFloat::IEEEsingle(), MinNormalStr);
Shuxin Yang4fb504f2013-01-07 18:59:35 +0000569 T.divide(Val2, rdmd);
570 EXPECT_TRUE(T.isDenormal());
571 }
572
573 // Test double precision
574 {
575 const char *MinNormalStr = "2.22507385850720138309e-308";
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000576 EXPECT_FALSE(APFloat(APFloat::IEEEdouble(), MinNormalStr).isDenormal());
577 EXPECT_FALSE(APFloat(APFloat::IEEEdouble(), 0.0).isDenormal());
Shuxin Yang4fb504f2013-01-07 18:59:35 +0000578
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000579 APFloat Val2(APFloat::IEEEdouble(), 2.0e0);
580 APFloat T(APFloat::IEEEdouble(), MinNormalStr);
Shuxin Yang4fb504f2013-01-07 18:59:35 +0000581 T.divide(Val2, rdmd);
582 EXPECT_TRUE(T.isDenormal());
583 }
584
585 // Test Intel double-ext
586 {
587 const char *MinNormalStr = "3.36210314311209350626e-4932";
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000588 EXPECT_FALSE(APFloat(APFloat::x87DoubleExtended(), MinNormalStr).isDenormal());
589 EXPECT_FALSE(APFloat(APFloat::x87DoubleExtended(), 0.0).isDenormal());
Shuxin Yang4fb504f2013-01-07 18:59:35 +0000590
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000591 APFloat Val2(APFloat::x87DoubleExtended(), 2.0e0);
592 APFloat T(APFloat::x87DoubleExtended(), MinNormalStr);
Shuxin Yang4fb504f2013-01-07 18:59:35 +0000593 T.divide(Val2, rdmd);
594 EXPECT_TRUE(T.isDenormal());
595 }
596
597 // Test quadruple precision
598 {
599 const char *MinNormalStr = "3.36210314311209350626267781732175260e-4932";
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000600 EXPECT_FALSE(APFloat(APFloat::IEEEquad(), MinNormalStr).isDenormal());
601 EXPECT_FALSE(APFloat(APFloat::IEEEquad(), 0.0).isDenormal());
Shuxin Yang4fb504f2013-01-07 18:59:35 +0000602
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000603 APFloat Val2(APFloat::IEEEquad(), 2.0e0);
604 APFloat T(APFloat::IEEEquad(), MinNormalStr);
Shuxin Yang4fb504f2013-01-07 18:59:35 +0000605 T.divide(Val2, rdmd);
606 EXPECT_TRUE(T.isDenormal());
607 }
608}
609
Erick Tryzelaar19f63b22009-08-16 23:36:19 +0000610TEST(APFloatTest, Zero) {
Matt Beaumont-Gaya421ee12011-08-29 17:54:20 +0000611 EXPECT_EQ(0.0f, APFloat(0.0f).convertToFloat());
612 EXPECT_EQ(-0.0f, APFloat(-0.0f).convertToFloat());
613 EXPECT_TRUE(APFloat(-0.0f).isNegative());
Erick Tryzelaar19f63b22009-08-16 23:36:19 +0000614
Matt Beaumont-Gaya421ee12011-08-29 17:54:20 +0000615 EXPECT_EQ(0.0, APFloat(0.0).convertToDouble());
616 EXPECT_EQ(-0.0, APFloat(-0.0).convertToDouble());
617 EXPECT_TRUE(APFloat(-0.0).isNegative());
Erick Tryzelaar19f63b22009-08-16 23:36:19 +0000618}
619
Michael Gottesman228156c2013-07-01 23:54:08 +0000620TEST(APFloatTest, DecimalStringsWithoutNullTerminators) {
621 // Make sure that we can parse strings without null terminators.
622 // rdar://14323230.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000623 APFloat Val(APFloat::IEEEdouble());
Michael Gottesman228156c2013-07-01 23:54:08 +0000624 Val.convertFromString(StringRef("0.00", 3),
625 llvm::APFloat::rmNearestTiesToEven);
626 EXPECT_EQ(Val.convertToDouble(), 0.0);
627 Val.convertFromString(StringRef("0.01", 3),
628 llvm::APFloat::rmNearestTiesToEven);
629 EXPECT_EQ(Val.convertToDouble(), 0.0);
630 Val.convertFromString(StringRef("0.09", 3),
631 llvm::APFloat::rmNearestTiesToEven);
632 EXPECT_EQ(Val.convertToDouble(), 0.0);
633 Val.convertFromString(StringRef("0.095", 4),
634 llvm::APFloat::rmNearestTiesToEven);
635 EXPECT_EQ(Val.convertToDouble(), 0.09);
636 Val.convertFromString(StringRef("0.00e+3", 7),
637 llvm::APFloat::rmNearestTiesToEven);
638 EXPECT_EQ(Val.convertToDouble(), 0.00);
639 Val.convertFromString(StringRef("0e+3", 4),
640 llvm::APFloat::rmNearestTiesToEven);
641 EXPECT_EQ(Val.convertToDouble(), 0.00);
642
643}
644
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000645TEST(APFloatTest, fromZeroDecimalString) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000646 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0").convertToDouble());
647 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0").convertToDouble());
648 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000649
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000650 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.").convertToDouble());
651 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.").convertToDouble());
652 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000653
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000654 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), ".0").convertToDouble());
655 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+.0").convertToDouble());
656 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-.0").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000657
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000658 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.0").convertToDouble());
659 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.0").convertToDouble());
660 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.0").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000661
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000662 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "00000.").convertToDouble());
663 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+00000.").convertToDouble());
664 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-00000.").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000665
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000666 EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble(), ".00000").convertToDouble());
667 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+.00000").convertToDouble());
668 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-.00000").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000669
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000670 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0000.00000").convertToDouble());
671 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0000.00000").convertToDouble());
672 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0000.00000").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000673}
674
675TEST(APFloatTest, fromZeroDecimalSingleExponentString) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000676 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e1").convertToDouble());
677 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e1").convertToDouble());
678 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000679
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000680 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e+1").convertToDouble());
681 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e+1").convertToDouble());
682 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e+1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000683
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000684 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e-1").convertToDouble());
685 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e-1").convertToDouble());
686 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e-1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000687
688
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000689 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.e1").convertToDouble());
690 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.e1").convertToDouble());
691 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.e1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000692
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000693 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.e+1").convertToDouble());
694 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.e+1").convertToDouble());
695 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.e+1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000696
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000697 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.e-1").convertToDouble());
698 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.e-1").convertToDouble());
699 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.e-1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000700
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000701 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), ".0e1").convertToDouble());
702 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+.0e1").convertToDouble());
703 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-.0e1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000704
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000705 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), ".0e+1").convertToDouble());
706 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+.0e+1").convertToDouble());
707 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-.0e+1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000708
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000709 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), ".0e-1").convertToDouble());
710 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+.0e-1").convertToDouble());
711 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-.0e-1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000712
713
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000714 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.0e1").convertToDouble());
715 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.0e1").convertToDouble());
716 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.0e1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000717
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000718 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.0e+1").convertToDouble());
719 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.0e+1").convertToDouble());
720 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.0e+1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000721
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000722 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.0e-1").convertToDouble());
723 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.0e-1").convertToDouble());
724 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.0e-1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000725
726
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000727 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "000.0000e1").convertToDouble());
728 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+000.0000e+1").convertToDouble());
729 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-000.0000e+1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000730}
731
732TEST(APFloatTest, fromZeroDecimalLargeExponentString) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000733 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e1234").convertToDouble());
734 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e1234").convertToDouble());
735 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e1234").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000736
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000737 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e+1234").convertToDouble());
738 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e+1234").convertToDouble());
739 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e+1234").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000740
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000741 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e-1234").convertToDouble());
742 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e-1234").convertToDouble());
743 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e-1234").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000744
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000745 EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble(), "000.0000e1234").convertToDouble());
746 EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble(), "000.0000e-1234").convertToDouble());
Erick Tryzelaar19f63b22009-08-16 23:36:19 +0000747
Chandler Carruth170e6cc2017-07-09 07:37:47 +0000748 EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble(), StringRef("0e1234" "\0" "2", 6)).convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000749}
Erick Tryzelaar19f63b22009-08-16 23:36:19 +0000750
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000751TEST(APFloatTest, fromZeroHexadecimalString) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000752 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0p1").convertToDouble());
753 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0p1").convertToDouble());
754 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0p1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000755
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000756 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0p+1").convertToDouble());
757 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0p+1").convertToDouble());
758 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0p+1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000759
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000760 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0p-1").convertToDouble());
761 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0p-1").convertToDouble());
762 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0p-1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000763
764
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000765 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.p1").convertToDouble());
766 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.p1").convertToDouble());
767 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.p1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000768
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000769 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.p+1").convertToDouble());
770 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.p+1").convertToDouble());
771 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.p+1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000772
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000773 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.p-1").convertToDouble());
774 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.p-1").convertToDouble());
775 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.p-1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000776
777
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000778 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x.0p1").convertToDouble());
779 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x.0p1").convertToDouble());
780 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x.0p1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000781
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000782 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x.0p+1").convertToDouble());
783 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x.0p+1").convertToDouble());
784 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x.0p+1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000785
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000786 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x.0p-1").convertToDouble());
787 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x.0p-1").convertToDouble());
788 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x.0p-1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000789
790
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000791 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.0p1").convertToDouble());
792 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.0p1").convertToDouble());
793 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.0p1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000794
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000795 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.0p+1").convertToDouble());
796 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.0p+1").convertToDouble());
797 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.0p+1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000798
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000799 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.0p-1").convertToDouble());
800 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.0p-1").convertToDouble());
801 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.0p-1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000802
803
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000804 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x00000.p1").convertToDouble());
805 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0000.00000p1").convertToDouble());
806 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x.00000p1").convertToDouble());
807 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.p1").convertToDouble());
808 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0p1234").convertToDouble());
809 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0p1234").convertToDouble());
810 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x00000.p1234").convertToDouble());
811 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0000.00000p1234").convertToDouble());
812 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x.00000p1234").convertToDouble());
813 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.p1234").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000814}
815
816TEST(APFloatTest, fromDecimalString) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000817 EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1").convertToDouble());
818 EXPECT_EQ(2.0, APFloat(APFloat::IEEEdouble(), "2.").convertToDouble());
819 EXPECT_EQ(0.5, APFloat(APFloat::IEEEdouble(), ".5").convertToDouble());
820 EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1.0").convertToDouble());
821 EXPECT_EQ(-2.0, APFloat(APFloat::IEEEdouble(), "-2").convertToDouble());
822 EXPECT_EQ(-4.0, APFloat(APFloat::IEEEdouble(), "-4.").convertToDouble());
823 EXPECT_EQ(-0.5, APFloat(APFloat::IEEEdouble(), "-.5").convertToDouble());
824 EXPECT_EQ(-1.5, APFloat(APFloat::IEEEdouble(), "-1.5").convertToDouble());
825 EXPECT_EQ(1.25e12, APFloat(APFloat::IEEEdouble(), "1.25e12").convertToDouble());
826 EXPECT_EQ(1.25e+12, APFloat(APFloat::IEEEdouble(), "1.25e+12").convertToDouble());
827 EXPECT_EQ(1.25e-12, APFloat(APFloat::IEEEdouble(), "1.25e-12").convertToDouble());
828 EXPECT_EQ(1024.0, APFloat(APFloat::IEEEdouble(), "1024.").convertToDouble());
829 EXPECT_EQ(1024.05, APFloat(APFloat::IEEEdouble(), "1024.05000").convertToDouble());
830 EXPECT_EQ(0.05, APFloat(APFloat::IEEEdouble(), ".05000").convertToDouble());
831 EXPECT_EQ(2.0, APFloat(APFloat::IEEEdouble(), "2.").convertToDouble());
832 EXPECT_EQ(2.0e2, APFloat(APFloat::IEEEdouble(), "2.e2").convertToDouble());
833 EXPECT_EQ(2.0e+2, APFloat(APFloat::IEEEdouble(), "2.e+2").convertToDouble());
834 EXPECT_EQ(2.0e-2, APFloat(APFloat::IEEEdouble(), "2.e-2").convertToDouble());
835 EXPECT_EQ(2.05e2, APFloat(APFloat::IEEEdouble(), "002.05000e2").convertToDouble());
836 EXPECT_EQ(2.05e+2, APFloat(APFloat::IEEEdouble(), "002.05000e+2").convertToDouble());
837 EXPECT_EQ(2.05e-2, APFloat(APFloat::IEEEdouble(), "002.05000e-2").convertToDouble());
838 EXPECT_EQ(2.05e12, APFloat(APFloat::IEEEdouble(), "002.05000e12").convertToDouble());
839 EXPECT_EQ(2.05e+12, APFloat(APFloat::IEEEdouble(), "002.05000e+12").convertToDouble());
840 EXPECT_EQ(2.05e-12, APFloat(APFloat::IEEEdouble(), "002.05000e-12").convertToDouble());
John McCallb42cc682010-02-26 22:20:41 +0000841
842 // These are "carefully selected" to overflow the fast log-base
843 // calculations in APFloat.cpp
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000844 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "99e99999").isInfinity());
845 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-99e99999").isInfinity());
846 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "1e-99999").isPosZero());
847 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-1e-99999").isNegZero());
Eli Friedmand2eb07a2013-07-17 22:17:29 +0000848
849 EXPECT_EQ(2.71828, convertToDoubleFromString("2.71828"));
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000850}
851
Serguei Katkov768d6dd2017-12-19 04:27:39 +0000852TEST(APFloatTest, fromToStringSpecials) {
853 auto expects = [] (const char *first, const char *second) {
854 std::string roundtrip = convertToString(convertToDoubleFromString(second), 0, 3);
855 EXPECT_STREQ(first, roundtrip.c_str());
856 };
857 expects("+Inf", "+Inf");
858 expects("+Inf", "INFINITY");
859 expects("+Inf", "inf");
860 expects("-Inf", "-Inf");
861 expects("-Inf", "-INFINITY");
862 expects("-Inf", "-inf");
863 expects("NaN", "NaN");
864 expects("NaN", "nan");
865 expects("NaN", "-NaN");
866 expects("NaN", "-nan");
867}
868
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000869TEST(APFloatTest, fromHexadecimalString) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000870 EXPECT_EQ( 1.0, APFloat(APFloat::IEEEdouble(), "0x1p0").convertToDouble());
871 EXPECT_EQ(+1.0, APFloat(APFloat::IEEEdouble(), "+0x1p0").convertToDouble());
872 EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble(), "-0x1p0").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000873
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000874 EXPECT_EQ( 1.0, APFloat(APFloat::IEEEdouble(), "0x1p+0").convertToDouble());
875 EXPECT_EQ(+1.0, APFloat(APFloat::IEEEdouble(), "+0x1p+0").convertToDouble());
876 EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble(), "-0x1p+0").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000877
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000878 EXPECT_EQ( 1.0, APFloat(APFloat::IEEEdouble(), "0x1p-0").convertToDouble());
879 EXPECT_EQ(+1.0, APFloat(APFloat::IEEEdouble(), "+0x1p-0").convertToDouble());
880 EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble(), "-0x1p-0").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000881
882
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000883 EXPECT_EQ( 2.0, APFloat(APFloat::IEEEdouble(), "0x1p1").convertToDouble());
884 EXPECT_EQ(+2.0, APFloat(APFloat::IEEEdouble(), "+0x1p1").convertToDouble());
885 EXPECT_EQ(-2.0, APFloat(APFloat::IEEEdouble(), "-0x1p1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000886
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000887 EXPECT_EQ( 2.0, APFloat(APFloat::IEEEdouble(), "0x1p+1").convertToDouble());
888 EXPECT_EQ(+2.0, APFloat(APFloat::IEEEdouble(), "+0x1p+1").convertToDouble());
889 EXPECT_EQ(-2.0, APFloat(APFloat::IEEEdouble(), "-0x1p+1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000890
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000891 EXPECT_EQ( 0.5, APFloat(APFloat::IEEEdouble(), "0x1p-1").convertToDouble());
892 EXPECT_EQ(+0.5, APFloat(APFloat::IEEEdouble(), "+0x1p-1").convertToDouble());
893 EXPECT_EQ(-0.5, APFloat(APFloat::IEEEdouble(), "-0x1p-1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000894
895
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000896 EXPECT_EQ( 3.0, APFloat(APFloat::IEEEdouble(), "0x1.8p1").convertToDouble());
897 EXPECT_EQ(+3.0, APFloat(APFloat::IEEEdouble(), "+0x1.8p1").convertToDouble());
898 EXPECT_EQ(-3.0, APFloat(APFloat::IEEEdouble(), "-0x1.8p1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000899
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000900 EXPECT_EQ( 3.0, APFloat(APFloat::IEEEdouble(), "0x1.8p+1").convertToDouble());
901 EXPECT_EQ(+3.0, APFloat(APFloat::IEEEdouble(), "+0x1.8p+1").convertToDouble());
902 EXPECT_EQ(-3.0, APFloat(APFloat::IEEEdouble(), "-0x1.8p+1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000903
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000904 EXPECT_EQ( 0.75, APFloat(APFloat::IEEEdouble(), "0x1.8p-1").convertToDouble());
905 EXPECT_EQ(+0.75, APFloat(APFloat::IEEEdouble(), "+0x1.8p-1").convertToDouble());
906 EXPECT_EQ(-0.75, APFloat(APFloat::IEEEdouble(), "-0x1.8p-1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000907
908
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000909 EXPECT_EQ( 8192.0, APFloat(APFloat::IEEEdouble(), "0x1000.000p1").convertToDouble());
910 EXPECT_EQ(+8192.0, APFloat(APFloat::IEEEdouble(), "+0x1000.000p1").convertToDouble());
911 EXPECT_EQ(-8192.0, APFloat(APFloat::IEEEdouble(), "-0x1000.000p1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000912
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000913 EXPECT_EQ( 8192.0, APFloat(APFloat::IEEEdouble(), "0x1000.000p+1").convertToDouble());
914 EXPECT_EQ(+8192.0, APFloat(APFloat::IEEEdouble(), "+0x1000.000p+1").convertToDouble());
915 EXPECT_EQ(-8192.0, APFloat(APFloat::IEEEdouble(), "-0x1000.000p+1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000916
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000917 EXPECT_EQ( 2048.0, APFloat(APFloat::IEEEdouble(), "0x1000.000p-1").convertToDouble());
918 EXPECT_EQ(+2048.0, APFloat(APFloat::IEEEdouble(), "+0x1000.000p-1").convertToDouble());
919 EXPECT_EQ(-2048.0, APFloat(APFloat::IEEEdouble(), "-0x1000.000p-1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000920
921
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000922 EXPECT_EQ( 8192.0, APFloat(APFloat::IEEEdouble(), "0x1000p1").convertToDouble());
923 EXPECT_EQ(+8192.0, APFloat(APFloat::IEEEdouble(), "+0x1000p1").convertToDouble());
924 EXPECT_EQ(-8192.0, APFloat(APFloat::IEEEdouble(), "-0x1000p1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000925
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000926 EXPECT_EQ( 8192.0, APFloat(APFloat::IEEEdouble(), "0x1000p+1").convertToDouble());
927 EXPECT_EQ(+8192.0, APFloat(APFloat::IEEEdouble(), "+0x1000p+1").convertToDouble());
928 EXPECT_EQ(-8192.0, APFloat(APFloat::IEEEdouble(), "-0x1000p+1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000929
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000930 EXPECT_EQ( 2048.0, APFloat(APFloat::IEEEdouble(), "0x1000p-1").convertToDouble());
931 EXPECT_EQ(+2048.0, APFloat(APFloat::IEEEdouble(), "+0x1000p-1").convertToDouble());
932 EXPECT_EQ(-2048.0, APFloat(APFloat::IEEEdouble(), "-0x1000p-1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000933
934
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000935 EXPECT_EQ( 16384.0, APFloat(APFloat::IEEEdouble(), "0x10p10").convertToDouble());
936 EXPECT_EQ(+16384.0, APFloat(APFloat::IEEEdouble(), "+0x10p10").convertToDouble());
937 EXPECT_EQ(-16384.0, APFloat(APFloat::IEEEdouble(), "-0x10p10").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000938
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000939 EXPECT_EQ( 16384.0, APFloat(APFloat::IEEEdouble(), "0x10p+10").convertToDouble());
940 EXPECT_EQ(+16384.0, APFloat(APFloat::IEEEdouble(), "+0x10p+10").convertToDouble());
941 EXPECT_EQ(-16384.0, APFloat(APFloat::IEEEdouble(), "-0x10p+10").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000942
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000943 EXPECT_EQ( 0.015625, APFloat(APFloat::IEEEdouble(), "0x10p-10").convertToDouble());
944 EXPECT_EQ(+0.015625, APFloat(APFloat::IEEEdouble(), "+0x10p-10").convertToDouble());
945 EXPECT_EQ(-0.015625, APFloat(APFloat::IEEEdouble(), "-0x10p-10").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000946
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000947 EXPECT_EQ(1.0625, APFloat(APFloat::IEEEdouble(), "0x1.1p0").convertToDouble());
948 EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "0x1p0").convertToDouble());
Daniel Dunbarbc52e4f2009-09-03 22:57:02 +0000949
Eli Friedmand2eb07a2013-07-17 22:17:29 +0000950 EXPECT_EQ(convertToDoubleFromString("0x1p-150"),
951 convertToDoubleFromString("+0x800000000000000001.p-221"));
952 EXPECT_EQ(2251799813685248.5,
953 convertToDoubleFromString("0x80000000000004000000.010p-28"));
Erick Tryzelaar19f63b22009-08-16 23:36:19 +0000954}
955
John McCall29b5c282009-12-24 08:56:26 +0000956TEST(APFloatTest, toString) {
957 ASSERT_EQ("10", convertToString(10.0, 6, 3));
958 ASSERT_EQ("1.0E+1", convertToString(10.0, 6, 0));
959 ASSERT_EQ("10100", convertToString(1.01E+4, 5, 2));
960 ASSERT_EQ("1.01E+4", convertToString(1.01E+4, 4, 2));
961 ASSERT_EQ("1.01E+4", convertToString(1.01E+4, 5, 1));
962 ASSERT_EQ("0.0101", convertToString(1.01E-2, 5, 2));
John McCalldd5044a2009-12-24 23:18:09 +0000963 ASSERT_EQ("0.0101", convertToString(1.01E-2, 4, 2));
John McCall29b5c282009-12-24 08:56:26 +0000964 ASSERT_EQ("1.01E-2", convertToString(1.01E-2, 5, 1));
Eli Friedmane72f1322013-08-29 23:44:34 +0000965 ASSERT_EQ("0.78539816339744828", convertToString(0.78539816339744830961, 0, 3));
966 ASSERT_EQ("4.9406564584124654E-324", convertToString(4.9406564584124654e-324, 0, 3));
967 ASSERT_EQ("873.18340000000001", convertToString(873.1834, 0, 1));
968 ASSERT_EQ("8.7318340000000001E+2", convertToString(873.1834, 0, 0));
969 ASSERT_EQ("1.7976931348623157E+308", convertToString(1.7976931348623157E+308, 0, 0));
Serguei Katkov3a46eb42017-04-21 02:52:17 +0000970 ASSERT_EQ("10", convertToString(10.0, 6, 3, false));
971 ASSERT_EQ("1.000000e+01", convertToString(10.0, 6, 0, false));
972 ASSERT_EQ("10100", convertToString(1.01E+4, 5, 2, false));
973 ASSERT_EQ("1.0100e+04", convertToString(1.01E+4, 4, 2, false));
974 ASSERT_EQ("1.01000e+04", convertToString(1.01E+4, 5, 1, false));
975 ASSERT_EQ("0.0101", convertToString(1.01E-2, 5, 2, false));
976 ASSERT_EQ("0.0101", convertToString(1.01E-2, 4, 2, false));
977 ASSERT_EQ("1.01000e-02", convertToString(1.01E-2, 5, 1, false));
978 ASSERT_EQ("0.78539816339744828",
979 convertToString(0.78539816339744830961, 0, 3, false));
980 ASSERT_EQ("4.94065645841246540e-324",
981 convertToString(4.9406564584124654e-324, 0, 3, false));
982 ASSERT_EQ("873.18340000000001", convertToString(873.1834, 0, 1, false));
983 ASSERT_EQ("8.73183400000000010e+02", convertToString(873.1834, 0, 0, false));
984 ASSERT_EQ("1.79769313486231570e+308",
985 convertToString(1.7976931348623157E+308, 0, 0, false));
Pavel Labathb1bcafd2018-05-09 15:13:45 +0000986
987 {
988 SmallString<64> Str;
989 APFloat UnnormalZero(APFloat::x87DoubleExtended(), APInt(80, {0, 1}));
990 UnnormalZero.toString(Str);
991 ASSERT_EQ("NaN", Str);
992 }
John McCall29b5c282009-12-24 08:56:26 +0000993}
994
Jeffrey Yasskin03b81a22011-07-15 07:04:56 +0000995TEST(APFloatTest, toInteger) {
996 bool isExact = false;
997 APSInt result(5, /*isUnsigned=*/true);
998
999 EXPECT_EQ(APFloat::opOK,
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001000 APFloat(APFloat::IEEEdouble(), "10")
Jeffrey Yasskin03b81a22011-07-15 07:04:56 +00001001 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
1002 EXPECT_TRUE(isExact);
1003 EXPECT_EQ(APSInt(APInt(5, 10), true), result);
1004
1005 EXPECT_EQ(APFloat::opInvalidOp,
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001006 APFloat(APFloat::IEEEdouble(), "-10")
Jeffrey Yasskin03b81a22011-07-15 07:04:56 +00001007 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
1008 EXPECT_FALSE(isExact);
1009 EXPECT_EQ(APSInt::getMinValue(5, true), result);
1010
1011 EXPECT_EQ(APFloat::opInvalidOp,
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001012 APFloat(APFloat::IEEEdouble(), "32")
Jeffrey Yasskin03b81a22011-07-15 07:04:56 +00001013 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
1014 EXPECT_FALSE(isExact);
1015 EXPECT_EQ(APSInt::getMaxValue(5, true), result);
1016
1017 EXPECT_EQ(APFloat::opInexact,
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001018 APFloat(APFloat::IEEEdouble(), "7.9")
Jeffrey Yasskin03b81a22011-07-15 07:04:56 +00001019 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
1020 EXPECT_FALSE(isExact);
1021 EXPECT_EQ(APSInt(APInt(5, 7), true), result);
1022
1023 result.setIsUnsigned(false);
1024 EXPECT_EQ(APFloat::opOK,
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001025 APFloat(APFloat::IEEEdouble(), "-10")
Jeffrey Yasskin03b81a22011-07-15 07:04:56 +00001026 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
1027 EXPECT_TRUE(isExact);
1028 EXPECT_EQ(APSInt(APInt(5, -10, true), false), result);
1029
1030 EXPECT_EQ(APFloat::opInvalidOp,
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001031 APFloat(APFloat::IEEEdouble(), "-17")
Jeffrey Yasskin03b81a22011-07-15 07:04:56 +00001032 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
1033 EXPECT_FALSE(isExact);
1034 EXPECT_EQ(APSInt::getMinValue(5, false), result);
1035
1036 EXPECT_EQ(APFloat::opInvalidOp,
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001037 APFloat(APFloat::IEEEdouble(), "16")
Jeffrey Yasskin03b81a22011-07-15 07:04:56 +00001038 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
1039 EXPECT_FALSE(isExact);
1040 EXPECT_EQ(APSInt::getMaxValue(5, false), result);
1041}
1042
John McCalldcb9a7a2010-02-28 02:51:25 +00001043static APInt nanbits(const fltSemantics &Sem,
1044 bool SNaN, bool Negative, uint64_t fill) {
1045 APInt apfill(64, fill);
1046 if (SNaN)
1047 return APFloat::getSNaN(Sem, Negative, &apfill).bitcastToAPInt();
1048 else
1049 return APFloat::getQNaN(Sem, Negative, &apfill).bitcastToAPInt();
1050}
1051
1052TEST(APFloatTest, makeNaN) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001053 ASSERT_EQ(0x7fc00000, nanbits(APFloat::IEEEsingle(), false, false, 0));
1054 ASSERT_EQ(0xffc00000, nanbits(APFloat::IEEEsingle(), false, true, 0));
1055 ASSERT_EQ(0x7fc0ae72, nanbits(APFloat::IEEEsingle(), false, false, 0xae72));
1056 ASSERT_EQ(0x7fffae72, nanbits(APFloat::IEEEsingle(), false, false, 0xffffae72));
1057 ASSERT_EQ(0x7fa00000, nanbits(APFloat::IEEEsingle(), true, false, 0));
1058 ASSERT_EQ(0xffa00000, nanbits(APFloat::IEEEsingle(), true, true, 0));
1059 ASSERT_EQ(0x7f80ae72, nanbits(APFloat::IEEEsingle(), true, false, 0xae72));
1060 ASSERT_EQ(0x7fbfae72, nanbits(APFloat::IEEEsingle(), true, false, 0xffffae72));
John McCalldcb9a7a2010-02-28 02:51:25 +00001061
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001062 ASSERT_EQ(0x7ff8000000000000ULL, nanbits(APFloat::IEEEdouble(), false, false, 0));
1063 ASSERT_EQ(0xfff8000000000000ULL, nanbits(APFloat::IEEEdouble(), false, true, 0));
1064 ASSERT_EQ(0x7ff800000000ae72ULL, nanbits(APFloat::IEEEdouble(), false, false, 0xae72));
1065 ASSERT_EQ(0x7fffffffffffae72ULL, nanbits(APFloat::IEEEdouble(), false, false, 0xffffffffffffae72ULL));
1066 ASSERT_EQ(0x7ff4000000000000ULL, nanbits(APFloat::IEEEdouble(), true, false, 0));
1067 ASSERT_EQ(0xfff4000000000000ULL, nanbits(APFloat::IEEEdouble(), true, true, 0));
1068 ASSERT_EQ(0x7ff000000000ae72ULL, nanbits(APFloat::IEEEdouble(), true, false, 0xae72));
1069 ASSERT_EQ(0x7ff7ffffffffae72ULL, nanbits(APFloat::IEEEdouble(), true, false, 0xffffffffffffae72ULL));
John McCalldcb9a7a2010-02-28 02:51:25 +00001070}
1071
Erick Tryzelaar927191f2009-08-17 00:55:33 +00001072#ifdef GTEST_HAS_DEATH_TEST
Jeffrey Yasskinb5cd0132010-03-17 01:18:45 +00001073#ifndef NDEBUG
Erick Tryzelaar927191f2009-08-17 00:55:33 +00001074TEST(APFloatTest, SemanticsDeath) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001075 EXPECT_DEATH(APFloat(APFloat::IEEEsingle(), 0.0f).convertToDouble(), "Float semantics are not IEEEdouble");
1076 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), 0.0 ).convertToFloat(), "Float semantics are not IEEEsingle");
Erick Tryzelaar927191f2009-08-17 00:55:33 +00001077}
1078
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001079TEST(APFloatTest, StringDecimalDeath) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001080 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ""), "Invalid string length");
1081 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+"), "String has no digits");
1082 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-"), "String has no digits");
Erick Tryzelaar19f63b22009-08-16 23:36:19 +00001083
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001084 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("\0", 1)), "Invalid character in significand");
1085 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("1\0", 2)), "Invalid character in significand");
Chandler Carruth170e6cc2017-07-09 07:37:47 +00001086 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("1" "\0" "2", 3)), "Invalid character in significand");
1087 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("1" "\0" "2e1", 5)), "Invalid character in significand");
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001088 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("1e\0", 3)), "Invalid character in exponent");
1089 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("1e1\0", 4)), "Invalid character in exponent");
Chandler Carruth170e6cc2017-07-09 07:37:47 +00001090 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("1e1" "\0" "2", 5)), "Invalid character in exponent");
Erick Tryzelaar19f63b22009-08-16 23:36:19 +00001091
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001092 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.0f"), "Invalid character in significand");
Erick Tryzelaar19f63b22009-08-16 23:36:19 +00001093
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001094 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".."), "String contains multiple dots");
1095 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "..0"), "String contains multiple dots");
1096 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.0.0"), "String contains multiple dots");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001097}
1098
1099TEST(APFloatTest, StringDecimalSignificandDeath) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001100 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "."), "Significand has no digits");
1101 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+."), "Significand has no digits");
1102 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-."), "Significand has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001103
1104
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001105 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "e"), "Significand has no digits");
1106 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+e"), "Significand has no digits");
1107 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-e"), "Significand has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001108
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001109 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "e1"), "Significand has no digits");
1110 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+e1"), "Significand has no digits");
1111 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-e1"), "Significand has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001112
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001113 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".e1"), "Significand has no digits");
1114 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+.e1"), "Significand has no digits");
1115 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-.e1"), "Significand has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001116
1117
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001118 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".e"), "Significand has no digits");
1119 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+.e"), "Significand has no digits");
1120 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-.e"), "Significand has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001121}
1122
1123TEST(APFloatTest, StringDecimalExponentDeath) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001124 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1e"), "Exponent has no digits");
1125 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+1e"), "Exponent has no digits");
1126 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-1e"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001127
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001128 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.e"), "Exponent has no digits");
1129 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+1.e"), "Exponent has no digits");
1130 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-1.e"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001131
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001132 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".1e"), "Exponent has no digits");
1133 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+.1e"), "Exponent has no digits");
1134 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-.1e"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001135
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001136 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.1e"), "Exponent has no digits");
1137 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+1.1e"), "Exponent has no digits");
1138 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-1.1e"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001139
1140
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001141 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1e+"), "Exponent has no digits");
1142 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1e-"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001143
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001144 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".1e"), "Exponent has no digits");
1145 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".1e+"), "Exponent has no digits");
1146 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".1e-"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001147
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001148 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.0e"), "Exponent has no digits");
1149 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.0e+"), "Exponent has no digits");
1150 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.0e-"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001151}
1152
1153TEST(APFloatTest, StringHexadecimalDeath) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001154 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x"), "Invalid string");
1155 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x"), "Invalid string");
1156 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x"), "Invalid string");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001157
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001158 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x0"), "Hex strings require an exponent");
1159 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x0"), "Hex strings require an exponent");
1160 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x0"), "Hex strings require an exponent");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001161
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001162 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x0."), "Hex strings require an exponent");
1163 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x0."), "Hex strings require an exponent");
1164 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x0."), "Hex strings require an exponent");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001165
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001166 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x.0"), "Hex strings require an exponent");
1167 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x.0"), "Hex strings require an exponent");
1168 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x.0"), "Hex strings require an exponent");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001169
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001170 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x0.0"), "Hex strings require an exponent");
1171 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x0.0"), "Hex strings require an exponent");
1172 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x0.0"), "Hex strings require an exponent");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001173
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001174 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("0x\0", 3)), "Invalid character in significand");
1175 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("0x1\0", 4)), "Invalid character in significand");
Chandler Carruth170e6cc2017-07-09 07:37:47 +00001176 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("0x1" "\0" "2", 5)), "Invalid character in significand");
1177 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("0x1" "\0" "2p1", 7)), "Invalid character in significand");
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001178 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("0x1p\0", 5)), "Invalid character in exponent");
1179 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("0x1p1\0", 6)), "Invalid character in exponent");
Chandler Carruth170e6cc2017-07-09 07:37:47 +00001180 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("0x1p1" "\0" "2", 7)), "Invalid character in exponent");
Erick Tryzelaar19f63b22009-08-16 23:36:19 +00001181
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001182 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1p0f"), "Invalid character in exponent");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001183
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001184 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x..p1"), "String contains multiple dots");
1185 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x..0p1"), "String contains multiple dots");
1186 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1.0.0p1"), "String contains multiple dots");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001187}
1188
1189TEST(APFloatTest, StringHexadecimalSignificandDeath) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001190 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x."), "Significand has no digits");
1191 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x."), "Significand has no digits");
1192 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x."), "Significand has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001193
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001194 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0xp"), "Significand has no digits");
1195 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0xp"), "Significand has no digits");
1196 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0xp"), "Significand has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001197
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001198 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0xp+"), "Significand has no digits");
1199 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0xp+"), "Significand has no digits");
1200 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0xp+"), "Significand has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001201
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001202 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0xp-"), "Significand has no digits");
1203 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0xp-"), "Significand has no digits");
1204 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0xp-"), "Significand has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001205
1206
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001207 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x.p"), "Significand has no digits");
1208 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x.p"), "Significand has no digits");
1209 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x.p"), "Significand has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001210
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001211 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x.p+"), "Significand has no digits");
1212 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x.p+"), "Significand has no digits");
1213 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x.p+"), "Significand has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001214
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001215 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x.p-"), "Significand has no digits");
1216 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x.p-"), "Significand has no digits");
1217 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x.p-"), "Significand has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001218}
1219
1220TEST(APFloatTest, StringHexadecimalExponentDeath) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001221 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1p"), "Exponent has no digits");
1222 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1p"), "Exponent has no digits");
1223 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1p"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001224
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001225 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1p+"), "Exponent has no digits");
1226 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1p+"), "Exponent has no digits");
1227 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1p+"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001228
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001229 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1p-"), "Exponent has no digits");
1230 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1p-"), "Exponent has no digits");
1231 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1p-"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001232
1233
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001234 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1.p"), "Exponent has no digits");
1235 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1.p"), "Exponent has no digits");
1236 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1.p"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001237
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001238 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1.p+"), "Exponent has no digits");
1239 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1.p+"), "Exponent has no digits");
1240 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1.p+"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001241
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001242 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1.p-"), "Exponent has no digits");
1243 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1.p-"), "Exponent has no digits");
1244 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1.p-"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001245
1246
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001247 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x.1p"), "Exponent has no digits");
1248 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x.1p"), "Exponent has no digits");
1249 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x.1p"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001250
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001251 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x.1p+"), "Exponent has no digits");
1252 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x.1p+"), "Exponent has no digits");
1253 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x.1p+"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001254
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001255 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x.1p-"), "Exponent has no digits");
1256 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x.1p-"), "Exponent has no digits");
1257 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x.1p-"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001258
1259
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001260 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1.1p"), "Exponent has no digits");
1261 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1.1p"), "Exponent has no digits");
1262 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1.1p"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001263
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001264 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1.1p+"), "Exponent has no digits");
1265 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1.1p+"), "Exponent has no digits");
1266 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1.1p+"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001267
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001268 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1.1p-"), "Exponent has no digits");
1269 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1.1p-"), "Exponent has no digits");
1270 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1.1p-"), "Exponent has no digits");
Erick Tryzelaar19f63b22009-08-16 23:36:19 +00001271}
Erick Tryzelaar927191f2009-08-17 00:55:33 +00001272#endif
Jeffrey Yasskinb5cd0132010-03-17 01:18:45 +00001273#endif
Erick Tryzelaar19f63b22009-08-16 23:36:19 +00001274
Benjamin Kramer03fd6722011-03-30 15:42:27 +00001275TEST(APFloatTest, exactInverse) {
1276 APFloat inv(0.0f);
1277
1278 // Trivial operation.
1279 EXPECT_TRUE(APFloat(2.0).getExactInverse(&inv));
1280 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(0.5)));
1281 EXPECT_TRUE(APFloat(2.0f).getExactInverse(&inv));
1282 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(0.5f)));
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001283 EXPECT_TRUE(APFloat(APFloat::IEEEquad(), "2.0").getExactInverse(&inv));
1284 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(APFloat::IEEEquad(), "0.5")));
1285 EXPECT_TRUE(APFloat(APFloat::PPCDoubleDouble(), "2.0").getExactInverse(&inv));
1286 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(APFloat::PPCDoubleDouble(), "0.5")));
1287 EXPECT_TRUE(APFloat(APFloat::x87DoubleExtended(), "2.0").getExactInverse(&inv));
1288 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(APFloat::x87DoubleExtended(), "0.5")));
Benjamin Kramer03fd6722011-03-30 15:42:27 +00001289
1290 // FLT_MIN
1291 EXPECT_TRUE(APFloat(1.17549435e-38f).getExactInverse(&inv));
1292 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(8.5070592e+37f)));
1293
Benjamin Krameraf0ed952011-03-30 17:02:54 +00001294 // Large float, inverse is a denormal.
Craig Topper66f09ad2014-06-08 22:29:17 +00001295 EXPECT_FALSE(APFloat(1.7014118e38f).getExactInverse(nullptr));
Benjamin Kramer03fd6722011-03-30 15:42:27 +00001296 // Zero
Craig Topper66f09ad2014-06-08 22:29:17 +00001297 EXPECT_FALSE(APFloat(0.0).getExactInverse(nullptr));
Benjamin Kramer03fd6722011-03-30 15:42:27 +00001298 // Denormalized float
Craig Topper66f09ad2014-06-08 22:29:17 +00001299 EXPECT_FALSE(APFloat(1.40129846e-45f).getExactInverse(nullptr));
Benjamin Kramer03fd6722011-03-30 15:42:27 +00001300}
1301
Owen Anderson1ff74b02012-08-15 05:39:46 +00001302TEST(APFloatTest, roundToIntegral) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001303 APFloat T(-0.5), S(3.14), R(APFloat::getLargest(APFloat::IEEEdouble())), P(0.0);
Owen Anderson1ff74b02012-08-15 05:39:46 +00001304
1305 P = T;
1306 P.roundToIntegral(APFloat::rmTowardZero);
1307 EXPECT_EQ(-0.0, P.convertToDouble());
1308 P = T;
1309 P.roundToIntegral(APFloat::rmTowardNegative);
1310 EXPECT_EQ(-1.0, P.convertToDouble());
1311 P = T;
1312 P.roundToIntegral(APFloat::rmTowardPositive);
1313 EXPECT_EQ(-0.0, P.convertToDouble());
1314 P = T;
1315 P.roundToIntegral(APFloat::rmNearestTiesToEven);
1316 EXPECT_EQ(-0.0, P.convertToDouble());
1317
1318 P = S;
1319 P.roundToIntegral(APFloat::rmTowardZero);
1320 EXPECT_EQ(3.0, P.convertToDouble());
1321 P = S;
1322 P.roundToIntegral(APFloat::rmTowardNegative);
1323 EXPECT_EQ(3.0, P.convertToDouble());
1324 P = S;
1325 P.roundToIntegral(APFloat::rmTowardPositive);
1326 EXPECT_EQ(4.0, P.convertToDouble());
1327 P = S;
1328 P.roundToIntegral(APFloat::rmNearestTiesToEven);
1329 EXPECT_EQ(3.0, P.convertToDouble());
Owen Anderson352dfff2012-08-15 18:28:45 +00001330
1331 P = R;
1332 P.roundToIntegral(APFloat::rmTowardZero);
1333 EXPECT_EQ(R.convertToDouble(), P.convertToDouble());
1334 P = R;
1335 P.roundToIntegral(APFloat::rmTowardNegative);
1336 EXPECT_EQ(R.convertToDouble(), P.convertToDouble());
1337 P = R;
1338 P.roundToIntegral(APFloat::rmTowardPositive);
1339 EXPECT_EQ(R.convertToDouble(), P.convertToDouble());
1340 P = R;
1341 P.roundToIntegral(APFloat::rmNearestTiesToEven);
1342 EXPECT_EQ(R.convertToDouble(), P.convertToDouble());
Benjamin Kramerc38fab22012-09-26 14:06:58 +00001343
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001344 P = APFloat::getZero(APFloat::IEEEdouble());
Benjamin Kramerc38fab22012-09-26 14:06:58 +00001345 P.roundToIntegral(APFloat::rmTowardZero);
1346 EXPECT_EQ(0.0, P.convertToDouble());
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001347 P = APFloat::getZero(APFloat::IEEEdouble(), true);
Benjamin Kramerc38fab22012-09-26 14:06:58 +00001348 P.roundToIntegral(APFloat::rmTowardZero);
1349 EXPECT_EQ(-0.0, P.convertToDouble());
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001350 P = APFloat::getNaN(APFloat::IEEEdouble());
Benjamin Kramerc38fab22012-09-26 14:06:58 +00001351 P.roundToIntegral(APFloat::rmTowardZero);
Benjamin Kramer37dce442015-03-09 18:35:18 +00001352 EXPECT_TRUE(std::isnan(P.convertToDouble()));
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001353 P = APFloat::getInf(APFloat::IEEEdouble());
Benjamin Kramerc38fab22012-09-26 14:06:58 +00001354 P.roundToIntegral(APFloat::rmTowardZero);
Benjamin Kramer37dce442015-03-09 18:35:18 +00001355 EXPECT_TRUE(std::isinf(P.convertToDouble()) && P.convertToDouble() > 0.0);
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001356 P = APFloat::getInf(APFloat::IEEEdouble(), true);
Benjamin Kramerc38fab22012-09-26 14:06:58 +00001357 P.roundToIntegral(APFloat::rmTowardZero);
Benjamin Kramer37dce442015-03-09 18:35:18 +00001358 EXPECT_TRUE(std::isinf(P.convertToDouble()) && P.convertToDouble() < 0.0);
Stephen Canon1bfc89b2015-11-16 21:52:48 +00001359}
Matt Arsenaultc25a7112016-03-21 16:49:16 +00001360
Stephen Canon1bfc89b2015-11-16 21:52:48 +00001361TEST(APFloatTest, isInteger) {
1362 APFloat T(-0.0);
1363 EXPECT_TRUE(T.isInteger());
1364 T = APFloat(3.14159);
1365 EXPECT_FALSE(T.isInteger());
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001366 T = APFloat::getNaN(APFloat::IEEEdouble());
Stephen Canon1bfc89b2015-11-16 21:52:48 +00001367 EXPECT_FALSE(T.isInteger());
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001368 T = APFloat::getInf(APFloat::IEEEdouble());
Stephen Canon1bfc89b2015-11-16 21:52:48 +00001369 EXPECT_FALSE(T.isInteger());
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001370 T = APFloat::getInf(APFloat::IEEEdouble(), true);
Stephen Canon1bfc89b2015-11-16 21:52:48 +00001371 EXPECT_FALSE(T.isInteger());
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001372 T = APFloat::getLargest(APFloat::IEEEdouble());
Stephen Canon1bfc89b2015-11-16 21:52:48 +00001373 EXPECT_TRUE(T.isInteger());
Owen Anderson1ff74b02012-08-15 05:39:46 +00001374}
1375
Davide Italiano5a2530d2017-08-21 16:51:54 +00001376TEST(DoubleAPFloatTest, isInteger) {
1377 APFloat F1(-0.0);
1378 APFloat F2(-0.0);
1379 llvm::detail::DoubleAPFloat T(APFloat::PPCDoubleDouble(), std::move(F1),
1380 std::move(F2));
1381 EXPECT_TRUE(T.isInteger());
1382 APFloat F3(3.14159);
1383 APFloat F4(-0.0);
1384 llvm::detail::DoubleAPFloat T2(APFloat::PPCDoubleDouble(), std::move(F3),
1385 std::move(F4));
1386 EXPECT_FALSE(T2.isInteger());
1387 APFloat F5(-0.0);
1388 APFloat F6(3.14159);
1389 llvm::detail::DoubleAPFloat T3(APFloat::PPCDoubleDouble(), std::move(F5),
1390 std::move(F6));
1391 EXPECT_FALSE(T3.isInteger());
1392}
1393
Eli Friedmanc5322012011-10-12 21:51:36 +00001394TEST(APFloatTest, getLargest) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001395 EXPECT_EQ(3.402823466e+38f, APFloat::getLargest(APFloat::IEEEsingle()).convertToFloat());
1396 EXPECT_EQ(1.7976931348623158e+308, APFloat::getLargest(APFloat::IEEEdouble()).convertToDouble());
Eli Friedmanc5322012011-10-12 21:51:36 +00001397}
1398
Michael Gottesman63e6d212013-05-29 23:58:29 +00001399TEST(APFloatTest, getSmallest) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001400 APFloat test = APFloat::getSmallest(APFloat::IEEEsingle(), false);
1401 APFloat expected = APFloat(APFloat::IEEEsingle(), "0x0.000002p-126");
Michael Gottesman5455d5b2013-05-30 00:18:44 +00001402 EXPECT_FALSE(test.isNegative());
Michael Gottesmanb5101ab2013-06-19 21:53:45 +00001403 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman5455d5b2013-05-30 00:18:44 +00001404 EXPECT_TRUE(test.isDenormal());
Michael Gottesman63e6d212013-05-29 23:58:29 +00001405 EXPECT_TRUE(test.bitwiseIsEqual(expected));
1406
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001407 test = APFloat::getSmallest(APFloat::IEEEsingle(), true);
1408 expected = APFloat(APFloat::IEEEsingle(), "-0x0.000002p-126");
Michael Gottesman63e6d212013-05-29 23:58:29 +00001409 EXPECT_TRUE(test.isNegative());
Michael Gottesmanb5101ab2013-06-19 21:53:45 +00001410 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman5455d5b2013-05-30 00:18:44 +00001411 EXPECT_TRUE(test.isDenormal());
Michael Gottesman63e6d212013-05-29 23:58:29 +00001412 EXPECT_TRUE(test.bitwiseIsEqual(expected));
1413
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001414 test = APFloat::getSmallest(APFloat::IEEEquad(), false);
1415 expected = APFloat(APFloat::IEEEquad(), "0x0.0000000000000000000000000001p-16382");
Michael Gottesman5455d5b2013-05-30 00:18:44 +00001416 EXPECT_FALSE(test.isNegative());
Michael Gottesmanb5101ab2013-06-19 21:53:45 +00001417 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman5455d5b2013-05-30 00:18:44 +00001418 EXPECT_TRUE(test.isDenormal());
Michael Gottesman63e6d212013-05-29 23:58:29 +00001419 EXPECT_TRUE(test.bitwiseIsEqual(expected));
1420
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001421 test = APFloat::getSmallest(APFloat::IEEEquad(), true);
1422 expected = APFloat(APFloat::IEEEquad(), "-0x0.0000000000000000000000000001p-16382");
Michael Gottesman63e6d212013-05-29 23:58:29 +00001423 EXPECT_TRUE(test.isNegative());
Michael Gottesmanb5101ab2013-06-19 21:53:45 +00001424 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman5455d5b2013-05-30 00:18:44 +00001425 EXPECT_TRUE(test.isDenormal());
Michael Gottesmanf9899292013-06-24 09:58:09 +00001426 EXPECT_TRUE(test.bitwiseIsEqual(expected));
Michael Gottesman63e6d212013-05-29 23:58:29 +00001427}
1428
Michael Gottesman0db7c272013-05-30 00:18:47 +00001429TEST(APFloatTest, getSmallestNormalized) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001430 APFloat test = APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);
1431 APFloat expected = APFloat(APFloat::IEEEsingle(), "0x1p-126");
Michael Gottesman0db7c272013-05-30 00:18:47 +00001432 EXPECT_FALSE(test.isNegative());
Michael Gottesmanb5101ab2013-06-19 21:53:45 +00001433 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman0db7c272013-05-30 00:18:47 +00001434 EXPECT_FALSE(test.isDenormal());
1435 EXPECT_TRUE(test.bitwiseIsEqual(expected));
1436
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001437 test = APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);
1438 expected = APFloat(APFloat::IEEEsingle(), "-0x1p-126");
Michael Gottesman0db7c272013-05-30 00:18:47 +00001439 EXPECT_TRUE(test.isNegative());
Michael Gottesmanb5101ab2013-06-19 21:53:45 +00001440 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman0db7c272013-05-30 00:18:47 +00001441 EXPECT_FALSE(test.isDenormal());
1442 EXPECT_TRUE(test.bitwiseIsEqual(expected));
1443
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001444 test = APFloat::getSmallestNormalized(APFloat::IEEEquad(), false);
1445 expected = APFloat(APFloat::IEEEquad(), "0x1p-16382");
Michael Gottesman0db7c272013-05-30 00:18:47 +00001446 EXPECT_FALSE(test.isNegative());
Michael Gottesmanb5101ab2013-06-19 21:53:45 +00001447 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman0db7c272013-05-30 00:18:47 +00001448 EXPECT_FALSE(test.isDenormal());
1449 EXPECT_TRUE(test.bitwiseIsEqual(expected));
1450
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001451 test = APFloat::getSmallestNormalized(APFloat::IEEEquad(), true);
1452 expected = APFloat(APFloat::IEEEquad(), "-0x1p-16382");
Michael Gottesman0db7c272013-05-30 00:18:47 +00001453 EXPECT_TRUE(test.isNegative());
Michael Gottesmanb5101ab2013-06-19 21:53:45 +00001454 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman0db7c272013-05-30 00:18:47 +00001455 EXPECT_FALSE(test.isDenormal());
Michael Gottesmanf9899292013-06-24 09:58:09 +00001456 EXPECT_TRUE(test.bitwiseIsEqual(expected));
Michael Gottesman0db7c272013-05-30 00:18:47 +00001457}
1458
Michael Gottesmanfc718c92013-05-31 18:43:34 +00001459TEST(APFloatTest, getZero) {
1460 struct {
1461 const fltSemantics *semantics;
1462 const bool sign;
1463 const unsigned long long bitPattern[2];
1464 const unsigned bitPatternLength;
Benjamin Kramer0bb474f2013-06-01 22:29:41 +00001465 } const GetZeroTest[] = {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001466 { &APFloat::IEEEhalf(), false, {0, 0}, 1},
1467 { &APFloat::IEEEhalf(), true, {0x8000ULL, 0}, 1},
1468 { &APFloat::IEEEsingle(), false, {0, 0}, 1},
1469 { &APFloat::IEEEsingle(), true, {0x80000000ULL, 0}, 1},
1470 { &APFloat::IEEEdouble(), false, {0, 0}, 1},
1471 { &APFloat::IEEEdouble(), true, {0x8000000000000000ULL, 0}, 1},
1472 { &APFloat::IEEEquad(), false, {0, 0}, 2},
1473 { &APFloat::IEEEquad(), true, {0, 0x8000000000000000ULL}, 2},
1474 { &APFloat::PPCDoubleDouble(), false, {0, 0}, 2},
1475 { &APFloat::PPCDoubleDouble(), true, {0x8000000000000000ULL, 0}, 2},
1476 { &APFloat::x87DoubleExtended(), false, {0, 0}, 2},
1477 { &APFloat::x87DoubleExtended(), true, {0, 0x8000ULL}, 2},
Michael Gottesmanfc718c92013-05-31 18:43:34 +00001478 };
1479 const unsigned NumGetZeroTests = 12;
1480 for (unsigned i = 0; i < NumGetZeroTests; ++i) {
1481 APFloat test = APFloat::getZero(*GetZeroTest[i].semantics,
NAKAMURA Takumi6f43bd42017-10-18 13:31:28 +00001482 GetZeroTest[i].sign);
Michael Gottesmanfc718c92013-05-31 18:43:34 +00001483 const char *pattern = GetZeroTest[i].sign? "-0x0p+0" : "0x0p+0";
1484 APFloat expected = APFloat(*GetZeroTest[i].semantics,
NAKAMURA Takumi6f43bd42017-10-18 13:31:28 +00001485 pattern);
Michael Gottesmanfc718c92013-05-31 18:43:34 +00001486 EXPECT_TRUE(test.isZero());
1487 EXPECT_TRUE(GetZeroTest[i].sign? test.isNegative() : !test.isNegative());
1488 EXPECT_TRUE(test.bitwiseIsEqual(expected));
1489 for (unsigned j = 0, je = GetZeroTest[i].bitPatternLength; j < je; ++j) {
1490 EXPECT_EQ(GetZeroTest[i].bitPattern[j],
NAKAMURA Takumia1e97a72017-08-28 06:47:47 +00001491 test.bitcastToAPInt().getRawData()[j]);
Michael Gottesmanfc718c92013-05-31 18:43:34 +00001492 }
1493 }
1494}
1495
Chandler Carruthdf782e42014-10-09 23:26:15 +00001496TEST(APFloatTest, copySign) {
1497 EXPECT_TRUE(APFloat(-42.0).bitwiseIsEqual(
1498 APFloat::copySign(APFloat(42.0), APFloat(-1.0))));
1499 EXPECT_TRUE(APFloat(42.0).bitwiseIsEqual(
1500 APFloat::copySign(APFloat(-42.0), APFloat(1.0))));
1501 EXPECT_TRUE(APFloat(-42.0).bitwiseIsEqual(
1502 APFloat::copySign(APFloat(-42.0), APFloat(-1.0))));
1503 EXPECT_TRUE(APFloat(42.0).bitwiseIsEqual(
1504 APFloat::copySign(APFloat(42.0), APFloat(1.0))));
1505}
1506
Eli Friedmana84ad7d2011-11-26 03:38:02 +00001507TEST(APFloatTest, convert) {
1508 bool losesInfo;
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001509 APFloat test(APFloat::IEEEdouble(), "1.0");
1510 test.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &losesInfo);
Eli Friedmana84ad7d2011-11-26 03:38:02 +00001511 EXPECT_EQ(1.0f, test.convertToFloat());
1512 EXPECT_FALSE(losesInfo);
1513
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001514 test = APFloat(APFloat::x87DoubleExtended(), "0x1p-53");
1515 test.add(APFloat(APFloat::x87DoubleExtended(), "1.0"), APFloat::rmNearestTiesToEven);
1516 test.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &losesInfo);
Eli Friedmana84ad7d2011-11-26 03:38:02 +00001517 EXPECT_EQ(1.0, test.convertToDouble());
1518 EXPECT_TRUE(losesInfo);
1519
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001520 test = APFloat(APFloat::IEEEquad(), "0x1p-53");
1521 test.add(APFloat(APFloat::IEEEquad(), "1.0"), APFloat::rmNearestTiesToEven);
1522 test.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &losesInfo);
Eli Friedmana84ad7d2011-11-26 03:38:02 +00001523 EXPECT_EQ(1.0, test.convertToDouble());
1524 EXPECT_TRUE(losesInfo);
1525
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001526 test = APFloat(APFloat::x87DoubleExtended(), "0xf.fffffffp+28");
1527 test.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &losesInfo);
Eli Friedmana84ad7d2011-11-26 03:38:02 +00001528 EXPECT_EQ(4294967295.0, test.convertToDouble());
1529 EXPECT_FALSE(losesInfo);
Benjamin Kramerb361adb2013-01-25 17:01:00 +00001530
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001531 test = APFloat::getSNaN(APFloat::IEEEsingle());
1532 APFloat X87SNaN = APFloat::getSNaN(APFloat::x87DoubleExtended());
1533 test.convert(APFloat::x87DoubleExtended(), APFloat::rmNearestTiesToEven,
Benjamin Kramerb361adb2013-01-25 17:01:00 +00001534 &losesInfo);
1535 EXPECT_TRUE(test.bitwiseIsEqual(X87SNaN));
1536 EXPECT_FALSE(losesInfo);
1537
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001538 test = APFloat::getQNaN(APFloat::IEEEsingle());
1539 APFloat X87QNaN = APFloat::getQNaN(APFloat::x87DoubleExtended());
1540 test.convert(APFloat::x87DoubleExtended(), APFloat::rmNearestTiesToEven,
Benjamin Kramerb361adb2013-01-25 17:01:00 +00001541 &losesInfo);
1542 EXPECT_TRUE(test.bitwiseIsEqual(X87QNaN));
1543 EXPECT_FALSE(losesInfo);
1544
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001545 test = APFloat::getSNaN(APFloat::x87DoubleExtended());
1546 test.convert(APFloat::x87DoubleExtended(), APFloat::rmNearestTiesToEven,
Benjamin Kramerb361adb2013-01-25 17:01:00 +00001547 &losesInfo);
1548 EXPECT_TRUE(test.bitwiseIsEqual(X87SNaN));
1549 EXPECT_FALSE(losesInfo);
1550
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001551 test = APFloat::getQNaN(APFloat::x87DoubleExtended());
1552 test.convert(APFloat::x87DoubleExtended(), APFloat::rmNearestTiesToEven,
Benjamin Kramerb361adb2013-01-25 17:01:00 +00001553 &losesInfo);
1554 EXPECT_TRUE(test.bitwiseIsEqual(X87QNaN));
1555 EXPECT_FALSE(losesInfo);
Eli Friedmana84ad7d2011-11-26 03:38:02 +00001556}
Ulrich Weigandd9f7e252012-10-29 18:09:01 +00001557
1558TEST(APFloatTest, PPCDoubleDouble) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001559 APFloat test(APFloat::PPCDoubleDouble(), "1.0");
Ulrich Weigandd9f7e252012-10-29 18:09:01 +00001560 EXPECT_EQ(0x3ff0000000000000ull, test.bitcastToAPInt().getRawData()[0]);
1561 EXPECT_EQ(0x0000000000000000ull, test.bitcastToAPInt().getRawData()[1]);
1562
Ulrich Weigandd9f7e252012-10-29 18:09:01 +00001563 // LDBL_MAX
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001564 test = APFloat(APFloat::PPCDoubleDouble(), "1.79769313486231580793728971405301e+308");
Ulrich Weigandd9f7e252012-10-29 18:09:01 +00001565 EXPECT_EQ(0x7fefffffffffffffull, test.bitcastToAPInt().getRawData()[0]);
1566 EXPECT_EQ(0x7c8ffffffffffffeull, test.bitcastToAPInt().getRawData()[1]);
1567
1568 // LDBL_MIN
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001569 test = APFloat(APFloat::PPCDoubleDouble(), "2.00416836000897277799610805135016e-292");
Ulrich Weigandd9f7e252012-10-29 18:09:01 +00001570 EXPECT_EQ(0x0360000000000000ull, test.bitcastToAPInt().getRawData()[0]);
1571 EXPECT_EQ(0x0000000000000000ull, test.bitcastToAPInt().getRawData()[1]);
1572
Tim Shen398f90f2016-11-06 07:38:37 +00001573 // PR30869
1574 {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001575 auto Result = APFloat(APFloat::PPCDoubleDouble(), "1.0") +
1576 APFloat(APFloat::PPCDoubleDouble(), "1.0");
1577 EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics());
Tim Shen398f90f2016-11-06 07:38:37 +00001578
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001579 Result = APFloat(APFloat::PPCDoubleDouble(), "1.0") -
1580 APFloat(APFloat::PPCDoubleDouble(), "1.0");
1581 EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics());
Tim Shen398f90f2016-11-06 07:38:37 +00001582
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001583 Result = APFloat(APFloat::PPCDoubleDouble(), "1.0") *
1584 APFloat(APFloat::PPCDoubleDouble(), "1.0");
1585 EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics());
Tim Shen398f90f2016-11-06 07:38:37 +00001586
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001587 Result = APFloat(APFloat::PPCDoubleDouble(), "1.0") /
1588 APFloat(APFloat::PPCDoubleDouble(), "1.0");
1589 EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics());
Tim Shen398f90f2016-11-06 07:38:37 +00001590
1591 int Exp;
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001592 Result = frexp(APFloat(APFloat::PPCDoubleDouble(), "1.0"), Exp,
Tim Shen398f90f2016-11-06 07:38:37 +00001593 APFloat::rmNearestTiesToEven);
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001594 EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics());
Tim Shen398f90f2016-11-06 07:38:37 +00001595
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001596 Result = scalbn(APFloat(APFloat::PPCDoubleDouble(), "1.0"), 1,
Tim Shen398f90f2016-11-06 07:38:37 +00001597 APFloat::rmNearestTiesToEven);
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001598 EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics());
Tim Shen398f90f2016-11-06 07:38:37 +00001599 }
Ulrich Weigandd9f7e252012-10-29 18:09:01 +00001600}
Michael Gottesman3acedb62013-06-04 03:46:25 +00001601
1602TEST(APFloatTest, isNegative) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001603 APFloat t(APFloat::IEEEsingle(), "0x1p+0");
Michael Gottesman3acedb62013-06-04 03:46:25 +00001604 EXPECT_FALSE(t.isNegative());
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001605 t = APFloat(APFloat::IEEEsingle(), "-0x1p+0");
Michael Gottesman3acedb62013-06-04 03:46:25 +00001606 EXPECT_TRUE(t.isNegative());
Michael Gottesmanf9899292013-06-24 09:58:09 +00001607
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001608 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), false).isNegative());
1609 EXPECT_TRUE(APFloat::getInf(APFloat::IEEEsingle(), true).isNegative());
Michael Gottesmanf9899292013-06-24 09:58:09 +00001610
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001611 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), false).isNegative());
1612 EXPECT_TRUE(APFloat::getZero(APFloat::IEEEsingle(), true).isNegative());
Michael Gottesman3acedb62013-06-04 03:46:25 +00001613
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001614 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), false).isNegative());
1615 EXPECT_TRUE(APFloat::getNaN(APFloat::IEEEsingle(), true).isNegative());
Michael Gottesman3acedb62013-06-04 03:46:25 +00001616
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001617 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isNegative());
1618 EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle(), true).isNegative());
Michael Gottesman3acedb62013-06-04 03:46:25 +00001619}
1620
Michael Gottesman120c92882013-06-20 18:34:38 +00001621TEST(APFloatTest, isNormal) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001622 APFloat t(APFloat::IEEEsingle(), "0x1p+0");
Michael Gottesman120c92882013-06-20 18:34:38 +00001623 EXPECT_TRUE(t.isNormal());
Michael Gottesmanf9899292013-06-24 09:58:09 +00001624
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001625 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), false).isNormal());
1626 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), false).isNormal());
1627 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), false).isNormal());
1628 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isNormal());
1629 EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), "0x1p-149").isNormal());
Michael Gottesman3acedb62013-06-04 03:46:25 +00001630}
1631
1632TEST(APFloatTest, isFinite) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001633 APFloat t(APFloat::IEEEsingle(), "0x1p+0");
Michael Gottesmanf9899292013-06-24 09:58:09 +00001634 EXPECT_TRUE(t.isFinite());
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001635 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), false).isFinite());
1636 EXPECT_TRUE(APFloat::getZero(APFloat::IEEEsingle(), false).isFinite());
1637 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), false).isFinite());
1638 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isFinite());
1639 EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "0x1p-149").isFinite());
Michael Gottesman3acedb62013-06-04 03:46:25 +00001640}
1641
1642TEST(APFloatTest, isInfinity) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001643 APFloat t(APFloat::IEEEsingle(), "0x1p+0");
Michael Gottesman3acedb62013-06-04 03:46:25 +00001644 EXPECT_FALSE(t.isInfinity());
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001645 EXPECT_TRUE(APFloat::getInf(APFloat::IEEEsingle(), false).isInfinity());
1646 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), false).isInfinity());
1647 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), false).isInfinity());
1648 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isInfinity());
1649 EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), "0x1p-149").isInfinity());
Michael Gottesman3acedb62013-06-04 03:46:25 +00001650}
1651
1652TEST(APFloatTest, isNaN) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001653 APFloat t(APFloat::IEEEsingle(), "0x1p+0");
Michael Gottesmanf9899292013-06-24 09:58:09 +00001654 EXPECT_FALSE(t.isNaN());
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001655 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), false).isNaN());
1656 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), false).isNaN());
1657 EXPECT_TRUE(APFloat::getNaN(APFloat::IEEEsingle(), false).isNaN());
1658 EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isNaN());
1659 EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), "0x1p-149").isNaN());
Michael Gottesman3acedb62013-06-04 03:46:25 +00001660}
1661
Michael Gottesmand95d4472013-06-19 21:00:17 +00001662TEST(APFloatTest, isFiniteNonZero) {
1663 // Test positive/negative normal value.
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001664 EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "0x1p+0").isFiniteNonZero());
1665 EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "-0x1p+0").isFiniteNonZero());
Michael Gottesmand95d4472013-06-19 21:00:17 +00001666
1667 // Test positive/negative denormal value.
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001668 EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "0x1p-149").isFiniteNonZero());
1669 EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "-0x1p-149").isFiniteNonZero());
Michael Gottesmand95d4472013-06-19 21:00:17 +00001670
1671 // Test +/- Infinity.
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001672 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), false).isFiniteNonZero());
1673 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), true).isFiniteNonZero());
Michael Gottesmand95d4472013-06-19 21:00:17 +00001674
1675 // Test +/- Zero.
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001676 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), false).isFiniteNonZero());
1677 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), true).isFiniteNonZero());
Michael Gottesmand95d4472013-06-19 21:00:17 +00001678
1679 // Test +/- qNaN. +/- dont mean anything with qNaN but paranoia can't hurt in
1680 // this instance.
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001681 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), false).isFiniteNonZero());
1682 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), true).isFiniteNonZero());
Michael Gottesmand95d4472013-06-19 21:00:17 +00001683
1684 // Test +/- sNaN. +/- dont mean anything with sNaN but paranoia can't hurt in
1685 // this instance.
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001686 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isFiniteNonZero());
1687 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), true).isFiniteNonZero());
Michael Gottesmand95d4472013-06-19 21:00:17 +00001688}
1689
Michael Gottesmane45b1082013-06-24 09:58:07 +00001690TEST(APFloatTest, add) {
1691 // Test Special Cases against each other and normal values.
1692
1693 // TODOS/NOTES:
1694 // 1. Since we perform only default exception handling all operations with
1695 // signaling NaNs should have a result that is a quiet NaN. Currently they
1696 // return sNaN.
Michael Gottesmane45b1082013-06-24 09:58:07 +00001697
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001698 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle(), false);
1699 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle(), true);
1700 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle(), false);
1701 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle(), true);
1702 APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);
1703 APFloat SNaN = APFloat::getSNaN(APFloat::IEEEsingle(), false);
1704 APFloat PNormalValue = APFloat(APFloat::IEEEsingle(), "0x1p+0");
1705 APFloat MNormalValue = APFloat(APFloat::IEEEsingle(), "-0x1p+0");
1706 APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), false);
1707 APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), true);
1708 APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), false);
1709 APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), true);
Michael Gottesmane45b1082013-06-24 09:58:07 +00001710 APFloat PSmallestNormalized =
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001711 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);
Michael Gottesmane45b1082013-06-24 09:58:07 +00001712 APFloat MSmallestNormalized =
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001713 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);
Michael Gottesmane45b1082013-06-24 09:58:07 +00001714
1715 const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact;
1716
1717 const unsigned NumTests = 169;
1718 struct {
1719 APFloat x;
1720 APFloat y;
1721 const char *result;
1722 int status;
1723 int category;
1724 } SpecialCaseTests[NumTests] = {
1725 { PInf, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1726 { PInf, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1727 { PInf, PZero, "inf", APFloat::opOK, APFloat::fcInfinity },
1728 { PInf, MZero, "inf", APFloat::opOK, APFloat::fcInfinity },
1729 { PInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
1730#if 0
1731 // See Note 1.
1732 { PInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1733#endif
1734 { PInf, PNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1735 { PInf, MNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1736 { PInf, PLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1737 { PInf, MLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1738 { PInf, PSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1739 { PInf, MSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1740 { PInf, PSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
1741 { PInf, MSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
1742 { MInf, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1743 { MInf, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1744 { MInf, PZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
1745 { MInf, MZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00001746 { MInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmane45b1082013-06-24 09:58:07 +00001747#if 0
1748 // See Note 1.
1749 { MInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1750#endif
1751 { MInf, PNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1752 { MInf, MNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1753 { MInf, PLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1754 { MInf, MLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1755 { MInf, PSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1756 { MInf, MSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1757 { MInf, PSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
1758 { MInf, MSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
1759 { PZero, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1760 { PZero, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1761 { PZero, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1762 { PZero, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1763 { PZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
1764#if 0
1765 // See Note 1.
1766 { PZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1767#endif
1768 { PZero, PNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
1769 { PZero, MNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
1770 { PZero, PLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1771 { PZero, MLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1772 { PZero, PSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
1773 { PZero, MSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
1774 { PZero, PSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
1775 { PZero, MSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
1776 { MZero, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1777 { MZero, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1778 { MZero, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1779 { MZero, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00001780 { MZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmane45b1082013-06-24 09:58:07 +00001781#if 0
1782 // See Note 1.
1783 { MZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1784#endif
1785 { MZero, PNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
1786 { MZero, MNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
1787 { MZero, PLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1788 { MZero, MLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1789 { MZero, PSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
1790 { MZero, MSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
1791 { MZero, PSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
1792 { MZero, MSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
1793 { QNaN, PInf, "nan", APFloat::opOK, APFloat::fcNaN },
1794 { QNaN, MInf, "nan", APFloat::opOK, APFloat::fcNaN },
1795 { QNaN, PZero, "nan", APFloat::opOK, APFloat::fcNaN },
1796 { QNaN, MZero, "nan", APFloat::opOK, APFloat::fcNaN },
1797 { QNaN, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
1798#if 0
1799 // See Note 1.
1800 { QNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1801#endif
1802 { QNaN, PNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
1803 { QNaN, MNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
1804 { QNaN, PLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
1805 { QNaN, MLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
1806 { QNaN, PSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
1807 { QNaN, MSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
1808 { QNaN, PSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
1809 { QNaN, MSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
1810#if 0
1811 // See Note 1.
1812 { SNaN, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1813 { SNaN, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1814 { SNaN, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1815 { SNaN, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1816 { SNaN, QNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1817 { SNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1818 { SNaN, PNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1819 { SNaN, MNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1820 { SNaN, PLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1821 { SNaN, MLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1822 { SNaN, PSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1823 { SNaN, MSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1824 { SNaN, PSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1825 { SNaN, MSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1826#endif
1827 { PNormalValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1828 { PNormalValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1829 { PNormalValue, PZero, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
1830 { PNormalValue, MZero, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
1831 { PNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
1832#if 0
1833 // See Note 1.
1834 { PNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1835#endif
1836 { PNormalValue, PNormalValue, "0x1p+1", APFloat::opOK, APFloat::fcNormal },
1837 { PNormalValue, MNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1838 { PNormalValue, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1839 { PNormalValue, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1840 { PNormalValue, PSmallestValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1841 { PNormalValue, MSmallestValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1842 { PNormalValue, PSmallestNormalized, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1843 { PNormalValue, MSmallestNormalized, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1844 { MNormalValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1845 { MNormalValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1846 { MNormalValue, PZero, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
1847 { MNormalValue, MZero, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00001848 { MNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmane45b1082013-06-24 09:58:07 +00001849#if 0
1850 // See Note 1.
1851 { MNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1852#endif
1853 { MNormalValue, PNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1854 { MNormalValue, MNormalValue, "-0x1p+1", APFloat::opOK, APFloat::fcNormal },
1855 { MNormalValue, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1856 { MNormalValue, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1857 { MNormalValue, PSmallestValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1858 { MNormalValue, MSmallestValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1859 { MNormalValue, PSmallestNormalized, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1860 { MNormalValue, MSmallestNormalized, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1861 { PLargestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1862 { PLargestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1863 { PLargestValue, PZero, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1864 { PLargestValue, MZero, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1865 { PLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
1866#if 0
1867 // See Note 1.
1868 { PLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1869#endif
1870 { PLargestValue, PNormalValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1871 { PLargestValue, MNormalValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1872 { PLargestValue, PLargestValue, "inf", OverflowStatus, APFloat::fcInfinity },
1873 { PLargestValue, MLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1874 { PLargestValue, PSmallestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1875 { PLargestValue, MSmallestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1876 { PLargestValue, PSmallestNormalized, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1877 { PLargestValue, MSmallestNormalized, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1878 { MLargestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1879 { MLargestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1880 { MLargestValue, PZero, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1881 { MLargestValue, MZero, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00001882 { MLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmane45b1082013-06-24 09:58:07 +00001883#if 0
1884 // See Note 1.
1885 { MLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1886#endif
1887 { MLargestValue, PNormalValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1888 { MLargestValue, MNormalValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1889 { MLargestValue, PLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1890 { MLargestValue, MLargestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
1891 { MLargestValue, PSmallestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1892 { MLargestValue, MSmallestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1893 { MLargestValue, PSmallestNormalized, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1894 { MLargestValue, MSmallestNormalized, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1895 { PSmallestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1896 { PSmallestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1897 { PSmallestValue, PZero, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
1898 { PSmallestValue, MZero, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
1899 { PSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
1900#if 0
1901 // See Note 1.
1902 { PSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1903#endif
1904 { PSmallestValue, PNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1905 { PSmallestValue, MNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1906 { PSmallestValue, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1907 { PSmallestValue, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1908 { PSmallestValue, PSmallestValue, "0x1p-148", APFloat::opOK, APFloat::fcNormal },
1909 { PSmallestValue, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1910 { PSmallestValue, PSmallestNormalized, "0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
1911 { PSmallestValue, MSmallestNormalized, "-0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
1912 { MSmallestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1913 { MSmallestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1914 { MSmallestValue, PZero, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
1915 { MSmallestValue, MZero, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00001916 { MSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmane45b1082013-06-24 09:58:07 +00001917#if 0
1918 // See Note 1.
1919 { MSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1920#endif
1921 { MSmallestValue, PNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1922 { MSmallestValue, MNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1923 { MSmallestValue, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1924 { MSmallestValue, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1925 { MSmallestValue, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1926 { MSmallestValue, MSmallestValue, "-0x1p-148", APFloat::opOK, APFloat::fcNormal },
1927 { MSmallestValue, PSmallestNormalized, "0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
1928 { MSmallestValue, MSmallestNormalized, "-0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
1929 { PSmallestNormalized, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1930 { PSmallestNormalized, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1931 { PSmallestNormalized, PZero, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
1932 { PSmallestNormalized, MZero, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
1933 { PSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
1934#if 0
1935// See Note 1.
1936 { PSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1937#endif
1938 { PSmallestNormalized, PNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1939 { PSmallestNormalized, MNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1940 { PSmallestNormalized, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1941 { PSmallestNormalized, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1942 { PSmallestNormalized, PSmallestValue, "0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
1943 { PSmallestNormalized, MSmallestValue, "0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
1944 { PSmallestNormalized, PSmallestNormalized, "0x1p-125", APFloat::opOK, APFloat::fcNormal },
1945 { PSmallestNormalized, MSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1946 { MSmallestNormalized, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1947 { MSmallestNormalized, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1948 { MSmallestNormalized, PZero, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
1949 { MSmallestNormalized, MZero, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00001950 { MSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmane45b1082013-06-24 09:58:07 +00001951#if 0
1952 // See Note 1.
1953 { MSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1954#endif
1955 { MSmallestNormalized, PNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1956 { MSmallestNormalized, MNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1957 { MSmallestNormalized, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1958 { MSmallestNormalized, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1959 { MSmallestNormalized, PSmallestValue, "-0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
1960 { MSmallestNormalized, MSmallestValue, "-0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
1961 { MSmallestNormalized, PSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1962 { MSmallestNormalized, MSmallestNormalized, "-0x1p-125", APFloat::opOK, APFloat::fcNormal }
1963 };
1964
1965 for (size_t i = 0; i < NumTests; ++i) {
1966 APFloat x(SpecialCaseTests[i].x);
1967 APFloat y(SpecialCaseTests[i].y);
1968 APFloat::opStatus status = x.add(y, APFloat::rmNearestTiesToEven);
1969
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001970 APFloat result(APFloat::IEEEsingle(), SpecialCaseTests[i].result);
Michael Gottesmane45b1082013-06-24 09:58:07 +00001971
Michael Gottesmane45b1082013-06-24 09:58:07 +00001972 EXPECT_TRUE(result.bitwiseIsEqual(x));
1973 EXPECT_TRUE((int)status == SpecialCaseTests[i].status);
1974 EXPECT_TRUE((int)x.getCategory() == SpecialCaseTests[i].category);
1975 }
1976}
1977
Michael Gottesman9368a532013-06-26 23:55:23 +00001978TEST(APFloatTest, subtract) {
1979 // Test Special Cases against each other and normal values.
1980
1981 // TODOS/NOTES:
1982 // 1. Since we perform only default exception handling all operations with
1983 // signaling NaNs should have a result that is a quiet NaN. Currently they
1984 // return sNaN.
Michael Gottesman9368a532013-06-26 23:55:23 +00001985
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001986 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle(), false);
1987 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle(), true);
1988 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle(), false);
1989 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle(), true);
1990 APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);
1991 APFloat SNaN = APFloat::getSNaN(APFloat::IEEEsingle(), false);
1992 APFloat PNormalValue = APFloat(APFloat::IEEEsingle(), "0x1p+0");
1993 APFloat MNormalValue = APFloat(APFloat::IEEEsingle(), "-0x1p+0");
1994 APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), false);
1995 APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), true);
1996 APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), false);
1997 APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), true);
Michael Gottesman9368a532013-06-26 23:55:23 +00001998 APFloat PSmallestNormalized =
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001999 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);
Michael Gottesman9368a532013-06-26 23:55:23 +00002000 APFloat MSmallestNormalized =
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002001 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);
Michael Gottesman9368a532013-06-26 23:55:23 +00002002
2003 const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact;
2004
2005 const unsigned NumTests = 169;
2006 struct {
2007 APFloat x;
2008 APFloat y;
2009 const char *result;
2010 int status;
2011 int category;
2012 } SpecialCaseTests[NumTests] = {
2013 { PInf, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2014 { PInf, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2015 { PInf, PZero, "inf", APFloat::opOK, APFloat::fcInfinity },
2016 { PInf, MZero, "inf", APFloat::opOK, APFloat::fcInfinity },
Stephen Canond3278282014-06-08 16:53:31 +00002017 { PInf, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002018#if 0
2019// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002020 { PInf, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002021#endif
2022 { PInf, PNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2023 { PInf, MNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2024 { PInf, PLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2025 { PInf, MLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2026 { PInf, PSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2027 { PInf, MSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2028 { PInf, PSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
2029 { PInf, MSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
2030 { MInf, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2031 { MInf, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2032 { MInf, PZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
2033 { MInf, MZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
Stephen Canond3278282014-06-08 16:53:31 +00002034 { MInf, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002035#if 0
2036// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002037 { MInf, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002038#endif
2039 { MInf, PNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2040 { MInf, MNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2041 { MInf, PLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2042 { MInf, MLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2043 { MInf, PSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2044 { MInf, MSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2045 { MInf, PSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
2046 { MInf, MSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
2047 { PZero, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2048 { PZero, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2049 { PZero, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2050 { PZero, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
Stephen Canond3278282014-06-08 16:53:31 +00002051 { PZero, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002052#if 0
2053// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002054 { PZero, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002055#endif
2056 { PZero, PNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2057 { PZero, MNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2058 { PZero, PLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2059 { PZero, MLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2060 { PZero, PSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2061 { PZero, MSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2062 { PZero, PSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2063 { PZero, MSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2064 { MZero, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2065 { MZero, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2066 { MZero, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2067 { MZero, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
Stephen Canond3278282014-06-08 16:53:31 +00002068 { MZero, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002069#if 0
2070// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002071 { MZero, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002072#endif
2073 { MZero, PNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2074 { MZero, MNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2075 { MZero, PLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2076 { MZero, MLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2077 { MZero, PSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2078 { MZero, MSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2079 { MZero, PSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2080 { MZero, MSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2081 { QNaN, PInf, "nan", APFloat::opOK, APFloat::fcNaN },
2082 { QNaN, MInf, "nan", APFloat::opOK, APFloat::fcNaN },
2083 { QNaN, PZero, "nan", APFloat::opOK, APFloat::fcNaN },
2084 { QNaN, MZero, "nan", APFloat::opOK, APFloat::fcNaN },
2085 { QNaN, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2086#if 0
2087// See Note 1.
2088 { QNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2089#endif
2090 { QNaN, PNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
2091 { QNaN, MNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
2092 { QNaN, PLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
2093 { QNaN, MLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
2094 { QNaN, PSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
2095 { QNaN, MSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
2096 { QNaN, PSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
2097 { QNaN, MSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
2098#if 0
2099// See Note 1.
2100 { SNaN, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2101 { SNaN, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2102 { SNaN, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2103 { SNaN, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2104 { SNaN, QNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2105 { SNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2106 { SNaN, PNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2107 { SNaN, MNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2108 { SNaN, PLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2109 { SNaN, MLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2110 { SNaN, PSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2111 { SNaN, MSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2112 { SNaN, PSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2113 { SNaN, MSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2114#endif
2115 { PNormalValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2116 { PNormalValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2117 { PNormalValue, PZero, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2118 { PNormalValue, MZero, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
Stephen Canond3278282014-06-08 16:53:31 +00002119 { PNormalValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002120#if 0
2121// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002122 { PNormalValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002123#endif
2124 { PNormalValue, PNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2125 { PNormalValue, MNormalValue, "0x1p+1", APFloat::opOK, APFloat::fcNormal },
2126 { PNormalValue, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2127 { PNormalValue, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2128 { PNormalValue, PSmallestValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2129 { PNormalValue, MSmallestValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2130 { PNormalValue, PSmallestNormalized, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2131 { PNormalValue, MSmallestNormalized, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2132 { MNormalValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2133 { MNormalValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2134 { MNormalValue, PZero, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2135 { MNormalValue, MZero, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
Stephen Canond3278282014-06-08 16:53:31 +00002136 { MNormalValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002137#if 0
2138// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002139 { MNormalValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002140#endif
2141 { MNormalValue, PNormalValue, "-0x1p+1", APFloat::opOK, APFloat::fcNormal },
2142 { MNormalValue, MNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2143 { MNormalValue, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2144 { MNormalValue, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2145 { MNormalValue, PSmallestValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2146 { MNormalValue, MSmallestValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2147 { MNormalValue, PSmallestNormalized, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2148 { MNormalValue, MSmallestNormalized, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2149 { PLargestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2150 { PLargestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2151 { PLargestValue, PZero, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2152 { PLargestValue, MZero, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
Stephen Canond3278282014-06-08 16:53:31 +00002153 { PLargestValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002154#if 0
2155// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002156 { PLargestValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002157#endif
2158 { PLargestValue, PNormalValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2159 { PLargestValue, MNormalValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2160 { PLargestValue, PLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2161 { PLargestValue, MLargestValue, "inf", OverflowStatus, APFloat::fcInfinity },
2162 { PLargestValue, PSmallestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2163 { PLargestValue, MSmallestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2164 { PLargestValue, PSmallestNormalized, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2165 { PLargestValue, MSmallestNormalized, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2166 { MLargestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2167 { MLargestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2168 { MLargestValue, PZero, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2169 { MLargestValue, MZero, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
Stephen Canond3278282014-06-08 16:53:31 +00002170 { MLargestValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002171#if 0
2172// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002173 { MLargestValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002174#endif
2175 { MLargestValue, PNormalValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2176 { MLargestValue, MNormalValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2177 { MLargestValue, PLargestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
2178 { MLargestValue, MLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2179 { MLargestValue, PSmallestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2180 { MLargestValue, MSmallestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2181 { MLargestValue, PSmallestNormalized, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2182 { MLargestValue, MSmallestNormalized, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2183 { PSmallestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2184 { PSmallestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2185 { PSmallestValue, PZero, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2186 { PSmallestValue, MZero, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
Stephen Canond3278282014-06-08 16:53:31 +00002187 { PSmallestValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002188#if 0
2189// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002190 { PSmallestValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002191#endif
2192 { PSmallestValue, PNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2193 { PSmallestValue, MNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2194 { PSmallestValue, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2195 { PSmallestValue, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2196 { PSmallestValue, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2197 { PSmallestValue, MSmallestValue, "0x1p-148", APFloat::opOK, APFloat::fcNormal },
2198 { PSmallestValue, PSmallestNormalized, "-0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
2199 { PSmallestValue, MSmallestNormalized, "0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
2200 { MSmallestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2201 { MSmallestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2202 { MSmallestValue, PZero, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2203 { MSmallestValue, MZero, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
Stephen Canond3278282014-06-08 16:53:31 +00002204 { MSmallestValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002205#if 0
2206// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002207 { MSmallestValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002208#endif
2209 { MSmallestValue, PNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2210 { MSmallestValue, MNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2211 { MSmallestValue, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2212 { MSmallestValue, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2213 { MSmallestValue, PSmallestValue, "-0x1p-148", APFloat::opOK, APFloat::fcNormal },
2214 { MSmallestValue, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2215 { MSmallestValue, PSmallestNormalized, "-0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
2216 { MSmallestValue, MSmallestNormalized, "0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
2217 { PSmallestNormalized, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2218 { PSmallestNormalized, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2219 { PSmallestNormalized, PZero, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2220 { PSmallestNormalized, MZero, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
Stephen Canond3278282014-06-08 16:53:31 +00002221 { PSmallestNormalized, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002222#if 0
2223// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002224 { PSmallestNormalized, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002225#endif
2226 { PSmallestNormalized, PNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2227 { PSmallestNormalized, MNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2228 { PSmallestNormalized, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2229 { PSmallestNormalized, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2230 { PSmallestNormalized, PSmallestValue, "0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
2231 { PSmallestNormalized, MSmallestValue, "0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
2232 { PSmallestNormalized, PSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2233 { PSmallestNormalized, MSmallestNormalized, "0x1p-125", APFloat::opOK, APFloat::fcNormal },
2234 { MSmallestNormalized, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2235 { MSmallestNormalized, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2236 { MSmallestNormalized, PZero, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2237 { MSmallestNormalized, MZero, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
Stephen Canond3278282014-06-08 16:53:31 +00002238 { MSmallestNormalized, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002239#if 0
2240// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002241 { MSmallestNormalized, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002242#endif
2243 { MSmallestNormalized, PNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2244 { MSmallestNormalized, MNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2245 { MSmallestNormalized, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2246 { MSmallestNormalized, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2247 { MSmallestNormalized, PSmallestValue, "-0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
2248 { MSmallestNormalized, MSmallestValue, "-0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
2249 { MSmallestNormalized, PSmallestNormalized, "-0x1p-125", APFloat::opOK, APFloat::fcNormal },
2250 { MSmallestNormalized, MSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero }
2251 };
2252
2253 for (size_t i = 0; i < NumTests; ++i) {
2254 APFloat x(SpecialCaseTests[i].x);
2255 APFloat y(SpecialCaseTests[i].y);
2256 APFloat::opStatus status = x.subtract(y, APFloat::rmNearestTiesToEven);
2257
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002258 APFloat result(APFloat::IEEEsingle(), SpecialCaseTests[i].result);
Michael Gottesman9368a532013-06-26 23:55:23 +00002259
Michael Gottesman9368a532013-06-26 23:55:23 +00002260 EXPECT_TRUE(result.bitwiseIsEqual(x));
2261 EXPECT_TRUE((int)status == SpecialCaseTests[i].status);
2262 EXPECT_TRUE((int)x.getCategory() == SpecialCaseTests[i].category);
2263 }
2264}
2265
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002266TEST(APFloatTest, multiply) {
2267 // Test Special Cases against each other and normal values.
2268
2269 // TODOS/NOTES:
2270 // 1. Since we perform only default exception handling all operations with
2271 // signaling NaNs should have a result that is a quiet NaN. Currently they
2272 // return sNaN.
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002273
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002274 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle(), false);
2275 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle(), true);
2276 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle(), false);
2277 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle(), true);
2278 APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);
2279 APFloat SNaN = APFloat::getSNaN(APFloat::IEEEsingle(), false);
2280 APFloat PNormalValue = APFloat(APFloat::IEEEsingle(), "0x1p+0");
2281 APFloat MNormalValue = APFloat(APFloat::IEEEsingle(), "-0x1p+0");
2282 APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), false);
2283 APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), true);
2284 APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), false);
2285 APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), true);
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002286 APFloat PSmallestNormalized =
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002287 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002288 APFloat MSmallestNormalized =
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002289 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002290
2291 const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact;
2292 const int UnderflowStatus = APFloat::opUnderflow | APFloat::opInexact;
2293
2294 const unsigned NumTests = 169;
2295 struct {
2296 APFloat x;
2297 APFloat y;
2298 const char *result;
2299 int status;
2300 int category;
2301 } SpecialCaseTests[NumTests] = {
2302 { PInf, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2303 { PInf, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2304 { PInf, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2305 { PInf, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2306 { PInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2307#if 0
2308// See Note 1.
2309 { PInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2310#endif
2311 { PInf, PNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2312 { PInf, MNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2313 { PInf, PLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2314 { PInf, MLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2315 { PInf, PSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2316 { PInf, MSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2317 { PInf, PSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
2318 { PInf, MSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
2319 { MInf, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2320 { MInf, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2321 { MInf, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2322 { MInf, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002323 { MInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002324#if 0
2325// See Note 1.
2326 { MInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2327#endif
2328 { MInf, PNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2329 { MInf, MNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2330 { MInf, PLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2331 { MInf, MLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2332 { MInf, PSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2333 { MInf, MSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2334 { MInf, PSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
2335 { MInf, MSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
2336 { PZero, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2337 { PZero, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2338 { PZero, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2339 { PZero, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2340 { PZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2341#if 0
2342// See Note 1.
2343 { PZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2344#endif
2345 { PZero, PNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2346 { PZero, MNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2347 { PZero, PLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2348 { PZero, MLargestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2349 { PZero, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2350 { PZero, MSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2351 { PZero, PSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2352 { PZero, MSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2353 { MZero, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2354 { MZero, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2355 { MZero, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2356 { MZero, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002357 { MZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002358#if 0
2359// See Note 1.
2360 { MZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2361#endif
2362 { MZero, PNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2363 { MZero, MNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2364 { MZero, PLargestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2365 { MZero, MLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2366 { MZero, PSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2367 { MZero, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2368 { MZero, PSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2369 { MZero, MSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2370 { QNaN, PInf, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002371 { QNaN, MInf, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002372 { QNaN, PZero, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002373 { QNaN, MZero, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002374 { QNaN, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2375#if 0
2376// See Note 1.
2377 { QNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2378#endif
2379 { QNaN, PNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002380 { QNaN, MNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002381 { QNaN, PLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002382 { QNaN, MLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002383 { QNaN, PSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002384 { QNaN, MSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002385 { QNaN, PSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002386 { QNaN, MSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002387#if 0
2388// See Note 1.
2389 { SNaN, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2390 { SNaN, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2391 { SNaN, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2392 { SNaN, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2393 { SNaN, QNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2394 { SNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2395 { SNaN, PNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2396 { SNaN, MNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2397 { SNaN, PLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2398 { SNaN, MLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2399 { SNaN, PSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2400 { SNaN, MSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2401 { SNaN, PSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2402 { SNaN, MSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2403#endif
2404 { PNormalValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2405 { PNormalValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2406 { PNormalValue, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2407 { PNormalValue, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2408 { PNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2409#if 0
2410// See Note 1.
2411 { PNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2412#endif
2413 { PNormalValue, PNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2414 { PNormalValue, MNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2415 { PNormalValue, PLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2416 { PNormalValue, MLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2417 { PNormalValue, PSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2418 { PNormalValue, MSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2419 { PNormalValue, PSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2420 { PNormalValue, MSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2421 { MNormalValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2422 { MNormalValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2423 { MNormalValue, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2424 { MNormalValue, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002425 { MNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002426#if 0
2427// See Note 1.
2428 { MNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2429#endif
2430 { MNormalValue, PNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2431 { MNormalValue, MNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2432 { MNormalValue, PLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2433 { MNormalValue, MLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2434 { MNormalValue, PSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2435 { MNormalValue, MSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2436 { MNormalValue, PSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2437 { MNormalValue, MSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2438 { PLargestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2439 { PLargestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2440 { PLargestValue, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2441 { PLargestValue, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2442 { PLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2443#if 0
2444// See Note 1.
2445 { PLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2446#endif
2447 { PLargestValue, PNormalValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2448 { PLargestValue, MNormalValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2449 { PLargestValue, PLargestValue, "inf", OverflowStatus, APFloat::fcInfinity },
2450 { PLargestValue, MLargestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
2451 { PLargestValue, PSmallestValue, "0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2452 { PLargestValue, MSmallestValue, "-0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2453 { PLargestValue, PSmallestNormalized, "0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2454 { PLargestValue, MSmallestNormalized, "-0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2455 { MLargestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2456 { MLargestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2457 { MLargestValue, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2458 { MLargestValue, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002459 { MLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002460#if 0
2461// See Note 1.
2462 { MLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2463#endif
2464 { MLargestValue, PNormalValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2465 { MLargestValue, MNormalValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2466 { MLargestValue, PLargestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
2467 { MLargestValue, MLargestValue, "inf", OverflowStatus, APFloat::fcInfinity },
2468 { MLargestValue, PSmallestValue, "-0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2469 { MLargestValue, MSmallestValue, "0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2470 { MLargestValue, PSmallestNormalized, "-0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2471 { MLargestValue, MSmallestNormalized, "0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2472 { PSmallestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2473 { PSmallestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2474 { PSmallestValue, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2475 { PSmallestValue, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2476 { PSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2477#if 0
2478// See Note 1.
2479 { PSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2480#endif
2481 { PSmallestValue, PNormalValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2482 { PSmallestValue, MNormalValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2483 { PSmallestValue, PLargestValue, "0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2484 { PSmallestValue, MLargestValue, "-0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2485 { PSmallestValue, PSmallestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2486 { PSmallestValue, MSmallestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2487 { PSmallestValue, PSmallestNormalized, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2488 { PSmallestValue, MSmallestNormalized, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2489 { MSmallestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2490 { MSmallestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2491 { MSmallestValue, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2492 { MSmallestValue, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002493 { MSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002494#if 0
2495// See Note 1.
2496 { MSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2497#endif
2498 { MSmallestValue, PNormalValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2499 { MSmallestValue, MNormalValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2500 { MSmallestValue, PLargestValue, "-0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2501 { MSmallestValue, MLargestValue, "0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2502 { MSmallestValue, PSmallestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2503 { MSmallestValue, MSmallestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2504 { MSmallestValue, PSmallestNormalized, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2505 { MSmallestValue, MSmallestNormalized, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2506 { PSmallestNormalized, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2507 { PSmallestNormalized, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2508 { PSmallestNormalized, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2509 { PSmallestNormalized, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2510 { PSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2511#if 0
2512// See Note 1.
2513 { PSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2514#endif
2515 { PSmallestNormalized, PNormalValue, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2516 { PSmallestNormalized, MNormalValue, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2517 { PSmallestNormalized, PLargestValue, "0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2518 { PSmallestNormalized, MLargestValue, "-0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2519 { PSmallestNormalized, PSmallestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2520 { PSmallestNormalized, MSmallestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2521 { PSmallestNormalized, PSmallestNormalized, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2522 { PSmallestNormalized, MSmallestNormalized, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2523 { MSmallestNormalized, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2524 { MSmallestNormalized, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2525 { MSmallestNormalized, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2526 { MSmallestNormalized, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002527 { MSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002528#if 0
2529// See Note 1.
2530 { MSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2531#endif
2532 { MSmallestNormalized, PNormalValue, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2533 { MSmallestNormalized, MNormalValue, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2534 { MSmallestNormalized, PLargestValue, "-0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2535 { MSmallestNormalized, MLargestValue, "0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2536 { MSmallestNormalized, PSmallestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2537 { MSmallestNormalized, MSmallestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2538 { MSmallestNormalized, PSmallestNormalized, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2539 { MSmallestNormalized, MSmallestNormalized, "0x0p+0", UnderflowStatus, APFloat::fcZero }
2540 };
2541
2542 for (size_t i = 0; i < NumTests; ++i) {
2543 APFloat x(SpecialCaseTests[i].x);
2544 APFloat y(SpecialCaseTests[i].y);
2545 APFloat::opStatus status = x.multiply(y, APFloat::rmNearestTiesToEven);
2546
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002547 APFloat result(APFloat::IEEEsingle(), SpecialCaseTests[i].result);
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002548
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002549 EXPECT_TRUE(result.bitwiseIsEqual(x));
2550 EXPECT_TRUE((int)status == SpecialCaseTests[i].status);
2551 EXPECT_TRUE((int)x.getCategory() == SpecialCaseTests[i].category);
2552 }
2553}
Michael Gottesman9368a532013-06-26 23:55:23 +00002554
Michael Gottesman3eacb582013-06-27 00:42:00 +00002555TEST(APFloatTest, divide) {
2556 // Test Special Cases against each other and normal values.
2557
2558 // TODOS/NOTES:
2559 // 1. Since we perform only default exception handling all operations with
2560 // signaling NaNs should have a result that is a quiet NaN. Currently they
2561 // return sNaN.
Michael Gottesman3eacb582013-06-27 00:42:00 +00002562
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002563 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle(), false);
2564 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle(), true);
2565 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle(), false);
2566 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle(), true);
2567 APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);
2568 APFloat SNaN = APFloat::getSNaN(APFloat::IEEEsingle(), false);
2569 APFloat PNormalValue = APFloat(APFloat::IEEEsingle(), "0x1p+0");
2570 APFloat MNormalValue = APFloat(APFloat::IEEEsingle(), "-0x1p+0");
2571 APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), false);
2572 APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), true);
2573 APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), false);
2574 APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), true);
Michael Gottesman3eacb582013-06-27 00:42:00 +00002575 APFloat PSmallestNormalized =
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002576 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);
Michael Gottesman3eacb582013-06-27 00:42:00 +00002577 APFloat MSmallestNormalized =
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002578 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);
Michael Gottesman3eacb582013-06-27 00:42:00 +00002579
2580 const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact;
2581 const int UnderflowStatus = APFloat::opUnderflow | APFloat::opInexact;
2582
2583 const unsigned NumTests = 169;
2584 struct {
2585 APFloat x;
2586 APFloat y;
2587 const char *result;
2588 int status;
2589 int category;
2590 } SpecialCaseTests[NumTests] = {
2591 { PInf, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2592 { PInf, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2593 { PInf, PZero, "inf", APFloat::opOK, APFloat::fcInfinity },
2594 { PInf, MZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
2595 { PInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2596#if 0
2597// See Note 1.
2598 { PInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2599#endif
2600 { PInf, PNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2601 { PInf, MNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2602 { PInf, PLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2603 { PInf, MLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2604 { PInf, PSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2605 { PInf, MSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2606 { PInf, PSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
2607 { PInf, MSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
2608 { MInf, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2609 { MInf, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2610 { MInf, PZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
2611 { MInf, MZero, "inf", APFloat::opOK, APFloat::fcInfinity },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002612 { MInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002613#if 0
2614// See Note 1.
2615 { MInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2616#endif
2617 { MInf, PNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2618 { MInf, MNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2619 { MInf, PLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2620 { MInf, MLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2621 { MInf, PSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2622 { MInf, MSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2623 { MInf, PSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
2624 { MInf, MSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
2625 { PZero, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2626 { PZero, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2627 { PZero, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2628 { PZero, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2629 { PZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2630#if 0
2631// See Note 1.
2632 { PZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2633#endif
2634 { PZero, PNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2635 { PZero, MNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2636 { PZero, PLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2637 { PZero, MLargestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2638 { PZero, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2639 { PZero, MSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2640 { PZero, PSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2641 { PZero, MSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2642 { MZero, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2643 { MZero, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2644 { MZero, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2645 { MZero, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002646 { MZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002647#if 0
2648// See Note 1.
2649 { MZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2650#endif
2651 { MZero, PNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2652 { MZero, MNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2653 { MZero, PLargestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2654 { MZero, MLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2655 { MZero, PSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2656 { MZero, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2657 { MZero, PSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2658 { MZero, MSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2659 { QNaN, PInf, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002660 { QNaN, MInf, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002661 { QNaN, PZero, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002662 { QNaN, MZero, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002663 { QNaN, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2664#if 0
2665// See Note 1.
2666 { QNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2667#endif
2668 { QNaN, PNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002669 { QNaN, MNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002670 { QNaN, PLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002671 { QNaN, MLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002672 { QNaN, PSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002673 { QNaN, MSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002674 { QNaN, PSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002675 { QNaN, MSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002676#if 0
2677// See Note 1.
2678 { SNaN, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2679 { SNaN, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2680 { SNaN, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2681 { SNaN, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2682 { SNaN, QNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2683 { SNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2684 { SNaN, PNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2685 { SNaN, MNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2686 { SNaN, PLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2687 { SNaN, MLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2688 { SNaN, PSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2689 { SNaN, MSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2690 { SNaN, PSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2691 { SNaN, MSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2692#endif
2693 { PNormalValue, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2694 { PNormalValue, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2695 { PNormalValue, PZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
2696 { PNormalValue, MZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2697 { PNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2698#if 0
2699// See Note 1.
2700 { PNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2701#endif
2702 { PNormalValue, PNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2703 { PNormalValue, MNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2704 { PNormalValue, PLargestValue, "0x1p-128", UnderflowStatus, APFloat::fcNormal },
2705 { PNormalValue, MLargestValue, "-0x1p-128", UnderflowStatus, APFloat::fcNormal },
2706 { PNormalValue, PSmallestValue, "inf", OverflowStatus, APFloat::fcInfinity },
2707 { PNormalValue, MSmallestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
2708 { PNormalValue, PSmallestNormalized, "0x1p+126", APFloat::opOK, APFloat::fcNormal },
2709 { PNormalValue, MSmallestNormalized, "-0x1p+126", APFloat::opOK, APFloat::fcNormal },
2710 { MNormalValue, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2711 { MNormalValue, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2712 { MNormalValue, PZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2713 { MNormalValue, MZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002714 { MNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002715#if 0
2716// See Note 1.
2717 { MNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2718#endif
2719 { MNormalValue, PNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2720 { MNormalValue, MNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2721 { MNormalValue, PLargestValue, "-0x1p-128", UnderflowStatus, APFloat::fcNormal },
2722 { MNormalValue, MLargestValue, "0x1p-128", UnderflowStatus, APFloat::fcNormal },
2723 { MNormalValue, PSmallestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
2724 { MNormalValue, MSmallestValue, "inf", OverflowStatus, APFloat::fcInfinity },
2725 { MNormalValue, PSmallestNormalized, "-0x1p+126", APFloat::opOK, APFloat::fcNormal },
2726 { MNormalValue, MSmallestNormalized, "0x1p+126", APFloat::opOK, APFloat::fcNormal },
2727 { PLargestValue, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2728 { PLargestValue, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2729 { PLargestValue, PZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
2730 { PLargestValue, MZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2731 { PLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2732#if 0
2733// See Note 1.
2734 { PLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2735#endif
2736 { PLargestValue, PNormalValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2737 { PLargestValue, MNormalValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2738 { PLargestValue, PLargestValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2739 { PLargestValue, MLargestValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2740 { PLargestValue, PSmallestValue, "inf", OverflowStatus, APFloat::fcInfinity },
2741 { PLargestValue, MSmallestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
2742 { PLargestValue, PSmallestNormalized, "inf", OverflowStatus, APFloat::fcInfinity },
2743 { PLargestValue, MSmallestNormalized, "-inf", OverflowStatus, APFloat::fcInfinity },
2744 { MLargestValue, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2745 { MLargestValue, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2746 { MLargestValue, PZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2747 { MLargestValue, MZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002748 { MLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002749#if 0
2750// See Note 1.
2751 { MLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2752#endif
2753 { MLargestValue, PNormalValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2754 { MLargestValue, MNormalValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2755 { MLargestValue, PLargestValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2756 { MLargestValue, MLargestValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2757 { MLargestValue, PSmallestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
2758 { MLargestValue, MSmallestValue, "inf", OverflowStatus, APFloat::fcInfinity },
2759 { MLargestValue, PSmallestNormalized, "-inf", OverflowStatus, APFloat::fcInfinity },
2760 { MLargestValue, MSmallestNormalized, "inf", OverflowStatus, APFloat::fcInfinity },
2761 { PSmallestValue, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2762 { PSmallestValue, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2763 { PSmallestValue, PZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
2764 { PSmallestValue, MZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2765 { PSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2766#if 0
2767// See Note 1.
2768 { PSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2769#endif
2770 { PSmallestValue, PNormalValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2771 { PSmallestValue, MNormalValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2772 { PSmallestValue, PLargestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2773 { PSmallestValue, MLargestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2774 { PSmallestValue, PSmallestValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2775 { PSmallestValue, MSmallestValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2776 { PSmallestValue, PSmallestNormalized, "0x1p-23", APFloat::opOK, APFloat::fcNormal },
2777 { PSmallestValue, MSmallestNormalized, "-0x1p-23", APFloat::opOK, APFloat::fcNormal },
2778 { MSmallestValue, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2779 { MSmallestValue, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2780 { MSmallestValue, PZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2781 { MSmallestValue, MZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002782 { MSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002783#if 0
2784// See Note 1.
2785 { MSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2786#endif
2787 { MSmallestValue, PNormalValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2788 { MSmallestValue, MNormalValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2789 { MSmallestValue, PLargestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2790 { MSmallestValue, MLargestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2791 { MSmallestValue, PSmallestValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2792 { MSmallestValue, MSmallestValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2793 { MSmallestValue, PSmallestNormalized, "-0x1p-23", APFloat::opOK, APFloat::fcNormal },
2794 { MSmallestValue, MSmallestNormalized, "0x1p-23", APFloat::opOK, APFloat::fcNormal },
2795 { PSmallestNormalized, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2796 { PSmallestNormalized, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2797 { PSmallestNormalized, PZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
2798 { PSmallestNormalized, MZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2799 { PSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2800#if 0
2801// See Note 1.
2802 { PSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2803#endif
2804 { PSmallestNormalized, PNormalValue, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2805 { PSmallestNormalized, MNormalValue, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2806 { PSmallestNormalized, PLargestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2807 { PSmallestNormalized, MLargestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2808 { PSmallestNormalized, PSmallestValue, "0x1p+23", APFloat::opOK, APFloat::fcNormal },
2809 { PSmallestNormalized, MSmallestValue, "-0x1p+23", APFloat::opOK, APFloat::fcNormal },
2810 { PSmallestNormalized, PSmallestNormalized, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2811 { PSmallestNormalized, MSmallestNormalized, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2812 { MSmallestNormalized, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2813 { MSmallestNormalized, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2814 { MSmallestNormalized, PZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2815 { MSmallestNormalized, MZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002816 { MSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002817#if 0
2818// See Note 1.
2819 { MSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2820#endif
2821 { MSmallestNormalized, PNormalValue, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2822 { MSmallestNormalized, MNormalValue, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2823 { MSmallestNormalized, PLargestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2824 { MSmallestNormalized, MLargestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2825 { MSmallestNormalized, PSmallestValue, "-0x1p+23", APFloat::opOK, APFloat::fcNormal },
2826 { MSmallestNormalized, MSmallestValue, "0x1p+23", APFloat::opOK, APFloat::fcNormal },
2827 { MSmallestNormalized, PSmallestNormalized, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2828 { MSmallestNormalized, MSmallestNormalized, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2829 };
2830
2831 for (size_t i = 0; i < NumTests; ++i) {
2832 APFloat x(SpecialCaseTests[i].x);
2833 APFloat y(SpecialCaseTests[i].y);
2834 APFloat::opStatus status = x.divide(y, APFloat::rmNearestTiesToEven);
2835
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002836 APFloat result(APFloat::IEEEsingle(), SpecialCaseTests[i].result);
Michael Gottesman3eacb582013-06-27 00:42:00 +00002837
2838 EXPECT_TRUE(result.bitwiseIsEqual(x));
2839 EXPECT_TRUE((int)status == SpecialCaseTests[i].status);
2840 EXPECT_TRUE((int)x.getCategory() == SpecialCaseTests[i].category);
2841 }
2842}
2843
Chandler Carruthdf782e42014-10-09 23:26:15 +00002844TEST(APFloatTest, operatorOverloads) {
2845 // This is mostly testing that these operator overloads compile.
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002846 APFloat One = APFloat(APFloat::IEEEsingle(), "0x1p+0");
2847 APFloat Two = APFloat(APFloat::IEEEsingle(), "0x2p+0");
Chandler Carruthdf782e42014-10-09 23:26:15 +00002848 EXPECT_TRUE(Two.bitwiseIsEqual(One + One));
2849 EXPECT_TRUE(One.bitwiseIsEqual(Two - One));
2850 EXPECT_TRUE(Two.bitwiseIsEqual(One * Two));
2851 EXPECT_TRUE(One.bitwiseIsEqual(Two / Two));
2852}
Chandler Carruth7468b062014-10-10 04:17:04 +00002853
Chandler Carruthafe56ae2014-10-10 08:27:22 +00002854TEST(APFloatTest, abs) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002855 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle(), false);
2856 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle(), true);
2857 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle(), false);
2858 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle(), true);
2859 APFloat PQNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);
2860 APFloat MQNaN = APFloat::getNaN(APFloat::IEEEsingle(), true);
2861 APFloat PSNaN = APFloat::getSNaN(APFloat::IEEEsingle(), false);
2862 APFloat MSNaN = APFloat::getSNaN(APFloat::IEEEsingle(), true);
2863 APFloat PNormalValue = APFloat(APFloat::IEEEsingle(), "0x1p+0");
2864 APFloat MNormalValue = APFloat(APFloat::IEEEsingle(), "-0x1p+0");
2865 APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), false);
2866 APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), true);
2867 APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), false);
2868 APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), true);
Chandler Carruthafe56ae2014-10-10 08:27:22 +00002869 APFloat PSmallestNormalized =
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002870 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);
Chandler Carruthafe56ae2014-10-10 08:27:22 +00002871 APFloat MSmallestNormalized =
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002872 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);
Chandler Carruthafe56ae2014-10-10 08:27:22 +00002873
2874 EXPECT_TRUE(PInf.bitwiseIsEqual(abs(PInf)));
2875 EXPECT_TRUE(PInf.bitwiseIsEqual(abs(MInf)));
2876 EXPECT_TRUE(PZero.bitwiseIsEqual(abs(PZero)));
2877 EXPECT_TRUE(PZero.bitwiseIsEqual(abs(MZero)));
2878 EXPECT_TRUE(PQNaN.bitwiseIsEqual(abs(PQNaN)));
2879 EXPECT_TRUE(PQNaN.bitwiseIsEqual(abs(MQNaN)));
2880 EXPECT_TRUE(PSNaN.bitwiseIsEqual(abs(PSNaN)));
2881 EXPECT_TRUE(PSNaN.bitwiseIsEqual(abs(MSNaN)));
2882 EXPECT_TRUE(PNormalValue.bitwiseIsEqual(abs(PNormalValue)));
2883 EXPECT_TRUE(PNormalValue.bitwiseIsEqual(abs(MNormalValue)));
2884 EXPECT_TRUE(PLargestValue.bitwiseIsEqual(abs(PLargestValue)));
2885 EXPECT_TRUE(PLargestValue.bitwiseIsEqual(abs(MLargestValue)));
2886 EXPECT_TRUE(PSmallestValue.bitwiseIsEqual(abs(PSmallestValue)));
2887 EXPECT_TRUE(PSmallestValue.bitwiseIsEqual(abs(MSmallestValue)));
2888 EXPECT_TRUE(PSmallestNormalized.bitwiseIsEqual(abs(PSmallestNormalized)));
2889 EXPECT_TRUE(PSmallestNormalized.bitwiseIsEqual(abs(MSmallestNormalized)));
2890}
2891
Matt Arsenault8a27aee2017-01-25 04:54:34 +00002892TEST(APFloatTest, neg) {
2893 APFloat One = APFloat(APFloat::IEEEsingle(), "1.0");
2894 APFloat NegOne = APFloat(APFloat::IEEEsingle(), "-1.0");
2895 APFloat Zero = APFloat::getZero(APFloat::IEEEsingle(), false);
2896 APFloat NegZero = APFloat::getZero(APFloat::IEEEsingle(), true);
2897 APFloat Inf = APFloat::getInf(APFloat::IEEEsingle(), false);
2898 APFloat NegInf = APFloat::getInf(APFloat::IEEEsingle(), true);
2899 APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);
2900 APFloat NegQNaN = APFloat::getNaN(APFloat::IEEEsingle(), true);
2901
2902 EXPECT_TRUE(NegOne.bitwiseIsEqual(neg(One)));
2903 EXPECT_TRUE(One.bitwiseIsEqual(neg(NegOne)));
2904 EXPECT_TRUE(NegZero.bitwiseIsEqual(neg(Zero)));
2905 EXPECT_TRUE(Zero.bitwiseIsEqual(neg(NegZero)));
2906 EXPECT_TRUE(NegInf.bitwiseIsEqual(neg(Inf)));
2907 EXPECT_TRUE(Inf.bitwiseIsEqual(neg(NegInf)));
2908 EXPECT_TRUE(NegInf.bitwiseIsEqual(neg(Inf)));
2909 EXPECT_TRUE(Inf.bitwiseIsEqual(neg(NegInf)));
2910 EXPECT_TRUE(NegQNaN.bitwiseIsEqual(neg(QNaN)));
2911 EXPECT_TRUE(QNaN.bitwiseIsEqual(neg(NegQNaN)));
2912}
2913
Chandler Carruthca067142014-10-10 05:14:12 +00002914TEST(APFloatTest, ilogb) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002915 EXPECT_EQ(-1074, ilogb(APFloat::getSmallest(APFloat::IEEEdouble(), false)));
2916 EXPECT_EQ(-1074, ilogb(APFloat::getSmallest(APFloat::IEEEdouble(), true)));
2917 EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1024")));
2918 EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1023")));
2919 EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble(), "-0x1.ffffffffffffep-1023")));
2920 EXPECT_EQ(-51, ilogb(APFloat(APFloat::IEEEdouble(), "0x1p-51")));
2921 EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp-1023")));
2922 EXPECT_EQ(-2, ilogb(APFloat(APFloat::IEEEdouble(), "0x0.ffffp-1")));
2923 EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble(), "0x1.fffep-1023")));
2924 EXPECT_EQ(1023, ilogb(APFloat::getLargest(APFloat::IEEEdouble(), false)));
2925 EXPECT_EQ(1023, ilogb(APFloat::getLargest(APFloat::IEEEdouble(), true)));
Matt Arsenault69fdf9b2016-03-13 05:12:32 +00002926
2927
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002928 EXPECT_EQ(0, ilogb(APFloat(APFloat::IEEEsingle(), "0x1p+0")));
2929 EXPECT_EQ(0, ilogb(APFloat(APFloat::IEEEsingle(), "-0x1p+0")));
2930 EXPECT_EQ(42, ilogb(APFloat(APFloat::IEEEsingle(), "0x1p+42")));
2931 EXPECT_EQ(-42, ilogb(APFloat(APFloat::IEEEsingle(), "0x1p-42")));
Chandler Carruth7468b062014-10-10 04:17:04 +00002932
Chandler Carruthca067142014-10-10 05:14:12 +00002933 EXPECT_EQ(APFloat::IEK_Inf,
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002934 ilogb(APFloat::getInf(APFloat::IEEEsingle(), false)));
Chandler Carruthca067142014-10-10 05:14:12 +00002935 EXPECT_EQ(APFloat::IEK_Inf,
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002936 ilogb(APFloat::getInf(APFloat::IEEEsingle(), true)));
Chandler Carruthca067142014-10-10 05:14:12 +00002937 EXPECT_EQ(APFloat::IEK_Zero,
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002938 ilogb(APFloat::getZero(APFloat::IEEEsingle(), false)));
Chandler Carruthca067142014-10-10 05:14:12 +00002939 EXPECT_EQ(APFloat::IEK_Zero,
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002940 ilogb(APFloat::getZero(APFloat::IEEEsingle(), true)));
Chandler Carruthca067142014-10-10 05:14:12 +00002941 EXPECT_EQ(APFloat::IEK_NaN,
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002942 ilogb(APFloat::getNaN(APFloat::IEEEsingle(), false)));
Chandler Carruthca067142014-10-10 05:14:12 +00002943 EXPECT_EQ(APFloat::IEK_NaN,
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002944 ilogb(APFloat::getSNaN(APFloat::IEEEsingle(), false)));
Chandler Carruth7468b062014-10-10 04:17:04 +00002945
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002946 EXPECT_EQ(127, ilogb(APFloat::getLargest(APFloat::IEEEsingle(), false)));
2947 EXPECT_EQ(127, ilogb(APFloat::getLargest(APFloat::IEEEsingle(), true)));
Matt Arsenault69fdf9b2016-03-13 05:12:32 +00002948
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002949 EXPECT_EQ(-149, ilogb(APFloat::getSmallest(APFloat::IEEEsingle(), false)));
2950 EXPECT_EQ(-149, ilogb(APFloat::getSmallest(APFloat::IEEEsingle(), true)));
Chandler Carruthca067142014-10-10 05:14:12 +00002951 EXPECT_EQ(-126,
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002952 ilogb(APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false)));
Chandler Carruthca067142014-10-10 05:14:12 +00002953 EXPECT_EQ(-126,
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002954 ilogb(APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true)));
Chandler Carruth7468b062014-10-10 04:17:04 +00002955}
Chandler Carruthd9edd1e2014-10-10 04:54:30 +00002956
2957TEST(APFloatTest, scalbn) {
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00002958
2959 const APFloat::roundingMode RM = APFloat::rmNearestTiesToEven;
Chandler Carruthd9edd1e2014-10-10 04:54:30 +00002960 EXPECT_TRUE(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002961 APFloat(APFloat::IEEEsingle(), "0x1p+0")
2962 .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEsingle(), "0x1p+0"), 0, RM)));
Chandler Carruthd9edd1e2014-10-10 04:54:30 +00002963 EXPECT_TRUE(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002964 APFloat(APFloat::IEEEsingle(), "0x1p+42")
2965 .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEsingle(), "0x1p+0"), 42, RM)));
Chandler Carruthd9edd1e2014-10-10 04:54:30 +00002966 EXPECT_TRUE(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002967 APFloat(APFloat::IEEEsingle(), "0x1p-42")
2968 .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEsingle(), "0x1p+0"), -42, RM)));
Chandler Carruthd9edd1e2014-10-10 04:54:30 +00002969
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002970 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle(), false);
2971 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle(), true);
2972 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle(), false);
2973 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle(), true);
2974 APFloat QPNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);
2975 APFloat QMNaN = APFloat::getNaN(APFloat::IEEEsingle(), true);
2976 APFloat SNaN = APFloat::getSNaN(APFloat::IEEEsingle(), false);
Chandler Carruthd9edd1e2014-10-10 04:54:30 +00002977
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00002978 EXPECT_TRUE(PInf.bitwiseIsEqual(scalbn(PInf, 0, RM)));
2979 EXPECT_TRUE(MInf.bitwiseIsEqual(scalbn(MInf, 0, RM)));
2980 EXPECT_TRUE(PZero.bitwiseIsEqual(scalbn(PZero, 0, RM)));
2981 EXPECT_TRUE(MZero.bitwiseIsEqual(scalbn(MZero, 0, RM)));
2982 EXPECT_TRUE(QPNaN.bitwiseIsEqual(scalbn(QPNaN, 0, RM)));
2983 EXPECT_TRUE(QMNaN.bitwiseIsEqual(scalbn(QMNaN, 0, RM)));
Matt Arsenaultea00b492016-03-23 23:51:45 +00002984 EXPECT_FALSE(scalbn(SNaN, 0, RM).isSignaling());
2985
2986 APFloat ScalbnSNaN = scalbn(SNaN, 1, RM);
2987 EXPECT_TRUE(ScalbnSNaN.isNaN() && !ScalbnSNaN.isSignaling());
2988
2989 // Make sure highest bit of payload is preserved.
2990 const APInt Payload(64, (UINT64_C(1) << 50) |
2991 (UINT64_C(1) << 49) |
2992 (UINT64_C(1234) << 32) |
2993 1);
2994
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002995 APFloat SNaNWithPayload = APFloat::getSNaN(APFloat::IEEEdouble(), false,
Matt Arsenaultea00b492016-03-23 23:51:45 +00002996 &Payload);
2997 APFloat QuietPayload = scalbn(SNaNWithPayload, 1, RM);
2998 EXPECT_TRUE(QuietPayload.isNaN() && !QuietPayload.isSignaling());
2999 EXPECT_EQ(Payload, QuietPayload.bitcastToAPInt().getLoBits(51));
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003000
3001 EXPECT_TRUE(PInf.bitwiseIsEqual(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003002 scalbn(APFloat(APFloat::IEEEsingle(), "0x1p+0"), 128, RM)));
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003003 EXPECT_TRUE(MInf.bitwiseIsEqual(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003004 scalbn(APFloat(APFloat::IEEEsingle(), "-0x1p+0"), 128, RM)));
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003005 EXPECT_TRUE(PInf.bitwiseIsEqual(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003006 scalbn(APFloat(APFloat::IEEEsingle(), "0x1p+127"), 1, RM)));
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003007 EXPECT_TRUE(PZero.bitwiseIsEqual(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003008 scalbn(APFloat(APFloat::IEEEsingle(), "0x1p-127"), -127, RM)));
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003009 EXPECT_TRUE(MZero.bitwiseIsEqual(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003010 scalbn(APFloat(APFloat::IEEEsingle(), "-0x1p-127"), -127, RM)));
3011 EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "-0x1p-149").bitwiseIsEqual(
3012 scalbn(APFloat(APFloat::IEEEsingle(), "-0x1p-127"), -22, RM)));
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003013 EXPECT_TRUE(PZero.bitwiseIsEqual(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003014 scalbn(APFloat(APFloat::IEEEsingle(), "0x1p-126"), -24, RM)));
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003015
3016
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003017 APFloat SmallestF64 = APFloat::getSmallest(APFloat::IEEEdouble(), false);
3018 APFloat NegSmallestF64 = APFloat::getSmallest(APFloat::IEEEdouble(), true);
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003019
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003020 APFloat LargestF64 = APFloat::getLargest(APFloat::IEEEdouble(), false);
3021 APFloat NegLargestF64 = APFloat::getLargest(APFloat::IEEEdouble(), true);
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003022
3023 APFloat SmallestNormalizedF64
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003024 = APFloat::getSmallestNormalized(APFloat::IEEEdouble(), false);
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003025 APFloat NegSmallestNormalizedF64
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003026 = APFloat::getSmallestNormalized(APFloat::IEEEdouble(), true);
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003027
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003028 APFloat LargestDenormalF64(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1023");
3029 APFloat NegLargestDenormalF64(APFloat::IEEEdouble(), "-0x1.ffffffffffffep-1023");
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003030
3031
3032 EXPECT_TRUE(SmallestF64.bitwiseIsEqual(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003033 scalbn(APFloat(APFloat::IEEEdouble(), "0x1p-1074"), 0, RM)));
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003034 EXPECT_TRUE(NegSmallestF64.bitwiseIsEqual(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003035 scalbn(APFloat(APFloat::IEEEdouble(), "-0x1p-1074"), 0, RM)));
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003036
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003037 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p+1023")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003038 .bitwiseIsEqual(scalbn(SmallestF64, 2097, RM)));
3039
3040 EXPECT_TRUE(scalbn(SmallestF64, -2097, RM).isPosZero());
3041 EXPECT_TRUE(scalbn(SmallestF64, -2098, RM).isPosZero());
3042 EXPECT_TRUE(scalbn(SmallestF64, -2099, RM).isPosZero());
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003043 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p+1022")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003044 .bitwiseIsEqual(scalbn(SmallestF64, 2096, RM)));
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003045 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p+1023")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003046 .bitwiseIsEqual(scalbn(SmallestF64, 2097, RM)));
3047 EXPECT_TRUE(scalbn(SmallestF64, 2098, RM).isInfinity());
3048 EXPECT_TRUE(scalbn(SmallestF64, 2099, RM).isInfinity());
3049
3050 // Test for integer overflows when adding to exponent.
3051 EXPECT_TRUE(scalbn(SmallestF64, -INT_MAX, RM).isPosZero());
3052 EXPECT_TRUE(scalbn(LargestF64, INT_MAX, RM).isInfinity());
3053
3054 EXPECT_TRUE(LargestDenormalF64
3055 .bitwiseIsEqual(scalbn(LargestDenormalF64, 0, RM)));
3056 EXPECT_TRUE(NegLargestDenormalF64
3057 .bitwiseIsEqual(scalbn(NegLargestDenormalF64, 0, RM)));
3058
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003059 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1022")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003060 .bitwiseIsEqual(scalbn(LargestDenormalF64, 1, RM)));
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003061 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1.ffffffffffffep-1021")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003062 .bitwiseIsEqual(scalbn(NegLargestDenormalF64, 2, RM)));
3063
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003064 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep+1")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003065 .bitwiseIsEqual(scalbn(LargestDenormalF64, 1024, RM)));
3066 EXPECT_TRUE(scalbn(LargestDenormalF64, -1023, RM).isPosZero());
3067 EXPECT_TRUE(scalbn(LargestDenormalF64, -1024, RM).isPosZero());
3068 EXPECT_TRUE(scalbn(LargestDenormalF64, -2048, RM).isPosZero());
3069 EXPECT_TRUE(scalbn(LargestDenormalF64, 2047, RM).isInfinity());
3070 EXPECT_TRUE(scalbn(LargestDenormalF64, 2098, RM).isInfinity());
3071 EXPECT_TRUE(scalbn(LargestDenormalF64, 2099, RM).isInfinity());
3072
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003073 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-2")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003074 .bitwiseIsEqual(scalbn(LargestDenormalF64, 1021, RM)));
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003075 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003076 .bitwiseIsEqual(scalbn(LargestDenormalF64, 1022, RM)));
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003077 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep+0")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003078 .bitwiseIsEqual(scalbn(LargestDenormalF64, 1023, RM)));
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003079 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep+1023")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003080 .bitwiseIsEqual(scalbn(LargestDenormalF64, 2046, RM)));
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003081 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p+974")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003082 .bitwiseIsEqual(scalbn(SmallestF64, 2048, RM)));
3083
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003084 APFloat RandomDenormalF64(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp+51");
3085 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp-972")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003086 .bitwiseIsEqual(scalbn(RandomDenormalF64, -1023, RM)));
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003087 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp-1")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003088 .bitwiseIsEqual(scalbn(RandomDenormalF64, -52, RM)));
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003089 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp-2")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003090 .bitwiseIsEqual(scalbn(RandomDenormalF64, -53, RM)));
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003091 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp+0")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003092 .bitwiseIsEqual(scalbn(RandomDenormalF64, -51, RM)));
3093
3094 EXPECT_TRUE(scalbn(RandomDenormalF64, -2097, RM).isPosZero());
3095 EXPECT_TRUE(scalbn(RandomDenormalF64, -2090, RM).isPosZero());
3096
Chandler Carruthd9edd1e2014-10-10 04:54:30 +00003097
3098 EXPECT_TRUE(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003099 APFloat(APFloat::IEEEdouble(), "-0x1p-1073")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003100 .bitwiseIsEqual(scalbn(NegLargestF64, -2097, RM)));
3101
Chandler Carruthd9edd1e2014-10-10 04:54:30 +00003102 EXPECT_TRUE(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003103 APFloat(APFloat::IEEEdouble(), "-0x1p-1024")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003104 .bitwiseIsEqual(scalbn(NegLargestF64, -2048, RM)));
3105
3106 EXPECT_TRUE(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003107 APFloat(APFloat::IEEEdouble(), "0x1p-1073")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003108 .bitwiseIsEqual(scalbn(LargestF64, -2097, RM)));
3109
3110 EXPECT_TRUE(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003111 APFloat(APFloat::IEEEdouble(), "0x1p-1074")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003112 .bitwiseIsEqual(scalbn(LargestF64, -2098, RM)));
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003113 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1p-1074")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003114 .bitwiseIsEqual(scalbn(NegLargestF64, -2098, RM)));
3115 EXPECT_TRUE(scalbn(NegLargestF64, -2099, RM).isNegZero());
3116 EXPECT_TRUE(scalbn(LargestF64, 1, RM).isInfinity());
3117
3118
3119 EXPECT_TRUE(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003120 APFloat(APFloat::IEEEdouble(), "0x1p+0")
3121 .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEdouble(), "0x1p+52"), -52, RM)));
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003122
3123 EXPECT_TRUE(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003124 APFloat(APFloat::IEEEdouble(), "0x1p-103")
3125 .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEdouble(), "0x1p-51"), -52, RM)));
Chandler Carruthd9edd1e2014-10-10 04:54:30 +00003126}
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003127
3128TEST(APFloatTest, frexp) {
3129 const APFloat::roundingMode RM = APFloat::rmNearestTiesToEven;
3130
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003131 APFloat PZero = APFloat::getZero(APFloat::IEEEdouble(), false);
3132 APFloat MZero = APFloat::getZero(APFloat::IEEEdouble(), true);
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003133 APFloat One(1.0);
3134 APFloat MOne(-1.0);
3135 APFloat Two(2.0);
3136 APFloat MTwo(-2.0);
3137
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003138 APFloat LargestDenormal(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1023");
3139 APFloat NegLargestDenormal(APFloat::IEEEdouble(), "-0x1.ffffffffffffep-1023");
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003140
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003141 APFloat Smallest = APFloat::getSmallest(APFloat::IEEEdouble(), false);
3142 APFloat NegSmallest = APFloat::getSmallest(APFloat::IEEEdouble(), true);
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003143
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003144 APFloat Largest = APFloat::getLargest(APFloat::IEEEdouble(), false);
3145 APFloat NegLargest = APFloat::getLargest(APFloat::IEEEdouble(), true);
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003146
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003147 APFloat PInf = APFloat::getInf(APFloat::IEEEdouble(), false);
3148 APFloat MInf = APFloat::getInf(APFloat::IEEEdouble(), true);
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003149
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003150 APFloat QPNaN = APFloat::getNaN(APFloat::IEEEdouble(), false);
3151 APFloat QMNaN = APFloat::getNaN(APFloat::IEEEdouble(), true);
3152 APFloat SNaN = APFloat::getSNaN(APFloat::IEEEdouble(), false);
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003153
3154 // Make sure highest bit of payload is preserved.
3155 const APInt Payload(64, (UINT64_C(1) << 50) |
3156 (UINT64_C(1) << 49) |
3157 (UINT64_C(1234) << 32) |
3158 1);
3159
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003160 APFloat SNaNWithPayload = APFloat::getSNaN(APFloat::IEEEdouble(), false,
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003161 &Payload);
3162
3163 APFloat SmallestNormalized
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003164 = APFloat::getSmallestNormalized(APFloat::IEEEdouble(), false);
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003165 APFloat NegSmallestNormalized
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003166 = APFloat::getSmallestNormalized(APFloat::IEEEdouble(), true);
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003167
3168 int Exp;
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003169 APFloat Frac(APFloat::IEEEdouble());
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003170
3171
3172 Frac = frexp(PZero, Exp, RM);
3173 EXPECT_EQ(0, Exp);
3174 EXPECT_TRUE(Frac.isPosZero());
3175
3176 Frac = frexp(MZero, Exp, RM);
3177 EXPECT_EQ(0, Exp);
3178 EXPECT_TRUE(Frac.isNegZero());
3179
3180
3181 Frac = frexp(One, Exp, RM);
3182 EXPECT_EQ(1, Exp);
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003183 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p-1").bitwiseIsEqual(Frac));
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003184
3185 Frac = frexp(MOne, Exp, RM);
3186 EXPECT_EQ(1, Exp);
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003187 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1p-1").bitwiseIsEqual(Frac));
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003188
3189 Frac = frexp(LargestDenormal, Exp, RM);
3190 EXPECT_EQ(-1022, Exp);
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003191 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1").bitwiseIsEqual(Frac));
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003192
3193 Frac = frexp(NegLargestDenormal, Exp, RM);
3194 EXPECT_EQ(-1022, Exp);
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003195 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1.ffffffffffffep-1").bitwiseIsEqual(Frac));
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003196
3197
3198 Frac = frexp(Smallest, Exp, RM);
3199 EXPECT_EQ(-1073, Exp);
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003200 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p-1").bitwiseIsEqual(Frac));
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003201
3202 Frac = frexp(NegSmallest, Exp, RM);
3203 EXPECT_EQ(-1073, Exp);
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003204 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1p-1").bitwiseIsEqual(Frac));
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003205
3206
3207 Frac = frexp(Largest, Exp, RM);
3208 EXPECT_EQ(1024, Exp);
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003209 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.fffffffffffffp-1").bitwiseIsEqual(Frac));
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003210
3211 Frac = frexp(NegLargest, Exp, RM);
3212 EXPECT_EQ(1024, Exp);
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003213 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1.fffffffffffffp-1").bitwiseIsEqual(Frac));
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003214
3215
3216 Frac = frexp(PInf, Exp, RM);
3217 EXPECT_EQ(INT_MAX, Exp);
3218 EXPECT_TRUE(Frac.isInfinity() && !Frac.isNegative());
3219
3220 Frac = frexp(MInf, Exp, RM);
3221 EXPECT_EQ(INT_MAX, Exp);
3222 EXPECT_TRUE(Frac.isInfinity() && Frac.isNegative());
3223
3224 Frac = frexp(QPNaN, Exp, RM);
3225 EXPECT_EQ(INT_MIN, Exp);
3226 EXPECT_TRUE(Frac.isNaN());
3227
3228 Frac = frexp(QMNaN, Exp, RM);
3229 EXPECT_EQ(INT_MIN, Exp);
3230 EXPECT_TRUE(Frac.isNaN());
3231
3232 Frac = frexp(SNaN, Exp, RM);
3233 EXPECT_EQ(INT_MIN, Exp);
3234 EXPECT_TRUE(Frac.isNaN() && !Frac.isSignaling());
3235
3236 Frac = frexp(SNaNWithPayload, Exp, RM);
3237 EXPECT_EQ(INT_MIN, Exp);
3238 EXPECT_TRUE(Frac.isNaN() && !Frac.isSignaling());
3239 EXPECT_EQ(Payload, Frac.bitcastToAPInt().getLoBits(51));
3240
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003241 Frac = frexp(APFloat(APFloat::IEEEdouble(), "0x0.ffffp-1"), Exp, RM);
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003242 EXPECT_EQ(-1, Exp);
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003243 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.fffep-1").bitwiseIsEqual(Frac));
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003244
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003245 Frac = frexp(APFloat(APFloat::IEEEdouble(), "0x1p-51"), Exp, RM);
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003246 EXPECT_EQ(-50, Exp);
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003247 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p-1").bitwiseIsEqual(Frac));
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003248
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003249 Frac = frexp(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp+51"), Exp, RM);
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003250 EXPECT_EQ(52, Exp);
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003251 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp-1").bitwiseIsEqual(Frac));
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003252}
Tim Shen44bde892016-12-12 21:59:30 +00003253
Stephen Canon157c8692017-03-31 20:31:33 +00003254TEST(APFloatTest, mod) {
3255 {
3256 APFloat f1(APFloat::IEEEdouble(), "1.5");
3257 APFloat f2(APFloat::IEEEdouble(), "1.0");
3258 APFloat expected(APFloat::IEEEdouble(), "0.5");
3259 EXPECT_EQ(f1.mod(f2), APFloat::opOK);
3260 EXPECT_TRUE(f1.bitwiseIsEqual(expected));
3261 }
3262 {
3263 APFloat f1(APFloat::IEEEdouble(), "0.5");
3264 APFloat f2(APFloat::IEEEdouble(), "1.0");
3265 APFloat expected(APFloat::IEEEdouble(), "0.5");
3266 EXPECT_EQ(f1.mod(f2), APFloat::opOK);
3267 EXPECT_TRUE(f1.bitwiseIsEqual(expected));
3268 }
3269 {
3270 APFloat f1(APFloat::IEEEdouble(), "0x1.3333333333333p-2"); // 0.3
3271 APFloat f2(APFloat::IEEEdouble(), "0x1.47ae147ae147bp-7"); // 0.01
3272 APFloat expected(APFloat::IEEEdouble(),
3273 "0x1.47ae147ae1471p-7"); // 0.009999999999999983
3274 EXPECT_EQ(f1.mod(f2), APFloat::opOK);
3275 EXPECT_TRUE(f1.bitwiseIsEqual(expected));
3276 }
3277 {
3278 APFloat f1(APFloat::IEEEdouble(), "0x1p64"); // 1.8446744073709552e19
3279 APFloat f2(APFloat::IEEEdouble(), "1.5");
3280 APFloat expected(APFloat::IEEEdouble(), "1.0");
3281 EXPECT_EQ(f1.mod(f2), APFloat::opOK);
3282 EXPECT_TRUE(f1.bitwiseIsEqual(expected));
3283 }
3284 {
3285 APFloat f1(APFloat::IEEEdouble(), "0x1p1000");
3286 APFloat f2(APFloat::IEEEdouble(), "0x1p-1000");
3287 APFloat expected(APFloat::IEEEdouble(), "0.0");
3288 EXPECT_EQ(f1.mod(f2), APFloat::opOK);
3289 EXPECT_TRUE(f1.bitwiseIsEqual(expected));
3290 }
3291 {
3292 APFloat f1(APFloat::IEEEdouble(), "0.0");
3293 APFloat f2(APFloat::IEEEdouble(), "1.0");
3294 APFloat expected(APFloat::IEEEdouble(), "0.0");
3295 EXPECT_EQ(f1.mod(f2), APFloat::opOK);
3296 EXPECT_TRUE(f1.bitwiseIsEqual(expected));
3297 }
3298 {
3299 APFloat f1(APFloat::IEEEdouble(), "1.0");
3300 APFloat f2(APFloat::IEEEdouble(), "0.0");
3301 EXPECT_EQ(f1.mod(f2), APFloat::opInvalidOp);
3302 EXPECT_TRUE(f1.isNaN());
3303 }
3304 {
3305 APFloat f1(APFloat::IEEEdouble(), "0.0");
3306 APFloat f2(APFloat::IEEEdouble(), "0.0");
3307 EXPECT_EQ(f1.mod(f2), APFloat::opInvalidOp);
3308 EXPECT_TRUE(f1.isNaN());
3309 }
3310 {
3311 APFloat f1 = APFloat::getInf(APFloat::IEEEdouble(), false);
3312 APFloat f2(APFloat::IEEEdouble(), "1.0");
3313 EXPECT_EQ(f1.mod(f2), APFloat::opInvalidOp);
3314 EXPECT_TRUE(f1.isNaN());
3315 }
Serguei Katkovf2c28512017-11-01 07:56:55 +00003316 {
3317 APFloat f1(APFloat::IEEEdouble(), "-4.0");
3318 APFloat f2(APFloat::IEEEdouble(), "-2.0");
3319 APFloat expected(APFloat::IEEEdouble(), "-0.0");
3320 EXPECT_EQ(f1.mod(f2), APFloat::opOK);
3321 EXPECT_TRUE(f1.bitwiseIsEqual(expected));
3322 }
3323 {
3324 APFloat f1(APFloat::IEEEdouble(), "-4.0");
3325 APFloat f2(APFloat::IEEEdouble(), "2.0");
3326 APFloat expected(APFloat::IEEEdouble(), "-0.0");
3327 EXPECT_EQ(f1.mod(f2), APFloat::opOK);
3328 EXPECT_TRUE(f1.bitwiseIsEqual(expected));
3329 }
Stephen Canon157c8692017-03-31 20:31:33 +00003330}
3331
Tim Shen44bde892016-12-12 21:59:30 +00003332TEST(APFloatTest, PPCDoubleDoubleAddSpecial) {
3333 using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t,
Stephen Canon29a9ba22017-03-31 20:35:02 +00003334 APFloat::fltCategory, APFloat::roundingMode>;
3335 DataType Data[] = {
Tim Shen44bde892016-12-12 21:59:30 +00003336 // (1 + 0) + (-1 + 0) = fcZero
Tim Shen18e7ae62016-12-12 22:16:08 +00003337 std::make_tuple(0x3ff0000000000000ull, 0, 0xbff0000000000000ull, 0,
3338 APFloat::fcZero, APFloat::rmNearestTiesToEven),
Tim Shen44bde892016-12-12 21:59:30 +00003339 // LDBL_MAX + (1.1 >> (1023 - 106) + 0)) = fcInfinity
Tim Shen18e7ae62016-12-12 22:16:08 +00003340 std::make_tuple(0x7fefffffffffffffull, 0x7c8ffffffffffffeull,
3341 0x7948000000000000ull, 0ull, APFloat::fcInfinity,
3342 APFloat::rmNearestTiesToEven),
Tim Shen44bde892016-12-12 21:59:30 +00003343 // TODO: change the 4th 0x75effffffffffffe to 0x75efffffffffffff when
Tim Shenfd1e5aa2017-01-23 22:39:35 +00003344 // semPPCDoubleDoubleLegacy is gone.
Tim Shen44bde892016-12-12 21:59:30 +00003345 // LDBL_MAX + (1.011111... >> (1023 - 106) + (1.1111111...0 >> (1023 -
3346 // 160))) = fcNormal
Tim Shen18e7ae62016-12-12 22:16:08 +00003347 std::make_tuple(0x7fefffffffffffffull, 0x7c8ffffffffffffeull,
3348 0x7947ffffffffffffull, 0x75effffffffffffeull,
3349 APFloat::fcNormal, APFloat::rmNearestTiesToEven),
Tim Shen44bde892016-12-12 21:59:30 +00003350 // LDBL_MAX + (1.1 >> (1023 - 106) + 0)) = fcInfinity
Tim Shen18e7ae62016-12-12 22:16:08 +00003351 std::make_tuple(0x7fefffffffffffffull, 0x7c8ffffffffffffeull,
3352 0x7fefffffffffffffull, 0x7c8ffffffffffffeull,
3353 APFloat::fcInfinity, APFloat::rmNearestTiesToEven),
Tim Shen44bde892016-12-12 21:59:30 +00003354 // NaN + (1 + 0) = fcNaN
Tim Shen18e7ae62016-12-12 22:16:08 +00003355 std::make_tuple(0x7ff8000000000000ull, 0, 0x3ff0000000000000ull, 0,
3356 APFloat::fcNaN, APFloat::rmNearestTiesToEven),
Tim Shen44bde892016-12-12 21:59:30 +00003357 };
3358
3359 for (auto Tp : Data) {
3360 uint64_t Op1[2], Op2[2];
3361 APFloat::fltCategory Expected;
3362 APFloat::roundingMode RM;
3363 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected, RM) = Tp;
3364
Tim Shen7f127622017-01-24 00:19:45 +00003365 {
3366 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1));
3367 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2));
3368 A1.add(A2, RM);
Tim Shen44bde892016-12-12 21:59:30 +00003369
Tim Shen7f127622017-01-24 00:19:45 +00003370 EXPECT_EQ(Expected, A1.getCategory())
3371 << formatv("({0:x} + {1:x}) + ({2:x} + {3:x})", Op1[0], Op1[1],
3372 Op2[0], Op2[1])
3373 .str();
3374 }
3375 {
3376 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1));
3377 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2));
3378 A2.add(A1, RM);
3379
3380 EXPECT_EQ(Expected, A2.getCategory())
3381 << formatv("({0:x} + {1:x}) + ({2:x} + {3:x})", Op2[0], Op2[1],
3382 Op1[0], Op1[1])
3383 .str();
3384 }
Tim Shen44bde892016-12-12 21:59:30 +00003385 }
3386}
3387
3388TEST(APFloatTest, PPCDoubleDoubleAdd) {
3389 using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,
3390 uint64_t, APFloat::roundingMode>;
3391 DataType Data[] = {
3392 // (1 + 0) + (1e-105 + 0) = (1 + 1e-105)
Tim Shen18e7ae62016-12-12 22:16:08 +00003393 std::make_tuple(0x3ff0000000000000ull, 0, 0x3960000000000000ull, 0,
3394 0x3ff0000000000000ull, 0x3960000000000000ull,
3395 APFloat::rmNearestTiesToEven),
Tim Shen44bde892016-12-12 21:59:30 +00003396 // (1 + 0) + (1e-106 + 0) = (1 + 1e-106)
Tim Shen18e7ae62016-12-12 22:16:08 +00003397 std::make_tuple(0x3ff0000000000000ull, 0, 0x3950000000000000ull, 0,
3398 0x3ff0000000000000ull, 0x3950000000000000ull,
3399 APFloat::rmNearestTiesToEven),
Tim Shen44bde892016-12-12 21:59:30 +00003400 // (1 + 1e-106) + (1e-106 + 0) = (1 + 1e-105)
Tim Shen18e7ae62016-12-12 22:16:08 +00003401 std::make_tuple(0x3ff0000000000000ull, 0x3950000000000000ull,
3402 0x3950000000000000ull, 0, 0x3ff0000000000000ull,
3403 0x3960000000000000ull, APFloat::rmNearestTiesToEven),
Tim Shen44bde892016-12-12 21:59:30 +00003404 // (1 + 0) + (epsilon + 0) = (1 + epsilon)
Tim Shen18e7ae62016-12-12 22:16:08 +00003405 std::make_tuple(0x3ff0000000000000ull, 0, 0x0000000000000001ull, 0,
3406 0x3ff0000000000000ull, 0x0000000000000001ull,
3407 APFloat::rmNearestTiesToEven),
Tim Shen44bde892016-12-12 21:59:30 +00003408 // TODO: change 0xf950000000000000 to 0xf940000000000000, when
Tim Shenfd1e5aa2017-01-23 22:39:35 +00003409 // semPPCDoubleDoubleLegacy is gone.
Tim Shen44bde892016-12-12 21:59:30 +00003410 // (DBL_MAX - 1 << (1023 - 105)) + (1 << (1023 - 53) + 0) = DBL_MAX +
3411 // 1.11111... << (1023 - 52)
Tim Shen18e7ae62016-12-12 22:16:08 +00003412 std::make_tuple(0x7fefffffffffffffull, 0xf950000000000000ull,
3413 0x7c90000000000000ull, 0, 0x7fefffffffffffffull,
3414 0x7c8ffffffffffffeull, APFloat::rmNearestTiesToEven),
Tim Shen44bde892016-12-12 21:59:30 +00003415 // TODO: change 0xf950000000000000 to 0xf940000000000000, when
Tim Shenfd1e5aa2017-01-23 22:39:35 +00003416 // semPPCDoubleDoubleLegacy is gone.
Tim Shen44bde892016-12-12 21:59:30 +00003417 // (1 << (1023 - 53) + 0) + (DBL_MAX - 1 << (1023 - 105)) = DBL_MAX +
3418 // 1.11111... << (1023 - 52)
Tim Shen18e7ae62016-12-12 22:16:08 +00003419 std::make_tuple(0x7c90000000000000ull, 0, 0x7fefffffffffffffull,
3420 0xf950000000000000ull, 0x7fefffffffffffffull,
3421 0x7c8ffffffffffffeull, APFloat::rmNearestTiesToEven),
Tim Shen44bde892016-12-12 21:59:30 +00003422 };
3423
3424 for (auto Tp : Data) {
3425 uint64_t Op1[2], Op2[2], Expected[2];
3426 APFloat::roundingMode RM;
3427 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected[0], Expected[1], RM) = Tp;
3428
Tim Shen7f127622017-01-24 00:19:45 +00003429 {
3430 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1));
3431 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2));
3432 A1.add(A2, RM);
Tim Shen44bde892016-12-12 21:59:30 +00003433
Tim Shen7f127622017-01-24 00:19:45 +00003434 EXPECT_EQ(Expected[0], A1.bitcastToAPInt().getRawData()[0])
3435 << formatv("({0:x} + {1:x}) + ({2:x} + {3:x})", Op1[0], Op1[1],
3436 Op2[0], Op2[1])
3437 .str();
3438 EXPECT_EQ(Expected[1], A1.bitcastToAPInt().getRawData()[1])
3439 << formatv("({0:x} + {1:x}) + ({2:x} + {3:x})", Op1[0], Op1[1],
3440 Op2[0], Op2[1])
3441 .str();
3442 }
3443 {
3444 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1));
3445 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2));
3446 A2.add(A1, RM);
3447
3448 EXPECT_EQ(Expected[0], A2.bitcastToAPInt().getRawData()[0])
3449 << formatv("({0:x} + {1:x}) + ({2:x} + {3:x})", Op2[0], Op2[1],
3450 Op1[0], Op1[1])
3451 .str();
3452 EXPECT_EQ(Expected[1], A2.bitcastToAPInt().getRawData()[1])
3453 << formatv("({0:x} + {1:x}) + ({2:x} + {3:x})", Op2[0], Op2[1],
3454 Op1[0], Op1[1])
3455 .str();
3456 }
Tim Shen44bde892016-12-12 21:59:30 +00003457 }
3458}
3459
3460TEST(APFloatTest, PPCDoubleDoubleSubtract) {
3461 using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,
3462 uint64_t, APFloat::roundingMode>;
3463 DataType Data[] = {
3464 // (1 + 0) - (-1e-105 + 0) = (1 + 1e-105)
Tim Shen18e7ae62016-12-12 22:16:08 +00003465 std::make_tuple(0x3ff0000000000000ull, 0, 0xb960000000000000ull, 0,
3466 0x3ff0000000000000ull, 0x3960000000000000ull,
3467 APFloat::rmNearestTiesToEven),
Tim Shen44bde892016-12-12 21:59:30 +00003468 // (1 + 0) - (-1e-106 + 0) = (1 + 1e-106)
Tim Shen18e7ae62016-12-12 22:16:08 +00003469 std::make_tuple(0x3ff0000000000000ull, 0, 0xb950000000000000ull, 0,
3470 0x3ff0000000000000ull, 0x3950000000000000ull,
3471 APFloat::rmNearestTiesToEven),
Tim Shen44bde892016-12-12 21:59:30 +00003472 };
3473
3474 for (auto Tp : Data) {
3475 uint64_t Op1[2], Op2[2], Expected[2];
3476 APFloat::roundingMode RM;
3477 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected[0], Expected[1], RM) = Tp;
3478
Stephan Bergmann7d94d542016-12-14 12:11:35 +00003479 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1));
3480 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2));
Tim Shen44bde892016-12-12 21:59:30 +00003481 A1.subtract(A2, RM);
3482
Tim Shen53f14c72016-12-16 00:47:17 +00003483 EXPECT_EQ(Expected[0], A1.bitcastToAPInt().getRawData()[0])
3484 << formatv("({0:x} + {1:x}) - ({2:x} + {3:x})", Op1[0], Op1[1], Op2[0],
3485 Op2[1])
3486 .str();
Tim Shenfd1e5aa2017-01-23 22:39:35 +00003487 EXPECT_EQ(Expected[1], A1.bitcastToAPInt().getRawData()[1])
Tim Shen53f14c72016-12-16 00:47:17 +00003488 << formatv("({0:x} + {1:x}) - ({2:x} + {3:x})", Op1[0], Op1[1], Op2[0],
3489 Op2[1])
3490 .str();
Tim Shen44bde892016-12-12 21:59:30 +00003491 }
3492}
Tim Shen1594e062017-01-05 22:57:54 +00003493
Tim Shen7f127622017-01-24 00:19:45 +00003494TEST(APFloatTest, PPCDoubleDoubleMultiplySpecial) {
3495 using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t,
3496 APFloat::fltCategory, APFloat::roundingMode>;
3497 DataType Data[] = {
3498 // fcNaN * fcNaN = fcNaN
3499 std::make_tuple(0x7ff8000000000000ull, 0, 0x7ff8000000000000ull, 0,
3500 APFloat::fcNaN, APFloat::rmNearestTiesToEven),
3501 // fcNaN * fcZero = fcNaN
3502 std::make_tuple(0x7ff8000000000000ull, 0, 0, 0, APFloat::fcNaN,
3503 APFloat::rmNearestTiesToEven),
3504 // fcNaN * fcInfinity = fcNaN
3505 std::make_tuple(0x7ff8000000000000ull, 0, 0x7ff0000000000000ull, 0,
3506 APFloat::fcNaN, APFloat::rmNearestTiesToEven),
3507 // fcNaN * fcNormal = fcNaN
3508 std::make_tuple(0x7ff8000000000000ull, 0, 0x3ff0000000000000ull, 0,
3509 APFloat::fcNaN, APFloat::rmNearestTiesToEven),
3510 // fcInfinity * fcInfinity = fcInfinity
3511 std::make_tuple(0x7ff0000000000000ull, 0, 0x7ff0000000000000ull, 0,
3512 APFloat::fcInfinity, APFloat::rmNearestTiesToEven),
3513 // fcInfinity * fcZero = fcNaN
3514 std::make_tuple(0x7ff0000000000000ull, 0, 0, 0, APFloat::fcNaN,
3515 APFloat::rmNearestTiesToEven),
3516 // fcInfinity * fcNormal = fcInfinity
3517 std::make_tuple(0x7ff0000000000000ull, 0, 0x3ff0000000000000ull, 0,
3518 APFloat::fcInfinity, APFloat::rmNearestTiesToEven),
3519 // fcZero * fcZero = fcZero
3520 std::make_tuple(0, 0, 0, 0, APFloat::fcZero,
3521 APFloat::rmNearestTiesToEven),
3522 // fcZero * fcNormal = fcZero
3523 std::make_tuple(0, 0, 0x3ff0000000000000ull, 0, APFloat::fcZero,
3524 APFloat::rmNearestTiesToEven),
3525 };
3526
3527 for (auto Tp : Data) {
3528 uint64_t Op1[2], Op2[2];
3529 APFloat::fltCategory Expected;
3530 APFloat::roundingMode RM;
3531 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected, RM) = Tp;
3532
3533 {
3534 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1));
3535 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2));
3536 A1.multiply(A2, RM);
3537
3538 EXPECT_EQ(Expected, A1.getCategory())
3539 << formatv("({0:x} + {1:x}) * ({2:x} + {3:x})", Op1[0], Op1[1],
3540 Op2[0], Op2[1])
3541 .str();
3542 }
3543 {
3544 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1));
3545 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2));
3546 A2.multiply(A1, RM);
3547
3548 EXPECT_EQ(Expected, A2.getCategory())
3549 << formatv("({0:x} + {1:x}) * ({2:x} + {3:x})", Op2[0], Op2[1],
3550 Op1[0], Op1[1])
3551 .str();
3552 }
3553 }
3554}
3555
Tim Shen1594e062017-01-05 22:57:54 +00003556TEST(APFloatTest, PPCDoubleDoubleMultiply) {
3557 using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,
3558 uint64_t, APFloat::roundingMode>;
Tim Shen1594e062017-01-05 22:57:54 +00003559 DataType Data[] = {
3560 // 1/3 * 3 = 1.0
3561 std::make_tuple(0x3fd5555555555555ull, 0x3c75555555555556ull,
3562 0x4008000000000000ull, 0, 0x3ff0000000000000ull, 0,
3563 APFloat::rmNearestTiesToEven),
Tim Shen7f127622017-01-24 00:19:45 +00003564 // (1 + epsilon) * (1 + 0) = fcZero
3565 std::make_tuple(0x3ff0000000000000ull, 0x0000000000000001ull,
3566 0x3ff0000000000000ull, 0, 0x3ff0000000000000ull,
3567 0x0000000000000001ull, APFloat::rmNearestTiesToEven),
3568 // (1 + epsilon) * (1 + epsilon) = 1 + 2 * epsilon
3569 std::make_tuple(0x3ff0000000000000ull, 0x0000000000000001ull,
3570 0x3ff0000000000000ull, 0x0000000000000001ull,
3571 0x3ff0000000000000ull, 0x0000000000000002ull,
3572 APFloat::rmNearestTiesToEven),
3573 // -(1 + epsilon) * (1 + epsilon) = -1
3574 std::make_tuple(0xbff0000000000000ull, 0x0000000000000001ull,
3575 0x3ff0000000000000ull, 0x0000000000000001ull,
3576 0xbff0000000000000ull, 0, APFloat::rmNearestTiesToEven),
3577 // (0.5 + 0) * (1 + 2 * epsilon) = 0.5 + epsilon
3578 std::make_tuple(0x3fe0000000000000ull, 0, 0x3ff0000000000000ull,
3579 0x0000000000000002ull, 0x3fe0000000000000ull,
3580 0x0000000000000001ull, APFloat::rmNearestTiesToEven),
3581 // (0.5 + 0) * (1 + epsilon) = 0.5
3582 std::make_tuple(0x3fe0000000000000ull, 0, 0x3ff0000000000000ull,
3583 0x0000000000000001ull, 0x3fe0000000000000ull, 0,
3584 APFloat::rmNearestTiesToEven),
3585 // __LDBL_MAX__ * (1 + 1 << 106) = inf
3586 std::make_tuple(0x7fefffffffffffffull, 0x7c8ffffffffffffeull,
3587 0x3ff0000000000000ull, 0x3950000000000000ull,
3588 0x7ff0000000000000ull, 0, APFloat::rmNearestTiesToEven),
3589 // __LDBL_MAX__ * (1 + 1 << 107) > __LDBL_MAX__, but not inf, yes =_=|||
3590 std::make_tuple(0x7fefffffffffffffull, 0x7c8ffffffffffffeull,
3591 0x3ff0000000000000ull, 0x3940000000000000ull,
3592 0x7fefffffffffffffull, 0x7c8fffffffffffffull,
3593 APFloat::rmNearestTiesToEven),
3594 // __LDBL_MAX__ * (1 + 1 << 108) = __LDBL_MAX__
3595 std::make_tuple(0x7fefffffffffffffull, 0x7c8ffffffffffffeull,
3596 0x3ff0000000000000ull, 0x3930000000000000ull,
3597 0x7fefffffffffffffull, 0x7c8ffffffffffffeull,
3598 APFloat::rmNearestTiesToEven),
Tim Shen1594e062017-01-05 22:57:54 +00003599 };
3600
3601 for (auto Tp : Data) {
3602 uint64_t Op1[2], Op2[2], Expected[2];
3603 APFloat::roundingMode RM;
3604 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected[0], Expected[1], RM) = Tp;
3605
Tim Shen7f127622017-01-24 00:19:45 +00003606 {
3607 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1));
3608 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2));
3609 A1.multiply(A2, RM);
Tim Shen1594e062017-01-05 22:57:54 +00003610
Tim Shen7f127622017-01-24 00:19:45 +00003611 EXPECT_EQ(Expected[0], A1.bitcastToAPInt().getRawData()[0])
3612 << formatv("({0:x} + {1:x}) * ({2:x} + {3:x})", Op1[0], Op1[1],
3613 Op2[0], Op2[1])
3614 .str();
3615 EXPECT_EQ(Expected[1], A1.bitcastToAPInt().getRawData()[1])
3616 << formatv("({0:x} + {1:x}) * ({2:x} + {3:x})", Op1[0], Op1[1],
3617 Op2[0], Op2[1])
3618 .str();
3619 }
3620 {
3621 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1));
3622 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2));
3623 A2.multiply(A1, RM);
3624
3625 EXPECT_EQ(Expected[0], A2.bitcastToAPInt().getRawData()[0])
3626 << formatv("({0:x} + {1:x}) * ({2:x} + {3:x})", Op2[0], Op2[1],
3627 Op1[0], Op1[1])
3628 .str();
3629 EXPECT_EQ(Expected[1], A2.bitcastToAPInt().getRawData()[1])
3630 << formatv("({0:x} + {1:x}) * ({2:x} + {3:x})", Op2[0], Op2[1],
3631 Op1[0], Op1[1])
3632 .str();
3633 }
Tim Shen1594e062017-01-05 22:57:54 +00003634 }
3635}
3636
3637TEST(APFloatTest, PPCDoubleDoubleDivide) {
3638 using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,
3639 uint64_t, APFloat::roundingMode>;
3640 // TODO: Only a sanity check for now. Add more edge cases when the
3641 // double-double algorithm is implemented.
3642 DataType Data[] = {
3643 // 1 / 3 = 1/3
3644 std::make_tuple(0x3ff0000000000000ull, 0, 0x4008000000000000ull, 0,
3645 0x3fd5555555555555ull, 0x3c75555555555556ull,
3646 APFloat::rmNearestTiesToEven),
3647 };
3648
3649 for (auto Tp : Data) {
3650 uint64_t Op1[2], Op2[2], Expected[2];
3651 APFloat::roundingMode RM;
3652 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected[0], Expected[1], RM) = Tp;
3653
3654 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1));
3655 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2));
3656 A1.divide(A2, RM);
3657
3658 EXPECT_EQ(Expected[0], A1.bitcastToAPInt().getRawData()[0])
3659 << formatv("({0:x} + {1:x}) / ({2:x} + {3:x})", Op1[0], Op1[1], Op2[0],
3660 Op2[1])
3661 .str();
3662 EXPECT_EQ(Expected[1], A1.bitcastToAPInt().getRawData()[1])
3663 << formatv("({0:x} + {1:x}) / ({2:x} + {3:x})", Op1[0], Op1[1], Op2[0],
3664 Op2[1])
3665 .str();
3666 }
3667}
3668
3669TEST(APFloatTest, PPCDoubleDoubleRemainder) {
3670 using DataType =
3671 std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t>;
3672 DataType Data[] = {
3673 // remainder(3.0 + 3.0 << 53, 1.25 + 1.25 << 53) = (0.5 + 0.5 << 53)
3674 std::make_tuple(0x4008000000000000ull, 0x3cb8000000000000ull,
3675 0x3ff4000000000000ull, 0x3ca4000000000000ull,
3676 0x3fe0000000000000ull, 0x3c90000000000000ull),
3677 // remainder(3.0 + 3.0 << 53, 1.75 + 1.75 << 53) = (-0.5 - 0.5 << 53)
3678 std::make_tuple(0x4008000000000000ull, 0x3cb8000000000000ull,
3679 0x3ffc000000000000ull, 0x3cac000000000000ull,
3680 0xbfe0000000000000ull, 0xbc90000000000000ull),
3681 };
3682
3683 for (auto Tp : Data) {
3684 uint64_t Op1[2], Op2[2], Expected[2];
3685 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected[0], Expected[1]) = Tp;
3686
3687 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1));
3688 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2));
3689 A1.remainder(A2);
3690
3691 EXPECT_EQ(Expected[0], A1.bitcastToAPInt().getRawData()[0])
3692 << formatv("remainder({0:x} + {1:x}), ({2:x} + {3:x}))", Op1[0], Op1[1],
3693 Op2[0], Op2[1])
3694 .str();
3695 EXPECT_EQ(Expected[1], A1.bitcastToAPInt().getRawData()[1])
3696 << formatv("remainder(({0:x} + {1:x}), ({2:x} + {3:x}))", Op1[0],
3697 Op1[1], Op2[0], Op2[1])
3698 .str();
3699 }
3700}
3701
3702TEST(APFloatTest, PPCDoubleDoubleMod) {
3703 using DataType =
3704 std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t>;
3705 DataType Data[] = {
3706 // mod(3.0 + 3.0 << 53, 1.25 + 1.25 << 53) = (0.5 + 0.5 << 53)
3707 std::make_tuple(0x4008000000000000ull, 0x3cb8000000000000ull,
3708 0x3ff4000000000000ull, 0x3ca4000000000000ull,
3709 0x3fe0000000000000ull, 0x3c90000000000000ull),
3710 // mod(3.0 + 3.0 << 53, 1.75 + 1.75 << 53) = (1.25 + 1.25 << 53)
3711 // 0xbc98000000000000 doesn't seem right, but it's what we currently have.
3712 // TODO: investigate
3713 std::make_tuple(0x4008000000000000ull, 0x3cb8000000000000ull,
3714 0x3ffc000000000000ull, 0x3cac000000000000ull,
3715 0x3ff4000000000001ull, 0xbc98000000000000ull),
3716 };
3717
3718 for (auto Tp : Data) {
3719 uint64_t Op1[2], Op2[2], Expected[2];
3720 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected[0], Expected[1]) = Tp;
3721
3722 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1));
3723 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2));
3724 A1.mod(A2);
3725
3726 EXPECT_EQ(Expected[0], A1.bitcastToAPInt().getRawData()[0])
3727 << formatv("fmod(({0:x} + {1:x}), ({2:x} + {3:x}))", Op1[0], Op1[1],
3728 Op2[0], Op2[1])
3729 .str();
3730 EXPECT_EQ(Expected[1], A1.bitcastToAPInt().getRawData()[1])
3731 << formatv("fmod(({0:x} + {1:x}), ({2:x} + {3:x}))", Op1[0], Op1[1],
3732 Op2[0], Op2[1])
3733 .str();
3734 }
3735}
3736
3737TEST(APFloatTest, PPCDoubleDoubleFMA) {
3738 // Sanity check for now.
3739 APFloat A(APFloat::PPCDoubleDouble(), "2");
3740 A.fusedMultiplyAdd(APFloat(APFloat::PPCDoubleDouble(), "3"),
3741 APFloat(APFloat::PPCDoubleDouble(), "4"),
3742 APFloat::rmNearestTiesToEven);
3743 EXPECT_EQ(APFloat::cmpEqual,
3744 APFloat(APFloat::PPCDoubleDouble(), "10").compare(A));
3745}
3746
3747TEST(APFloatTest, PPCDoubleDoubleRoundToIntegral) {
3748 {
3749 APFloat A(APFloat::PPCDoubleDouble(), "1.5");
3750 A.roundToIntegral(APFloat::rmNearestTiesToEven);
3751 EXPECT_EQ(APFloat::cmpEqual,
3752 APFloat(APFloat::PPCDoubleDouble(), "2").compare(A));
3753 }
3754 {
3755 APFloat A(APFloat::PPCDoubleDouble(), "2.5");
3756 A.roundToIntegral(APFloat::rmNearestTiesToEven);
3757 EXPECT_EQ(APFloat::cmpEqual,
3758 APFloat(APFloat::PPCDoubleDouble(), "2").compare(A));
3759 }
3760}
3761
3762TEST(APFloatTest, PPCDoubleDoubleCompare) {
3763 using DataType =
3764 std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, APFloat::cmpResult>;
3765
3766 DataType Data[] = {
3767 // (1 + 0) = (1 + 0)
3768 std::make_tuple(0x3ff0000000000000ull, 0, 0x3ff0000000000000ull, 0,
3769 APFloat::cmpEqual),
3770 // (1 + 0) < (1.00...1 + 0)
3771 std::make_tuple(0x3ff0000000000000ull, 0, 0x3ff0000000000001ull, 0,
3772 APFloat::cmpLessThan),
3773 // (1.00...1 + 0) > (1 + 0)
3774 std::make_tuple(0x3ff0000000000001ull, 0, 0x3ff0000000000000ull, 0,
3775 APFloat::cmpGreaterThan),
3776 // (1 + 0) < (1 + epsilon)
3777 std::make_tuple(0x3ff0000000000000ull, 0, 0x3ff0000000000001ull,
3778 0x0000000000000001ull, APFloat::cmpLessThan),
3779 // NaN != NaN
3780 std::make_tuple(0x7ff8000000000000ull, 0, 0x7ff8000000000000ull, 0,
3781 APFloat::cmpUnordered),
3782 // (1 + 0) != NaN
3783 std::make_tuple(0x3ff0000000000000ull, 0, 0x7ff8000000000000ull, 0,
3784 APFloat::cmpUnordered),
3785 // Inf = Inf
3786 std::make_tuple(0x7ff0000000000000ull, 0, 0x7ff0000000000000ull, 0,
3787 APFloat::cmpEqual),
3788 };
3789
3790 for (auto Tp : Data) {
3791 uint64_t Op1[2], Op2[2];
3792 APFloat::cmpResult Expected;
3793 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected) = Tp;
3794
3795 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1));
3796 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2));
3797 EXPECT_EQ(Expected, A1.compare(A2))
Tim Shenfd1e5aa2017-01-23 22:39:35 +00003798 << formatv("compare(({0:x} + {1:x}), ({2:x} + {3:x}))", Op1[0], Op1[1],
3799 Op2[0], Op2[1])
3800 .str();
3801 }
3802}
3803
3804TEST(APFloatTest, PPCDoubleDoubleBitwiseIsEqual) {
3805 using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, bool>;
3806
3807 DataType Data[] = {
3808 // (1 + 0) = (1 + 0)
3809 std::make_tuple(0x3ff0000000000000ull, 0, 0x3ff0000000000000ull, 0, true),
3810 // (1 + 0) != (1.00...1 + 0)
3811 std::make_tuple(0x3ff0000000000000ull, 0, 0x3ff0000000000001ull, 0,
3812 false),
3813 // NaN = NaN
3814 std::make_tuple(0x7ff8000000000000ull, 0, 0x7ff8000000000000ull, 0, true),
3815 // NaN != NaN with a different bit pattern
3816 std::make_tuple(0x7ff8000000000000ull, 0, 0x7ff8000000000000ull,
3817 0x3ff0000000000000ull, false),
3818 // Inf = Inf
3819 std::make_tuple(0x7ff0000000000000ull, 0, 0x7ff0000000000000ull, 0, true),
3820 };
3821
3822 for (auto Tp : Data) {
3823 uint64_t Op1[2], Op2[2];
3824 bool Expected;
3825 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected) = Tp;
3826
3827 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, 2, Op1));
3828 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, 2, Op2));
3829 EXPECT_EQ(Expected, A1.bitwiseIsEqual(A2))
3830 << formatv("({0:x} + {1:x}) = ({2:x} + {3:x})", Op1[0], Op1[1], Op2[0],
Tim Shen1594e062017-01-05 22:57:54 +00003831 Op2[1])
3832 .str();
3833 }
3834}
3835
Tim Shenfd1e5aa2017-01-23 22:39:35 +00003836TEST(APFloatTest, PPCDoubleDoubleHashValue) {
3837 uint64_t Data1[] = {0x3ff0000000000001ull, 0x0000000000000001ull};
3838 uint64_t Data2[] = {0x3ff0000000000001ull, 0};
3839 // The hash values are *hopefully* different.
3840 EXPECT_NE(
3841 hash_value(APFloat(APFloat::PPCDoubleDouble(), APInt(128, 2, Data1))),
3842 hash_value(APFloat(APFloat::PPCDoubleDouble(), APInt(128, 2, Data2))));
3843}
3844
Tim Shen1594e062017-01-05 22:57:54 +00003845TEST(APFloatTest, PPCDoubleDoubleChangeSign) {
3846 uint64_t Data[] = {
3847 0x400f000000000000ull, 0xbcb0000000000000ull,
3848 };
3849 APFloat Float(APFloat::PPCDoubleDouble(), APInt(128, 2, Data));
3850 {
3851 APFloat Actual =
3852 APFloat::copySign(Float, APFloat(APFloat::IEEEdouble(), "1"));
3853 EXPECT_EQ(0x400f000000000000ull, Actual.bitcastToAPInt().getRawData()[0]);
3854 EXPECT_EQ(0xbcb0000000000000ull, Actual.bitcastToAPInt().getRawData()[1]);
3855 }
3856 {
3857 APFloat Actual =
3858 APFloat::copySign(Float, APFloat(APFloat::IEEEdouble(), "-1"));
3859 EXPECT_EQ(0xc00f000000000000ull, Actual.bitcastToAPInt().getRawData()[0]);
3860 EXPECT_EQ(0x3cb0000000000000ull, Actual.bitcastToAPInt().getRawData()[1]);
3861 }
3862}
3863
3864TEST(APFloatTest, PPCDoubleDoubleFactories) {
3865 {
3866 uint64_t Data[] = {
3867 0, 0,
3868 };
3869 EXPECT_EQ(APInt(128, 2, Data),
3870 APFloat::getZero(APFloat::PPCDoubleDouble()).bitcastToAPInt());
3871 }
3872 {
3873 uint64_t Data[] = {
Tim Shenfd1e5aa2017-01-23 22:39:35 +00003874 0x7fefffffffffffffull, 0x7c8ffffffffffffeull,
3875 };
3876 EXPECT_EQ(APInt(128, 2, Data),
3877 APFloat::getLargest(APFloat::PPCDoubleDouble()).bitcastToAPInt());
3878 }
3879 {
3880 uint64_t Data[] = {
Tim Shen1594e062017-01-05 22:57:54 +00003881 0x0000000000000001ull, 0,
3882 };
3883 EXPECT_EQ(
3884 APInt(128, 2, Data),
3885 APFloat::getSmallest(APFloat::PPCDoubleDouble()).bitcastToAPInt());
3886 }
3887 {
3888 uint64_t Data[] = {0x0360000000000000ull, 0};
3889 EXPECT_EQ(APInt(128, 2, Data),
3890 APFloat::getSmallestNormalized(APFloat::PPCDoubleDouble())
3891 .bitcastToAPInt());
3892 }
3893 {
3894 uint64_t Data[] = {
3895 0x8000000000000000ull, 0x0000000000000000ull,
3896 };
3897 EXPECT_EQ(
3898 APInt(128, 2, Data),
3899 APFloat::getZero(APFloat::PPCDoubleDouble(), true).bitcastToAPInt());
3900 }
3901 {
3902 uint64_t Data[] = {
Tim Shenfd1e5aa2017-01-23 22:39:35 +00003903 0xffefffffffffffffull, 0xfc8ffffffffffffeull,
3904 };
3905 EXPECT_EQ(
3906 APInt(128, 2, Data),
3907 APFloat::getLargest(APFloat::PPCDoubleDouble(), true).bitcastToAPInt());
3908 }
3909 {
3910 uint64_t Data[] = {
Tim Shen1594e062017-01-05 22:57:54 +00003911 0x8000000000000001ull, 0x0000000000000000ull,
3912 };
3913 EXPECT_EQ(APInt(128, 2, Data),
3914 APFloat::getSmallest(APFloat::PPCDoubleDouble(), true)
3915 .bitcastToAPInt());
3916 }
Tim Shenfd1e5aa2017-01-23 22:39:35 +00003917 {
3918 uint64_t Data[] = {
3919 0x8360000000000000ull, 0x0000000000000000ull,
3920 };
3921 EXPECT_EQ(APInt(128, 2, Data),
3922 APFloat::getSmallestNormalized(APFloat::PPCDoubleDouble(), true)
3923 .bitcastToAPInt());
3924 }
Tim Shen1594e062017-01-05 22:57:54 +00003925 EXPECT_TRUE(APFloat::getSmallest(APFloat::PPCDoubleDouble()).isSmallest());
3926 EXPECT_TRUE(APFloat::getLargest(APFloat::PPCDoubleDouble()).isLargest());
3927}
Tim Shenfd1e5aa2017-01-23 22:39:35 +00003928
3929TEST(APFloatTest, PPCDoubleDoubleIsDenormal) {
3930 EXPECT_TRUE(APFloat::getSmallest(APFloat::PPCDoubleDouble()).isDenormal());
3931 EXPECT_FALSE(APFloat::getLargest(APFloat::PPCDoubleDouble()).isDenormal());
3932 EXPECT_FALSE(
3933 APFloat::getSmallestNormalized(APFloat::PPCDoubleDouble()).isDenormal());
3934 {
3935 // (4 + 3) is not normalized
3936 uint64_t Data[] = {
3937 0x4010000000000000ull, 0x4008000000000000ull,
3938 };
3939 EXPECT_TRUE(
3940 APFloat(APFloat::PPCDoubleDouble(), APInt(128, 2, Data)).isDenormal());
3941 }
3942}
3943
3944TEST(APFloatTest, PPCDoubleDoubleScalbn) {
3945 // 3.0 + 3.0 << 53
3946 uint64_t Input[] = {
3947 0x4008000000000000ull, 0x3cb8000000000000ull,
3948 };
3949 APFloat Result =
3950 scalbn(APFloat(APFloat::PPCDoubleDouble(), APInt(128, 2, Input)), 1,
3951 APFloat::rmNearestTiesToEven);
3952 // 6.0 + 6.0 << 53
3953 EXPECT_EQ(0x4018000000000000ull, Result.bitcastToAPInt().getRawData()[0]);
3954 EXPECT_EQ(0x3cc8000000000000ull, Result.bitcastToAPInt().getRawData()[1]);
3955}
3956
3957TEST(APFloatTest, PPCDoubleDoubleFrexp) {
3958 // 3.0 + 3.0 << 53
3959 uint64_t Input[] = {
3960 0x4008000000000000ull, 0x3cb8000000000000ull,
3961 };
3962 int Exp;
3963 // 0.75 + 0.75 << 53
3964 APFloat Result =
3965 frexp(APFloat(APFloat::PPCDoubleDouble(), APInt(128, 2, Input)), Exp,
3966 APFloat::rmNearestTiesToEven);
3967 EXPECT_EQ(2, Exp);
3968 EXPECT_EQ(0x3fe8000000000000ull, Result.bitcastToAPInt().getRawData()[0]);
3969 EXPECT_EQ(0x3c98000000000000ull, Result.bitcastToAPInt().getRawData()[1]);
3970}
Erick Tryzelaar19f63b22009-08-16 23:36:19 +00003971}