blob: 1b1d616f99feb0e6a2e2c22bea8bdb8cf3f30a89 [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"
John McCall29b5c282009-12-24 08:56:26 +000012#include "llvm/ADT/SmallVector.h"
Chandler Carruth130cec22012-12-04 10:23:08 +000013#include "llvm/Support/raw_ostream.h"
14#include "gtest/gtest.h"
Benjamin Kramer37dce442015-03-09 18:35:18 +000015#include <cmath>
Chandler Carruth130cec22012-12-04 10:23:08 +000016#include <ostream>
17#include <string>
Tim Shen18e7ae62016-12-12 22:16:08 +000018#include <tuple>
Erick Tryzelaar19f63b22009-08-16 23:36:19 +000019
20using namespace llvm;
21
Daniel Dunbarbc52e4f2009-09-03 22:57:02 +000022static double convertToDoubleFromString(const char *Str) {
23 llvm::APFloat F(0.0);
24 F.convertFromString(Str, llvm::APFloat::rmNearestTiesToEven);
25 return F.convertToDouble();
26}
27
John McCall29b5c282009-12-24 08:56:26 +000028static std::string convertToString(double d, unsigned Prec, unsigned Pad) {
29 llvm::SmallVector<char, 100> Buffer;
30 llvm::APFloat F(d);
31 F.toString(Buffer, Prec, Pad);
32 return std::string(Buffer.data(), Buffer.size());
33}
34
Erick Tryzelaar19f63b22009-08-16 23:36:19 +000035namespace {
36
Michael Gottesman0c622ea2013-05-30 18:07:13 +000037TEST(APFloatTest, isSignaling) {
38 // We test qNaN, -qNaN, +sNaN, -sNaN with and without payloads. *NOTE* The
39 // positive/negative distinction is included only since the getQNaN/getSNaN
40 // API provides the option.
41 APInt payload = APInt::getOneBitSet(4, 2);
Stephan Bergmann17c7f702016-12-14 11:57:17 +000042 EXPECT_FALSE(APFloat::getQNaN(APFloat::IEEEsingle(), false).isSignaling());
43 EXPECT_FALSE(APFloat::getQNaN(APFloat::IEEEsingle(), true).isSignaling());
44 EXPECT_FALSE(APFloat::getQNaN(APFloat::IEEEsingle(), false, &payload).isSignaling());
45 EXPECT_FALSE(APFloat::getQNaN(APFloat::IEEEsingle(), true, &payload).isSignaling());
46 EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isSignaling());
47 EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle(), true).isSignaling());
48 EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle(), false, &payload).isSignaling());
49 EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle(), true, &payload).isSignaling());
Michael Gottesman0c622ea2013-05-30 18:07:13 +000050}
51
52TEST(APFloatTest, next) {
53
Stephan Bergmann17c7f702016-12-14 11:57:17 +000054 APFloat test(APFloat::IEEEquad(), APFloat::uninitialized);
55 APFloat expected(APFloat::IEEEquad(), APFloat::uninitialized);
Michael Gottesman0c622ea2013-05-30 18:07:13 +000056
57 // 1. Test Special Cases Values.
58 //
59 // Test all special values for nextUp and nextDown perscribed by IEEE-754R
60 // 2008. These are:
61 // 1. +inf
62 // 2. -inf
63 // 3. getLargest()
64 // 4. -getLargest()
65 // 5. getSmallest()
66 // 6. -getSmallest()
67 // 7. qNaN
68 // 8. sNaN
69 // 9. +0
70 // 10. -0
71
72 // nextUp(+inf) = +inf.
Stephan Bergmann17c7f702016-12-14 11:57:17 +000073 test = APFloat::getInf(APFloat::IEEEquad(), false);
74 expected = APFloat::getInf(APFloat::IEEEquad(), false);
Michael Gottesman0c622ea2013-05-30 18:07:13 +000075 EXPECT_EQ(test.next(false), APFloat::opOK);
76 EXPECT_TRUE(test.isInfinity());
77 EXPECT_TRUE(!test.isNegative());
78 EXPECT_TRUE(test.bitwiseIsEqual(expected));
79
80 // nextDown(+inf) = -nextUp(-inf) = -(-getLargest()) = getLargest()
Stephan Bergmann17c7f702016-12-14 11:57:17 +000081 test = APFloat::getInf(APFloat::IEEEquad(), false);
82 expected = APFloat::getLargest(APFloat::IEEEquad(), false);
Michael Gottesman0c622ea2013-05-30 18:07:13 +000083 EXPECT_EQ(test.next(true), APFloat::opOK);
84 EXPECT_TRUE(!test.isNegative());
85 EXPECT_TRUE(test.bitwiseIsEqual(expected));
86
87 // nextUp(-inf) = -getLargest()
Stephan Bergmann17c7f702016-12-14 11:57:17 +000088 test = APFloat::getInf(APFloat::IEEEquad(), true);
89 expected = APFloat::getLargest(APFloat::IEEEquad(), true);
Michael Gottesman0c622ea2013-05-30 18:07:13 +000090 EXPECT_EQ(test.next(false), APFloat::opOK);
91 EXPECT_TRUE(test.isNegative());
92 EXPECT_TRUE(test.bitwiseIsEqual(expected));
93
94 // nextDown(-inf) = -nextUp(+inf) = -(+inf) = -inf.
Stephan Bergmann17c7f702016-12-14 11:57:17 +000095 test = APFloat::getInf(APFloat::IEEEquad(), true);
96 expected = APFloat::getInf(APFloat::IEEEquad(), true);
Michael Gottesman0c622ea2013-05-30 18:07:13 +000097 EXPECT_EQ(test.next(true), APFloat::opOK);
98 EXPECT_TRUE(test.isInfinity() && test.isNegative());
99 EXPECT_TRUE(test.bitwiseIsEqual(expected));
100
101 // nextUp(getLargest()) = +inf
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000102 test = APFloat::getLargest(APFloat::IEEEquad(), false);
103 expected = APFloat::getInf(APFloat::IEEEquad(), false);
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000104 EXPECT_EQ(test.next(false), APFloat::opOK);
105 EXPECT_TRUE(test.isInfinity() && !test.isNegative());
106 EXPECT_TRUE(test.bitwiseIsEqual(expected));
107
108 // nextDown(getLargest()) = -nextUp(-getLargest())
109 // = -(-getLargest() + inc)
110 // = getLargest() - inc.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000111 test = APFloat::getLargest(APFloat::IEEEquad(), false);
112 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000113 "0x1.fffffffffffffffffffffffffffep+16383");
114 EXPECT_EQ(test.next(true), APFloat::opOK);
115 EXPECT_TRUE(!test.isInfinity() && !test.isNegative());
116 EXPECT_TRUE(test.bitwiseIsEqual(expected));
117
118 // nextUp(-getLargest()) = -getLargest() + inc.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000119 test = APFloat::getLargest(APFloat::IEEEquad(), true);
120 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000121 "-0x1.fffffffffffffffffffffffffffep+16383");
122 EXPECT_EQ(test.next(false), APFloat::opOK);
123 EXPECT_TRUE(test.bitwiseIsEqual(expected));
124
125 // nextDown(-getLargest()) = -nextUp(getLargest()) = -(inf) = -inf.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000126 test = APFloat::getLargest(APFloat::IEEEquad(), true);
127 expected = APFloat::getInf(APFloat::IEEEquad(), true);
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000128 EXPECT_EQ(test.next(true), APFloat::opOK);
129 EXPECT_TRUE(test.isInfinity() && test.isNegative());
130 EXPECT_TRUE(test.bitwiseIsEqual(expected));
131
132 // nextUp(getSmallest()) = getSmallest() + inc.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000133 test = APFloat(APFloat::IEEEquad(), "0x0.0000000000000000000000000001p-16382");
134 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000135 "0x0.0000000000000000000000000002p-16382");
136 EXPECT_EQ(test.next(false), APFloat::opOK);
137 EXPECT_TRUE(test.bitwiseIsEqual(expected));
138
139 // nextDown(getSmallest()) = -nextUp(-getSmallest()) = -(-0) = +0.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000140 test = APFloat(APFloat::IEEEquad(), "0x0.0000000000000000000000000001p-16382");
141 expected = APFloat::getZero(APFloat::IEEEquad(), false);
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000142 EXPECT_EQ(test.next(true), APFloat::opOK);
Matt Arsenaultafa31cf2016-03-13 05:11:51 +0000143 EXPECT_TRUE(test.isPosZero());
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000144 EXPECT_TRUE(test.bitwiseIsEqual(expected));
145
146 // nextUp(-getSmallest()) = -0.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000147 test = APFloat(APFloat::IEEEquad(), "-0x0.0000000000000000000000000001p-16382");
148 expected = APFloat::getZero(APFloat::IEEEquad(), true);
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000149 EXPECT_EQ(test.next(false), APFloat::opOK);
Matt Arsenaultafa31cf2016-03-13 05:11:51 +0000150 EXPECT_TRUE(test.isNegZero());
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000151 EXPECT_TRUE(test.bitwiseIsEqual(expected));
152
153 // nextDown(-getSmallest()) = -nextUp(getSmallest()) = -getSmallest() - inc.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000154 test = APFloat(APFloat::IEEEquad(), "-0x0.0000000000000000000000000001p-16382");
155 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000156 "-0x0.0000000000000000000000000002p-16382");
157 EXPECT_EQ(test.next(true), APFloat::opOK);
158 EXPECT_TRUE(test.bitwiseIsEqual(expected));
159
160 // nextUp(qNaN) = qNaN
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000161 test = APFloat::getQNaN(APFloat::IEEEquad(), false);
162 expected = APFloat::getQNaN(APFloat::IEEEquad(), false);
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000163 EXPECT_EQ(test.next(false), APFloat::opOK);
164 EXPECT_TRUE(test.bitwiseIsEqual(expected));
165
166 // nextDown(qNaN) = qNaN
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000167 test = APFloat::getQNaN(APFloat::IEEEquad(), false);
168 expected = APFloat::getQNaN(APFloat::IEEEquad(), false);
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000169 EXPECT_EQ(test.next(true), APFloat::opOK);
170 EXPECT_TRUE(test.bitwiseIsEqual(expected));
171
172 // nextUp(sNaN) = qNaN
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000173 test = APFloat::getSNaN(APFloat::IEEEquad(), false);
174 expected = APFloat::getQNaN(APFloat::IEEEquad(), false);
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000175 EXPECT_EQ(test.next(false), APFloat::opInvalidOp);
176 EXPECT_TRUE(test.bitwiseIsEqual(expected));
177
178 // nextDown(sNaN) = qNaN
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000179 test = APFloat::getSNaN(APFloat::IEEEquad(), false);
180 expected = APFloat::getQNaN(APFloat::IEEEquad(), false);
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000181 EXPECT_EQ(test.next(true), APFloat::opInvalidOp);
182 EXPECT_TRUE(test.bitwiseIsEqual(expected));
183
184 // nextUp(+0) = +getSmallest()
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000185 test = APFloat::getZero(APFloat::IEEEquad(), false);
186 expected = APFloat::getSmallest(APFloat::IEEEquad(), false);
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000187 EXPECT_EQ(test.next(false), APFloat::opOK);
188 EXPECT_TRUE(test.bitwiseIsEqual(expected));
189
190 // nextDown(+0) = -nextUp(-0) = -getSmallest()
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000191 test = APFloat::getZero(APFloat::IEEEquad(), false);
192 expected = APFloat::getSmallest(APFloat::IEEEquad(), true);
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000193 EXPECT_EQ(test.next(true), APFloat::opOK);
194 EXPECT_TRUE(test.bitwiseIsEqual(expected));
195
196 // nextUp(-0) = +getSmallest()
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000197 test = APFloat::getZero(APFloat::IEEEquad(), true);
198 expected = APFloat::getSmallest(APFloat::IEEEquad(), false);
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000199 EXPECT_EQ(test.next(false), APFloat::opOK);
200 EXPECT_TRUE(test.bitwiseIsEqual(expected));
201
202 // nextDown(-0) = -nextUp(0) = -getSmallest()
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000203 test = APFloat::getZero(APFloat::IEEEquad(), true);
204 expected = APFloat::getSmallest(APFloat::IEEEquad(), true);
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000205 EXPECT_EQ(test.next(true), APFloat::opOK);
206 EXPECT_TRUE(test.bitwiseIsEqual(expected));
207
208 // 2. Binade Boundary Tests.
209
210 // 2a. Test denormal <-> normal binade boundaries.
211 // * nextUp(+Largest Denormal) -> +Smallest Normal.
212 // * nextDown(-Largest Denormal) -> -Smallest Normal.
213 // * nextUp(-Smallest Normal) -> -Largest Denormal.
214 // * nextDown(+Smallest Normal) -> +Largest Denormal.
215
216 // nextUp(+Largest Denormal) -> +Smallest Normal.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000217 test = APFloat(APFloat::IEEEquad(), "0x0.ffffffffffffffffffffffffffffp-16382");
218 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000219 "0x1.0000000000000000000000000000p-16382");
220 EXPECT_EQ(test.next(false), APFloat::opOK);
221 EXPECT_FALSE(test.isDenormal());
222 EXPECT_TRUE(test.bitwiseIsEqual(expected));
223
224 // nextDown(-Largest Denormal) -> -Smallest Normal.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000225 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000226 "-0x0.ffffffffffffffffffffffffffffp-16382");
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000227 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000228 "-0x1.0000000000000000000000000000p-16382");
229 EXPECT_EQ(test.next(true), APFloat::opOK);
230 EXPECT_FALSE(test.isDenormal());
231 EXPECT_TRUE(test.bitwiseIsEqual(expected));
232
233 // nextUp(-Smallest Normal) -> -LargestDenormal.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000234 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000235 "-0x1.0000000000000000000000000000p-16382");
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000236 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000237 "-0x0.ffffffffffffffffffffffffffffp-16382");
238 EXPECT_EQ(test.next(false), APFloat::opOK);
239 EXPECT_TRUE(test.isDenormal());
240 EXPECT_TRUE(test.bitwiseIsEqual(expected));
241
242 // nextDown(+Smallest Normal) -> +Largest Denormal.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000243 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000244 "+0x1.0000000000000000000000000000p-16382");
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000245 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000246 "+0x0.ffffffffffffffffffffffffffffp-16382");
247 EXPECT_EQ(test.next(true), APFloat::opOK);
248 EXPECT_TRUE(test.isDenormal());
249 EXPECT_TRUE(test.bitwiseIsEqual(expected));
250
251 // 2b. Test normal <-> normal binade boundaries.
252 // * nextUp(-Normal Binade Boundary) -> -Normal Binade Boundary + 1.
253 // * nextDown(+Normal Binade Boundary) -> +Normal Binade Boundary - 1.
254 // * nextUp(+Normal Binade Boundary - 1) -> +Normal Binade Boundary.
255 // * nextDown(-Normal Binade Boundary + 1) -> -Normal Binade Boundary.
256
257 // nextUp(-Normal Binade Boundary) -> -Normal Binade Boundary + 1.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000258 test = APFloat(APFloat::IEEEquad(), "-0x1p+1");
259 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000260 "-0x1.ffffffffffffffffffffffffffffp+0");
261 EXPECT_EQ(test.next(false), APFloat::opOK);
262 EXPECT_TRUE(test.bitwiseIsEqual(expected));
263
264 // nextDown(+Normal Binade Boundary) -> +Normal Binade Boundary - 1.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000265 test = APFloat(APFloat::IEEEquad(), "0x1p+1");
266 expected = APFloat(APFloat::IEEEquad(), "0x1.ffffffffffffffffffffffffffffp+0");
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000267 EXPECT_EQ(test.next(true), APFloat::opOK);
268 EXPECT_TRUE(test.bitwiseIsEqual(expected));
269
270 // nextUp(+Normal Binade Boundary - 1) -> +Normal Binade Boundary.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000271 test = APFloat(APFloat::IEEEquad(), "0x1.ffffffffffffffffffffffffffffp+0");
272 expected = APFloat(APFloat::IEEEquad(), "0x1p+1");
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000273 EXPECT_EQ(test.next(false), APFloat::opOK);
274 EXPECT_TRUE(test.bitwiseIsEqual(expected));
275
276 // nextDown(-Normal Binade Boundary + 1) -> -Normal Binade Boundary.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000277 test = APFloat(APFloat::IEEEquad(), "-0x1.ffffffffffffffffffffffffffffp+0");
278 expected = APFloat(APFloat::IEEEquad(), "-0x1p+1");
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000279 EXPECT_EQ(test.next(true), APFloat::opOK);
280 EXPECT_TRUE(test.bitwiseIsEqual(expected));
281
282 // 2c. Test using next at binade boundaries with a direction away from the
283 // binade boundary. Away from denormal <-> normal boundaries.
284 //
285 // This is to make sure that even though we are at a binade boundary, since
286 // we are rounding away, we do not trigger the binade boundary code. Thus we
287 // test:
288 // * nextUp(-Largest Denormal) -> -Largest Denormal + inc.
289 // * nextDown(+Largest Denormal) -> +Largest Denormal - inc.
290 // * nextUp(+Smallest Normal) -> +Smallest Normal + inc.
291 // * nextDown(-Smallest Normal) -> -Smallest Normal - inc.
292
293 // nextUp(-Largest Denormal) -> -Largest Denormal + inc.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000294 test = APFloat(APFloat::IEEEquad(), "-0x0.ffffffffffffffffffffffffffffp-16382");
295 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000296 "-0x0.fffffffffffffffffffffffffffep-16382");
297 EXPECT_EQ(test.next(false), APFloat::opOK);
298 EXPECT_TRUE(test.isDenormal());
299 EXPECT_TRUE(test.isNegative());
300 EXPECT_TRUE(test.bitwiseIsEqual(expected));
301
302 // nextDown(+Largest Denormal) -> +Largest Denormal - inc.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000303 test = APFloat(APFloat::IEEEquad(), "0x0.ffffffffffffffffffffffffffffp-16382");
304 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000305 "0x0.fffffffffffffffffffffffffffep-16382");
306 EXPECT_EQ(test.next(true), APFloat::opOK);
307 EXPECT_TRUE(test.isDenormal());
308 EXPECT_TRUE(!test.isNegative());
309 EXPECT_TRUE(test.bitwiseIsEqual(expected));
310
311 // nextUp(+Smallest Normal) -> +Smallest Normal + inc.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000312 test = APFloat(APFloat::IEEEquad(), "0x1.0000000000000000000000000000p-16382");
313 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000314 "0x1.0000000000000000000000000001p-16382");
315 EXPECT_EQ(test.next(false), APFloat::opOK);
316 EXPECT_TRUE(!test.isDenormal());
317 EXPECT_TRUE(!test.isNegative());
318 EXPECT_TRUE(test.bitwiseIsEqual(expected));
319
320 // nextDown(-Smallest Normal) -> -Smallest Normal - inc.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000321 test = APFloat(APFloat::IEEEquad(), "-0x1.0000000000000000000000000000p-16382");
322 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000323 "-0x1.0000000000000000000000000001p-16382");
324 EXPECT_EQ(test.next(true), APFloat::opOK);
325 EXPECT_TRUE(!test.isDenormal());
326 EXPECT_TRUE(test.isNegative());
327 EXPECT_TRUE(test.bitwiseIsEqual(expected));
328
329 // 2d. Test values which cause our exponent to go to min exponent. This
330 // is to ensure that guards in the code to check for min exponent
331 // trigger properly.
332 // * nextUp(-0x1p-16381) -> -0x1.ffffffffffffffffffffffffffffp-16382
333 // * nextDown(-0x1.ffffffffffffffffffffffffffffp-16382) ->
334 // -0x1p-16381
335 // * nextUp(0x1.ffffffffffffffffffffffffffffp-16382) -> 0x1p-16382
336 // * nextDown(0x1p-16382) -> 0x1.ffffffffffffffffffffffffffffp-16382
337
338 // nextUp(-0x1p-16381) -> -0x1.ffffffffffffffffffffffffffffp-16382
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000339 test = APFloat(APFloat::IEEEquad(), "-0x1p-16381");
340 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000341 "-0x1.ffffffffffffffffffffffffffffp-16382");
342 EXPECT_EQ(test.next(false), APFloat::opOK);
343 EXPECT_TRUE(test.bitwiseIsEqual(expected));
344
345 // nextDown(-0x1.ffffffffffffffffffffffffffffp-16382) ->
346 // -0x1p-16381
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000347 test = APFloat(APFloat::IEEEquad(), "-0x1.ffffffffffffffffffffffffffffp-16382");
348 expected = APFloat(APFloat::IEEEquad(), "-0x1p-16381");
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000349 EXPECT_EQ(test.next(true), APFloat::opOK);
350 EXPECT_TRUE(test.bitwiseIsEqual(expected));
351
352 // nextUp(0x1.ffffffffffffffffffffffffffffp-16382) -> 0x1p-16381
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000353 test = APFloat(APFloat::IEEEquad(), "0x1.ffffffffffffffffffffffffffffp-16382");
354 expected = APFloat(APFloat::IEEEquad(), "0x1p-16381");
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000355 EXPECT_EQ(test.next(false), APFloat::opOK);
356 EXPECT_TRUE(test.bitwiseIsEqual(expected));
357
358 // nextDown(0x1p-16381) -> 0x1.ffffffffffffffffffffffffffffp-16382
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000359 test = APFloat(APFloat::IEEEquad(), "0x1p-16381");
360 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000361 "0x1.ffffffffffffffffffffffffffffp-16382");
362 EXPECT_EQ(test.next(true), APFloat::opOK);
363 EXPECT_TRUE(test.bitwiseIsEqual(expected));
364
365 // 3. Now we test both denormal/normal computation which will not cause us
366 // to go across binade boundaries. Specifically we test:
367 // * nextUp(+Denormal) -> +Denormal.
368 // * nextDown(+Denormal) -> +Denormal.
369 // * nextUp(-Denormal) -> -Denormal.
370 // * nextDown(-Denormal) -> -Denormal.
371 // * nextUp(+Normal) -> +Normal.
372 // * nextDown(+Normal) -> +Normal.
373 // * nextUp(-Normal) -> -Normal.
374 // * nextDown(-Normal) -> -Normal.
375
376 // nextUp(+Denormal) -> +Denormal.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000377 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000378 "0x0.ffffffffffffffffffffffff000cp-16382");
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000379 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000380 "0x0.ffffffffffffffffffffffff000dp-16382");
381 EXPECT_EQ(test.next(false), APFloat::opOK);
382 EXPECT_TRUE(test.isDenormal());
383 EXPECT_TRUE(!test.isNegative());
384 EXPECT_TRUE(test.bitwiseIsEqual(expected));
385
386 // nextDown(+Denormal) -> +Denormal.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000387 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000388 "0x0.ffffffffffffffffffffffff000cp-16382");
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000389 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000390 "0x0.ffffffffffffffffffffffff000bp-16382");
391 EXPECT_EQ(test.next(true), APFloat::opOK);
392 EXPECT_TRUE(test.isDenormal());
393 EXPECT_TRUE(!test.isNegative());
394 EXPECT_TRUE(test.bitwiseIsEqual(expected));
395
396 // nextUp(-Denormal) -> -Denormal.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000397 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000398 "-0x0.ffffffffffffffffffffffff000cp-16382");
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000399 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000400 "-0x0.ffffffffffffffffffffffff000bp-16382");
401 EXPECT_EQ(test.next(false), APFloat::opOK);
402 EXPECT_TRUE(test.isDenormal());
403 EXPECT_TRUE(test.isNegative());
404 EXPECT_TRUE(test.bitwiseIsEqual(expected));
405
406 // nextDown(-Denormal) -> -Denormal
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000407 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000408 "-0x0.ffffffffffffffffffffffff000cp-16382");
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000409 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000410 "-0x0.ffffffffffffffffffffffff000dp-16382");
411 EXPECT_EQ(test.next(true), APFloat::opOK);
412 EXPECT_TRUE(test.isDenormal());
413 EXPECT_TRUE(test.isNegative());
414 EXPECT_TRUE(test.bitwiseIsEqual(expected));
415
416 // nextUp(+Normal) -> +Normal.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000417 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000418 "0x1.ffffffffffffffffffffffff000cp-16000");
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000419 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000420 "0x1.ffffffffffffffffffffffff000dp-16000");
421 EXPECT_EQ(test.next(false), APFloat::opOK);
422 EXPECT_TRUE(!test.isDenormal());
423 EXPECT_TRUE(!test.isNegative());
424 EXPECT_TRUE(test.bitwiseIsEqual(expected));
425
426 // nextDown(+Normal) -> +Normal.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000427 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000428 "0x1.ffffffffffffffffffffffff000cp-16000");
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000429 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000430 "0x1.ffffffffffffffffffffffff000bp-16000");
431 EXPECT_EQ(test.next(true), APFloat::opOK);
432 EXPECT_TRUE(!test.isDenormal());
433 EXPECT_TRUE(!test.isNegative());
434 EXPECT_TRUE(test.bitwiseIsEqual(expected));
435
436 // nextUp(-Normal) -> -Normal.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000437 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000438 "-0x1.ffffffffffffffffffffffff000cp-16000");
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000439 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000440 "-0x1.ffffffffffffffffffffffff000bp-16000");
441 EXPECT_EQ(test.next(false), APFloat::opOK);
442 EXPECT_TRUE(!test.isDenormal());
443 EXPECT_TRUE(test.isNegative());
444 EXPECT_TRUE(test.bitwiseIsEqual(expected));
445
446 // nextDown(-Normal) -> -Normal.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000447 test = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000448 "-0x1.ffffffffffffffffffffffff000cp-16000");
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000449 expected = APFloat(APFloat::IEEEquad(),
Michael Gottesman0c622ea2013-05-30 18:07:13 +0000450 "-0x1.ffffffffffffffffffffffff000dp-16000");
451 EXPECT_EQ(test.next(true), APFloat::opOK);
452 EXPECT_TRUE(!test.isDenormal());
453 EXPECT_TRUE(test.isNegative());
454 EXPECT_TRUE(test.bitwiseIsEqual(expected));
455}
456
Shuxin Yangbbddbac2013-05-13 18:03:12 +0000457TEST(APFloatTest, FMA) {
458 APFloat::roundingMode rdmd = APFloat::rmNearestTiesToEven;
459
460 {
461 APFloat f1(14.5f);
462 APFloat f2(-14.5f);
463 APFloat f3(225.0f);
464 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);
465 EXPECT_EQ(14.75f, f1.convertToFloat());
466 }
467
468 {
469 APFloat Val2(2.0f);
470 APFloat f1((float)1.17549435e-38F);
471 APFloat f2((float)1.17549435e-38F);
472 f1.divide(Val2, rdmd);
473 f2.divide(Val2, rdmd);
474 APFloat f3(12.0f);
475 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);
476 EXPECT_EQ(12.0f, f1.convertToFloat());
477 }
Lang Hames56c0eb22014-11-19 19:15:41 +0000478
Lang Hames12b12e82015-01-04 01:20:55 +0000479 // Test for correct zero sign when answer is exactly zero.
480 // fma(1.0, -1.0, 1.0) -> +ve 0.
481 {
482 APFloat f1(1.0);
483 APFloat f2(-1.0);
484 APFloat f3(1.0);
485 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);
486 EXPECT_TRUE(!f1.isNegative() && f1.isZero());
487 }
488
489 // Test for correct zero sign when answer is exactly zero and rounding towards
490 // negative.
491 // fma(1.0, -1.0, 1.0) -> +ve 0.
492 {
493 APFloat f1(1.0);
494 APFloat f2(-1.0);
495 APFloat f3(1.0);
496 f1.fusedMultiplyAdd(f2, f3, APFloat::rmTowardNegative);
497 EXPECT_TRUE(f1.isNegative() && f1.isZero());
498 }
499
500 // Test for correct (in this case -ve) sign when adding like signed zeros.
501 // Test fma(0.0, -0.0, -0.0) -> -ve 0.
502 {
503 APFloat f1(0.0);
504 APFloat f2(-0.0);
505 APFloat f3(-0.0);
506 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);
507 EXPECT_TRUE(f1.isNegative() && f1.isZero());
508 }
509
510 // Test -ve sign preservation when small negative results underflow.
511 {
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000512 APFloat f1(APFloat::IEEEdouble(), "-0x1p-1074");
513 APFloat f2(APFloat::IEEEdouble(), "+0x1p-1074");
Lang Hames12b12e82015-01-04 01:20:55 +0000514 APFloat f3(0.0);
515 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);
516 EXPECT_TRUE(f1.isNegative() && f1.isZero());
517 }
518
519 // Test x87 extended precision case from http://llvm.org/PR20728.
Lang Hames56c0eb22014-11-19 19:15:41 +0000520 {
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000521 APFloat M1(APFloat::x87DoubleExtended(), 1.0);
522 APFloat M2(APFloat::x87DoubleExtended(), 1.0);
523 APFloat A(APFloat::x87DoubleExtended(), 3.0);
Lang Hames56c0eb22014-11-19 19:15:41 +0000524
525 bool losesInfo = false;
526 M1.fusedMultiplyAdd(M1, A, APFloat::rmNearestTiesToEven);
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000527 M1.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &losesInfo);
Lang Hames56c0eb22014-11-19 19:15:41 +0000528 EXPECT_FALSE(losesInfo);
529 EXPECT_EQ(4.0f, M1.convertToFloat());
530 }
Shuxin Yangbbddbac2013-05-13 18:03:12 +0000531}
532
Matt Arsenault5ccdb982014-10-10 05:21:32 +0000533TEST(APFloatTest, MinNum) {
534 APFloat f1(1.0);
535 APFloat f2(2.0);
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000536 APFloat nan = APFloat::getNaN(APFloat::IEEEdouble());
Matt Arsenault5ccdb982014-10-10 05:21:32 +0000537
538 EXPECT_EQ(1.0, minnum(f1, f2).convertToDouble());
539 EXPECT_EQ(1.0, minnum(f2, f1).convertToDouble());
540 EXPECT_EQ(1.0, minnum(f1, nan).convertToDouble());
541 EXPECT_EQ(1.0, minnum(nan, f1).convertToDouble());
542}
543
544TEST(APFloatTest, MaxNum) {
545 APFloat f1(1.0);
546 APFloat f2(2.0);
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000547 APFloat nan = APFloat::getNaN(APFloat::IEEEdouble());
Matt Arsenault5ccdb982014-10-10 05:21:32 +0000548
549 EXPECT_EQ(2.0, maxnum(f1, f2).convertToDouble());
550 EXPECT_EQ(2.0, maxnum(f2, f1).convertToDouble());
551 EXPECT_EQ(1.0, maxnum(f1, nan).convertToDouble());
552 EXPECT_EQ(1.0, minnum(nan, f1).convertToDouble());
553}
554
Shuxin Yang4fb504f2013-01-07 18:59:35 +0000555TEST(APFloatTest, Denormal) {
556 APFloat::roundingMode rdmd = APFloat::rmNearestTiesToEven;
557
558 // Test single precision
559 {
560 const char *MinNormalStr = "1.17549435082228750797e-38";
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000561 EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), MinNormalStr).isDenormal());
562 EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), 0.0).isDenormal());
Shuxin Yang4fb504f2013-01-07 18:59:35 +0000563
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000564 APFloat Val2(APFloat::IEEEsingle(), 2.0e0);
565 APFloat T(APFloat::IEEEsingle(), MinNormalStr);
Shuxin Yang4fb504f2013-01-07 18:59:35 +0000566 T.divide(Val2, rdmd);
567 EXPECT_TRUE(T.isDenormal());
568 }
569
570 // Test double precision
571 {
572 const char *MinNormalStr = "2.22507385850720138309e-308";
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000573 EXPECT_FALSE(APFloat(APFloat::IEEEdouble(), MinNormalStr).isDenormal());
574 EXPECT_FALSE(APFloat(APFloat::IEEEdouble(), 0.0).isDenormal());
Shuxin Yang4fb504f2013-01-07 18:59:35 +0000575
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000576 APFloat Val2(APFloat::IEEEdouble(), 2.0e0);
577 APFloat T(APFloat::IEEEdouble(), MinNormalStr);
Shuxin Yang4fb504f2013-01-07 18:59:35 +0000578 T.divide(Val2, rdmd);
579 EXPECT_TRUE(T.isDenormal());
580 }
581
582 // Test Intel double-ext
583 {
584 const char *MinNormalStr = "3.36210314311209350626e-4932";
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000585 EXPECT_FALSE(APFloat(APFloat::x87DoubleExtended(), MinNormalStr).isDenormal());
586 EXPECT_FALSE(APFloat(APFloat::x87DoubleExtended(), 0.0).isDenormal());
Shuxin Yang4fb504f2013-01-07 18:59:35 +0000587
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000588 APFloat Val2(APFloat::x87DoubleExtended(), 2.0e0);
589 APFloat T(APFloat::x87DoubleExtended(), MinNormalStr);
Shuxin Yang4fb504f2013-01-07 18:59:35 +0000590 T.divide(Val2, rdmd);
591 EXPECT_TRUE(T.isDenormal());
592 }
593
594 // Test quadruple precision
595 {
596 const char *MinNormalStr = "3.36210314311209350626267781732175260e-4932";
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000597 EXPECT_FALSE(APFloat(APFloat::IEEEquad(), MinNormalStr).isDenormal());
598 EXPECT_FALSE(APFloat(APFloat::IEEEquad(), 0.0).isDenormal());
Shuxin Yang4fb504f2013-01-07 18:59:35 +0000599
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000600 APFloat Val2(APFloat::IEEEquad(), 2.0e0);
601 APFloat T(APFloat::IEEEquad(), MinNormalStr);
Shuxin Yang4fb504f2013-01-07 18:59:35 +0000602 T.divide(Val2, rdmd);
603 EXPECT_TRUE(T.isDenormal());
604 }
605}
606
Erick Tryzelaar19f63b22009-08-16 23:36:19 +0000607TEST(APFloatTest, Zero) {
Matt Beaumont-Gaya421ee12011-08-29 17:54:20 +0000608 EXPECT_EQ(0.0f, APFloat(0.0f).convertToFloat());
609 EXPECT_EQ(-0.0f, APFloat(-0.0f).convertToFloat());
610 EXPECT_TRUE(APFloat(-0.0f).isNegative());
Erick Tryzelaar19f63b22009-08-16 23:36:19 +0000611
Matt Beaumont-Gaya421ee12011-08-29 17:54:20 +0000612 EXPECT_EQ(0.0, APFloat(0.0).convertToDouble());
613 EXPECT_EQ(-0.0, APFloat(-0.0).convertToDouble());
614 EXPECT_TRUE(APFloat(-0.0).isNegative());
Erick Tryzelaar19f63b22009-08-16 23:36:19 +0000615}
616
Michael Gottesman228156c2013-07-01 23:54:08 +0000617TEST(APFloatTest, DecimalStringsWithoutNullTerminators) {
618 // Make sure that we can parse strings without null terminators.
619 // rdar://14323230.
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000620 APFloat Val(APFloat::IEEEdouble());
Michael Gottesman228156c2013-07-01 23:54:08 +0000621 Val.convertFromString(StringRef("0.00", 3),
622 llvm::APFloat::rmNearestTiesToEven);
623 EXPECT_EQ(Val.convertToDouble(), 0.0);
624 Val.convertFromString(StringRef("0.01", 3),
625 llvm::APFloat::rmNearestTiesToEven);
626 EXPECT_EQ(Val.convertToDouble(), 0.0);
627 Val.convertFromString(StringRef("0.09", 3),
628 llvm::APFloat::rmNearestTiesToEven);
629 EXPECT_EQ(Val.convertToDouble(), 0.0);
630 Val.convertFromString(StringRef("0.095", 4),
631 llvm::APFloat::rmNearestTiesToEven);
632 EXPECT_EQ(Val.convertToDouble(), 0.09);
633 Val.convertFromString(StringRef("0.00e+3", 7),
634 llvm::APFloat::rmNearestTiesToEven);
635 EXPECT_EQ(Val.convertToDouble(), 0.00);
636 Val.convertFromString(StringRef("0e+3", 4),
637 llvm::APFloat::rmNearestTiesToEven);
638 EXPECT_EQ(Val.convertToDouble(), 0.00);
639
640}
641
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000642TEST(APFloatTest, fromZeroDecimalString) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000643 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0").convertToDouble());
644 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0").convertToDouble());
645 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000646
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000647 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.").convertToDouble());
648 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.").convertToDouble());
649 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000650
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000651 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), ".0").convertToDouble());
652 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+.0").convertToDouble());
653 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-.0").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000654
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000655 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.0").convertToDouble());
656 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.0").convertToDouble());
657 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.0").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000658
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000659 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "00000.").convertToDouble());
660 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+00000.").convertToDouble());
661 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-00000.").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000662
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000663 EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble(), ".00000").convertToDouble());
664 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+.00000").convertToDouble());
665 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-.00000").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000666
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000667 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0000.00000").convertToDouble());
668 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0000.00000").convertToDouble());
669 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0000.00000").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000670}
671
672TEST(APFloatTest, fromZeroDecimalSingleExponentString) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000673 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e1").convertToDouble());
674 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e1").convertToDouble());
675 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000676
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000677 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e+1").convertToDouble());
678 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e+1").convertToDouble());
679 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e+1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000680
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000681 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e-1").convertToDouble());
682 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e-1").convertToDouble());
683 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e-1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000684
685
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000686 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.e1").convertToDouble());
687 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.e1").convertToDouble());
688 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.e1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000689
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000690 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.e+1").convertToDouble());
691 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.e+1").convertToDouble());
692 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.e+1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000693
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000694 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.e-1").convertToDouble());
695 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.e-1").convertToDouble());
696 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.e-1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000697
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000698 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), ".0e1").convertToDouble());
699 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+.0e1").convertToDouble());
700 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-.0e1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000701
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000702 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), ".0e+1").convertToDouble());
703 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+.0e+1").convertToDouble());
704 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-.0e+1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000705
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000706 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), ".0e-1").convertToDouble());
707 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+.0e-1").convertToDouble());
708 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-.0e-1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000709
710
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000711 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.0e1").convertToDouble());
712 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.0e1").convertToDouble());
713 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.0e1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000714
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000715 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.0e+1").convertToDouble());
716 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.0e+1").convertToDouble());
717 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.0e+1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000718
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000719 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.0e-1").convertToDouble());
720 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.0e-1").convertToDouble());
721 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.0e-1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000722
723
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000724 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "000.0000e1").convertToDouble());
725 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+000.0000e+1").convertToDouble());
726 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-000.0000e+1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000727}
728
729TEST(APFloatTest, fromZeroDecimalLargeExponentString) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000730 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e1234").convertToDouble());
731 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e1234").convertToDouble());
732 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e1234").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000733
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000734 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e+1234").convertToDouble());
735 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e+1234").convertToDouble());
736 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e+1234").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000737
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000738 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e-1234").convertToDouble());
739 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e-1234").convertToDouble());
740 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e-1234").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000741
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000742 EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble(), "000.0000e1234").convertToDouble());
743 EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble(), "000.0000e-1234").convertToDouble());
Erick Tryzelaar19f63b22009-08-16 23:36:19 +0000744
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000745 EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble(), StringRef("0e1234\02", 6)).convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000746}
Erick Tryzelaar19f63b22009-08-16 23:36:19 +0000747
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000748TEST(APFloatTest, fromZeroHexadecimalString) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000749 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0p1").convertToDouble());
750 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0p1").convertToDouble());
751 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0p1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000752
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000753 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0p+1").convertToDouble());
754 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0p+1").convertToDouble());
755 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0p+1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000756
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000757 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0p-1").convertToDouble());
758 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0p-1").convertToDouble());
759 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0p-1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000760
761
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000762 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.p1").convertToDouble());
763 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.p1").convertToDouble());
764 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.p1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000765
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000766 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.p+1").convertToDouble());
767 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.p+1").convertToDouble());
768 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.p+1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000769
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000770 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.p-1").convertToDouble());
771 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.p-1").convertToDouble());
772 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.p-1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000773
774
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000775 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x.0p1").convertToDouble());
776 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x.0p1").convertToDouble());
777 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x.0p1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000778
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000779 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x.0p+1").convertToDouble());
780 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x.0p+1").convertToDouble());
781 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x.0p+1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000782
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000783 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x.0p-1").convertToDouble());
784 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x.0p-1").convertToDouble());
785 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x.0p-1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000786
787
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000788 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.0p1").convertToDouble());
789 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.0p1").convertToDouble());
790 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.0p1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000791
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000792 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.0p+1").convertToDouble());
793 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.0p+1").convertToDouble());
794 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.0p+1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000795
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000796 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.0p-1").convertToDouble());
797 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.0p-1").convertToDouble());
798 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.0p-1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000799
800
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000801 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x00000.p1").convertToDouble());
802 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0000.00000p1").convertToDouble());
803 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x.00000p1").convertToDouble());
804 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.p1").convertToDouble());
805 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0p1234").convertToDouble());
806 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0p1234").convertToDouble());
807 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x00000.p1234").convertToDouble());
808 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0000.00000p1234").convertToDouble());
809 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x.00000p1234").convertToDouble());
810 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.p1234").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000811}
812
813TEST(APFloatTest, fromDecimalString) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000814 EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1").convertToDouble());
815 EXPECT_EQ(2.0, APFloat(APFloat::IEEEdouble(), "2.").convertToDouble());
816 EXPECT_EQ(0.5, APFloat(APFloat::IEEEdouble(), ".5").convertToDouble());
817 EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1.0").convertToDouble());
818 EXPECT_EQ(-2.0, APFloat(APFloat::IEEEdouble(), "-2").convertToDouble());
819 EXPECT_EQ(-4.0, APFloat(APFloat::IEEEdouble(), "-4.").convertToDouble());
820 EXPECT_EQ(-0.5, APFloat(APFloat::IEEEdouble(), "-.5").convertToDouble());
821 EXPECT_EQ(-1.5, APFloat(APFloat::IEEEdouble(), "-1.5").convertToDouble());
822 EXPECT_EQ(1.25e12, APFloat(APFloat::IEEEdouble(), "1.25e12").convertToDouble());
823 EXPECT_EQ(1.25e+12, APFloat(APFloat::IEEEdouble(), "1.25e+12").convertToDouble());
824 EXPECT_EQ(1.25e-12, APFloat(APFloat::IEEEdouble(), "1.25e-12").convertToDouble());
825 EXPECT_EQ(1024.0, APFloat(APFloat::IEEEdouble(), "1024.").convertToDouble());
826 EXPECT_EQ(1024.05, APFloat(APFloat::IEEEdouble(), "1024.05000").convertToDouble());
827 EXPECT_EQ(0.05, APFloat(APFloat::IEEEdouble(), ".05000").convertToDouble());
828 EXPECT_EQ(2.0, APFloat(APFloat::IEEEdouble(), "2.").convertToDouble());
829 EXPECT_EQ(2.0e2, APFloat(APFloat::IEEEdouble(), "2.e2").convertToDouble());
830 EXPECT_EQ(2.0e+2, APFloat(APFloat::IEEEdouble(), "2.e+2").convertToDouble());
831 EXPECT_EQ(2.0e-2, APFloat(APFloat::IEEEdouble(), "2.e-2").convertToDouble());
832 EXPECT_EQ(2.05e2, APFloat(APFloat::IEEEdouble(), "002.05000e2").convertToDouble());
833 EXPECT_EQ(2.05e+2, APFloat(APFloat::IEEEdouble(), "002.05000e+2").convertToDouble());
834 EXPECT_EQ(2.05e-2, APFloat(APFloat::IEEEdouble(), "002.05000e-2").convertToDouble());
835 EXPECT_EQ(2.05e12, APFloat(APFloat::IEEEdouble(), "002.05000e12").convertToDouble());
836 EXPECT_EQ(2.05e+12, APFloat(APFloat::IEEEdouble(), "002.05000e+12").convertToDouble());
837 EXPECT_EQ(2.05e-12, APFloat(APFloat::IEEEdouble(), "002.05000e-12").convertToDouble());
John McCallb42cc682010-02-26 22:20:41 +0000838
839 // These are "carefully selected" to overflow the fast log-base
840 // calculations in APFloat.cpp
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000841 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "99e99999").isInfinity());
842 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-99e99999").isInfinity());
843 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "1e-99999").isPosZero());
844 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-1e-99999").isNegZero());
Eli Friedmand2eb07a2013-07-17 22:17:29 +0000845
846 EXPECT_EQ(2.71828, convertToDoubleFromString("2.71828"));
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000847}
848
849TEST(APFloatTest, fromHexadecimalString) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000850 EXPECT_EQ( 1.0, APFloat(APFloat::IEEEdouble(), "0x1p0").convertToDouble());
851 EXPECT_EQ(+1.0, APFloat(APFloat::IEEEdouble(), "+0x1p0").convertToDouble());
852 EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble(), "-0x1p0").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000853
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000854 EXPECT_EQ( 1.0, APFloat(APFloat::IEEEdouble(), "0x1p+0").convertToDouble());
855 EXPECT_EQ(+1.0, APFloat(APFloat::IEEEdouble(), "+0x1p+0").convertToDouble());
856 EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble(), "-0x1p+0").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000857
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000858 EXPECT_EQ( 1.0, APFloat(APFloat::IEEEdouble(), "0x1p-0").convertToDouble());
859 EXPECT_EQ(+1.0, APFloat(APFloat::IEEEdouble(), "+0x1p-0").convertToDouble());
860 EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble(), "-0x1p-0").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000861
862
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000863 EXPECT_EQ( 2.0, APFloat(APFloat::IEEEdouble(), "0x1p1").convertToDouble());
864 EXPECT_EQ(+2.0, APFloat(APFloat::IEEEdouble(), "+0x1p1").convertToDouble());
865 EXPECT_EQ(-2.0, APFloat(APFloat::IEEEdouble(), "-0x1p1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000866
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000867 EXPECT_EQ( 2.0, APFloat(APFloat::IEEEdouble(), "0x1p+1").convertToDouble());
868 EXPECT_EQ(+2.0, APFloat(APFloat::IEEEdouble(), "+0x1p+1").convertToDouble());
869 EXPECT_EQ(-2.0, APFloat(APFloat::IEEEdouble(), "-0x1p+1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000870
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000871 EXPECT_EQ( 0.5, APFloat(APFloat::IEEEdouble(), "0x1p-1").convertToDouble());
872 EXPECT_EQ(+0.5, APFloat(APFloat::IEEEdouble(), "+0x1p-1").convertToDouble());
873 EXPECT_EQ(-0.5, APFloat(APFloat::IEEEdouble(), "-0x1p-1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000874
875
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000876 EXPECT_EQ( 3.0, APFloat(APFloat::IEEEdouble(), "0x1.8p1").convertToDouble());
877 EXPECT_EQ(+3.0, APFloat(APFloat::IEEEdouble(), "+0x1.8p1").convertToDouble());
878 EXPECT_EQ(-3.0, APFloat(APFloat::IEEEdouble(), "-0x1.8p1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000879
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000880 EXPECT_EQ( 3.0, APFloat(APFloat::IEEEdouble(), "0x1.8p+1").convertToDouble());
881 EXPECT_EQ(+3.0, APFloat(APFloat::IEEEdouble(), "+0x1.8p+1").convertToDouble());
882 EXPECT_EQ(-3.0, APFloat(APFloat::IEEEdouble(), "-0x1.8p+1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000883
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000884 EXPECT_EQ( 0.75, APFloat(APFloat::IEEEdouble(), "0x1.8p-1").convertToDouble());
885 EXPECT_EQ(+0.75, APFloat(APFloat::IEEEdouble(), "+0x1.8p-1").convertToDouble());
886 EXPECT_EQ(-0.75, APFloat(APFloat::IEEEdouble(), "-0x1.8p-1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000887
888
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000889 EXPECT_EQ( 8192.0, APFloat(APFloat::IEEEdouble(), "0x1000.000p1").convertToDouble());
890 EXPECT_EQ(+8192.0, APFloat(APFloat::IEEEdouble(), "+0x1000.000p1").convertToDouble());
891 EXPECT_EQ(-8192.0, APFloat(APFloat::IEEEdouble(), "-0x1000.000p1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000892
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000893 EXPECT_EQ( 8192.0, APFloat(APFloat::IEEEdouble(), "0x1000.000p+1").convertToDouble());
894 EXPECT_EQ(+8192.0, APFloat(APFloat::IEEEdouble(), "+0x1000.000p+1").convertToDouble());
895 EXPECT_EQ(-8192.0, APFloat(APFloat::IEEEdouble(), "-0x1000.000p+1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000896
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000897 EXPECT_EQ( 2048.0, APFloat(APFloat::IEEEdouble(), "0x1000.000p-1").convertToDouble());
898 EXPECT_EQ(+2048.0, APFloat(APFloat::IEEEdouble(), "+0x1000.000p-1").convertToDouble());
899 EXPECT_EQ(-2048.0, APFloat(APFloat::IEEEdouble(), "-0x1000.000p-1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000900
901
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000902 EXPECT_EQ( 8192.0, APFloat(APFloat::IEEEdouble(), "0x1000p1").convertToDouble());
903 EXPECT_EQ(+8192.0, APFloat(APFloat::IEEEdouble(), "+0x1000p1").convertToDouble());
904 EXPECT_EQ(-8192.0, APFloat(APFloat::IEEEdouble(), "-0x1000p1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000905
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000906 EXPECT_EQ( 8192.0, APFloat(APFloat::IEEEdouble(), "0x1000p+1").convertToDouble());
907 EXPECT_EQ(+8192.0, APFloat(APFloat::IEEEdouble(), "+0x1000p+1").convertToDouble());
908 EXPECT_EQ(-8192.0, APFloat(APFloat::IEEEdouble(), "-0x1000p+1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000909
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000910 EXPECT_EQ( 2048.0, APFloat(APFloat::IEEEdouble(), "0x1000p-1").convertToDouble());
911 EXPECT_EQ(+2048.0, APFloat(APFloat::IEEEdouble(), "+0x1000p-1").convertToDouble());
912 EXPECT_EQ(-2048.0, APFloat(APFloat::IEEEdouble(), "-0x1000p-1").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000913
914
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000915 EXPECT_EQ( 16384.0, APFloat(APFloat::IEEEdouble(), "0x10p10").convertToDouble());
916 EXPECT_EQ(+16384.0, APFloat(APFloat::IEEEdouble(), "+0x10p10").convertToDouble());
917 EXPECT_EQ(-16384.0, APFloat(APFloat::IEEEdouble(), "-0x10p10").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000918
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000919 EXPECT_EQ( 16384.0, APFloat(APFloat::IEEEdouble(), "0x10p+10").convertToDouble());
920 EXPECT_EQ(+16384.0, APFloat(APFloat::IEEEdouble(), "+0x10p+10").convertToDouble());
921 EXPECT_EQ(-16384.0, APFloat(APFloat::IEEEdouble(), "-0x10p+10").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000922
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000923 EXPECT_EQ( 0.015625, APFloat(APFloat::IEEEdouble(), "0x10p-10").convertToDouble());
924 EXPECT_EQ(+0.015625, APFloat(APFloat::IEEEdouble(), "+0x10p-10").convertToDouble());
925 EXPECT_EQ(-0.015625, APFloat(APFloat::IEEEdouble(), "-0x10p-10").convertToDouble());
Erick Tryzelaarda666c82009-08-20 23:30:43 +0000926
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000927 EXPECT_EQ(1.0625, APFloat(APFloat::IEEEdouble(), "0x1.1p0").convertToDouble());
928 EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "0x1p0").convertToDouble());
Daniel Dunbarbc52e4f2009-09-03 22:57:02 +0000929
Eli Friedmand2eb07a2013-07-17 22:17:29 +0000930 EXPECT_EQ(convertToDoubleFromString("0x1p-150"),
931 convertToDoubleFromString("+0x800000000000000001.p-221"));
932 EXPECT_EQ(2251799813685248.5,
933 convertToDoubleFromString("0x80000000000004000000.010p-28"));
Erick Tryzelaar19f63b22009-08-16 23:36:19 +0000934}
935
John McCall29b5c282009-12-24 08:56:26 +0000936TEST(APFloatTest, toString) {
937 ASSERT_EQ("10", convertToString(10.0, 6, 3));
938 ASSERT_EQ("1.0E+1", convertToString(10.0, 6, 0));
939 ASSERT_EQ("10100", convertToString(1.01E+4, 5, 2));
940 ASSERT_EQ("1.01E+4", convertToString(1.01E+4, 4, 2));
941 ASSERT_EQ("1.01E+4", convertToString(1.01E+4, 5, 1));
942 ASSERT_EQ("0.0101", convertToString(1.01E-2, 5, 2));
John McCalldd5044a2009-12-24 23:18:09 +0000943 ASSERT_EQ("0.0101", convertToString(1.01E-2, 4, 2));
John McCall29b5c282009-12-24 08:56:26 +0000944 ASSERT_EQ("1.01E-2", convertToString(1.01E-2, 5, 1));
Eli Friedmane72f1322013-08-29 23:44:34 +0000945 ASSERT_EQ("0.78539816339744828", convertToString(0.78539816339744830961, 0, 3));
946 ASSERT_EQ("4.9406564584124654E-324", convertToString(4.9406564584124654e-324, 0, 3));
947 ASSERT_EQ("873.18340000000001", convertToString(873.1834, 0, 1));
948 ASSERT_EQ("8.7318340000000001E+2", convertToString(873.1834, 0, 0));
949 ASSERT_EQ("1.7976931348623157E+308", convertToString(1.7976931348623157E+308, 0, 0));
John McCall29b5c282009-12-24 08:56:26 +0000950}
951
Jeffrey Yasskin03b81a22011-07-15 07:04:56 +0000952TEST(APFloatTest, toInteger) {
953 bool isExact = false;
954 APSInt result(5, /*isUnsigned=*/true);
955
956 EXPECT_EQ(APFloat::opOK,
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000957 APFloat(APFloat::IEEEdouble(), "10")
Jeffrey Yasskin03b81a22011-07-15 07:04:56 +0000958 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
959 EXPECT_TRUE(isExact);
960 EXPECT_EQ(APSInt(APInt(5, 10), true), result);
961
962 EXPECT_EQ(APFloat::opInvalidOp,
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000963 APFloat(APFloat::IEEEdouble(), "-10")
Jeffrey Yasskin03b81a22011-07-15 07:04:56 +0000964 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
965 EXPECT_FALSE(isExact);
966 EXPECT_EQ(APSInt::getMinValue(5, true), result);
967
968 EXPECT_EQ(APFloat::opInvalidOp,
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000969 APFloat(APFloat::IEEEdouble(), "32")
Jeffrey Yasskin03b81a22011-07-15 07:04:56 +0000970 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
971 EXPECT_FALSE(isExact);
972 EXPECT_EQ(APSInt::getMaxValue(5, true), result);
973
974 EXPECT_EQ(APFloat::opInexact,
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000975 APFloat(APFloat::IEEEdouble(), "7.9")
Jeffrey Yasskin03b81a22011-07-15 07:04:56 +0000976 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
977 EXPECT_FALSE(isExact);
978 EXPECT_EQ(APSInt(APInt(5, 7), true), result);
979
980 result.setIsUnsigned(false);
981 EXPECT_EQ(APFloat::opOK,
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000982 APFloat(APFloat::IEEEdouble(), "-10")
Jeffrey Yasskin03b81a22011-07-15 07:04:56 +0000983 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
984 EXPECT_TRUE(isExact);
985 EXPECT_EQ(APSInt(APInt(5, -10, true), false), result);
986
987 EXPECT_EQ(APFloat::opInvalidOp,
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000988 APFloat(APFloat::IEEEdouble(), "-17")
Jeffrey Yasskin03b81a22011-07-15 07:04:56 +0000989 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
990 EXPECT_FALSE(isExact);
991 EXPECT_EQ(APSInt::getMinValue(5, false), result);
992
993 EXPECT_EQ(APFloat::opInvalidOp,
Stephan Bergmann17c7f702016-12-14 11:57:17 +0000994 APFloat(APFloat::IEEEdouble(), "16")
Jeffrey Yasskin03b81a22011-07-15 07:04:56 +0000995 .convertToInteger(result, APFloat::rmTowardZero, &isExact));
996 EXPECT_FALSE(isExact);
997 EXPECT_EQ(APSInt::getMaxValue(5, false), result);
998}
999
John McCalldcb9a7a2010-02-28 02:51:25 +00001000static APInt nanbits(const fltSemantics &Sem,
1001 bool SNaN, bool Negative, uint64_t fill) {
1002 APInt apfill(64, fill);
1003 if (SNaN)
1004 return APFloat::getSNaN(Sem, Negative, &apfill).bitcastToAPInt();
1005 else
1006 return APFloat::getQNaN(Sem, Negative, &apfill).bitcastToAPInt();
1007}
1008
1009TEST(APFloatTest, makeNaN) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001010 ASSERT_EQ(0x7fc00000, nanbits(APFloat::IEEEsingle(), false, false, 0));
1011 ASSERT_EQ(0xffc00000, nanbits(APFloat::IEEEsingle(), false, true, 0));
1012 ASSERT_EQ(0x7fc0ae72, nanbits(APFloat::IEEEsingle(), false, false, 0xae72));
1013 ASSERT_EQ(0x7fffae72, nanbits(APFloat::IEEEsingle(), false, false, 0xffffae72));
1014 ASSERT_EQ(0x7fa00000, nanbits(APFloat::IEEEsingle(), true, false, 0));
1015 ASSERT_EQ(0xffa00000, nanbits(APFloat::IEEEsingle(), true, true, 0));
1016 ASSERT_EQ(0x7f80ae72, nanbits(APFloat::IEEEsingle(), true, false, 0xae72));
1017 ASSERT_EQ(0x7fbfae72, nanbits(APFloat::IEEEsingle(), true, false, 0xffffae72));
John McCalldcb9a7a2010-02-28 02:51:25 +00001018
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001019 ASSERT_EQ(0x7ff8000000000000ULL, nanbits(APFloat::IEEEdouble(), false, false, 0));
1020 ASSERT_EQ(0xfff8000000000000ULL, nanbits(APFloat::IEEEdouble(), false, true, 0));
1021 ASSERT_EQ(0x7ff800000000ae72ULL, nanbits(APFloat::IEEEdouble(), false, false, 0xae72));
1022 ASSERT_EQ(0x7fffffffffffae72ULL, nanbits(APFloat::IEEEdouble(), false, false, 0xffffffffffffae72ULL));
1023 ASSERT_EQ(0x7ff4000000000000ULL, nanbits(APFloat::IEEEdouble(), true, false, 0));
1024 ASSERT_EQ(0xfff4000000000000ULL, nanbits(APFloat::IEEEdouble(), true, true, 0));
1025 ASSERT_EQ(0x7ff000000000ae72ULL, nanbits(APFloat::IEEEdouble(), true, false, 0xae72));
1026 ASSERT_EQ(0x7ff7ffffffffae72ULL, nanbits(APFloat::IEEEdouble(), true, false, 0xffffffffffffae72ULL));
John McCalldcb9a7a2010-02-28 02:51:25 +00001027}
1028
Erick Tryzelaar927191f2009-08-17 00:55:33 +00001029#ifdef GTEST_HAS_DEATH_TEST
Jeffrey Yasskinb5cd0132010-03-17 01:18:45 +00001030#ifndef NDEBUG
Erick Tryzelaar927191f2009-08-17 00:55:33 +00001031TEST(APFloatTest, SemanticsDeath) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001032 EXPECT_DEATH(APFloat(APFloat::IEEEsingle(), 0.0f).convertToDouble(), "Float semantics are not IEEEdouble");
1033 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), 0.0 ).convertToFloat(), "Float semantics are not IEEEsingle");
Erick Tryzelaar927191f2009-08-17 00:55:33 +00001034}
1035
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001036TEST(APFloatTest, StringDecimalDeath) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001037 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ""), "Invalid string length");
1038 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+"), "String has no digits");
1039 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-"), "String has no digits");
Erick Tryzelaar19f63b22009-08-16 23:36:19 +00001040
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001041 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("\0", 1)), "Invalid character in significand");
1042 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("1\0", 2)), "Invalid character in significand");
1043 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("1\02", 3)), "Invalid character in significand");
1044 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("1\02e1", 5)), "Invalid character in significand");
1045 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("1e\0", 3)), "Invalid character in exponent");
1046 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("1e1\0", 4)), "Invalid character in exponent");
1047 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("1e1\02", 5)), "Invalid character in exponent");
Erick Tryzelaar19f63b22009-08-16 23:36:19 +00001048
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001049 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.0f"), "Invalid character in significand");
Erick Tryzelaar19f63b22009-08-16 23:36:19 +00001050
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001051 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".."), "String contains multiple dots");
1052 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "..0"), "String contains multiple dots");
1053 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.0.0"), "String contains multiple dots");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001054}
1055
1056TEST(APFloatTest, StringDecimalSignificandDeath) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001057 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "."), "Significand has no digits");
1058 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+."), "Significand has no digits");
1059 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-."), "Significand has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001060
1061
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001062 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "e"), "Significand has no digits");
1063 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+e"), "Significand has no digits");
1064 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-e"), "Significand has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001065
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001066 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "e1"), "Significand has no digits");
1067 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+e1"), "Significand has no digits");
1068 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-e1"), "Significand has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001069
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001070 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".e1"), "Significand has no digits");
1071 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+.e1"), "Significand has no digits");
1072 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-.e1"), "Significand has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001073
1074
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001075 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".e"), "Significand has no digits");
1076 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+.e"), "Significand has no digits");
1077 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-.e"), "Significand has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001078}
1079
1080TEST(APFloatTest, StringDecimalExponentDeath) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001081 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1e"), "Exponent has no digits");
1082 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+1e"), "Exponent has no digits");
1083 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-1e"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001084
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001085 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.e"), "Exponent has no digits");
1086 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+1.e"), "Exponent has no digits");
1087 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-1.e"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001088
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001089 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".1e"), "Exponent has no digits");
1090 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+.1e"), "Exponent has no digits");
1091 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-.1e"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001092
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001093 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.1e"), "Exponent has no digits");
1094 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+1.1e"), "Exponent has no digits");
1095 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-1.1e"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001096
1097
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001098 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1e+"), "Exponent has no digits");
1099 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1e-"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001100
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001101 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".1e"), "Exponent has no digits");
1102 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".1e+"), "Exponent has no digits");
1103 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), ".1e-"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001104
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001105 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.0e"), "Exponent has no digits");
1106 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.0e+"), "Exponent has no digits");
1107 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "1.0e-"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001108}
1109
1110TEST(APFloatTest, StringHexadecimalDeath) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001111 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x"), "Invalid string");
1112 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x"), "Invalid string");
1113 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x"), "Invalid string");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001114
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001115 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x0"), "Hex strings require an exponent");
1116 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x0"), "Hex strings require an exponent");
1117 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x0"), "Hex strings require an exponent");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001118
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001119 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x0."), "Hex strings require an exponent");
1120 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x0."), "Hex strings require an exponent");
1121 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x0."), "Hex strings require an exponent");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001122
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001123 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x.0"), "Hex strings require an exponent");
1124 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x.0"), "Hex strings require an exponent");
1125 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x.0"), "Hex strings require an exponent");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001126
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001127 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x0.0"), "Hex strings require an exponent");
1128 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x0.0"), "Hex strings require an exponent");
1129 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x0.0"), "Hex strings require an exponent");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001130
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001131 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("0x\0", 3)), "Invalid character in significand");
1132 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("0x1\0", 4)), "Invalid character in significand");
1133 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("0x1\02", 5)), "Invalid character in significand");
1134 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("0x1\02p1", 7)), "Invalid character in significand");
1135 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("0x1p\0", 5)), "Invalid character in exponent");
1136 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("0x1p1\0", 6)), "Invalid character in exponent");
1137 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), StringRef("0x1p1\02", 7)), "Invalid character in exponent");
Erick Tryzelaar19f63b22009-08-16 23:36:19 +00001138
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001139 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1p0f"), "Invalid character in exponent");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001140
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001141 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x..p1"), "String contains multiple dots");
1142 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x..0p1"), "String contains multiple dots");
1143 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1.0.0p1"), "String contains multiple dots");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001144}
1145
1146TEST(APFloatTest, StringHexadecimalSignificandDeath) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001147 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x."), "Significand has no digits");
1148 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x."), "Significand has no digits");
1149 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x."), "Significand has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001150
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001151 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0xp"), "Significand has no digits");
1152 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0xp"), "Significand has no digits");
1153 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0xp"), "Significand has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001154
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001155 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0xp+"), "Significand has no digits");
1156 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0xp+"), "Significand has no digits");
1157 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0xp+"), "Significand has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001158
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001159 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0xp-"), "Significand has no digits");
1160 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0xp-"), "Significand has no digits");
1161 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0xp-"), "Significand has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001162
1163
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001164 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x.p"), "Significand has no digits");
1165 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x.p"), "Significand has no digits");
1166 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x.p"), "Significand has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001167
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001168 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x.p+"), "Significand has no digits");
1169 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x.p+"), "Significand has no digits");
1170 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x.p+"), "Significand has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001171
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001172 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x.p-"), "Significand has no digits");
1173 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x.p-"), "Significand has no digits");
1174 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x.p-"), "Significand has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001175}
1176
1177TEST(APFloatTest, StringHexadecimalExponentDeath) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001178 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1p"), "Exponent has no digits");
1179 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1p"), "Exponent has no digits");
1180 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1p"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001181
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001182 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1p+"), "Exponent has no digits");
1183 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1p+"), "Exponent has no digits");
1184 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1p+"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001185
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001186 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1p-"), "Exponent has no digits");
1187 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1p-"), "Exponent has no digits");
1188 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1p-"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001189
1190
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001191 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1.p"), "Exponent has no digits");
1192 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1.p"), "Exponent has no digits");
1193 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1.p"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001194
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001195 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1.p+"), "Exponent has no digits");
1196 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1.p+"), "Exponent has no digits");
1197 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1.p+"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001198
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001199 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1.p-"), "Exponent has no digits");
1200 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1.p-"), "Exponent has no digits");
1201 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1.p-"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001202
1203
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001204 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x.1p"), "Exponent has no digits");
1205 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x.1p"), "Exponent has no digits");
1206 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x.1p"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001207
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001208 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x.1p+"), "Exponent has no digits");
1209 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x.1p+"), "Exponent has no digits");
1210 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x.1p+"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001211
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001212 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x.1p-"), "Exponent has no digits");
1213 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x.1p-"), "Exponent has no digits");
1214 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x.1p-"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001215
1216
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001217 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1.1p"), "Exponent has no digits");
1218 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1.1p"), "Exponent has no digits");
1219 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1.1p"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001220
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001221 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1.1p+"), "Exponent has no digits");
1222 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1.1p+"), "Exponent has no digits");
1223 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1.1p+"), "Exponent has no digits");
Erick Tryzelaarda666c82009-08-20 23:30:43 +00001224
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001225 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "0x1.1p-"), "Exponent has no digits");
1226 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "+0x1.1p-"), "Exponent has no digits");
1227 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), "-0x1.1p-"), "Exponent has no digits");
Erick Tryzelaar19f63b22009-08-16 23:36:19 +00001228}
Erick Tryzelaar927191f2009-08-17 00:55:33 +00001229#endif
Jeffrey Yasskinb5cd0132010-03-17 01:18:45 +00001230#endif
Erick Tryzelaar19f63b22009-08-16 23:36:19 +00001231
Benjamin Kramer03fd6722011-03-30 15:42:27 +00001232TEST(APFloatTest, exactInverse) {
1233 APFloat inv(0.0f);
1234
1235 // Trivial operation.
1236 EXPECT_TRUE(APFloat(2.0).getExactInverse(&inv));
1237 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(0.5)));
1238 EXPECT_TRUE(APFloat(2.0f).getExactInverse(&inv));
1239 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(0.5f)));
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001240 EXPECT_TRUE(APFloat(APFloat::IEEEquad(), "2.0").getExactInverse(&inv));
1241 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(APFloat::IEEEquad(), "0.5")));
1242 EXPECT_TRUE(APFloat(APFloat::PPCDoubleDouble(), "2.0").getExactInverse(&inv));
1243 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(APFloat::PPCDoubleDouble(), "0.5")));
1244 EXPECT_TRUE(APFloat(APFloat::x87DoubleExtended(), "2.0").getExactInverse(&inv));
1245 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(APFloat::x87DoubleExtended(), "0.5")));
Benjamin Kramer03fd6722011-03-30 15:42:27 +00001246
1247 // FLT_MIN
1248 EXPECT_TRUE(APFloat(1.17549435e-38f).getExactInverse(&inv));
1249 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(8.5070592e+37f)));
1250
Benjamin Krameraf0ed952011-03-30 17:02:54 +00001251 // Large float, inverse is a denormal.
Craig Topper66f09ad2014-06-08 22:29:17 +00001252 EXPECT_FALSE(APFloat(1.7014118e38f).getExactInverse(nullptr));
Benjamin Kramer03fd6722011-03-30 15:42:27 +00001253 // Zero
Craig Topper66f09ad2014-06-08 22:29:17 +00001254 EXPECT_FALSE(APFloat(0.0).getExactInverse(nullptr));
Benjamin Kramer03fd6722011-03-30 15:42:27 +00001255 // Denormalized float
Craig Topper66f09ad2014-06-08 22:29:17 +00001256 EXPECT_FALSE(APFloat(1.40129846e-45f).getExactInverse(nullptr));
Benjamin Kramer03fd6722011-03-30 15:42:27 +00001257}
1258
Owen Anderson1ff74b02012-08-15 05:39:46 +00001259TEST(APFloatTest, roundToIntegral) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001260 APFloat T(-0.5), S(3.14), R(APFloat::getLargest(APFloat::IEEEdouble())), P(0.0);
Owen Anderson1ff74b02012-08-15 05:39:46 +00001261
1262 P = T;
1263 P.roundToIntegral(APFloat::rmTowardZero);
1264 EXPECT_EQ(-0.0, P.convertToDouble());
1265 P = T;
1266 P.roundToIntegral(APFloat::rmTowardNegative);
1267 EXPECT_EQ(-1.0, P.convertToDouble());
1268 P = T;
1269 P.roundToIntegral(APFloat::rmTowardPositive);
1270 EXPECT_EQ(-0.0, P.convertToDouble());
1271 P = T;
1272 P.roundToIntegral(APFloat::rmNearestTiesToEven);
1273 EXPECT_EQ(-0.0, P.convertToDouble());
1274
1275 P = S;
1276 P.roundToIntegral(APFloat::rmTowardZero);
1277 EXPECT_EQ(3.0, P.convertToDouble());
1278 P = S;
1279 P.roundToIntegral(APFloat::rmTowardNegative);
1280 EXPECT_EQ(3.0, P.convertToDouble());
1281 P = S;
1282 P.roundToIntegral(APFloat::rmTowardPositive);
1283 EXPECT_EQ(4.0, P.convertToDouble());
1284 P = S;
1285 P.roundToIntegral(APFloat::rmNearestTiesToEven);
1286 EXPECT_EQ(3.0, P.convertToDouble());
Owen Anderson352dfff2012-08-15 18:28:45 +00001287
1288 P = R;
1289 P.roundToIntegral(APFloat::rmTowardZero);
1290 EXPECT_EQ(R.convertToDouble(), P.convertToDouble());
1291 P = R;
1292 P.roundToIntegral(APFloat::rmTowardNegative);
1293 EXPECT_EQ(R.convertToDouble(), P.convertToDouble());
1294 P = R;
1295 P.roundToIntegral(APFloat::rmTowardPositive);
1296 EXPECT_EQ(R.convertToDouble(), P.convertToDouble());
1297 P = R;
1298 P.roundToIntegral(APFloat::rmNearestTiesToEven);
1299 EXPECT_EQ(R.convertToDouble(), P.convertToDouble());
Benjamin Kramerc38fab22012-09-26 14:06:58 +00001300
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001301 P = APFloat::getZero(APFloat::IEEEdouble());
Benjamin Kramerc38fab22012-09-26 14:06:58 +00001302 P.roundToIntegral(APFloat::rmTowardZero);
1303 EXPECT_EQ(0.0, P.convertToDouble());
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001304 P = APFloat::getZero(APFloat::IEEEdouble(), true);
Benjamin Kramerc38fab22012-09-26 14:06:58 +00001305 P.roundToIntegral(APFloat::rmTowardZero);
1306 EXPECT_EQ(-0.0, P.convertToDouble());
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001307 P = APFloat::getNaN(APFloat::IEEEdouble());
Benjamin Kramerc38fab22012-09-26 14:06:58 +00001308 P.roundToIntegral(APFloat::rmTowardZero);
Benjamin Kramer37dce442015-03-09 18:35:18 +00001309 EXPECT_TRUE(std::isnan(P.convertToDouble()));
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001310 P = APFloat::getInf(APFloat::IEEEdouble());
Benjamin Kramerc38fab22012-09-26 14:06:58 +00001311 P.roundToIntegral(APFloat::rmTowardZero);
Benjamin Kramer37dce442015-03-09 18:35:18 +00001312 EXPECT_TRUE(std::isinf(P.convertToDouble()) && P.convertToDouble() > 0.0);
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001313 P = APFloat::getInf(APFloat::IEEEdouble(), true);
Benjamin Kramerc38fab22012-09-26 14:06:58 +00001314 P.roundToIntegral(APFloat::rmTowardZero);
Benjamin Kramer37dce442015-03-09 18:35:18 +00001315 EXPECT_TRUE(std::isinf(P.convertToDouble()) && P.convertToDouble() < 0.0);
Stephen Canon1bfc89b2015-11-16 21:52:48 +00001316}
Matt Arsenaultc25a7112016-03-21 16:49:16 +00001317
Stephen Canon1bfc89b2015-11-16 21:52:48 +00001318TEST(APFloatTest, isInteger) {
1319 APFloat T(-0.0);
1320 EXPECT_TRUE(T.isInteger());
1321 T = APFloat(3.14159);
1322 EXPECT_FALSE(T.isInteger());
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001323 T = APFloat::getNaN(APFloat::IEEEdouble());
Stephen Canon1bfc89b2015-11-16 21:52:48 +00001324 EXPECT_FALSE(T.isInteger());
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001325 T = APFloat::getInf(APFloat::IEEEdouble());
Stephen Canon1bfc89b2015-11-16 21:52:48 +00001326 EXPECT_FALSE(T.isInteger());
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001327 T = APFloat::getInf(APFloat::IEEEdouble(), true);
Stephen Canon1bfc89b2015-11-16 21:52:48 +00001328 EXPECT_FALSE(T.isInteger());
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001329 T = APFloat::getLargest(APFloat::IEEEdouble());
Stephen Canon1bfc89b2015-11-16 21:52:48 +00001330 EXPECT_TRUE(T.isInteger());
Owen Anderson1ff74b02012-08-15 05:39:46 +00001331}
1332
Eli Friedmanc5322012011-10-12 21:51:36 +00001333TEST(APFloatTest, getLargest) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001334 EXPECT_EQ(3.402823466e+38f, APFloat::getLargest(APFloat::IEEEsingle()).convertToFloat());
1335 EXPECT_EQ(1.7976931348623158e+308, APFloat::getLargest(APFloat::IEEEdouble()).convertToDouble());
Eli Friedmanc5322012011-10-12 21:51:36 +00001336}
1337
Michael Gottesman63e6d212013-05-29 23:58:29 +00001338TEST(APFloatTest, getSmallest) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001339 APFloat test = APFloat::getSmallest(APFloat::IEEEsingle(), false);
1340 APFloat expected = APFloat(APFloat::IEEEsingle(), "0x0.000002p-126");
Michael Gottesman5455d5b2013-05-30 00:18:44 +00001341 EXPECT_FALSE(test.isNegative());
Michael Gottesmanb5101ab2013-06-19 21:53:45 +00001342 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman5455d5b2013-05-30 00:18:44 +00001343 EXPECT_TRUE(test.isDenormal());
Michael Gottesman63e6d212013-05-29 23:58:29 +00001344 EXPECT_TRUE(test.bitwiseIsEqual(expected));
1345
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001346 test = APFloat::getSmallest(APFloat::IEEEsingle(), true);
1347 expected = APFloat(APFloat::IEEEsingle(), "-0x0.000002p-126");
Michael Gottesman63e6d212013-05-29 23:58:29 +00001348 EXPECT_TRUE(test.isNegative());
Michael Gottesmanb5101ab2013-06-19 21:53:45 +00001349 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman5455d5b2013-05-30 00:18:44 +00001350 EXPECT_TRUE(test.isDenormal());
Michael Gottesman63e6d212013-05-29 23:58:29 +00001351 EXPECT_TRUE(test.bitwiseIsEqual(expected));
1352
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001353 test = APFloat::getSmallest(APFloat::IEEEquad(), false);
1354 expected = APFloat(APFloat::IEEEquad(), "0x0.0000000000000000000000000001p-16382");
Michael Gottesman5455d5b2013-05-30 00:18:44 +00001355 EXPECT_FALSE(test.isNegative());
Michael Gottesmanb5101ab2013-06-19 21:53:45 +00001356 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman5455d5b2013-05-30 00:18:44 +00001357 EXPECT_TRUE(test.isDenormal());
Michael Gottesman63e6d212013-05-29 23:58:29 +00001358 EXPECT_TRUE(test.bitwiseIsEqual(expected));
1359
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001360 test = APFloat::getSmallest(APFloat::IEEEquad(), true);
1361 expected = APFloat(APFloat::IEEEquad(), "-0x0.0000000000000000000000000001p-16382");
Michael Gottesman63e6d212013-05-29 23:58:29 +00001362 EXPECT_TRUE(test.isNegative());
Michael Gottesmanb5101ab2013-06-19 21:53:45 +00001363 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman5455d5b2013-05-30 00:18:44 +00001364 EXPECT_TRUE(test.isDenormal());
Michael Gottesmanf9899292013-06-24 09:58:09 +00001365 EXPECT_TRUE(test.bitwiseIsEqual(expected));
Michael Gottesman63e6d212013-05-29 23:58:29 +00001366}
1367
Michael Gottesman0db7c272013-05-30 00:18:47 +00001368TEST(APFloatTest, getSmallestNormalized) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001369 APFloat test = APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);
1370 APFloat expected = APFloat(APFloat::IEEEsingle(), "0x1p-126");
Michael Gottesman0db7c272013-05-30 00:18:47 +00001371 EXPECT_FALSE(test.isNegative());
Michael Gottesmanb5101ab2013-06-19 21:53:45 +00001372 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman0db7c272013-05-30 00:18:47 +00001373 EXPECT_FALSE(test.isDenormal());
1374 EXPECT_TRUE(test.bitwiseIsEqual(expected));
1375
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001376 test = APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);
1377 expected = APFloat(APFloat::IEEEsingle(), "-0x1p-126");
Michael Gottesman0db7c272013-05-30 00:18:47 +00001378 EXPECT_TRUE(test.isNegative());
Michael Gottesmanb5101ab2013-06-19 21:53:45 +00001379 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman0db7c272013-05-30 00:18:47 +00001380 EXPECT_FALSE(test.isDenormal());
1381 EXPECT_TRUE(test.bitwiseIsEqual(expected));
1382
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001383 test = APFloat::getSmallestNormalized(APFloat::IEEEquad(), false);
1384 expected = APFloat(APFloat::IEEEquad(), "0x1p-16382");
Michael Gottesman0db7c272013-05-30 00:18:47 +00001385 EXPECT_FALSE(test.isNegative());
Michael Gottesmanb5101ab2013-06-19 21:53:45 +00001386 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman0db7c272013-05-30 00:18:47 +00001387 EXPECT_FALSE(test.isDenormal());
1388 EXPECT_TRUE(test.bitwiseIsEqual(expected));
1389
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001390 test = APFloat::getSmallestNormalized(APFloat::IEEEquad(), true);
1391 expected = APFloat(APFloat::IEEEquad(), "-0x1p-16382");
Michael Gottesman0db7c272013-05-30 00:18:47 +00001392 EXPECT_TRUE(test.isNegative());
Michael Gottesmanb5101ab2013-06-19 21:53:45 +00001393 EXPECT_TRUE(test.isFiniteNonZero());
Michael Gottesman0db7c272013-05-30 00:18:47 +00001394 EXPECT_FALSE(test.isDenormal());
Michael Gottesmanf9899292013-06-24 09:58:09 +00001395 EXPECT_TRUE(test.bitwiseIsEqual(expected));
Michael Gottesman0db7c272013-05-30 00:18:47 +00001396}
1397
Michael Gottesmanfc718c92013-05-31 18:43:34 +00001398TEST(APFloatTest, getZero) {
1399 struct {
1400 const fltSemantics *semantics;
1401 const bool sign;
1402 const unsigned long long bitPattern[2];
1403 const unsigned bitPatternLength;
Benjamin Kramer0bb474f2013-06-01 22:29:41 +00001404 } const GetZeroTest[] = {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001405 { &APFloat::IEEEhalf(), false, {0, 0}, 1},
1406 { &APFloat::IEEEhalf(), true, {0x8000ULL, 0}, 1},
1407 { &APFloat::IEEEsingle(), false, {0, 0}, 1},
1408 { &APFloat::IEEEsingle(), true, {0x80000000ULL, 0}, 1},
1409 { &APFloat::IEEEdouble(), false, {0, 0}, 1},
1410 { &APFloat::IEEEdouble(), true, {0x8000000000000000ULL, 0}, 1},
1411 { &APFloat::IEEEquad(), false, {0, 0}, 2},
1412 { &APFloat::IEEEquad(), true, {0, 0x8000000000000000ULL}, 2},
1413 { &APFloat::PPCDoubleDouble(), false, {0, 0}, 2},
1414 { &APFloat::PPCDoubleDouble(), true, {0x8000000000000000ULL, 0}, 2},
1415 { &APFloat::x87DoubleExtended(), false, {0, 0}, 2},
1416 { &APFloat::x87DoubleExtended(), true, {0, 0x8000ULL}, 2},
Michael Gottesmanfc718c92013-05-31 18:43:34 +00001417 };
1418 const unsigned NumGetZeroTests = 12;
1419 for (unsigned i = 0; i < NumGetZeroTests; ++i) {
1420 APFloat test = APFloat::getZero(*GetZeroTest[i].semantics,
1421 GetZeroTest[i].sign);
1422 const char *pattern = GetZeroTest[i].sign? "-0x0p+0" : "0x0p+0";
1423 APFloat expected = APFloat(*GetZeroTest[i].semantics,
1424 pattern);
1425 EXPECT_TRUE(test.isZero());
1426 EXPECT_TRUE(GetZeroTest[i].sign? test.isNegative() : !test.isNegative());
1427 EXPECT_TRUE(test.bitwiseIsEqual(expected));
1428 for (unsigned j = 0, je = GetZeroTest[i].bitPatternLength; j < je; ++j) {
1429 EXPECT_EQ(GetZeroTest[i].bitPattern[j],
1430 test.bitcastToAPInt().getRawData()[j]);
1431 }
1432 }
1433}
1434
Chandler Carruthdf782e42014-10-09 23:26:15 +00001435TEST(APFloatTest, copySign) {
1436 EXPECT_TRUE(APFloat(-42.0).bitwiseIsEqual(
1437 APFloat::copySign(APFloat(42.0), APFloat(-1.0))));
1438 EXPECT_TRUE(APFloat(42.0).bitwiseIsEqual(
1439 APFloat::copySign(APFloat(-42.0), APFloat(1.0))));
1440 EXPECT_TRUE(APFloat(-42.0).bitwiseIsEqual(
1441 APFloat::copySign(APFloat(-42.0), APFloat(-1.0))));
1442 EXPECT_TRUE(APFloat(42.0).bitwiseIsEqual(
1443 APFloat::copySign(APFloat(42.0), APFloat(1.0))));
1444}
1445
Eli Friedmana84ad7d2011-11-26 03:38:02 +00001446TEST(APFloatTest, convert) {
1447 bool losesInfo;
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001448 APFloat test(APFloat::IEEEdouble(), "1.0");
1449 test.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &losesInfo);
Eli Friedmana84ad7d2011-11-26 03:38:02 +00001450 EXPECT_EQ(1.0f, test.convertToFloat());
1451 EXPECT_FALSE(losesInfo);
1452
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001453 test = APFloat(APFloat::x87DoubleExtended(), "0x1p-53");
1454 test.add(APFloat(APFloat::x87DoubleExtended(), "1.0"), APFloat::rmNearestTiesToEven);
1455 test.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &losesInfo);
Eli Friedmana84ad7d2011-11-26 03:38:02 +00001456 EXPECT_EQ(1.0, test.convertToDouble());
1457 EXPECT_TRUE(losesInfo);
1458
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001459 test = APFloat(APFloat::IEEEquad(), "0x1p-53");
1460 test.add(APFloat(APFloat::IEEEquad(), "1.0"), APFloat::rmNearestTiesToEven);
1461 test.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &losesInfo);
Eli Friedmana84ad7d2011-11-26 03:38:02 +00001462 EXPECT_EQ(1.0, test.convertToDouble());
1463 EXPECT_TRUE(losesInfo);
1464
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001465 test = APFloat(APFloat::x87DoubleExtended(), "0xf.fffffffp+28");
1466 test.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &losesInfo);
Eli Friedmana84ad7d2011-11-26 03:38:02 +00001467 EXPECT_EQ(4294967295.0, test.convertToDouble());
1468 EXPECT_FALSE(losesInfo);
Benjamin Kramerb361adb2013-01-25 17:01:00 +00001469
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001470 test = APFloat::getSNaN(APFloat::IEEEsingle());
1471 APFloat X87SNaN = APFloat::getSNaN(APFloat::x87DoubleExtended());
1472 test.convert(APFloat::x87DoubleExtended(), APFloat::rmNearestTiesToEven,
Benjamin Kramerb361adb2013-01-25 17:01:00 +00001473 &losesInfo);
1474 EXPECT_TRUE(test.bitwiseIsEqual(X87SNaN));
1475 EXPECT_FALSE(losesInfo);
1476
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001477 test = APFloat::getQNaN(APFloat::IEEEsingle());
1478 APFloat X87QNaN = APFloat::getQNaN(APFloat::x87DoubleExtended());
1479 test.convert(APFloat::x87DoubleExtended(), APFloat::rmNearestTiesToEven,
Benjamin Kramerb361adb2013-01-25 17:01:00 +00001480 &losesInfo);
1481 EXPECT_TRUE(test.bitwiseIsEqual(X87QNaN));
1482 EXPECT_FALSE(losesInfo);
1483
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001484 test = APFloat::getSNaN(APFloat::x87DoubleExtended());
1485 test.convert(APFloat::x87DoubleExtended(), APFloat::rmNearestTiesToEven,
Benjamin Kramerb361adb2013-01-25 17:01:00 +00001486 &losesInfo);
1487 EXPECT_TRUE(test.bitwiseIsEqual(X87SNaN));
1488 EXPECT_FALSE(losesInfo);
1489
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001490 test = APFloat::getQNaN(APFloat::x87DoubleExtended());
1491 test.convert(APFloat::x87DoubleExtended(), APFloat::rmNearestTiesToEven,
Benjamin Kramerb361adb2013-01-25 17:01:00 +00001492 &losesInfo);
1493 EXPECT_TRUE(test.bitwiseIsEqual(X87QNaN));
1494 EXPECT_FALSE(losesInfo);
Eli Friedmana84ad7d2011-11-26 03:38:02 +00001495}
Ulrich Weigandd9f7e252012-10-29 18:09:01 +00001496
1497TEST(APFloatTest, PPCDoubleDouble) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001498 APFloat test(APFloat::PPCDoubleDouble(), "1.0");
Ulrich Weigandd9f7e252012-10-29 18:09:01 +00001499 EXPECT_EQ(0x3ff0000000000000ull, test.bitcastToAPInt().getRawData()[0]);
1500 EXPECT_EQ(0x0000000000000000ull, test.bitcastToAPInt().getRawData()[1]);
1501
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001502 test.divide(APFloat(APFloat::PPCDoubleDouble(), "3.0"), APFloat::rmNearestTiesToEven);
Ulrich Weigandd9f7e252012-10-29 18:09:01 +00001503 EXPECT_EQ(0x3fd5555555555555ull, test.bitcastToAPInt().getRawData()[0]);
1504 EXPECT_EQ(0x3c75555555555556ull, test.bitcastToAPInt().getRawData()[1]);
1505
1506 // LDBL_MAX
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001507 test = APFloat(APFloat::PPCDoubleDouble(), "1.79769313486231580793728971405301e+308");
Ulrich Weigandd9f7e252012-10-29 18:09:01 +00001508 EXPECT_EQ(0x7fefffffffffffffull, test.bitcastToAPInt().getRawData()[0]);
1509 EXPECT_EQ(0x7c8ffffffffffffeull, test.bitcastToAPInt().getRawData()[1]);
1510
1511 // LDBL_MIN
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001512 test = APFloat(APFloat::PPCDoubleDouble(), "2.00416836000897277799610805135016e-292");
Ulrich Weigandd9f7e252012-10-29 18:09:01 +00001513 EXPECT_EQ(0x0360000000000000ull, test.bitcastToAPInt().getRawData()[0]);
1514 EXPECT_EQ(0x0000000000000000ull, test.bitcastToAPInt().getRawData()[1]);
1515
Tim Shen398f90f2016-11-06 07:38:37 +00001516 // PR30869
1517 {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001518 auto Result = APFloat(APFloat::PPCDoubleDouble(), "1.0") +
1519 APFloat(APFloat::PPCDoubleDouble(), "1.0");
1520 EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics());
Tim Shen398f90f2016-11-06 07:38:37 +00001521
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001522 Result = APFloat(APFloat::PPCDoubleDouble(), "1.0") -
1523 APFloat(APFloat::PPCDoubleDouble(), "1.0");
1524 EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics());
Tim Shen398f90f2016-11-06 07:38:37 +00001525
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001526 Result = APFloat(APFloat::PPCDoubleDouble(), "1.0") *
1527 APFloat(APFloat::PPCDoubleDouble(), "1.0");
1528 EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics());
Tim Shen398f90f2016-11-06 07:38:37 +00001529
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001530 Result = APFloat(APFloat::PPCDoubleDouble(), "1.0") /
1531 APFloat(APFloat::PPCDoubleDouble(), "1.0");
1532 EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics());
Tim Shen398f90f2016-11-06 07:38:37 +00001533
1534 int Exp;
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001535 Result = frexp(APFloat(APFloat::PPCDoubleDouble(), "1.0"), Exp,
Tim Shen398f90f2016-11-06 07:38:37 +00001536 APFloat::rmNearestTiesToEven);
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001537 EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics());
Tim Shen398f90f2016-11-06 07:38:37 +00001538
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001539 Result = scalbn(APFloat(APFloat::PPCDoubleDouble(), "1.0"), 1,
Tim Shen398f90f2016-11-06 07:38:37 +00001540 APFloat::rmNearestTiesToEven);
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001541 EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics());
Tim Shen398f90f2016-11-06 07:38:37 +00001542 }
Ulrich Weigandd9f7e252012-10-29 18:09:01 +00001543}
Michael Gottesman3acedb62013-06-04 03:46:25 +00001544
1545TEST(APFloatTest, isNegative) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001546 APFloat t(APFloat::IEEEsingle(), "0x1p+0");
Michael Gottesman3acedb62013-06-04 03:46:25 +00001547 EXPECT_FALSE(t.isNegative());
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001548 t = APFloat(APFloat::IEEEsingle(), "-0x1p+0");
Michael Gottesman3acedb62013-06-04 03:46:25 +00001549 EXPECT_TRUE(t.isNegative());
Michael Gottesmanf9899292013-06-24 09:58:09 +00001550
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001551 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), false).isNegative());
1552 EXPECT_TRUE(APFloat::getInf(APFloat::IEEEsingle(), true).isNegative());
Michael Gottesmanf9899292013-06-24 09:58:09 +00001553
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001554 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), false).isNegative());
1555 EXPECT_TRUE(APFloat::getZero(APFloat::IEEEsingle(), true).isNegative());
Michael Gottesman3acedb62013-06-04 03:46:25 +00001556
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001557 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), false).isNegative());
1558 EXPECT_TRUE(APFloat::getNaN(APFloat::IEEEsingle(), true).isNegative());
Michael Gottesman3acedb62013-06-04 03:46:25 +00001559
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001560 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isNegative());
1561 EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle(), true).isNegative());
Michael Gottesman3acedb62013-06-04 03:46:25 +00001562}
1563
Michael Gottesman120c92882013-06-20 18:34:38 +00001564TEST(APFloatTest, isNormal) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001565 APFloat t(APFloat::IEEEsingle(), "0x1p+0");
Michael Gottesman120c92882013-06-20 18:34:38 +00001566 EXPECT_TRUE(t.isNormal());
Michael Gottesmanf9899292013-06-24 09:58:09 +00001567
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001568 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), false).isNormal());
1569 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), false).isNormal());
1570 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), false).isNormal());
1571 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isNormal());
1572 EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), "0x1p-149").isNormal());
Michael Gottesman3acedb62013-06-04 03:46:25 +00001573}
1574
1575TEST(APFloatTest, isFinite) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001576 APFloat t(APFloat::IEEEsingle(), "0x1p+0");
Michael Gottesmanf9899292013-06-24 09:58:09 +00001577 EXPECT_TRUE(t.isFinite());
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001578 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), false).isFinite());
1579 EXPECT_TRUE(APFloat::getZero(APFloat::IEEEsingle(), false).isFinite());
1580 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), false).isFinite());
1581 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isFinite());
1582 EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "0x1p-149").isFinite());
Michael Gottesman3acedb62013-06-04 03:46:25 +00001583}
1584
1585TEST(APFloatTest, isInfinity) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001586 APFloat t(APFloat::IEEEsingle(), "0x1p+0");
Michael Gottesman3acedb62013-06-04 03:46:25 +00001587 EXPECT_FALSE(t.isInfinity());
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001588 EXPECT_TRUE(APFloat::getInf(APFloat::IEEEsingle(), false).isInfinity());
1589 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), false).isInfinity());
1590 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), false).isInfinity());
1591 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isInfinity());
1592 EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), "0x1p-149").isInfinity());
Michael Gottesman3acedb62013-06-04 03:46:25 +00001593}
1594
1595TEST(APFloatTest, isNaN) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001596 APFloat t(APFloat::IEEEsingle(), "0x1p+0");
Michael Gottesmanf9899292013-06-24 09:58:09 +00001597 EXPECT_FALSE(t.isNaN());
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001598 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), false).isNaN());
1599 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), false).isNaN());
1600 EXPECT_TRUE(APFloat::getNaN(APFloat::IEEEsingle(), false).isNaN());
1601 EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isNaN());
1602 EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), "0x1p-149").isNaN());
Michael Gottesman3acedb62013-06-04 03:46:25 +00001603}
1604
Michael Gottesmand95d4472013-06-19 21:00:17 +00001605TEST(APFloatTest, isFiniteNonZero) {
1606 // Test positive/negative normal value.
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001607 EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "0x1p+0").isFiniteNonZero());
1608 EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "-0x1p+0").isFiniteNonZero());
Michael Gottesmand95d4472013-06-19 21:00:17 +00001609
1610 // Test positive/negative denormal value.
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001611 EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "0x1p-149").isFiniteNonZero());
1612 EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "-0x1p-149").isFiniteNonZero());
Michael Gottesmand95d4472013-06-19 21:00:17 +00001613
1614 // Test +/- Infinity.
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001615 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), false).isFiniteNonZero());
1616 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), true).isFiniteNonZero());
Michael Gottesmand95d4472013-06-19 21:00:17 +00001617
1618 // Test +/- Zero.
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001619 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), false).isFiniteNonZero());
1620 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), true).isFiniteNonZero());
Michael Gottesmand95d4472013-06-19 21:00:17 +00001621
1622 // Test +/- qNaN. +/- dont mean anything with qNaN but paranoia can't hurt in
1623 // this instance.
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001624 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), false).isFiniteNonZero());
1625 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), true).isFiniteNonZero());
Michael Gottesmand95d4472013-06-19 21:00:17 +00001626
1627 // Test +/- sNaN. +/- dont mean anything with sNaN but paranoia can't hurt in
1628 // this instance.
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001629 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isFiniteNonZero());
1630 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), true).isFiniteNonZero());
Michael Gottesmand95d4472013-06-19 21:00:17 +00001631}
1632
Michael Gottesmane45b1082013-06-24 09:58:07 +00001633TEST(APFloatTest, add) {
1634 // Test Special Cases against each other and normal values.
1635
1636 // TODOS/NOTES:
1637 // 1. Since we perform only default exception handling all operations with
1638 // signaling NaNs should have a result that is a quiet NaN. Currently they
1639 // return sNaN.
Michael Gottesmane45b1082013-06-24 09:58:07 +00001640
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001641 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle(), false);
1642 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle(), true);
1643 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle(), false);
1644 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle(), true);
1645 APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);
1646 APFloat SNaN = APFloat::getSNaN(APFloat::IEEEsingle(), false);
1647 APFloat PNormalValue = APFloat(APFloat::IEEEsingle(), "0x1p+0");
1648 APFloat MNormalValue = APFloat(APFloat::IEEEsingle(), "-0x1p+0");
1649 APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), false);
1650 APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), true);
1651 APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), false);
1652 APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), true);
Michael Gottesmane45b1082013-06-24 09:58:07 +00001653 APFloat PSmallestNormalized =
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001654 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);
Michael Gottesmane45b1082013-06-24 09:58:07 +00001655 APFloat MSmallestNormalized =
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001656 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);
Michael Gottesmane45b1082013-06-24 09:58:07 +00001657
1658 const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact;
1659
1660 const unsigned NumTests = 169;
1661 struct {
1662 APFloat x;
1663 APFloat y;
1664 const char *result;
1665 int status;
1666 int category;
1667 } SpecialCaseTests[NumTests] = {
1668 { PInf, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1669 { PInf, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1670 { PInf, PZero, "inf", APFloat::opOK, APFloat::fcInfinity },
1671 { PInf, MZero, "inf", APFloat::opOK, APFloat::fcInfinity },
1672 { PInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
1673#if 0
1674 // See Note 1.
1675 { PInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1676#endif
1677 { PInf, PNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1678 { PInf, MNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1679 { PInf, PLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1680 { PInf, MLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1681 { PInf, PSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1682 { PInf, MSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1683 { PInf, PSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
1684 { PInf, MSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
1685 { MInf, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1686 { MInf, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1687 { MInf, PZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
1688 { MInf, MZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00001689 { MInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmane45b1082013-06-24 09:58:07 +00001690#if 0
1691 // See Note 1.
1692 { MInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1693#endif
1694 { MInf, PNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1695 { MInf, MNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1696 { MInf, PLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1697 { MInf, MLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1698 { MInf, PSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1699 { MInf, MSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1700 { MInf, PSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
1701 { MInf, MSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
1702 { PZero, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1703 { PZero, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1704 { PZero, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1705 { PZero, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1706 { PZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
1707#if 0
1708 // See Note 1.
1709 { PZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1710#endif
1711 { PZero, PNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
1712 { PZero, MNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
1713 { PZero, PLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1714 { PZero, MLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1715 { PZero, PSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
1716 { PZero, MSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
1717 { PZero, PSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
1718 { PZero, MSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
1719 { MZero, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1720 { MZero, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1721 { MZero, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1722 { MZero, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00001723 { MZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmane45b1082013-06-24 09:58:07 +00001724#if 0
1725 // See Note 1.
1726 { MZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1727#endif
1728 { MZero, PNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
1729 { MZero, MNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
1730 { MZero, PLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1731 { MZero, MLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1732 { MZero, PSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
1733 { MZero, MSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
1734 { MZero, PSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
1735 { MZero, MSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
1736 { QNaN, PInf, "nan", APFloat::opOK, APFloat::fcNaN },
1737 { QNaN, MInf, "nan", APFloat::opOK, APFloat::fcNaN },
1738 { QNaN, PZero, "nan", APFloat::opOK, APFloat::fcNaN },
1739 { QNaN, MZero, "nan", APFloat::opOK, APFloat::fcNaN },
1740 { QNaN, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
1741#if 0
1742 // See Note 1.
1743 { QNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1744#endif
1745 { QNaN, PNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
1746 { QNaN, MNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
1747 { QNaN, PLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
1748 { QNaN, MLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
1749 { QNaN, PSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
1750 { QNaN, MSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
1751 { QNaN, PSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
1752 { QNaN, MSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
1753#if 0
1754 // See Note 1.
1755 { SNaN, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1756 { SNaN, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1757 { SNaN, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1758 { SNaN, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1759 { SNaN, QNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1760 { SNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1761 { SNaN, PNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1762 { SNaN, MNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1763 { SNaN, PLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1764 { SNaN, MLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1765 { SNaN, PSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1766 { SNaN, MSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1767 { SNaN, PSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1768 { SNaN, MSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1769#endif
1770 { PNormalValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1771 { PNormalValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1772 { PNormalValue, PZero, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
1773 { PNormalValue, MZero, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
1774 { PNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
1775#if 0
1776 // See Note 1.
1777 { PNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1778#endif
1779 { PNormalValue, PNormalValue, "0x1p+1", APFloat::opOK, APFloat::fcNormal },
1780 { PNormalValue, MNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1781 { PNormalValue, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1782 { PNormalValue, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1783 { PNormalValue, PSmallestValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1784 { PNormalValue, MSmallestValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1785 { PNormalValue, PSmallestNormalized, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1786 { PNormalValue, MSmallestNormalized, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1787 { MNormalValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1788 { MNormalValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1789 { MNormalValue, PZero, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
1790 { MNormalValue, MZero, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00001791 { MNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmane45b1082013-06-24 09:58:07 +00001792#if 0
1793 // See Note 1.
1794 { MNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1795#endif
1796 { MNormalValue, PNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1797 { MNormalValue, MNormalValue, "-0x1p+1", APFloat::opOK, APFloat::fcNormal },
1798 { MNormalValue, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1799 { MNormalValue, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1800 { MNormalValue, PSmallestValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1801 { MNormalValue, MSmallestValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1802 { MNormalValue, PSmallestNormalized, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1803 { MNormalValue, MSmallestNormalized, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1804 { PLargestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1805 { PLargestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1806 { PLargestValue, PZero, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1807 { PLargestValue, MZero, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1808 { PLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
1809#if 0
1810 // See Note 1.
1811 { PLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1812#endif
1813 { PLargestValue, PNormalValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1814 { PLargestValue, MNormalValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1815 { PLargestValue, PLargestValue, "inf", OverflowStatus, APFloat::fcInfinity },
1816 { PLargestValue, MLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1817 { PLargestValue, PSmallestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1818 { PLargestValue, MSmallestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1819 { PLargestValue, PSmallestNormalized, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1820 { PLargestValue, MSmallestNormalized, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1821 { MLargestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1822 { MLargestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1823 { MLargestValue, PZero, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
1824 { MLargestValue, MZero, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00001825 { MLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmane45b1082013-06-24 09:58:07 +00001826#if 0
1827 // See Note 1.
1828 { MLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1829#endif
1830 { MLargestValue, PNormalValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1831 { MLargestValue, MNormalValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1832 { MLargestValue, PLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1833 { MLargestValue, MLargestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
1834 { MLargestValue, PSmallestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1835 { MLargestValue, MSmallestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1836 { MLargestValue, PSmallestNormalized, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1837 { MLargestValue, MSmallestNormalized, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1838 { PSmallestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1839 { PSmallestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1840 { PSmallestValue, PZero, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
1841 { PSmallestValue, MZero, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
1842 { PSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
1843#if 0
1844 // See Note 1.
1845 { PSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1846#endif
1847 { PSmallestValue, PNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1848 { PSmallestValue, MNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1849 { PSmallestValue, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1850 { PSmallestValue, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1851 { PSmallestValue, PSmallestValue, "0x1p-148", APFloat::opOK, APFloat::fcNormal },
1852 { PSmallestValue, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1853 { PSmallestValue, PSmallestNormalized, "0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
1854 { PSmallestValue, MSmallestNormalized, "-0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
1855 { MSmallestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1856 { MSmallestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1857 { MSmallestValue, PZero, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
1858 { MSmallestValue, MZero, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00001859 { MSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmane45b1082013-06-24 09:58:07 +00001860#if 0
1861 // See Note 1.
1862 { MSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1863#endif
1864 { MSmallestValue, PNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1865 { MSmallestValue, MNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1866 { MSmallestValue, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1867 { MSmallestValue, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1868 { MSmallestValue, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1869 { MSmallestValue, MSmallestValue, "-0x1p-148", APFloat::opOK, APFloat::fcNormal },
1870 { MSmallestValue, PSmallestNormalized, "0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
1871 { MSmallestValue, MSmallestNormalized, "-0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
1872 { PSmallestNormalized, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1873 { PSmallestNormalized, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1874 { PSmallestNormalized, PZero, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
1875 { PSmallestNormalized, MZero, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
1876 { PSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
1877#if 0
1878// See Note 1.
1879 { PSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1880#endif
1881 { PSmallestNormalized, PNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1882 { PSmallestNormalized, MNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1883 { PSmallestNormalized, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1884 { PSmallestNormalized, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1885 { PSmallestNormalized, PSmallestValue, "0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
1886 { PSmallestNormalized, MSmallestValue, "0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
1887 { PSmallestNormalized, PSmallestNormalized, "0x1p-125", APFloat::opOK, APFloat::fcNormal },
1888 { PSmallestNormalized, MSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1889 { MSmallestNormalized, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1890 { MSmallestNormalized, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1891 { MSmallestNormalized, PZero, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
1892 { MSmallestNormalized, MZero, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00001893 { MSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmane45b1082013-06-24 09:58:07 +00001894#if 0
1895 // See Note 1.
1896 { MSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1897#endif
1898 { MSmallestNormalized, PNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1899 { MSmallestNormalized, MNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
1900 { MSmallestNormalized, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1901 { MSmallestNormalized, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
1902 { MSmallestNormalized, PSmallestValue, "-0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
1903 { MSmallestNormalized, MSmallestValue, "-0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
1904 { MSmallestNormalized, PSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1905 { MSmallestNormalized, MSmallestNormalized, "-0x1p-125", APFloat::opOK, APFloat::fcNormal }
1906 };
1907
1908 for (size_t i = 0; i < NumTests; ++i) {
1909 APFloat x(SpecialCaseTests[i].x);
1910 APFloat y(SpecialCaseTests[i].y);
1911 APFloat::opStatus status = x.add(y, APFloat::rmNearestTiesToEven);
1912
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001913 APFloat result(APFloat::IEEEsingle(), SpecialCaseTests[i].result);
Michael Gottesmane45b1082013-06-24 09:58:07 +00001914
Michael Gottesmane45b1082013-06-24 09:58:07 +00001915 EXPECT_TRUE(result.bitwiseIsEqual(x));
1916 EXPECT_TRUE((int)status == SpecialCaseTests[i].status);
1917 EXPECT_TRUE((int)x.getCategory() == SpecialCaseTests[i].category);
1918 }
1919}
1920
Michael Gottesman9368a532013-06-26 23:55:23 +00001921TEST(APFloatTest, subtract) {
1922 // Test Special Cases against each other and normal values.
1923
1924 // TODOS/NOTES:
1925 // 1. Since we perform only default exception handling all operations with
1926 // signaling NaNs should have a result that is a quiet NaN. Currently they
1927 // return sNaN.
Michael Gottesman9368a532013-06-26 23:55:23 +00001928
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001929 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle(), false);
1930 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle(), true);
1931 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle(), false);
1932 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle(), true);
1933 APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);
1934 APFloat SNaN = APFloat::getSNaN(APFloat::IEEEsingle(), false);
1935 APFloat PNormalValue = APFloat(APFloat::IEEEsingle(), "0x1p+0");
1936 APFloat MNormalValue = APFloat(APFloat::IEEEsingle(), "-0x1p+0");
1937 APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), false);
1938 APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), true);
1939 APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), false);
1940 APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), true);
Michael Gottesman9368a532013-06-26 23:55:23 +00001941 APFloat PSmallestNormalized =
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001942 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);
Michael Gottesman9368a532013-06-26 23:55:23 +00001943 APFloat MSmallestNormalized =
Stephan Bergmann17c7f702016-12-14 11:57:17 +00001944 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);
Michael Gottesman9368a532013-06-26 23:55:23 +00001945
1946 const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact;
1947
1948 const unsigned NumTests = 169;
1949 struct {
1950 APFloat x;
1951 APFloat y;
1952 const char *result;
1953 int status;
1954 int category;
1955 } SpecialCaseTests[NumTests] = {
1956 { PInf, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1957 { PInf, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1958 { PInf, PZero, "inf", APFloat::opOK, APFloat::fcInfinity },
1959 { PInf, MZero, "inf", APFloat::opOK, APFloat::fcInfinity },
Stephen Canond3278282014-06-08 16:53:31 +00001960 { PInf, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00001961#if 0
1962// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00001963 { PInf, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00001964#endif
1965 { PInf, PNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1966 { PInf, MNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1967 { PInf, PLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1968 { PInf, MLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1969 { PInf, PSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1970 { PInf, MSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
1971 { PInf, PSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
1972 { PInf, MSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
1973 { MInf, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1974 { MInf, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
1975 { MInf, PZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
1976 { MInf, MZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
Stephen Canond3278282014-06-08 16:53:31 +00001977 { MInf, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00001978#if 0
1979// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00001980 { MInf, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00001981#endif
1982 { MInf, PNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1983 { MInf, MNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1984 { MInf, PLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1985 { MInf, MLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1986 { MInf, PSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1987 { MInf, MSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
1988 { MInf, PSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
1989 { MInf, MSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
1990 { PZero, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
1991 { PZero, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
1992 { PZero, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
1993 { PZero, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
Stephen Canond3278282014-06-08 16:53:31 +00001994 { PZero, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00001995#if 0
1996// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00001997 { PZero, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00001998#endif
1999 { PZero, PNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2000 { PZero, MNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2001 { PZero, PLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2002 { PZero, MLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2003 { PZero, PSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2004 { PZero, MSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2005 { PZero, PSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2006 { PZero, MSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2007 { MZero, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2008 { MZero, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2009 { MZero, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2010 { MZero, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
Stephen Canond3278282014-06-08 16:53:31 +00002011 { MZero, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002012#if 0
2013// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002014 { MZero, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002015#endif
2016 { MZero, PNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2017 { MZero, MNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2018 { MZero, PLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2019 { MZero, MLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2020 { MZero, PSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2021 { MZero, MSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2022 { MZero, PSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2023 { MZero, MSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2024 { QNaN, PInf, "nan", APFloat::opOK, APFloat::fcNaN },
2025 { QNaN, MInf, "nan", APFloat::opOK, APFloat::fcNaN },
2026 { QNaN, PZero, "nan", APFloat::opOK, APFloat::fcNaN },
2027 { QNaN, MZero, "nan", APFloat::opOK, APFloat::fcNaN },
2028 { QNaN, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2029#if 0
2030// See Note 1.
2031 { QNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2032#endif
2033 { QNaN, PNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
2034 { QNaN, MNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
2035 { QNaN, PLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
2036 { QNaN, MLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
2037 { QNaN, PSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
2038 { QNaN, MSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
2039 { QNaN, PSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
2040 { QNaN, MSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
2041#if 0
2042// See Note 1.
2043 { SNaN, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2044 { SNaN, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2045 { SNaN, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2046 { SNaN, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2047 { SNaN, QNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2048 { SNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2049 { SNaN, PNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2050 { SNaN, MNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2051 { SNaN, PLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2052 { SNaN, MLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2053 { SNaN, PSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2054 { SNaN, MSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2055 { SNaN, PSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2056 { SNaN, MSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2057#endif
2058 { PNormalValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2059 { PNormalValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2060 { PNormalValue, PZero, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2061 { PNormalValue, MZero, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
Stephen Canond3278282014-06-08 16:53:31 +00002062 { PNormalValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002063#if 0
2064// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002065 { PNormalValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002066#endif
2067 { PNormalValue, PNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2068 { PNormalValue, MNormalValue, "0x1p+1", APFloat::opOK, APFloat::fcNormal },
2069 { PNormalValue, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2070 { PNormalValue, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2071 { PNormalValue, PSmallestValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2072 { PNormalValue, MSmallestValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2073 { PNormalValue, PSmallestNormalized, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2074 { PNormalValue, MSmallestNormalized, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2075 { MNormalValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2076 { MNormalValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2077 { MNormalValue, PZero, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2078 { MNormalValue, MZero, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
Stephen Canond3278282014-06-08 16:53:31 +00002079 { MNormalValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002080#if 0
2081// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002082 { MNormalValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002083#endif
2084 { MNormalValue, PNormalValue, "-0x1p+1", APFloat::opOK, APFloat::fcNormal },
2085 { MNormalValue, MNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2086 { MNormalValue, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2087 { MNormalValue, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2088 { MNormalValue, PSmallestValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2089 { MNormalValue, MSmallestValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2090 { MNormalValue, PSmallestNormalized, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2091 { MNormalValue, MSmallestNormalized, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2092 { PLargestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2093 { PLargestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2094 { PLargestValue, PZero, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2095 { PLargestValue, MZero, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
Stephen Canond3278282014-06-08 16:53:31 +00002096 { PLargestValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002097#if 0
2098// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002099 { PLargestValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002100#endif
2101 { PLargestValue, PNormalValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2102 { PLargestValue, MNormalValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2103 { PLargestValue, PLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2104 { PLargestValue, MLargestValue, "inf", OverflowStatus, APFloat::fcInfinity },
2105 { PLargestValue, PSmallestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2106 { PLargestValue, MSmallestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2107 { PLargestValue, PSmallestNormalized, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2108 { PLargestValue, MSmallestNormalized, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2109 { MLargestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2110 { MLargestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2111 { MLargestValue, PZero, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2112 { MLargestValue, MZero, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
Stephen Canond3278282014-06-08 16:53:31 +00002113 { MLargestValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002114#if 0
2115// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002116 { MLargestValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002117#endif
2118 { MLargestValue, PNormalValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2119 { MLargestValue, MNormalValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2120 { MLargestValue, PLargestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
2121 { MLargestValue, MLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2122 { MLargestValue, PSmallestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2123 { MLargestValue, MSmallestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2124 { MLargestValue, PSmallestNormalized, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2125 { MLargestValue, MSmallestNormalized, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2126 { PSmallestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2127 { PSmallestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2128 { PSmallestValue, PZero, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2129 { PSmallestValue, MZero, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
Stephen Canond3278282014-06-08 16:53:31 +00002130 { PSmallestValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002131#if 0
2132// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002133 { PSmallestValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002134#endif
2135 { PSmallestValue, PNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2136 { PSmallestValue, MNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2137 { PSmallestValue, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2138 { PSmallestValue, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2139 { PSmallestValue, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2140 { PSmallestValue, MSmallestValue, "0x1p-148", APFloat::opOK, APFloat::fcNormal },
2141 { PSmallestValue, PSmallestNormalized, "-0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
2142 { PSmallestValue, MSmallestNormalized, "0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
2143 { MSmallestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2144 { MSmallestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2145 { MSmallestValue, PZero, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2146 { MSmallestValue, MZero, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
Stephen Canond3278282014-06-08 16:53:31 +00002147 { MSmallestValue, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002148#if 0
2149// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002150 { MSmallestValue, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002151#endif
2152 { MSmallestValue, PNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2153 { MSmallestValue, MNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2154 { MSmallestValue, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2155 { MSmallestValue, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2156 { MSmallestValue, PSmallestValue, "-0x1p-148", APFloat::opOK, APFloat::fcNormal },
2157 { MSmallestValue, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2158 { MSmallestValue, PSmallestNormalized, "-0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
2159 { MSmallestValue, MSmallestNormalized, "0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
2160 { PSmallestNormalized, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2161 { PSmallestNormalized, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2162 { PSmallestNormalized, PZero, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2163 { PSmallestNormalized, MZero, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
Stephen Canond3278282014-06-08 16:53:31 +00002164 { PSmallestNormalized, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002165#if 0
2166// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002167 { PSmallestNormalized, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002168#endif
2169 { PSmallestNormalized, PNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2170 { PSmallestNormalized, MNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2171 { PSmallestNormalized, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2172 { PSmallestNormalized, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2173 { PSmallestNormalized, PSmallestValue, "0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
2174 { PSmallestNormalized, MSmallestValue, "0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
2175 { PSmallestNormalized, PSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2176 { PSmallestNormalized, MSmallestNormalized, "0x1p-125", APFloat::opOK, APFloat::fcNormal },
2177 { MSmallestNormalized, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2178 { MSmallestNormalized, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2179 { MSmallestNormalized, PZero, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2180 { MSmallestNormalized, MZero, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
Stephen Canond3278282014-06-08 16:53:31 +00002181 { MSmallestNormalized, QNaN, "-nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002182#if 0
2183// See Note 1.
Stephen Canond3278282014-06-08 16:53:31 +00002184 { MSmallestNormalized, SNaN, "-nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesman9368a532013-06-26 23:55:23 +00002185#endif
2186 { MSmallestNormalized, PNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2187 { MSmallestNormalized, MNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },
2188 { MSmallestNormalized, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2189 { MSmallestNormalized, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },
2190 { MSmallestNormalized, PSmallestValue, "-0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },
2191 { MSmallestNormalized, MSmallestValue, "-0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },
2192 { MSmallestNormalized, PSmallestNormalized, "-0x1p-125", APFloat::opOK, APFloat::fcNormal },
2193 { MSmallestNormalized, MSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero }
2194 };
2195
2196 for (size_t i = 0; i < NumTests; ++i) {
2197 APFloat x(SpecialCaseTests[i].x);
2198 APFloat y(SpecialCaseTests[i].y);
2199 APFloat::opStatus status = x.subtract(y, APFloat::rmNearestTiesToEven);
2200
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002201 APFloat result(APFloat::IEEEsingle(), SpecialCaseTests[i].result);
Michael Gottesman9368a532013-06-26 23:55:23 +00002202
Michael Gottesman9368a532013-06-26 23:55:23 +00002203 EXPECT_TRUE(result.bitwiseIsEqual(x));
2204 EXPECT_TRUE((int)status == SpecialCaseTests[i].status);
2205 EXPECT_TRUE((int)x.getCategory() == SpecialCaseTests[i].category);
2206 }
2207}
2208
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002209TEST(APFloatTest, multiply) {
2210 // Test Special Cases against each other and normal values.
2211
2212 // TODOS/NOTES:
2213 // 1. Since we perform only default exception handling all operations with
2214 // signaling NaNs should have a result that is a quiet NaN. Currently they
2215 // return sNaN.
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002216
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002217 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle(), false);
2218 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle(), true);
2219 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle(), false);
2220 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle(), true);
2221 APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);
2222 APFloat SNaN = APFloat::getSNaN(APFloat::IEEEsingle(), false);
2223 APFloat PNormalValue = APFloat(APFloat::IEEEsingle(), "0x1p+0");
2224 APFloat MNormalValue = APFloat(APFloat::IEEEsingle(), "-0x1p+0");
2225 APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), false);
2226 APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), true);
2227 APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), false);
2228 APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), true);
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002229 APFloat PSmallestNormalized =
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002230 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002231 APFloat MSmallestNormalized =
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002232 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002233
2234 const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact;
2235 const int UnderflowStatus = APFloat::opUnderflow | APFloat::opInexact;
2236
2237 const unsigned NumTests = 169;
2238 struct {
2239 APFloat x;
2240 APFloat y;
2241 const char *result;
2242 int status;
2243 int category;
2244 } SpecialCaseTests[NumTests] = {
2245 { PInf, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2246 { PInf, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2247 { PInf, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2248 { PInf, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2249 { PInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2250#if 0
2251// See Note 1.
2252 { PInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2253#endif
2254 { PInf, PNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2255 { PInf, MNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2256 { PInf, PLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2257 { PInf, MLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2258 { PInf, PSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2259 { PInf, MSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2260 { PInf, PSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
2261 { PInf, MSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
2262 { MInf, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2263 { MInf, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2264 { MInf, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2265 { MInf, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002266 { MInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002267#if 0
2268// See Note 1.
2269 { MInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2270#endif
2271 { MInf, PNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2272 { MInf, MNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2273 { MInf, PLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2274 { MInf, MLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2275 { MInf, PSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2276 { MInf, MSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2277 { MInf, PSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
2278 { MInf, MSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
2279 { PZero, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2280 { PZero, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2281 { PZero, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2282 { PZero, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2283 { PZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2284#if 0
2285// See Note 1.
2286 { PZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2287#endif
2288 { PZero, PNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2289 { PZero, MNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2290 { PZero, PLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2291 { PZero, MLargestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2292 { PZero, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2293 { PZero, MSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2294 { PZero, PSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2295 { PZero, MSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2296 { MZero, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2297 { MZero, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2298 { MZero, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2299 { MZero, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002300 { MZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002301#if 0
2302// See Note 1.
2303 { MZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2304#endif
2305 { MZero, PNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2306 { MZero, MNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2307 { MZero, PLargestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2308 { MZero, MLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2309 { MZero, PSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2310 { MZero, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2311 { MZero, PSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2312 { MZero, MSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2313 { QNaN, PInf, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002314 { QNaN, MInf, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002315 { QNaN, PZero, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002316 { QNaN, MZero, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002317 { QNaN, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2318#if 0
2319// See Note 1.
2320 { QNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2321#endif
2322 { QNaN, PNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002323 { QNaN, MNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002324 { QNaN, PLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002325 { QNaN, MLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002326 { QNaN, PSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002327 { QNaN, MSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002328 { QNaN, PSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002329 { QNaN, MSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002330#if 0
2331// See Note 1.
2332 { SNaN, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2333 { SNaN, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2334 { SNaN, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2335 { SNaN, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2336 { SNaN, QNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2337 { SNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2338 { SNaN, PNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2339 { SNaN, MNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2340 { SNaN, PLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2341 { SNaN, MLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2342 { SNaN, PSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2343 { SNaN, MSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2344 { SNaN, PSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2345 { SNaN, MSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2346#endif
2347 { PNormalValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2348 { PNormalValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2349 { PNormalValue, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2350 { PNormalValue, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2351 { PNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2352#if 0
2353// See Note 1.
2354 { PNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2355#endif
2356 { PNormalValue, PNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2357 { PNormalValue, MNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2358 { PNormalValue, PLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2359 { PNormalValue, MLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2360 { PNormalValue, PSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2361 { PNormalValue, MSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2362 { PNormalValue, PSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2363 { PNormalValue, MSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2364 { MNormalValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2365 { MNormalValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2366 { MNormalValue, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2367 { MNormalValue, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002368 { MNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002369#if 0
2370// See Note 1.
2371 { MNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2372#endif
2373 { MNormalValue, PNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2374 { MNormalValue, MNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2375 { MNormalValue, PLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2376 { MNormalValue, MLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2377 { MNormalValue, PSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2378 { MNormalValue, MSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2379 { MNormalValue, PSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2380 { MNormalValue, MSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2381 { PLargestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2382 { PLargestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2383 { PLargestValue, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2384 { PLargestValue, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2385 { PLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2386#if 0
2387// See Note 1.
2388 { PLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2389#endif
2390 { PLargestValue, PNormalValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2391 { PLargestValue, MNormalValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2392 { PLargestValue, PLargestValue, "inf", OverflowStatus, APFloat::fcInfinity },
2393 { PLargestValue, MLargestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
2394 { PLargestValue, PSmallestValue, "0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2395 { PLargestValue, MSmallestValue, "-0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2396 { PLargestValue, PSmallestNormalized, "0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2397 { PLargestValue, MSmallestNormalized, "-0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2398 { MLargestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2399 { MLargestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2400 { MLargestValue, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2401 { MLargestValue, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002402 { MLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002403#if 0
2404// See Note 1.
2405 { MLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2406#endif
2407 { MLargestValue, PNormalValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2408 { MLargestValue, MNormalValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2409 { MLargestValue, PLargestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
2410 { MLargestValue, MLargestValue, "inf", OverflowStatus, APFloat::fcInfinity },
2411 { MLargestValue, PSmallestValue, "-0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2412 { MLargestValue, MSmallestValue, "0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2413 { MLargestValue, PSmallestNormalized, "-0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2414 { MLargestValue, MSmallestNormalized, "0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2415 { PSmallestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2416 { PSmallestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2417 { PSmallestValue, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2418 { PSmallestValue, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2419 { PSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2420#if 0
2421// See Note 1.
2422 { PSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2423#endif
2424 { PSmallestValue, PNormalValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2425 { PSmallestValue, MNormalValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2426 { PSmallestValue, PLargestValue, "0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2427 { PSmallestValue, MLargestValue, "-0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2428 { PSmallestValue, PSmallestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2429 { PSmallestValue, MSmallestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2430 { PSmallestValue, PSmallestNormalized, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2431 { PSmallestValue, MSmallestNormalized, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2432 { MSmallestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2433 { MSmallestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2434 { MSmallestValue, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2435 { MSmallestValue, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002436 { MSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002437#if 0
2438// See Note 1.
2439 { MSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2440#endif
2441 { MSmallestValue, PNormalValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2442 { MSmallestValue, MNormalValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2443 { MSmallestValue, PLargestValue, "-0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2444 { MSmallestValue, MLargestValue, "0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },
2445 { MSmallestValue, PSmallestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2446 { MSmallestValue, MSmallestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2447 { MSmallestValue, PSmallestNormalized, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2448 { MSmallestValue, MSmallestNormalized, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2449 { PSmallestNormalized, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2450 { PSmallestNormalized, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2451 { PSmallestNormalized, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2452 { PSmallestNormalized, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2453 { PSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2454#if 0
2455// See Note 1.
2456 { PSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2457#endif
2458 { PSmallestNormalized, PNormalValue, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2459 { PSmallestNormalized, MNormalValue, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2460 { PSmallestNormalized, PLargestValue, "0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2461 { PSmallestNormalized, MLargestValue, "-0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2462 { PSmallestNormalized, PSmallestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2463 { PSmallestNormalized, MSmallestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2464 { PSmallestNormalized, PSmallestNormalized, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2465 { PSmallestNormalized, MSmallestNormalized, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2466 { MSmallestNormalized, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },
2467 { MSmallestNormalized, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },
2468 { MSmallestNormalized, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2469 { MSmallestNormalized, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002470 { MSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002471#if 0
2472// See Note 1.
2473 { MSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2474#endif
2475 { MSmallestNormalized, PNormalValue, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2476 { MSmallestNormalized, MNormalValue, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2477 { MSmallestNormalized, PLargestValue, "-0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2478 { MSmallestNormalized, MLargestValue, "0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },
2479 { MSmallestNormalized, PSmallestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2480 { MSmallestNormalized, MSmallestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2481 { MSmallestNormalized, PSmallestNormalized, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2482 { MSmallestNormalized, MSmallestNormalized, "0x0p+0", UnderflowStatus, APFloat::fcZero }
2483 };
2484
2485 for (size_t i = 0; i < NumTests; ++i) {
2486 APFloat x(SpecialCaseTests[i].x);
2487 APFloat y(SpecialCaseTests[i].y);
2488 APFloat::opStatus status = x.multiply(y, APFloat::rmNearestTiesToEven);
2489
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002490 APFloat result(APFloat::IEEEsingle(), SpecialCaseTests[i].result);
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002491
Michael Gottesman9debdfd2013-06-26 23:55:26 +00002492 EXPECT_TRUE(result.bitwiseIsEqual(x));
2493 EXPECT_TRUE((int)status == SpecialCaseTests[i].status);
2494 EXPECT_TRUE((int)x.getCategory() == SpecialCaseTests[i].category);
2495 }
2496}
Michael Gottesman9368a532013-06-26 23:55:23 +00002497
Michael Gottesman3eacb582013-06-27 00:42:00 +00002498TEST(APFloatTest, divide) {
2499 // Test Special Cases against each other and normal values.
2500
2501 // TODOS/NOTES:
2502 // 1. Since we perform only default exception handling all operations with
2503 // signaling NaNs should have a result that is a quiet NaN. Currently they
2504 // return sNaN.
Michael Gottesman3eacb582013-06-27 00:42:00 +00002505
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002506 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle(), false);
2507 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle(), true);
2508 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle(), false);
2509 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle(), true);
2510 APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);
2511 APFloat SNaN = APFloat::getSNaN(APFloat::IEEEsingle(), false);
2512 APFloat PNormalValue = APFloat(APFloat::IEEEsingle(), "0x1p+0");
2513 APFloat MNormalValue = APFloat(APFloat::IEEEsingle(), "-0x1p+0");
2514 APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), false);
2515 APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), true);
2516 APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), false);
2517 APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), true);
Michael Gottesman3eacb582013-06-27 00:42:00 +00002518 APFloat PSmallestNormalized =
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002519 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);
Michael Gottesman3eacb582013-06-27 00:42:00 +00002520 APFloat MSmallestNormalized =
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002521 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);
Michael Gottesman3eacb582013-06-27 00:42:00 +00002522
2523 const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact;
2524 const int UnderflowStatus = APFloat::opUnderflow | APFloat::opInexact;
2525
2526 const unsigned NumTests = 169;
2527 struct {
2528 APFloat x;
2529 APFloat y;
2530 const char *result;
2531 int status;
2532 int category;
2533 } SpecialCaseTests[NumTests] = {
2534 { PInf, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2535 { PInf, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2536 { PInf, PZero, "inf", APFloat::opOK, APFloat::fcInfinity },
2537 { PInf, MZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
2538 { PInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2539#if 0
2540// See Note 1.
2541 { PInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2542#endif
2543 { PInf, PNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2544 { PInf, MNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2545 { PInf, PLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2546 { PInf, MLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2547 { PInf, PSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2548 { PInf, MSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2549 { PInf, PSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
2550 { PInf, MSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
2551 { MInf, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2552 { MInf, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2553 { MInf, PZero, "-inf", APFloat::opOK, APFloat::fcInfinity },
2554 { MInf, MZero, "inf", APFloat::opOK, APFloat::fcInfinity },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002555 { MInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002556#if 0
2557// See Note 1.
2558 { MInf, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2559#endif
2560 { MInf, PNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2561 { MInf, MNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2562 { MInf, PLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2563 { MInf, MLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2564 { MInf, PSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },
2565 { MInf, MSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },
2566 { MInf, PSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },
2567 { MInf, MSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },
2568 { PZero, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2569 { PZero, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2570 { PZero, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2571 { PZero, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2572 { PZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2573#if 0
2574// See Note 1.
2575 { PZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2576#endif
2577 { PZero, PNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2578 { PZero, MNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2579 { PZero, PLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2580 { PZero, MLargestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2581 { PZero, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2582 { PZero, MSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2583 { PZero, PSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2584 { PZero, MSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2585 { MZero, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2586 { MZero, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2587 { MZero, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2588 { MZero, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002589 { MZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002590#if 0
2591// See Note 1.
2592 { MZero, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2593#endif
2594 { MZero, PNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2595 { MZero, MNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2596 { MZero, PLargestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2597 { MZero, MLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2598 { MZero, PSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2599 { MZero, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2600 { MZero, PSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2601 { MZero, MSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2602 { QNaN, PInf, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002603 { QNaN, MInf, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002604 { QNaN, PZero, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002605 { QNaN, MZero, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002606 { QNaN, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2607#if 0
2608// See Note 1.
2609 { QNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2610#endif
2611 { QNaN, PNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002612 { QNaN, MNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002613 { QNaN, PLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002614 { QNaN, MLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002615 { QNaN, PSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002616 { QNaN, MSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002617 { QNaN, PSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002618 { QNaN, MSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002619#if 0
2620// See Note 1.
2621 { SNaN, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2622 { SNaN, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2623 { SNaN, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2624 { SNaN, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2625 { SNaN, QNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2626 { SNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2627 { SNaN, PNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2628 { SNaN, MNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2629 { SNaN, PLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2630 { SNaN, MLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2631 { SNaN, PSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2632 { SNaN, MSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2633 { SNaN, PSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2634 { SNaN, MSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2635#endif
2636 { PNormalValue, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2637 { PNormalValue, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2638 { PNormalValue, PZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
2639 { PNormalValue, MZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2640 { PNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2641#if 0
2642// See Note 1.
2643 { PNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2644#endif
2645 { PNormalValue, PNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2646 { PNormalValue, MNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2647 { PNormalValue, PLargestValue, "0x1p-128", UnderflowStatus, APFloat::fcNormal },
2648 { PNormalValue, MLargestValue, "-0x1p-128", UnderflowStatus, APFloat::fcNormal },
2649 { PNormalValue, PSmallestValue, "inf", OverflowStatus, APFloat::fcInfinity },
2650 { PNormalValue, MSmallestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
2651 { PNormalValue, PSmallestNormalized, "0x1p+126", APFloat::opOK, APFloat::fcNormal },
2652 { PNormalValue, MSmallestNormalized, "-0x1p+126", APFloat::opOK, APFloat::fcNormal },
2653 { MNormalValue, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2654 { MNormalValue, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2655 { MNormalValue, PZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2656 { MNormalValue, MZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002657 { MNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002658#if 0
2659// See Note 1.
2660 { MNormalValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2661#endif
2662 { MNormalValue, PNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2663 { MNormalValue, MNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2664 { MNormalValue, PLargestValue, "-0x1p-128", UnderflowStatus, APFloat::fcNormal },
2665 { MNormalValue, MLargestValue, "0x1p-128", UnderflowStatus, APFloat::fcNormal },
2666 { MNormalValue, PSmallestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
2667 { MNormalValue, MSmallestValue, "inf", OverflowStatus, APFloat::fcInfinity },
2668 { MNormalValue, PSmallestNormalized, "-0x1p+126", APFloat::opOK, APFloat::fcNormal },
2669 { MNormalValue, MSmallestNormalized, "0x1p+126", APFloat::opOK, APFloat::fcNormal },
2670 { PLargestValue, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2671 { PLargestValue, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2672 { PLargestValue, PZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
2673 { PLargestValue, MZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2674 { PLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2675#if 0
2676// See Note 1.
2677 { PLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2678#endif
2679 { PLargestValue, PNormalValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2680 { PLargestValue, MNormalValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2681 { PLargestValue, PLargestValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2682 { PLargestValue, MLargestValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2683 { PLargestValue, PSmallestValue, "inf", OverflowStatus, APFloat::fcInfinity },
2684 { PLargestValue, MSmallestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
2685 { PLargestValue, PSmallestNormalized, "inf", OverflowStatus, APFloat::fcInfinity },
2686 { PLargestValue, MSmallestNormalized, "-inf", OverflowStatus, APFloat::fcInfinity },
2687 { MLargestValue, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2688 { MLargestValue, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2689 { MLargestValue, PZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2690 { MLargestValue, MZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002691 { MLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002692#if 0
2693// See Note 1.
2694 { MLargestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2695#endif
2696 { MLargestValue, PNormalValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2697 { MLargestValue, MNormalValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },
2698 { MLargestValue, PLargestValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2699 { MLargestValue, MLargestValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2700 { MLargestValue, PSmallestValue, "-inf", OverflowStatus, APFloat::fcInfinity },
2701 { MLargestValue, MSmallestValue, "inf", OverflowStatus, APFloat::fcInfinity },
2702 { MLargestValue, PSmallestNormalized, "-inf", OverflowStatus, APFloat::fcInfinity },
2703 { MLargestValue, MSmallestNormalized, "inf", OverflowStatus, APFloat::fcInfinity },
2704 { PSmallestValue, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2705 { PSmallestValue, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2706 { PSmallestValue, PZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
2707 { PSmallestValue, MZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2708 { PSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2709#if 0
2710// See Note 1.
2711 { PSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2712#endif
2713 { PSmallestValue, PNormalValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2714 { PSmallestValue, MNormalValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2715 { PSmallestValue, PLargestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2716 { PSmallestValue, MLargestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2717 { PSmallestValue, PSmallestValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2718 { PSmallestValue, MSmallestValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2719 { PSmallestValue, PSmallestNormalized, "0x1p-23", APFloat::opOK, APFloat::fcNormal },
2720 { PSmallestValue, MSmallestNormalized, "-0x1p-23", APFloat::opOK, APFloat::fcNormal },
2721 { MSmallestValue, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2722 { MSmallestValue, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2723 { MSmallestValue, PZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2724 { MSmallestValue, MZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002725 { MSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002726#if 0
2727// See Note 1.
2728 { MSmallestValue, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2729#endif
2730 { MSmallestValue, PNormalValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },
2731 { MSmallestValue, MNormalValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },
2732 { MSmallestValue, PLargestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2733 { MSmallestValue, MLargestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2734 { MSmallestValue, PSmallestValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2735 { MSmallestValue, MSmallestValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2736 { MSmallestValue, PSmallestNormalized, "-0x1p-23", APFloat::opOK, APFloat::fcNormal },
2737 { MSmallestValue, MSmallestNormalized, "0x1p-23", APFloat::opOK, APFloat::fcNormal },
2738 { PSmallestNormalized, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2739 { PSmallestNormalized, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2740 { PSmallestNormalized, PZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
2741 { PSmallestNormalized, MZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2742 { PSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
2743#if 0
2744// See Note 1.
2745 { PSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2746#endif
2747 { PSmallestNormalized, PNormalValue, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2748 { PSmallestNormalized, MNormalValue, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2749 { PSmallestNormalized, PLargestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2750 { PSmallestNormalized, MLargestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2751 { PSmallestNormalized, PSmallestValue, "0x1p+23", APFloat::opOK, APFloat::fcNormal },
2752 { PSmallestNormalized, MSmallestValue, "-0x1p+23", APFloat::opOK, APFloat::fcNormal },
2753 { PSmallestNormalized, PSmallestNormalized, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2754 { PSmallestNormalized, MSmallestNormalized, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2755 { MSmallestNormalized, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },
2756 { MSmallestNormalized, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },
2757 { MSmallestNormalized, PZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },
2758 { MSmallestNormalized, MZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },
Michael Gottesmanb0e688e2013-07-27 21:49:25 +00002759 { MSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },
Michael Gottesman3eacb582013-06-27 00:42:00 +00002760#if 0
2761// See Note 1.
2762 { MSmallestNormalized, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },
2763#endif
2764 { MSmallestNormalized, PNormalValue, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },
2765 { MSmallestNormalized, MNormalValue, "0x1p-126", APFloat::opOK, APFloat::fcNormal },
2766 { MSmallestNormalized, PLargestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },
2767 { MSmallestNormalized, MLargestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },
2768 { MSmallestNormalized, PSmallestValue, "-0x1p+23", APFloat::opOK, APFloat::fcNormal },
2769 { MSmallestNormalized, MSmallestValue, "0x1p+23", APFloat::opOK, APFloat::fcNormal },
2770 { MSmallestNormalized, PSmallestNormalized, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },
2771 { MSmallestNormalized, MSmallestNormalized, "0x1p+0", APFloat::opOK, APFloat::fcNormal },
2772 };
2773
2774 for (size_t i = 0; i < NumTests; ++i) {
2775 APFloat x(SpecialCaseTests[i].x);
2776 APFloat y(SpecialCaseTests[i].y);
2777 APFloat::opStatus status = x.divide(y, APFloat::rmNearestTiesToEven);
2778
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002779 APFloat result(APFloat::IEEEsingle(), SpecialCaseTests[i].result);
Michael Gottesman3eacb582013-06-27 00:42:00 +00002780
2781 EXPECT_TRUE(result.bitwiseIsEqual(x));
2782 EXPECT_TRUE((int)status == SpecialCaseTests[i].status);
2783 EXPECT_TRUE((int)x.getCategory() == SpecialCaseTests[i].category);
2784 }
2785}
2786
Chandler Carruthdf782e42014-10-09 23:26:15 +00002787TEST(APFloatTest, operatorOverloads) {
2788 // This is mostly testing that these operator overloads compile.
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002789 APFloat One = APFloat(APFloat::IEEEsingle(), "0x1p+0");
2790 APFloat Two = APFloat(APFloat::IEEEsingle(), "0x2p+0");
Chandler Carruthdf782e42014-10-09 23:26:15 +00002791 EXPECT_TRUE(Two.bitwiseIsEqual(One + One));
2792 EXPECT_TRUE(One.bitwiseIsEqual(Two - One));
2793 EXPECT_TRUE(Two.bitwiseIsEqual(One * Two));
2794 EXPECT_TRUE(One.bitwiseIsEqual(Two / Two));
2795}
Chandler Carruth7468b062014-10-10 04:17:04 +00002796
Chandler Carruthafe56ae2014-10-10 08:27:22 +00002797TEST(APFloatTest, abs) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002798 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle(), false);
2799 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle(), true);
2800 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle(), false);
2801 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle(), true);
2802 APFloat PQNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);
2803 APFloat MQNaN = APFloat::getNaN(APFloat::IEEEsingle(), true);
2804 APFloat PSNaN = APFloat::getSNaN(APFloat::IEEEsingle(), false);
2805 APFloat MSNaN = APFloat::getSNaN(APFloat::IEEEsingle(), true);
2806 APFloat PNormalValue = APFloat(APFloat::IEEEsingle(), "0x1p+0");
2807 APFloat MNormalValue = APFloat(APFloat::IEEEsingle(), "-0x1p+0");
2808 APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), false);
2809 APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), true);
2810 APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), false);
2811 APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), true);
Chandler Carruthafe56ae2014-10-10 08:27:22 +00002812 APFloat PSmallestNormalized =
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002813 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);
Chandler Carruthafe56ae2014-10-10 08:27:22 +00002814 APFloat MSmallestNormalized =
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002815 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);
Chandler Carruthafe56ae2014-10-10 08:27:22 +00002816
2817 EXPECT_TRUE(PInf.bitwiseIsEqual(abs(PInf)));
2818 EXPECT_TRUE(PInf.bitwiseIsEqual(abs(MInf)));
2819 EXPECT_TRUE(PZero.bitwiseIsEqual(abs(PZero)));
2820 EXPECT_TRUE(PZero.bitwiseIsEqual(abs(MZero)));
2821 EXPECT_TRUE(PQNaN.bitwiseIsEqual(abs(PQNaN)));
2822 EXPECT_TRUE(PQNaN.bitwiseIsEqual(abs(MQNaN)));
2823 EXPECT_TRUE(PSNaN.bitwiseIsEqual(abs(PSNaN)));
2824 EXPECT_TRUE(PSNaN.bitwiseIsEqual(abs(MSNaN)));
2825 EXPECT_TRUE(PNormalValue.bitwiseIsEqual(abs(PNormalValue)));
2826 EXPECT_TRUE(PNormalValue.bitwiseIsEqual(abs(MNormalValue)));
2827 EXPECT_TRUE(PLargestValue.bitwiseIsEqual(abs(PLargestValue)));
2828 EXPECT_TRUE(PLargestValue.bitwiseIsEqual(abs(MLargestValue)));
2829 EXPECT_TRUE(PSmallestValue.bitwiseIsEqual(abs(PSmallestValue)));
2830 EXPECT_TRUE(PSmallestValue.bitwiseIsEqual(abs(MSmallestValue)));
2831 EXPECT_TRUE(PSmallestNormalized.bitwiseIsEqual(abs(PSmallestNormalized)));
2832 EXPECT_TRUE(PSmallestNormalized.bitwiseIsEqual(abs(MSmallestNormalized)));
2833}
2834
Chandler Carruthca067142014-10-10 05:14:12 +00002835TEST(APFloatTest, ilogb) {
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002836 EXPECT_EQ(-1074, ilogb(APFloat::getSmallest(APFloat::IEEEdouble(), false)));
2837 EXPECT_EQ(-1074, ilogb(APFloat::getSmallest(APFloat::IEEEdouble(), true)));
2838 EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1024")));
2839 EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1023")));
2840 EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble(), "-0x1.ffffffffffffep-1023")));
2841 EXPECT_EQ(-51, ilogb(APFloat(APFloat::IEEEdouble(), "0x1p-51")));
2842 EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp-1023")));
2843 EXPECT_EQ(-2, ilogb(APFloat(APFloat::IEEEdouble(), "0x0.ffffp-1")));
2844 EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble(), "0x1.fffep-1023")));
2845 EXPECT_EQ(1023, ilogb(APFloat::getLargest(APFloat::IEEEdouble(), false)));
2846 EXPECT_EQ(1023, ilogb(APFloat::getLargest(APFloat::IEEEdouble(), true)));
Matt Arsenault69fdf9b2016-03-13 05:12:32 +00002847
2848
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002849 EXPECT_EQ(0, ilogb(APFloat(APFloat::IEEEsingle(), "0x1p+0")));
2850 EXPECT_EQ(0, ilogb(APFloat(APFloat::IEEEsingle(), "-0x1p+0")));
2851 EXPECT_EQ(42, ilogb(APFloat(APFloat::IEEEsingle(), "0x1p+42")));
2852 EXPECT_EQ(-42, ilogb(APFloat(APFloat::IEEEsingle(), "0x1p-42")));
Chandler Carruth7468b062014-10-10 04:17:04 +00002853
Chandler Carruthca067142014-10-10 05:14:12 +00002854 EXPECT_EQ(APFloat::IEK_Inf,
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002855 ilogb(APFloat::getInf(APFloat::IEEEsingle(), false)));
Chandler Carruthca067142014-10-10 05:14:12 +00002856 EXPECT_EQ(APFloat::IEK_Inf,
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002857 ilogb(APFloat::getInf(APFloat::IEEEsingle(), true)));
Chandler Carruthca067142014-10-10 05:14:12 +00002858 EXPECT_EQ(APFloat::IEK_Zero,
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002859 ilogb(APFloat::getZero(APFloat::IEEEsingle(), false)));
Chandler Carruthca067142014-10-10 05:14:12 +00002860 EXPECT_EQ(APFloat::IEK_Zero,
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002861 ilogb(APFloat::getZero(APFloat::IEEEsingle(), true)));
Chandler Carruthca067142014-10-10 05:14:12 +00002862 EXPECT_EQ(APFloat::IEK_NaN,
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002863 ilogb(APFloat::getNaN(APFloat::IEEEsingle(), false)));
Chandler Carruthca067142014-10-10 05:14:12 +00002864 EXPECT_EQ(APFloat::IEK_NaN,
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002865 ilogb(APFloat::getSNaN(APFloat::IEEEsingle(), false)));
Chandler Carruth7468b062014-10-10 04:17:04 +00002866
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002867 EXPECT_EQ(127, ilogb(APFloat::getLargest(APFloat::IEEEsingle(), false)));
2868 EXPECT_EQ(127, ilogb(APFloat::getLargest(APFloat::IEEEsingle(), true)));
Matt Arsenault69fdf9b2016-03-13 05:12:32 +00002869
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002870 EXPECT_EQ(-149, ilogb(APFloat::getSmallest(APFloat::IEEEsingle(), false)));
2871 EXPECT_EQ(-149, ilogb(APFloat::getSmallest(APFloat::IEEEsingle(), true)));
Chandler Carruthca067142014-10-10 05:14:12 +00002872 EXPECT_EQ(-126,
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002873 ilogb(APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false)));
Chandler Carruthca067142014-10-10 05:14:12 +00002874 EXPECT_EQ(-126,
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002875 ilogb(APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true)));
Chandler Carruth7468b062014-10-10 04:17:04 +00002876}
Chandler Carruthd9edd1e2014-10-10 04:54:30 +00002877
2878TEST(APFloatTest, scalbn) {
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00002879
2880 const APFloat::roundingMode RM = APFloat::rmNearestTiesToEven;
Chandler Carruthd9edd1e2014-10-10 04:54:30 +00002881 EXPECT_TRUE(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002882 APFloat(APFloat::IEEEsingle(), "0x1p+0")
2883 .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEsingle(), "0x1p+0"), 0, RM)));
Chandler Carruthd9edd1e2014-10-10 04:54:30 +00002884 EXPECT_TRUE(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002885 APFloat(APFloat::IEEEsingle(), "0x1p+42")
2886 .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEsingle(), "0x1p+0"), 42, RM)));
Chandler Carruthd9edd1e2014-10-10 04:54:30 +00002887 EXPECT_TRUE(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002888 APFloat(APFloat::IEEEsingle(), "0x1p-42")
2889 .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEsingle(), "0x1p+0"), -42, RM)));
Chandler Carruthd9edd1e2014-10-10 04:54:30 +00002890
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002891 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle(), false);
2892 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle(), true);
2893 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle(), false);
2894 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle(), true);
2895 APFloat QPNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);
2896 APFloat QMNaN = APFloat::getNaN(APFloat::IEEEsingle(), true);
2897 APFloat SNaN = APFloat::getSNaN(APFloat::IEEEsingle(), false);
Chandler Carruthd9edd1e2014-10-10 04:54:30 +00002898
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00002899 EXPECT_TRUE(PInf.bitwiseIsEqual(scalbn(PInf, 0, RM)));
2900 EXPECT_TRUE(MInf.bitwiseIsEqual(scalbn(MInf, 0, RM)));
2901 EXPECT_TRUE(PZero.bitwiseIsEqual(scalbn(PZero, 0, RM)));
2902 EXPECT_TRUE(MZero.bitwiseIsEqual(scalbn(MZero, 0, RM)));
2903 EXPECT_TRUE(QPNaN.bitwiseIsEqual(scalbn(QPNaN, 0, RM)));
2904 EXPECT_TRUE(QMNaN.bitwiseIsEqual(scalbn(QMNaN, 0, RM)));
Matt Arsenaultea00b492016-03-23 23:51:45 +00002905 EXPECT_FALSE(scalbn(SNaN, 0, RM).isSignaling());
2906
2907 APFloat ScalbnSNaN = scalbn(SNaN, 1, RM);
2908 EXPECT_TRUE(ScalbnSNaN.isNaN() && !ScalbnSNaN.isSignaling());
2909
2910 // Make sure highest bit of payload is preserved.
2911 const APInt Payload(64, (UINT64_C(1) << 50) |
2912 (UINT64_C(1) << 49) |
2913 (UINT64_C(1234) << 32) |
2914 1);
2915
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002916 APFloat SNaNWithPayload = APFloat::getSNaN(APFloat::IEEEdouble(), false,
Matt Arsenaultea00b492016-03-23 23:51:45 +00002917 &Payload);
2918 APFloat QuietPayload = scalbn(SNaNWithPayload, 1, RM);
2919 EXPECT_TRUE(QuietPayload.isNaN() && !QuietPayload.isSignaling());
2920 EXPECT_EQ(Payload, QuietPayload.bitcastToAPInt().getLoBits(51));
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00002921
2922 EXPECT_TRUE(PInf.bitwiseIsEqual(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002923 scalbn(APFloat(APFloat::IEEEsingle(), "0x1p+0"), 128, RM)));
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00002924 EXPECT_TRUE(MInf.bitwiseIsEqual(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002925 scalbn(APFloat(APFloat::IEEEsingle(), "-0x1p+0"), 128, RM)));
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00002926 EXPECT_TRUE(PInf.bitwiseIsEqual(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002927 scalbn(APFloat(APFloat::IEEEsingle(), "0x1p+127"), 1, RM)));
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00002928 EXPECT_TRUE(PZero.bitwiseIsEqual(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002929 scalbn(APFloat(APFloat::IEEEsingle(), "0x1p-127"), -127, RM)));
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00002930 EXPECT_TRUE(MZero.bitwiseIsEqual(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002931 scalbn(APFloat(APFloat::IEEEsingle(), "-0x1p-127"), -127, RM)));
2932 EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "-0x1p-149").bitwiseIsEqual(
2933 scalbn(APFloat(APFloat::IEEEsingle(), "-0x1p-127"), -22, RM)));
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00002934 EXPECT_TRUE(PZero.bitwiseIsEqual(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002935 scalbn(APFloat(APFloat::IEEEsingle(), "0x1p-126"), -24, RM)));
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00002936
2937
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002938 APFloat SmallestF64 = APFloat::getSmallest(APFloat::IEEEdouble(), false);
2939 APFloat NegSmallestF64 = APFloat::getSmallest(APFloat::IEEEdouble(), true);
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00002940
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002941 APFloat LargestF64 = APFloat::getLargest(APFloat::IEEEdouble(), false);
2942 APFloat NegLargestF64 = APFloat::getLargest(APFloat::IEEEdouble(), true);
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00002943
2944 APFloat SmallestNormalizedF64
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002945 = APFloat::getSmallestNormalized(APFloat::IEEEdouble(), false);
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00002946 APFloat NegSmallestNormalizedF64
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002947 = APFloat::getSmallestNormalized(APFloat::IEEEdouble(), true);
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00002948
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002949 APFloat LargestDenormalF64(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1023");
2950 APFloat NegLargestDenormalF64(APFloat::IEEEdouble(), "-0x1.ffffffffffffep-1023");
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00002951
2952
2953 EXPECT_TRUE(SmallestF64.bitwiseIsEqual(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002954 scalbn(APFloat(APFloat::IEEEdouble(), "0x1p-1074"), 0, RM)));
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00002955 EXPECT_TRUE(NegSmallestF64.bitwiseIsEqual(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002956 scalbn(APFloat(APFloat::IEEEdouble(), "-0x1p-1074"), 0, RM)));
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00002957
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002958 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p+1023")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00002959 .bitwiseIsEqual(scalbn(SmallestF64, 2097, RM)));
2960
2961 EXPECT_TRUE(scalbn(SmallestF64, -2097, RM).isPosZero());
2962 EXPECT_TRUE(scalbn(SmallestF64, -2098, RM).isPosZero());
2963 EXPECT_TRUE(scalbn(SmallestF64, -2099, RM).isPosZero());
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002964 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p+1022")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00002965 .bitwiseIsEqual(scalbn(SmallestF64, 2096, RM)));
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002966 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p+1023")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00002967 .bitwiseIsEqual(scalbn(SmallestF64, 2097, RM)));
2968 EXPECT_TRUE(scalbn(SmallestF64, 2098, RM).isInfinity());
2969 EXPECT_TRUE(scalbn(SmallestF64, 2099, RM).isInfinity());
2970
2971 // Test for integer overflows when adding to exponent.
2972 EXPECT_TRUE(scalbn(SmallestF64, -INT_MAX, RM).isPosZero());
2973 EXPECT_TRUE(scalbn(LargestF64, INT_MAX, RM).isInfinity());
2974
2975 EXPECT_TRUE(LargestDenormalF64
2976 .bitwiseIsEqual(scalbn(LargestDenormalF64, 0, RM)));
2977 EXPECT_TRUE(NegLargestDenormalF64
2978 .bitwiseIsEqual(scalbn(NegLargestDenormalF64, 0, RM)));
2979
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002980 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1022")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00002981 .bitwiseIsEqual(scalbn(LargestDenormalF64, 1, RM)));
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002982 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1.ffffffffffffep-1021")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00002983 .bitwiseIsEqual(scalbn(NegLargestDenormalF64, 2, RM)));
2984
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002985 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep+1")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00002986 .bitwiseIsEqual(scalbn(LargestDenormalF64, 1024, RM)));
2987 EXPECT_TRUE(scalbn(LargestDenormalF64, -1023, RM).isPosZero());
2988 EXPECT_TRUE(scalbn(LargestDenormalF64, -1024, RM).isPosZero());
2989 EXPECT_TRUE(scalbn(LargestDenormalF64, -2048, RM).isPosZero());
2990 EXPECT_TRUE(scalbn(LargestDenormalF64, 2047, RM).isInfinity());
2991 EXPECT_TRUE(scalbn(LargestDenormalF64, 2098, RM).isInfinity());
2992 EXPECT_TRUE(scalbn(LargestDenormalF64, 2099, RM).isInfinity());
2993
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002994 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-2")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00002995 .bitwiseIsEqual(scalbn(LargestDenormalF64, 1021, RM)));
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002996 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00002997 .bitwiseIsEqual(scalbn(LargestDenormalF64, 1022, RM)));
Stephan Bergmann17c7f702016-12-14 11:57:17 +00002998 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep+0")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00002999 .bitwiseIsEqual(scalbn(LargestDenormalF64, 1023, RM)));
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003000 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep+1023")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003001 .bitwiseIsEqual(scalbn(LargestDenormalF64, 2046, RM)));
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003002 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p+974")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003003 .bitwiseIsEqual(scalbn(SmallestF64, 2048, RM)));
3004
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003005 APFloat RandomDenormalF64(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp+51");
3006 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp-972")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003007 .bitwiseIsEqual(scalbn(RandomDenormalF64, -1023, RM)));
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003008 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp-1")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003009 .bitwiseIsEqual(scalbn(RandomDenormalF64, -52, RM)));
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003010 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp-2")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003011 .bitwiseIsEqual(scalbn(RandomDenormalF64, -53, RM)));
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003012 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp+0")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003013 .bitwiseIsEqual(scalbn(RandomDenormalF64, -51, RM)));
3014
3015 EXPECT_TRUE(scalbn(RandomDenormalF64, -2097, RM).isPosZero());
3016 EXPECT_TRUE(scalbn(RandomDenormalF64, -2090, RM).isPosZero());
3017
Chandler Carruthd9edd1e2014-10-10 04:54:30 +00003018
3019 EXPECT_TRUE(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003020 APFloat(APFloat::IEEEdouble(), "-0x1p-1073")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003021 .bitwiseIsEqual(scalbn(NegLargestF64, -2097, RM)));
3022
Chandler Carruthd9edd1e2014-10-10 04:54:30 +00003023 EXPECT_TRUE(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003024 APFloat(APFloat::IEEEdouble(), "-0x1p-1024")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003025 .bitwiseIsEqual(scalbn(NegLargestF64, -2048, RM)));
3026
3027 EXPECT_TRUE(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003028 APFloat(APFloat::IEEEdouble(), "0x1p-1073")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003029 .bitwiseIsEqual(scalbn(LargestF64, -2097, RM)));
3030
3031 EXPECT_TRUE(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003032 APFloat(APFloat::IEEEdouble(), "0x1p-1074")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003033 .bitwiseIsEqual(scalbn(LargestF64, -2098, RM)));
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003034 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1p-1074")
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003035 .bitwiseIsEqual(scalbn(NegLargestF64, -2098, RM)));
3036 EXPECT_TRUE(scalbn(NegLargestF64, -2099, RM).isNegZero());
3037 EXPECT_TRUE(scalbn(LargestF64, 1, RM).isInfinity());
3038
3039
3040 EXPECT_TRUE(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003041 APFloat(APFloat::IEEEdouble(), "0x1p+0")
3042 .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEdouble(), "0x1p+52"), -52, RM)));
Matt Arsenaultafa31cf2016-03-13 05:11:51 +00003043
3044 EXPECT_TRUE(
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003045 APFloat(APFloat::IEEEdouble(), "0x1p-103")
3046 .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEdouble(), "0x1p-51"), -52, RM)));
Chandler Carruthd9edd1e2014-10-10 04:54:30 +00003047}
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003048
3049TEST(APFloatTest, frexp) {
3050 const APFloat::roundingMode RM = APFloat::rmNearestTiesToEven;
3051
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003052 APFloat PZero = APFloat::getZero(APFloat::IEEEdouble(), false);
3053 APFloat MZero = APFloat::getZero(APFloat::IEEEdouble(), true);
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003054 APFloat One(1.0);
3055 APFloat MOne(-1.0);
3056 APFloat Two(2.0);
3057 APFloat MTwo(-2.0);
3058
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003059 APFloat LargestDenormal(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1023");
3060 APFloat NegLargestDenormal(APFloat::IEEEdouble(), "-0x1.ffffffffffffep-1023");
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003061
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003062 APFloat Smallest = APFloat::getSmallest(APFloat::IEEEdouble(), false);
3063 APFloat NegSmallest = APFloat::getSmallest(APFloat::IEEEdouble(), true);
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003064
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003065 APFloat Largest = APFloat::getLargest(APFloat::IEEEdouble(), false);
3066 APFloat NegLargest = APFloat::getLargest(APFloat::IEEEdouble(), true);
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003067
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003068 APFloat PInf = APFloat::getInf(APFloat::IEEEdouble(), false);
3069 APFloat MInf = APFloat::getInf(APFloat::IEEEdouble(), true);
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003070
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003071 APFloat QPNaN = APFloat::getNaN(APFloat::IEEEdouble(), false);
3072 APFloat QMNaN = APFloat::getNaN(APFloat::IEEEdouble(), true);
3073 APFloat SNaN = APFloat::getSNaN(APFloat::IEEEdouble(), false);
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003074
3075 // Make sure highest bit of payload is preserved.
3076 const APInt Payload(64, (UINT64_C(1) << 50) |
3077 (UINT64_C(1) << 49) |
3078 (UINT64_C(1234) << 32) |
3079 1);
3080
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003081 APFloat SNaNWithPayload = APFloat::getSNaN(APFloat::IEEEdouble(), false,
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003082 &Payload);
3083
3084 APFloat SmallestNormalized
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003085 = APFloat::getSmallestNormalized(APFloat::IEEEdouble(), false);
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003086 APFloat NegSmallestNormalized
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003087 = APFloat::getSmallestNormalized(APFloat::IEEEdouble(), true);
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003088
3089 int Exp;
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003090 APFloat Frac(APFloat::IEEEdouble());
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003091
3092
3093 Frac = frexp(PZero, Exp, RM);
3094 EXPECT_EQ(0, Exp);
3095 EXPECT_TRUE(Frac.isPosZero());
3096
3097 Frac = frexp(MZero, Exp, RM);
3098 EXPECT_EQ(0, Exp);
3099 EXPECT_TRUE(Frac.isNegZero());
3100
3101
3102 Frac = frexp(One, Exp, RM);
3103 EXPECT_EQ(1, Exp);
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003104 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p-1").bitwiseIsEqual(Frac));
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003105
3106 Frac = frexp(MOne, Exp, RM);
3107 EXPECT_EQ(1, Exp);
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003108 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1p-1").bitwiseIsEqual(Frac));
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003109
3110 Frac = frexp(LargestDenormal, Exp, RM);
3111 EXPECT_EQ(-1022, Exp);
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003112 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1").bitwiseIsEqual(Frac));
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003113
3114 Frac = frexp(NegLargestDenormal, Exp, RM);
3115 EXPECT_EQ(-1022, Exp);
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003116 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1.ffffffffffffep-1").bitwiseIsEqual(Frac));
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003117
3118
3119 Frac = frexp(Smallest, Exp, RM);
3120 EXPECT_EQ(-1073, Exp);
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003121 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p-1").bitwiseIsEqual(Frac));
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003122
3123 Frac = frexp(NegSmallest, Exp, RM);
3124 EXPECT_EQ(-1073, Exp);
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003125 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1p-1").bitwiseIsEqual(Frac));
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003126
3127
3128 Frac = frexp(Largest, Exp, RM);
3129 EXPECT_EQ(1024, Exp);
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003130 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.fffffffffffffp-1").bitwiseIsEqual(Frac));
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003131
3132 Frac = frexp(NegLargest, Exp, RM);
3133 EXPECT_EQ(1024, Exp);
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003134 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1.fffffffffffffp-1").bitwiseIsEqual(Frac));
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003135
3136
3137 Frac = frexp(PInf, Exp, RM);
3138 EXPECT_EQ(INT_MAX, Exp);
3139 EXPECT_TRUE(Frac.isInfinity() && !Frac.isNegative());
3140
3141 Frac = frexp(MInf, Exp, RM);
3142 EXPECT_EQ(INT_MAX, Exp);
3143 EXPECT_TRUE(Frac.isInfinity() && Frac.isNegative());
3144
3145 Frac = frexp(QPNaN, Exp, RM);
3146 EXPECT_EQ(INT_MIN, Exp);
3147 EXPECT_TRUE(Frac.isNaN());
3148
3149 Frac = frexp(QMNaN, Exp, RM);
3150 EXPECT_EQ(INT_MIN, Exp);
3151 EXPECT_TRUE(Frac.isNaN());
3152
3153 Frac = frexp(SNaN, Exp, RM);
3154 EXPECT_EQ(INT_MIN, Exp);
3155 EXPECT_TRUE(Frac.isNaN() && !Frac.isSignaling());
3156
3157 Frac = frexp(SNaNWithPayload, Exp, RM);
3158 EXPECT_EQ(INT_MIN, Exp);
3159 EXPECT_TRUE(Frac.isNaN() && !Frac.isSignaling());
3160 EXPECT_EQ(Payload, Frac.bitcastToAPInt().getLoBits(51));
3161
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003162 Frac = frexp(APFloat(APFloat::IEEEdouble(), "0x0.ffffp-1"), Exp, RM);
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003163 EXPECT_EQ(-1, Exp);
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003164 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.fffep-1").bitwiseIsEqual(Frac));
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003165
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003166 Frac = frexp(APFloat(APFloat::IEEEdouble(), "0x1p-51"), Exp, RM);
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003167 EXPECT_EQ(-50, Exp);
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003168 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p-1").bitwiseIsEqual(Frac));
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003169
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003170 Frac = frexp(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp+51"), Exp, RM);
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003171 EXPECT_EQ(52, Exp);
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003172 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp-1").bitwiseIsEqual(Frac));
Matt Arsenaultc25a7112016-03-21 16:49:16 +00003173}
Tim Shen44bde892016-12-12 21:59:30 +00003174
3175TEST(APFloatTest, PPCDoubleDoubleAddSpecial) {
3176 using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t,
3177 APFloat::fltCategory, APFloat::roundingMode>;
3178 DataType Data[] = {
3179 // (1 + 0) + (-1 + 0) = fcZero
Tim Shen18e7ae62016-12-12 22:16:08 +00003180 std::make_tuple(0x3ff0000000000000ull, 0, 0xbff0000000000000ull, 0,
3181 APFloat::fcZero, APFloat::rmNearestTiesToEven),
Tim Shen44bde892016-12-12 21:59:30 +00003182 // LDBL_MAX + (1.1 >> (1023 - 106) + 0)) = fcInfinity
Tim Shen18e7ae62016-12-12 22:16:08 +00003183 std::make_tuple(0x7fefffffffffffffull, 0x7c8ffffffffffffeull,
3184 0x7948000000000000ull, 0ull, APFloat::fcInfinity,
3185 APFloat::rmNearestTiesToEven),
Tim Shen44bde892016-12-12 21:59:30 +00003186 // TODO: change the 4th 0x75effffffffffffe to 0x75efffffffffffff when
3187 // PPCDoubleDoubleImpl is gone.
3188 // LDBL_MAX + (1.011111... >> (1023 - 106) + (1.1111111...0 >> (1023 -
3189 // 160))) = fcNormal
Tim Shen18e7ae62016-12-12 22:16:08 +00003190 std::make_tuple(0x7fefffffffffffffull, 0x7c8ffffffffffffeull,
3191 0x7947ffffffffffffull, 0x75effffffffffffeull,
3192 APFloat::fcNormal, APFloat::rmNearestTiesToEven),
Tim Shen44bde892016-12-12 21:59:30 +00003193 // LDBL_MAX + (1.1 >> (1023 - 106) + 0)) = fcInfinity
Tim Shen18e7ae62016-12-12 22:16:08 +00003194 std::make_tuple(0x7fefffffffffffffull, 0x7c8ffffffffffffeull,
3195 0x7fefffffffffffffull, 0x7c8ffffffffffffeull,
3196 APFloat::fcInfinity, APFloat::rmNearestTiesToEven),
Tim Shen44bde892016-12-12 21:59:30 +00003197 // NaN + (1 + 0) = fcNaN
Tim Shen18e7ae62016-12-12 22:16:08 +00003198 std::make_tuple(0x7ff8000000000000ull, 0, 0x3ff0000000000000ull, 0,
3199 APFloat::fcNaN, APFloat::rmNearestTiesToEven),
Tim Shen44bde892016-12-12 21:59:30 +00003200 };
3201
3202 for (auto Tp : Data) {
3203 uint64_t Op1[2], Op2[2];
3204 APFloat::fltCategory Expected;
3205 APFloat::roundingMode RM;
3206 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected, RM) = Tp;
3207
3208 APFloat A1(APFloat::PPCDoubleDouble, APInt(128, 2, Op1));
3209 APFloat A2(APFloat::PPCDoubleDouble, APInt(128, 2, Op2));
3210 A1.add(A2, RM);
3211
3212 EXPECT_EQ(Expected, A1.getCategory());
3213 }
3214}
3215
3216TEST(APFloatTest, PPCDoubleDoubleAdd) {
3217 using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,
3218 uint64_t, APFloat::roundingMode>;
3219 DataType Data[] = {
3220 // (1 + 0) + (1e-105 + 0) = (1 + 1e-105)
Tim Shen18e7ae62016-12-12 22:16:08 +00003221 std::make_tuple(0x3ff0000000000000ull, 0, 0x3960000000000000ull, 0,
3222 0x3ff0000000000000ull, 0x3960000000000000ull,
3223 APFloat::rmNearestTiesToEven),
Tim Shen44bde892016-12-12 21:59:30 +00003224 // (1 + 0) + (1e-106 + 0) = (1 + 1e-106)
Tim Shen18e7ae62016-12-12 22:16:08 +00003225 std::make_tuple(0x3ff0000000000000ull, 0, 0x3950000000000000ull, 0,
3226 0x3ff0000000000000ull, 0x3950000000000000ull,
3227 APFloat::rmNearestTiesToEven),
Tim Shen44bde892016-12-12 21:59:30 +00003228 // (1 + 1e-106) + (1e-106 + 0) = (1 + 1e-105)
Tim Shen18e7ae62016-12-12 22:16:08 +00003229 std::make_tuple(0x3ff0000000000000ull, 0x3950000000000000ull,
3230 0x3950000000000000ull, 0, 0x3ff0000000000000ull,
3231 0x3960000000000000ull, APFloat::rmNearestTiesToEven),
Tim Shen44bde892016-12-12 21:59:30 +00003232 // (1 + 0) + (epsilon + 0) = (1 + epsilon)
Tim Shen18e7ae62016-12-12 22:16:08 +00003233 std::make_tuple(0x3ff0000000000000ull, 0, 0x0000000000000001ull, 0,
3234 0x3ff0000000000000ull, 0x0000000000000001ull,
3235 APFloat::rmNearestTiesToEven),
Tim Shen44bde892016-12-12 21:59:30 +00003236 // TODO: change 0xf950000000000000 to 0xf940000000000000, when
3237 // PPCDoubleDoubleImpl is gone.
3238 // (DBL_MAX - 1 << (1023 - 105)) + (1 << (1023 - 53) + 0) = DBL_MAX +
3239 // 1.11111... << (1023 - 52)
Tim Shen18e7ae62016-12-12 22:16:08 +00003240 std::make_tuple(0x7fefffffffffffffull, 0xf950000000000000ull,
3241 0x7c90000000000000ull, 0, 0x7fefffffffffffffull,
3242 0x7c8ffffffffffffeull, APFloat::rmNearestTiesToEven),
Tim Shen44bde892016-12-12 21:59:30 +00003243 // TODO: change 0xf950000000000000 to 0xf940000000000000, when
3244 // PPCDoubleDoubleImpl is gone.
3245 // (1 << (1023 - 53) + 0) + (DBL_MAX - 1 << (1023 - 105)) = DBL_MAX +
3246 // 1.11111... << (1023 - 52)
Tim Shen18e7ae62016-12-12 22:16:08 +00003247 std::make_tuple(0x7c90000000000000ull, 0, 0x7fefffffffffffffull,
3248 0xf950000000000000ull, 0x7fefffffffffffffull,
3249 0x7c8ffffffffffffeull, APFloat::rmNearestTiesToEven),
Tim Shen44bde892016-12-12 21:59:30 +00003250 };
3251
3252 for (auto Tp : Data) {
3253 uint64_t Op1[2], Op2[2], Expected[2];
3254 APFloat::roundingMode RM;
3255 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected[0], Expected[1], RM) = Tp;
3256
3257 APFloat A1(APFloat::PPCDoubleDouble, APInt(128, 2, Op1));
3258 APFloat A2(APFloat::PPCDoubleDouble, APInt(128, 2, Op2));
3259 A1.add(A2, RM);
3260
3261 EXPECT_EQ(Expected[0], A1.bitcastToAPInt().getRawData()[0]);
3262 EXPECT_EQ(Expected[1],
3263 A1.getSecondFloat().bitcastToAPInt().getRawData()[0]);
3264 }
3265}
3266
3267TEST(APFloatTest, PPCDoubleDoubleSubtract) {
3268 using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,
3269 uint64_t, APFloat::roundingMode>;
3270 DataType Data[] = {
3271 // (1 + 0) - (-1e-105 + 0) = (1 + 1e-105)
Tim Shen18e7ae62016-12-12 22:16:08 +00003272 std::make_tuple(0x3ff0000000000000ull, 0, 0xb960000000000000ull, 0,
3273 0x3ff0000000000000ull, 0x3960000000000000ull,
3274 APFloat::rmNearestTiesToEven),
Tim Shen44bde892016-12-12 21:59:30 +00003275 // (1 + 0) - (-1e-106 + 0) = (1 + 1e-106)
Tim Shen18e7ae62016-12-12 22:16:08 +00003276 std::make_tuple(0x3ff0000000000000ull, 0, 0xb950000000000000ull, 0,
3277 0x3ff0000000000000ull, 0x3950000000000000ull,
3278 APFloat::rmNearestTiesToEven),
Tim Shen44bde892016-12-12 21:59:30 +00003279 };
3280
3281 for (auto Tp : Data) {
3282 uint64_t Op1[2], Op2[2], Expected[2];
3283 APFloat::roundingMode RM;
3284 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected[0], Expected[1], RM) = Tp;
3285
3286 APFloat A1(APFloat::PPCDoubleDouble, APInt(128, 2, Op1));
3287 APFloat A2(APFloat::PPCDoubleDouble, APInt(128, 2, Op2));
3288 A1.subtract(A2, RM);
3289
3290 EXPECT_EQ(Expected[0], A1.bitcastToAPInt().getRawData()[0]);
3291 EXPECT_EQ(Expected[1],
3292 A1.getSecondFloat().bitcastToAPInt().getRawData()[0]);
3293 }
3294}
Erick Tryzelaar19f63b22009-08-16 23:36:19 +00003295}