10186 lines · cpp
1//===- llvm/unittest/ADT/APFloat.cpp - APFloat unit tests ---------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/ADT/APFloat.h"10#include "llvm/ADT/APSInt.h"11#include "llvm/ADT/Hashing.h"12#include "llvm/ADT/SmallString.h"13#include "llvm/ADT/SmallVector.h"14#include "llvm/ADT/StringExtras.h"15#include "llvm/Support/Error.h"16#include "llvm/Support/FormatVariadic.h"17#include "gtest/gtest.h"18#include <cmath>19#include <limits>20#include <ostream>21#include <string>22#include <tuple>23#include <type_traits>24 25using namespace llvm;26 27static std::string convertToErrorFromString(StringRef Str) {28 llvm::APFloat F(0.0);29 auto StatusOrErr =30 F.convertFromString(Str, llvm::APFloat::rmNearestTiesToEven);31 EXPECT_TRUE(!StatusOrErr);32 return toString(StatusOrErr.takeError());33}34 35static double convertToDoubleFromString(StringRef Str) {36 llvm::APFloat F(0.0);37 auto StatusOrErr =38 F.convertFromString(Str, llvm::APFloat::rmNearestTiesToEven);39 EXPECT_FALSE(!StatusOrErr);40 consumeError(StatusOrErr.takeError());41 return F.convertToDouble();42}43 44static std::string convertToString(double d, unsigned Prec, unsigned Pad,45 bool Tr = true) {46 llvm::SmallVector<char, 100> Buffer;47 llvm::APFloat F(d);48 F.toString(Buffer, Prec, Pad, Tr);49 return std::string(Buffer.data(), Buffer.size());50}51 52namespace llvm {53namespace detail {54class IEEEFloatUnitTestHelper {55public:56 static void runTest(bool subtract, bool lhsSign,57 APFloat::ExponentType lhsExponent,58 APFloat::integerPart lhsSignificand, bool rhsSign,59 APFloat::ExponentType rhsExponent,60 APFloat::integerPart rhsSignificand, bool expectedSign,61 APFloat::ExponentType expectedExponent,62 APFloat::integerPart expectedSignificand,63 lostFraction expectedLoss) {64 // `addOrSubtractSignificand` only uses the sign, exponent and significand65 IEEEFloat lhs(1.0);66 lhs.sign = lhsSign;67 lhs.exponent = lhsExponent;68 lhs.significand.part = lhsSignificand;69 IEEEFloat rhs(1.0);70 rhs.sign = rhsSign;71 rhs.exponent = rhsExponent;72 rhs.significand.part = rhsSignificand;73 lostFraction resultLoss = lhs.addOrSubtractSignificand(rhs, subtract);74 EXPECT_EQ(resultLoss, expectedLoss);75 EXPECT_EQ(lhs.sign, expectedSign);76 EXPECT_EQ(lhs.exponent, expectedExponent);77 EXPECT_EQ(lhs.significand.part, expectedSignificand);78 }79};80} // namespace detail81} // namespace llvm82 83namespace {84 85TEST(APFloatTest, isSignaling) {86 // We test qNaN, -qNaN, +sNaN, -sNaN with and without payloads. *NOTE* The87 // positive/negative distinction is included only since the getQNaN/getSNaN88 // API provides the option.89 APInt payload = APInt::getOneBitSet(4, 2);90 APFloat QNan = APFloat::getQNaN(APFloat::IEEEsingle(), false);91 EXPECT_FALSE(QNan.isSignaling());92 EXPECT_EQ(fcQNan, QNan.classify());93 94 EXPECT_FALSE(APFloat::getQNaN(APFloat::IEEEsingle(), true).isSignaling());95 EXPECT_FALSE(APFloat::getQNaN(APFloat::IEEEsingle(), false, &payload).isSignaling());96 EXPECT_FALSE(APFloat::getQNaN(APFloat::IEEEsingle(), true, &payload).isSignaling());97 98 APFloat SNan = APFloat::getSNaN(APFloat::IEEEsingle(), false);99 EXPECT_TRUE(SNan.isSignaling());100 EXPECT_EQ(fcSNan, SNan.classify());101 102 EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle(), true).isSignaling());103 EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle(), false, &payload).isSignaling());104 EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle(), true, &payload).isSignaling());105}106 107TEST(APFloatTest, next) {108 109 APFloat test(APFloat::IEEEquad(), APFloat::uninitialized);110 APFloat expected(APFloat::IEEEquad(), APFloat::uninitialized);111 112 // 1. Test Special Cases Values.113 //114 // Test all special values for nextUp and nextDown perscribed by IEEE-754R115 // 2008. These are:116 // 1. +inf117 // 2. -inf118 // 3. getLargest()119 // 4. -getLargest()120 // 5. getSmallest()121 // 6. -getSmallest()122 // 7. qNaN123 // 8. sNaN124 // 9. +0125 // 10. -0126 127 // nextUp(+inf) = +inf.128 test = APFloat::getInf(APFloat::IEEEquad(), false);129 expected = APFloat::getInf(APFloat::IEEEquad(), false);130 EXPECT_EQ(test.next(false), APFloat::opOK);131 EXPECT_TRUE(test.isInfinity());132 EXPECT_TRUE(!test.isNegative());133 EXPECT_TRUE(test.bitwiseIsEqual(expected));134 135 // nextDown(+inf) = -nextUp(-inf) = -(-getLargest()) = getLargest()136 test = APFloat::getInf(APFloat::IEEEquad(), false);137 expected = APFloat::getLargest(APFloat::IEEEquad(), false);138 EXPECT_EQ(test.next(true), APFloat::opOK);139 EXPECT_TRUE(!test.isNegative());140 EXPECT_TRUE(test.bitwiseIsEqual(expected));141 142 // nextUp(-inf) = -getLargest()143 test = APFloat::getInf(APFloat::IEEEquad(), true);144 expected = APFloat::getLargest(APFloat::IEEEquad(), true);145 EXPECT_EQ(test.next(false), APFloat::opOK);146 EXPECT_TRUE(test.isNegative());147 EXPECT_TRUE(test.bitwiseIsEqual(expected));148 149 // nextDown(-inf) = -nextUp(+inf) = -(+inf) = -inf.150 test = APFloat::getInf(APFloat::IEEEquad(), true);151 expected = APFloat::getInf(APFloat::IEEEquad(), true);152 EXPECT_EQ(test.next(true), APFloat::opOK);153 EXPECT_TRUE(test.isInfinity() && test.isNegative());154 EXPECT_TRUE(test.bitwiseIsEqual(expected));155 156 // nextUp(getLargest()) = +inf157 test = APFloat::getLargest(APFloat::IEEEquad(), false);158 expected = APFloat::getInf(APFloat::IEEEquad(), false);159 EXPECT_EQ(test.next(false), APFloat::opOK);160 EXPECT_TRUE(test.isInfinity() && !test.isNegative());161 EXPECT_TRUE(test.bitwiseIsEqual(expected));162 163 // nextDown(getLargest()) = -nextUp(-getLargest())164 // = -(-getLargest() + inc)165 // = getLargest() - inc.166 test = APFloat::getLargest(APFloat::IEEEquad(), false);167 expected = APFloat(APFloat::IEEEquad(),168 "0x1.fffffffffffffffffffffffffffep+16383");169 EXPECT_EQ(test.next(true), APFloat::opOK);170 EXPECT_TRUE(!test.isInfinity() && !test.isNegative());171 EXPECT_TRUE(test.bitwiseIsEqual(expected));172 173 // nextUp(-getLargest()) = -getLargest() + inc.174 test = APFloat::getLargest(APFloat::IEEEquad(), true);175 expected = APFloat(APFloat::IEEEquad(),176 "-0x1.fffffffffffffffffffffffffffep+16383");177 EXPECT_EQ(test.next(false), APFloat::opOK);178 EXPECT_TRUE(test.bitwiseIsEqual(expected));179 180 // nextDown(-getLargest()) = -nextUp(getLargest()) = -(inf) = -inf.181 test = APFloat::getLargest(APFloat::IEEEquad(), true);182 expected = APFloat::getInf(APFloat::IEEEquad(), true);183 EXPECT_EQ(test.next(true), APFloat::opOK);184 EXPECT_TRUE(test.isInfinity() && test.isNegative());185 EXPECT_TRUE(test.bitwiseIsEqual(expected));186 187 // nextUp(getSmallest()) = getSmallest() + inc.188 test = APFloat(APFloat::IEEEquad(), "0x0.0000000000000000000000000001p-16382");189 expected = APFloat(APFloat::IEEEquad(),190 "0x0.0000000000000000000000000002p-16382");191 EXPECT_EQ(test.next(false), APFloat::opOK);192 EXPECT_TRUE(test.bitwiseIsEqual(expected));193 194 // nextDown(getSmallest()) = -nextUp(-getSmallest()) = -(-0) = +0.195 test = APFloat(APFloat::IEEEquad(), "0x0.0000000000000000000000000001p-16382");196 expected = APFloat::getZero(APFloat::IEEEquad(), false);197 EXPECT_EQ(test.next(true), APFloat::opOK);198 EXPECT_TRUE(test.isPosZero());199 EXPECT_TRUE(test.bitwiseIsEqual(expected));200 201 // nextUp(-getSmallest()) = -0.202 test = APFloat(APFloat::IEEEquad(), "-0x0.0000000000000000000000000001p-16382");203 expected = APFloat::getZero(APFloat::IEEEquad(), true);204 EXPECT_EQ(test.next(false), APFloat::opOK);205 EXPECT_TRUE(test.isNegZero());206 EXPECT_TRUE(test.bitwiseIsEqual(expected));207 208 // nextDown(-getSmallest()) = -nextUp(getSmallest()) = -getSmallest() - inc.209 test = APFloat(APFloat::IEEEquad(), "-0x0.0000000000000000000000000001p-16382");210 expected = APFloat(APFloat::IEEEquad(),211 "-0x0.0000000000000000000000000002p-16382");212 EXPECT_EQ(test.next(true), APFloat::opOK);213 EXPECT_TRUE(test.bitwiseIsEqual(expected));214 215 // nextUp(qNaN) = qNaN216 test = APFloat::getQNaN(APFloat::IEEEquad(), false);217 expected = APFloat::getQNaN(APFloat::IEEEquad(), false);218 EXPECT_EQ(test.next(false), APFloat::opOK);219 EXPECT_TRUE(test.bitwiseIsEqual(expected));220 221 // nextDown(qNaN) = qNaN222 test = APFloat::getQNaN(APFloat::IEEEquad(), false);223 expected = APFloat::getQNaN(APFloat::IEEEquad(), false);224 EXPECT_EQ(test.next(true), APFloat::opOK);225 EXPECT_TRUE(test.bitwiseIsEqual(expected));226 227 // nextUp(sNaN) = qNaN228 test = APFloat::getSNaN(APFloat::IEEEquad(), false);229 expected = APFloat::getQNaN(APFloat::IEEEquad(), false);230 EXPECT_EQ(test.next(false), APFloat::opInvalidOp);231 EXPECT_TRUE(test.bitwiseIsEqual(expected));232 233 // nextDown(sNaN) = qNaN234 test = APFloat::getSNaN(APFloat::IEEEquad(), false);235 expected = APFloat::getQNaN(APFloat::IEEEquad(), false);236 EXPECT_EQ(test.next(true), APFloat::opInvalidOp);237 EXPECT_TRUE(test.bitwiseIsEqual(expected));238 239 // nextUp(+0) = +getSmallest()240 test = APFloat::getZero(APFloat::IEEEquad(), false);241 expected = APFloat::getSmallest(APFloat::IEEEquad(), false);242 EXPECT_EQ(test.next(false), APFloat::opOK);243 EXPECT_TRUE(test.bitwiseIsEqual(expected));244 245 // nextDown(+0) = -nextUp(-0) = -getSmallest()246 test = APFloat::getZero(APFloat::IEEEquad(), false);247 expected = APFloat::getSmallest(APFloat::IEEEquad(), true);248 EXPECT_EQ(test.next(true), APFloat::opOK);249 EXPECT_TRUE(test.bitwiseIsEqual(expected));250 251 // nextUp(-0) = +getSmallest()252 test = APFloat::getZero(APFloat::IEEEquad(), true);253 expected = APFloat::getSmallest(APFloat::IEEEquad(), false);254 EXPECT_EQ(test.next(false), APFloat::opOK);255 EXPECT_TRUE(test.bitwiseIsEqual(expected));256 257 // nextDown(-0) = -nextUp(0) = -getSmallest()258 test = APFloat::getZero(APFloat::IEEEquad(), true);259 expected = APFloat::getSmallest(APFloat::IEEEquad(), true);260 EXPECT_EQ(test.next(true), APFloat::opOK);261 EXPECT_TRUE(test.bitwiseIsEqual(expected));262 263 // 2. Binade Boundary Tests.264 265 // 2a. Test denormal <-> normal binade boundaries.266 // * nextUp(+Largest Denormal) -> +Smallest Normal.267 // * nextDown(-Largest Denormal) -> -Smallest Normal.268 // * nextUp(-Smallest Normal) -> -Largest Denormal.269 // * nextDown(+Smallest Normal) -> +Largest Denormal.270 271 // nextUp(+Largest Denormal) -> +Smallest Normal.272 test = APFloat(APFloat::IEEEquad(), "0x0.ffffffffffffffffffffffffffffp-16382");273 expected = APFloat(APFloat::IEEEquad(),274 "0x1.0000000000000000000000000000p-16382");275 EXPECT_EQ(test.next(false), APFloat::opOK);276 EXPECT_FALSE(test.isDenormal());277 EXPECT_TRUE(test.bitwiseIsEqual(expected));278 279 // nextDown(-Largest Denormal) -> -Smallest Normal.280 test = APFloat(APFloat::IEEEquad(),281 "-0x0.ffffffffffffffffffffffffffffp-16382");282 expected = APFloat(APFloat::IEEEquad(),283 "-0x1.0000000000000000000000000000p-16382");284 EXPECT_EQ(test.next(true), APFloat::opOK);285 EXPECT_FALSE(test.isDenormal());286 EXPECT_TRUE(test.bitwiseIsEqual(expected));287 288 // nextUp(-Smallest Normal) -> -LargestDenormal.289 test = APFloat(APFloat::IEEEquad(),290 "-0x1.0000000000000000000000000000p-16382");291 expected = APFloat(APFloat::IEEEquad(),292 "-0x0.ffffffffffffffffffffffffffffp-16382");293 EXPECT_EQ(test.next(false), APFloat::opOK);294 EXPECT_TRUE(test.isDenormal());295 EXPECT_TRUE(test.bitwiseIsEqual(expected));296 297 // nextDown(+Smallest Normal) -> +Largest Denormal.298 test = APFloat(APFloat::IEEEquad(),299 "+0x1.0000000000000000000000000000p-16382");300 expected = APFloat(APFloat::IEEEquad(),301 "+0x0.ffffffffffffffffffffffffffffp-16382");302 EXPECT_EQ(test.next(true), APFloat::opOK);303 EXPECT_TRUE(test.isDenormal());304 EXPECT_TRUE(test.bitwiseIsEqual(expected));305 306 // 2b. Test normal <-> normal binade boundaries.307 // * nextUp(-Normal Binade Boundary) -> -Normal Binade Boundary + 1.308 // * nextDown(+Normal Binade Boundary) -> +Normal Binade Boundary - 1.309 // * nextUp(+Normal Binade Boundary - 1) -> +Normal Binade Boundary.310 // * nextDown(-Normal Binade Boundary + 1) -> -Normal Binade Boundary.311 312 // nextUp(-Normal Binade Boundary) -> -Normal Binade Boundary + 1.313 test = APFloat(APFloat::IEEEquad(), "-0x1p+1");314 expected = APFloat(APFloat::IEEEquad(),315 "-0x1.ffffffffffffffffffffffffffffp+0");316 EXPECT_EQ(test.next(false), APFloat::opOK);317 EXPECT_TRUE(test.bitwiseIsEqual(expected));318 319 // nextDown(+Normal Binade Boundary) -> +Normal Binade Boundary - 1.320 test = APFloat(APFloat::IEEEquad(), "0x1p+1");321 expected = APFloat(APFloat::IEEEquad(), "0x1.ffffffffffffffffffffffffffffp+0");322 EXPECT_EQ(test.next(true), APFloat::opOK);323 EXPECT_TRUE(test.bitwiseIsEqual(expected));324 325 // nextUp(+Normal Binade Boundary - 1) -> +Normal Binade Boundary.326 test = APFloat(APFloat::IEEEquad(), "0x1.ffffffffffffffffffffffffffffp+0");327 expected = APFloat(APFloat::IEEEquad(), "0x1p+1");328 EXPECT_EQ(test.next(false), APFloat::opOK);329 EXPECT_TRUE(test.bitwiseIsEqual(expected));330 331 // nextDown(-Normal Binade Boundary + 1) -> -Normal Binade Boundary.332 test = APFloat(APFloat::IEEEquad(), "-0x1.ffffffffffffffffffffffffffffp+0");333 expected = APFloat(APFloat::IEEEquad(), "-0x1p+1");334 EXPECT_EQ(test.next(true), APFloat::opOK);335 EXPECT_TRUE(test.bitwiseIsEqual(expected));336 337 // 2c. Test using next at binade boundaries with a direction away from the338 // binade boundary. Away from denormal <-> normal boundaries.339 //340 // This is to make sure that even though we are at a binade boundary, since341 // we are rounding away, we do not trigger the binade boundary code. Thus we342 // test:343 // * nextUp(-Largest Denormal) -> -Largest Denormal + inc.344 // * nextDown(+Largest Denormal) -> +Largest Denormal - inc.345 // * nextUp(+Smallest Normal) -> +Smallest Normal + inc.346 // * nextDown(-Smallest Normal) -> -Smallest Normal - inc.347 348 // nextUp(-Largest Denormal) -> -Largest Denormal + inc.349 test = APFloat(APFloat::IEEEquad(), "-0x0.ffffffffffffffffffffffffffffp-16382");350 expected = APFloat(APFloat::IEEEquad(),351 "-0x0.fffffffffffffffffffffffffffep-16382");352 EXPECT_EQ(test.next(false), APFloat::opOK);353 EXPECT_TRUE(test.isDenormal());354 EXPECT_TRUE(test.isNegative());355 EXPECT_TRUE(test.bitwiseIsEqual(expected));356 357 // nextDown(+Largest Denormal) -> +Largest Denormal - inc.358 test = APFloat(APFloat::IEEEquad(), "0x0.ffffffffffffffffffffffffffffp-16382");359 expected = APFloat(APFloat::IEEEquad(),360 "0x0.fffffffffffffffffffffffffffep-16382");361 EXPECT_EQ(test.next(true), APFloat::opOK);362 EXPECT_TRUE(test.isDenormal());363 EXPECT_TRUE(!test.isNegative());364 EXPECT_TRUE(test.bitwiseIsEqual(expected));365 366 // nextUp(+Smallest Normal) -> +Smallest Normal + inc.367 test = APFloat(APFloat::IEEEquad(), "0x1.0000000000000000000000000000p-16382");368 expected = APFloat(APFloat::IEEEquad(),369 "0x1.0000000000000000000000000001p-16382");370 EXPECT_EQ(test.next(false), APFloat::opOK);371 EXPECT_TRUE(!test.isDenormal());372 EXPECT_TRUE(!test.isNegative());373 EXPECT_TRUE(test.bitwiseIsEqual(expected));374 375 // nextDown(-Smallest Normal) -> -Smallest Normal - inc.376 test = APFloat(APFloat::IEEEquad(), "-0x1.0000000000000000000000000000p-16382");377 expected = APFloat(APFloat::IEEEquad(),378 "-0x1.0000000000000000000000000001p-16382");379 EXPECT_EQ(test.next(true), APFloat::opOK);380 EXPECT_TRUE(!test.isDenormal());381 EXPECT_TRUE(test.isNegative());382 EXPECT_TRUE(test.bitwiseIsEqual(expected));383 384 // 2d. Test values which cause our exponent to go to min exponent. This385 // is to ensure that guards in the code to check for min exponent386 // trigger properly.387 // * nextUp(-0x1p-16381) -> -0x1.ffffffffffffffffffffffffffffp-16382388 // * nextDown(-0x1.ffffffffffffffffffffffffffffp-16382) ->389 // -0x1p-16381390 // * nextUp(0x1.ffffffffffffffffffffffffffffp-16382) -> 0x1p-16382391 // * nextDown(0x1p-16382) -> 0x1.ffffffffffffffffffffffffffffp-16382392 393 // nextUp(-0x1p-16381) -> -0x1.ffffffffffffffffffffffffffffp-16382394 test = APFloat(APFloat::IEEEquad(), "-0x1p-16381");395 expected = APFloat(APFloat::IEEEquad(),396 "-0x1.ffffffffffffffffffffffffffffp-16382");397 EXPECT_EQ(test.next(false), APFloat::opOK);398 EXPECT_TRUE(test.bitwiseIsEqual(expected));399 400 // nextDown(-0x1.ffffffffffffffffffffffffffffp-16382) ->401 // -0x1p-16381402 test = APFloat(APFloat::IEEEquad(), "-0x1.ffffffffffffffffffffffffffffp-16382");403 expected = APFloat(APFloat::IEEEquad(), "-0x1p-16381");404 EXPECT_EQ(test.next(true), APFloat::opOK);405 EXPECT_TRUE(test.bitwiseIsEqual(expected));406 407 // nextUp(0x1.ffffffffffffffffffffffffffffp-16382) -> 0x1p-16381408 test = APFloat(APFloat::IEEEquad(), "0x1.ffffffffffffffffffffffffffffp-16382");409 expected = APFloat(APFloat::IEEEquad(), "0x1p-16381");410 EXPECT_EQ(test.next(false), APFloat::opOK);411 EXPECT_TRUE(test.bitwiseIsEqual(expected));412 413 // nextDown(0x1p-16381) -> 0x1.ffffffffffffffffffffffffffffp-16382414 test = APFloat(APFloat::IEEEquad(), "0x1p-16381");415 expected = APFloat(APFloat::IEEEquad(),416 "0x1.ffffffffffffffffffffffffffffp-16382");417 EXPECT_EQ(test.next(true), APFloat::opOK);418 EXPECT_TRUE(test.bitwiseIsEqual(expected));419 420 // 3. Now we test both denormal/normal computation which will not cause us421 // to go across binade boundaries. Specifically we test:422 // * nextUp(+Denormal) -> +Denormal.423 // * nextDown(+Denormal) -> +Denormal.424 // * nextUp(-Denormal) -> -Denormal.425 // * nextDown(-Denormal) -> -Denormal.426 // * nextUp(+Normal) -> +Normal.427 // * nextDown(+Normal) -> +Normal.428 // * nextUp(-Normal) -> -Normal.429 // * nextDown(-Normal) -> -Normal.430 431 // nextUp(+Denormal) -> +Denormal.432 test = APFloat(APFloat::IEEEquad(),433 "0x0.ffffffffffffffffffffffff000cp-16382");434 expected = APFloat(APFloat::IEEEquad(),435 "0x0.ffffffffffffffffffffffff000dp-16382");436 EXPECT_EQ(test.next(false), APFloat::opOK);437 EXPECT_TRUE(test.isDenormal());438 EXPECT_TRUE(!test.isNegative());439 EXPECT_TRUE(test.bitwiseIsEqual(expected));440 441 // nextDown(+Denormal) -> +Denormal.442 test = APFloat(APFloat::IEEEquad(),443 "0x0.ffffffffffffffffffffffff000cp-16382");444 expected = APFloat(APFloat::IEEEquad(),445 "0x0.ffffffffffffffffffffffff000bp-16382");446 EXPECT_EQ(test.next(true), APFloat::opOK);447 EXPECT_TRUE(test.isDenormal());448 EXPECT_TRUE(!test.isNegative());449 EXPECT_TRUE(test.bitwiseIsEqual(expected));450 451 // nextUp(-Denormal) -> -Denormal.452 test = APFloat(APFloat::IEEEquad(),453 "-0x0.ffffffffffffffffffffffff000cp-16382");454 expected = APFloat(APFloat::IEEEquad(),455 "-0x0.ffffffffffffffffffffffff000bp-16382");456 EXPECT_EQ(test.next(false), APFloat::opOK);457 EXPECT_TRUE(test.isDenormal());458 EXPECT_TRUE(test.isNegative());459 EXPECT_TRUE(test.bitwiseIsEqual(expected));460 461 // nextDown(-Denormal) -> -Denormal462 test = APFloat(APFloat::IEEEquad(),463 "-0x0.ffffffffffffffffffffffff000cp-16382");464 expected = APFloat(APFloat::IEEEquad(),465 "-0x0.ffffffffffffffffffffffff000dp-16382");466 EXPECT_EQ(test.next(true), APFloat::opOK);467 EXPECT_TRUE(test.isDenormal());468 EXPECT_TRUE(test.isNegative());469 EXPECT_TRUE(test.bitwiseIsEqual(expected));470 471 // nextUp(+Normal) -> +Normal.472 test = APFloat(APFloat::IEEEquad(),473 "0x1.ffffffffffffffffffffffff000cp-16000");474 expected = APFloat(APFloat::IEEEquad(),475 "0x1.ffffffffffffffffffffffff000dp-16000");476 EXPECT_EQ(test.next(false), APFloat::opOK);477 EXPECT_TRUE(!test.isDenormal());478 EXPECT_TRUE(!test.isNegative());479 EXPECT_TRUE(test.bitwiseIsEqual(expected));480 481 // nextDown(+Normal) -> +Normal.482 test = APFloat(APFloat::IEEEquad(),483 "0x1.ffffffffffffffffffffffff000cp-16000");484 expected = APFloat(APFloat::IEEEquad(),485 "0x1.ffffffffffffffffffffffff000bp-16000");486 EXPECT_EQ(test.next(true), APFloat::opOK);487 EXPECT_TRUE(!test.isDenormal());488 EXPECT_TRUE(!test.isNegative());489 EXPECT_TRUE(test.bitwiseIsEqual(expected));490 491 // nextUp(-Normal) -> -Normal.492 test = APFloat(APFloat::IEEEquad(),493 "-0x1.ffffffffffffffffffffffff000cp-16000");494 expected = APFloat(APFloat::IEEEquad(),495 "-0x1.ffffffffffffffffffffffff000bp-16000");496 EXPECT_EQ(test.next(false), APFloat::opOK);497 EXPECT_TRUE(!test.isDenormal());498 EXPECT_TRUE(test.isNegative());499 EXPECT_TRUE(test.bitwiseIsEqual(expected));500 501 // nextDown(-Normal) -> -Normal.502 test = APFloat(APFloat::IEEEquad(),503 "-0x1.ffffffffffffffffffffffff000cp-16000");504 expected = APFloat(APFloat::IEEEquad(),505 "-0x1.ffffffffffffffffffffffff000dp-16000");506 EXPECT_EQ(test.next(true), APFloat::opOK);507 EXPECT_TRUE(!test.isDenormal());508 EXPECT_TRUE(test.isNegative());509 EXPECT_TRUE(test.bitwiseIsEqual(expected));510}511 512TEST(APFloatTest, FMA) {513 APFloat::roundingMode rdmd = APFloat::rmNearestTiesToEven;514 515 {516 APFloat f1(14.5f);517 APFloat f2(-14.5f);518 APFloat f3(225.0f);519 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);520 EXPECT_EQ(14.75f, f1.convertToFloat());521 }522 523 {524 APFloat Val2(2.0f);525 APFloat f1((float)1.17549435e-38F);526 APFloat f2((float)1.17549435e-38F);527 f1.divide(Val2, rdmd);528 f2.divide(Val2, rdmd);529 APFloat f3(12.0f);530 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);531 EXPECT_EQ(12.0f, f1.convertToFloat());532 }533 534 // Test for correct zero sign when answer is exactly zero.535 // fma(1.0, -1.0, 1.0) -> +ve 0.536 {537 APFloat f1(1.0);538 APFloat f2(-1.0);539 APFloat f3(1.0);540 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);541 EXPECT_TRUE(!f1.isNegative() && f1.isZero());542 }543 544 // Test for correct zero sign when answer is exactly zero and rounding towards545 // negative.546 // fma(1.0, -1.0, 1.0) -> +ve 0.547 {548 APFloat f1(1.0);549 APFloat f2(-1.0);550 APFloat f3(1.0);551 f1.fusedMultiplyAdd(f2, f3, APFloat::rmTowardNegative);552 EXPECT_TRUE(f1.isNegative() && f1.isZero());553 }554 555 // Test for correct (in this case -ve) sign when adding like signed zeros.556 // Test fma(0.0, -0.0, -0.0) -> -ve 0.557 {558 APFloat f1(0.0);559 APFloat f2(-0.0);560 APFloat f3(-0.0);561 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);562 EXPECT_TRUE(f1.isNegative() && f1.isZero());563 }564 565 // Test -ve sign preservation when small negative results underflow.566 {567 APFloat f1(APFloat::IEEEdouble(), "-0x1p-1074");568 APFloat f2(APFloat::IEEEdouble(), "+0x1p-1074");569 APFloat f3(0.0);570 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);571 EXPECT_TRUE(f1.isNegative() && f1.isZero());572 }573 574 // Test x87 extended precision case from http://llvm.org/PR20728.575 {576 APFloat M1(APFloat::x87DoubleExtended(), 1);577 APFloat M2(APFloat::x87DoubleExtended(), 1);578 APFloat A(APFloat::x87DoubleExtended(), 3);579 580 bool losesInfo = false;581 M1.fusedMultiplyAdd(M1, A, APFloat::rmNearestTiesToEven);582 M1.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &losesInfo);583 EXPECT_FALSE(losesInfo);584 EXPECT_EQ(4.0f, M1.convertToFloat());585 }586 587 // Regression test that failed an assertion.588 {589 APFloat f1(-8.85242279E-41f);590 APFloat f2(2.0f);591 APFloat f3(8.85242279E-41f);592 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);593 EXPECT_EQ(-8.85242279E-41f, f1.convertToFloat());594 }595 596 // The `addOrSubtractSignificand` can be considered to have 9 possible cases597 // when subtracting: all combinations of {cmpLessThan, cmpGreaterThan,598 // cmpEqual} and {no loss, loss from lhs, loss from rhs}. Test each reachable599 // case here.600 601 // Regression test for failing the `assert(!carry)` in602 // `addOrSubtractSignificand` and normalizing the exponent even when the603 // significand is zero if there is a lost fraction.604 // This tests cmpEqual, loss from lhs605 {606 APFloat f1(-1.4728589E-38f);607 APFloat f2(3.7105144E-6f);608 APFloat f3(5.5E-44f);609 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);610 EXPECT_EQ(-0.0f, f1.convertToFloat());611 }612 613 // Test cmpGreaterThan, no loss614 {615 APFloat f1(2.0f);616 APFloat f2(2.0f);617 APFloat f3(-3.5f);618 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);619 EXPECT_EQ(0.5f, f1.convertToFloat());620 }621 622 // Test cmpLessThan, no loss623 {624 APFloat f1(2.0f);625 APFloat f2(2.0f);626 APFloat f3(-4.5f);627 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);628 EXPECT_EQ(-0.5f, f1.convertToFloat());629 }630 631 // Test cmpEqual, no loss632 {633 APFloat f1(2.0f);634 APFloat f2(2.0f);635 APFloat f3(-4.0f);636 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);637 EXPECT_EQ(0.0f, f1.convertToFloat());638 }639 640 // Test cmpLessThan, loss from lhs641 {642 APFloat f1(2.0000002f);643 APFloat f2(2.0000002f);644 APFloat f3(-32.0f);645 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);646 EXPECT_EQ(-27.999998f, f1.convertToFloat());647 }648 649 // Test cmpGreaterThan, loss from rhs650 {651 APFloat f1(1e10f);652 APFloat f2(1e10f);653 APFloat f3(-2.0000002f);654 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);655 EXPECT_EQ(1e20f, f1.convertToFloat());656 }657 658 // Test cmpGreaterThan, loss from lhs659 {660 APFloat f1(1e-36f);661 APFloat f2(0.0019531252f);662 APFloat f3(-1e-45f);663 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);664 EXPECT_EQ(1.953124e-39f, f1.convertToFloat());665 }666 667 // {cmpEqual, cmpLessThan} with loss from rhs can't occur for the usage in668 // `fusedMultiplyAdd` as `multiplySignificand` normalises the MSB of lhs to669 // one bit below the top.670 671 // Test cases from #104984672 {673 APFloat f1(0.24999998f);674 APFloat f2(2.3509885e-38f);675 APFloat f3(-1e-45f);676 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);677 EXPECT_EQ(5.87747e-39f, f1.convertToFloat());678 }679 {680 APFloat f1(4.4501477170144023e-308);681 APFloat f2(0.24999999999999997);682 APFloat f3(-8.475904604373977e-309);683 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);684 EXPECT_EQ(2.64946468816203e-309, f1.convertToDouble());685 }686 {687 APFloat f1(APFloat::IEEEhalf(), APInt(16, 0x8fffu));688 APFloat f2(APFloat::IEEEhalf(), APInt(16, 0x2bffu));689 APFloat f3(APFloat::IEEEhalf(), APInt(16, 0x0172u));690 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);691 EXPECT_EQ(0x808eu, f1.bitcastToAPInt().getZExtValue());692 }693 694 // Test using only a single instance of APFloat.695 {696 APFloat F(1.5);697 698 F.fusedMultiplyAdd(F, F, APFloat::rmNearestTiesToEven);699 EXPECT_EQ(3.75, F.convertToDouble());700 }701}702 703TEST(APFloatTest, MinNum) {704 APFloat f1(1.0);705 APFloat f2(2.0);706 APFloat nan = APFloat::getNaN(APFloat::IEEEdouble());707 708 EXPECT_EQ(1.0, minnum(f1, f2).convertToDouble());709 EXPECT_EQ(1.0, minnum(f2, f1).convertToDouble());710 EXPECT_EQ(1.0, minnum(f1, nan).convertToDouble());711 EXPECT_EQ(1.0, minnum(nan, f1).convertToDouble());712 713 APFloat zp(0.0);714 APFloat zn(-0.0);715 EXPECT_EQ(-0.0, minnum(zp, zn).convertToDouble());716 717 APInt intPayload_89ab(64, 0x89ab);718 APInt intPayload_cdef(64, 0xcdef);719 APFloat nan_0123[2] = {APFloat::getNaN(APFloat::IEEEdouble(), false, 0x0123),720 APFloat::getNaN(APFloat::IEEEdouble(), false, 0x0123)};721 APFloat mnan_4567[2] = {APFloat::getNaN(APFloat::IEEEdouble(), true, 0x4567),722 APFloat::getNaN(APFloat::IEEEdouble(), true, 0x4567)};723 APFloat nan_89ab[2] = {724 APFloat::getSNaN(APFloat::IEEEdouble(), false, &intPayload_89ab),725 APFloat::getNaN(APFloat::IEEEdouble(), false, 0x89ab)};726 APFloat mnan_cdef[2] = {727 APFloat::getSNaN(APFloat::IEEEdouble(), true, &intPayload_cdef),728 APFloat::getNaN(APFloat::IEEEdouble(), true, 0xcdef)};729 730 for (APFloat n : {nan_0123[0], mnan_4567[0]})731 for (APFloat f : {f1, f2, zn, zp}) {732 APFloat res = minnum(f, n);733 EXPECT_FALSE(res.isNaN());734 EXPECT_TRUE(res.bitwiseIsEqual(f));735 res = minnum(n, f);736 EXPECT_FALSE(res.isNaN());737 EXPECT_TRUE(res.bitwiseIsEqual(f));738 }739 for (auto n : {nan_89ab, mnan_cdef})740 for (APFloat f : {f1, f2, zn, zp}) {741 APFloat res = minnum(f, n[0]);742 EXPECT_TRUE(res.isNaN());743 EXPECT_TRUE(res.bitwiseIsEqual(n[1]));744 res = minnum(n[0], f);745 EXPECT_TRUE(res.isNaN());746 EXPECT_TRUE(res.bitwiseIsEqual(n[1]));747 }748 749 // When NaN vs NaN, we should keep payload/sign of either one.750 for (auto n1 : {nan_0123, mnan_4567, nan_89ab, mnan_cdef})751 for (auto n2 : {nan_0123, mnan_4567, nan_89ab, mnan_cdef}) {752 APFloat res = minnum(n1[0], n2[0]);753 EXPECT_TRUE(res.bitwiseIsEqual(n1[1]) || res.bitwiseIsEqual(n2[1]));754 EXPECT_FALSE(res.isSignaling());755 }756}757 758TEST(APFloatTest, MaxNum) {759 APFloat f1(1.0);760 APFloat f2(2.0);761 APFloat nan = APFloat::getNaN(APFloat::IEEEdouble());762 763 EXPECT_EQ(2.0, maxnum(f1, f2).convertToDouble());764 EXPECT_EQ(2.0, maxnum(f2, f1).convertToDouble());765 EXPECT_EQ(1.0, maxnum(f1, nan).convertToDouble());766 EXPECT_EQ(1.0, maxnum(nan, f1).convertToDouble());767 768 APFloat zp(0.0);769 APFloat zn(-0.0);770 EXPECT_EQ(0.0, maxnum(zp, zn).convertToDouble());771 EXPECT_EQ(0.0, maxnum(zn, zp).convertToDouble());772 773 APInt intPayload_89ab(64, 0x89ab);774 APInt intPayload_cdef(64, 0xcdef);775 APFloat nan_0123[2] = {APFloat::getNaN(APFloat::IEEEdouble(), false, 0x0123),776 APFloat::getNaN(APFloat::IEEEdouble(), false, 0x0123)};777 APFloat mnan_4567[2] = {APFloat::getNaN(APFloat::IEEEdouble(), true, 0x4567),778 APFloat::getNaN(APFloat::IEEEdouble(), true, 0x4567)};779 APFloat nan_89ab[2] = {780 APFloat::getSNaN(APFloat::IEEEdouble(), false, &intPayload_89ab),781 APFloat::getNaN(APFloat::IEEEdouble(), false, 0x89ab)};782 APFloat mnan_cdef[2] = {783 APFloat::getSNaN(APFloat::IEEEdouble(), true, &intPayload_cdef),784 APFloat::getNaN(APFloat::IEEEdouble(), true, 0xcdef)};785 786 for (APFloat n : {nan_0123[0], mnan_4567[0]})787 for (APFloat f : {f1, f2, zn, zp}) {788 APFloat res = maxnum(f, n);789 EXPECT_FALSE(res.isNaN());790 EXPECT_TRUE(res.bitwiseIsEqual(f));791 res = maxnum(n, f);792 EXPECT_FALSE(res.isNaN());793 EXPECT_TRUE(res.bitwiseIsEqual(f));794 }795 for (auto n : {nan_89ab, mnan_cdef})796 for (APFloat f : {f1, f2, zn, zp}) {797 APFloat res = maxnum(f, n[0]);798 EXPECT_TRUE(res.isNaN());799 EXPECT_TRUE(res.bitwiseIsEqual(n[1]));800 res = maxnum(n[0], f);801 EXPECT_TRUE(res.isNaN());802 EXPECT_TRUE(res.bitwiseIsEqual(n[1]));803 }804 805 // When NaN vs NaN, we should keep payload/sign of either one.806 for (auto n1 : {nan_0123, mnan_4567, nan_89ab, mnan_cdef})807 for (auto n2 : {nan_0123, mnan_4567, nan_89ab, mnan_cdef}) {808 APFloat res = maxnum(n1[0], n2[0]);809 EXPECT_TRUE(res.bitwiseIsEqual(n1[1]) || res.bitwiseIsEqual(n2[1]));810 EXPECT_FALSE(res.isSignaling());811 }812}813 814TEST(APFloatTest, Minimum) {815 APFloat f1(1.0);816 APFloat f2(2.0);817 APFloat zp(0.0);818 APFloat zn(-0.0);819 APFloat nan = APFloat::getNaN(APFloat::IEEEdouble());820 APFloat snan = APFloat::getSNaN(APFloat::IEEEdouble());821 822 EXPECT_EQ(1.0, minimum(f1, f2).convertToDouble());823 EXPECT_EQ(1.0, minimum(f2, f1).convertToDouble());824 EXPECT_EQ(-0.0, minimum(zp, zn).convertToDouble());825 EXPECT_EQ(-0.0, minimum(zn, zp).convertToDouble());826 EXPECT_TRUE(std::isnan(minimum(f1, nan).convertToDouble()));827 EXPECT_TRUE(std::isnan(minimum(nan, f1).convertToDouble()));828 EXPECT_TRUE(maximum(snan, f1).isNaN());829 EXPECT_TRUE(maximum(f1, snan).isNaN());830 EXPECT_FALSE(maximum(snan, f1).isSignaling());831 EXPECT_FALSE(maximum(f1, snan).isSignaling());832}833 834TEST(APFloatTest, Maximum) {835 APFloat f1(1.0);836 APFloat f2(2.0);837 APFloat zp(0.0);838 APFloat zn(-0.0);839 APFloat nan = APFloat::getNaN(APFloat::IEEEdouble());840 APFloat snan = APFloat::getSNaN(APFloat::IEEEdouble());841 842 EXPECT_EQ(2.0, maximum(f1, f2).convertToDouble());843 EXPECT_EQ(2.0, maximum(f2, f1).convertToDouble());844 EXPECT_EQ(0.0, maximum(zp, zn).convertToDouble());845 EXPECT_EQ(0.0, maximum(zn, zp).convertToDouble());846 EXPECT_TRUE(std::isnan(maximum(f1, nan).convertToDouble()));847 EXPECT_TRUE(std::isnan(maximum(nan, f1).convertToDouble()));848 EXPECT_TRUE(maximum(snan, f1).isNaN());849 EXPECT_TRUE(maximum(f1, snan).isNaN());850 EXPECT_FALSE(maximum(snan, f1).isSignaling());851 EXPECT_FALSE(maximum(f1, snan).isSignaling());852}853 854TEST(APFloatTest, MinimumNumber) {855 APFloat f1(1.0);856 APFloat f2(2.0);857 APFloat zp(0.0);858 APFloat zn(-0.0);859 APInt intPayload_89ab(64, 0x89ab);860 APInt intPayload_cdef(64, 0xcdef);861 APFloat nan_0123[2] = {APFloat::getNaN(APFloat::IEEEdouble(), false, 0x0123),862 APFloat::getNaN(APFloat::IEEEdouble(), false, 0x0123)};863 APFloat mnan_4567[2] = {APFloat::getNaN(APFloat::IEEEdouble(), true, 0x4567),864 APFloat::getNaN(APFloat::IEEEdouble(), true, 0x4567)};865 APFloat nan_89ab[2] = {866 APFloat::getSNaN(APFloat::IEEEdouble(), false, &intPayload_89ab),867 APFloat::getNaN(APFloat::IEEEdouble(), false, 0x89ab)};868 APFloat mnan_cdef[2] = {869 APFloat::getSNaN(APFloat::IEEEdouble(), true, &intPayload_cdef),870 APFloat::getNaN(APFloat::IEEEdouble(), true, 0xcdef)};871 872 EXPECT_TRUE(f1.bitwiseIsEqual(minimumnum(f1, f2)));873 EXPECT_TRUE(f1.bitwiseIsEqual(minimumnum(f2, f1)));874 EXPECT_TRUE(zn.bitwiseIsEqual(minimumnum(zp, zn)));875 EXPECT_TRUE(zn.bitwiseIsEqual(minimumnum(zn, zp)));876 877 EXPECT_TRUE(minimumnum(zn, zp).isNegative());878 EXPECT_TRUE(minimumnum(zp, zn).isNegative());879 EXPECT_TRUE(minimumnum(zn, zn).isNegative());880 EXPECT_FALSE(minimumnum(zp, zp).isNegative());881 882 for (APFloat n : {nan_0123[0], mnan_4567[0], nan_89ab[0], mnan_cdef[0]})883 for (APFloat f : {f1, f2, zn, zp}) {884 APFloat res = minimumnum(f, n);885 EXPECT_FALSE(res.isNaN());886 EXPECT_TRUE(res.bitwiseIsEqual(f));887 res = minimumnum(n, f);888 EXPECT_FALSE(res.isNaN());889 EXPECT_TRUE(res.bitwiseIsEqual(f));890 }891 892 // When NaN vs NaN, we should keep payload/sign of either one.893 for (auto n1 : {nan_0123, mnan_4567, nan_89ab, mnan_cdef})894 for (auto n2 : {nan_0123, mnan_4567, nan_89ab, mnan_cdef}) {895 APFloat res = minimumnum(n1[0], n2[0]);896 EXPECT_TRUE(res.bitwiseIsEqual(n1[1]) || res.bitwiseIsEqual(n2[1]));897 EXPECT_FALSE(res.isSignaling());898 }899}900 901TEST(APFloatTest, MaximumNumber) {902 APFloat f1(1.0);903 APFloat f2(2.0);904 APFloat zp(0.0);905 APFloat zn(-0.0);906 APInt intPayload_89ab(64, 0x89ab);907 APInt intPayload_cdef(64, 0xcdef);908 APFloat nan_0123[2] = {APFloat::getNaN(APFloat::IEEEdouble(), false, 0x0123),909 APFloat::getNaN(APFloat::IEEEdouble(), false, 0x0123)};910 APFloat mnan_4567[2] = {APFloat::getNaN(APFloat::IEEEdouble(), true, 0x4567),911 APFloat::getNaN(APFloat::IEEEdouble(), true, 0x4567)};912 APFloat nan_89ab[2] = {913 APFloat::getSNaN(APFloat::IEEEdouble(), false, &intPayload_89ab),914 APFloat::getNaN(APFloat::IEEEdouble(), false, 0x89ab)};915 APFloat mnan_cdef[2] = {916 APFloat::getSNaN(APFloat::IEEEdouble(), true, &intPayload_cdef),917 APFloat::getNaN(APFloat::IEEEdouble(), true, 0xcdef)};918 919 EXPECT_TRUE(f2.bitwiseIsEqual(maximumnum(f1, f2)));920 EXPECT_TRUE(f2.bitwiseIsEqual(maximumnum(f2, f1)));921 EXPECT_TRUE(zp.bitwiseIsEqual(maximumnum(zp, zn)));922 EXPECT_TRUE(zp.bitwiseIsEqual(maximumnum(zn, zp)));923 924 EXPECT_FALSE(maximumnum(zn, zp).isNegative());925 EXPECT_FALSE(maximumnum(zp, zn).isNegative());926 EXPECT_TRUE(maximumnum(zn, zn).isNegative());927 EXPECT_FALSE(maximumnum(zp, zp).isNegative());928 929 for (APFloat n : {nan_0123[0], mnan_4567[0], nan_89ab[0], mnan_cdef[0]})930 for (APFloat f : {f1, f2, zn, zp}) {931 APFloat res = maximumnum(f, n);932 EXPECT_FALSE(res.isNaN());933 EXPECT_TRUE(res.bitwiseIsEqual(f));934 res = maximumnum(n, f);935 EXPECT_FALSE(res.isNaN());936 EXPECT_TRUE(res.bitwiseIsEqual(f));937 }938 939 // When NaN vs NaN, we should keep payload/sign of either one.940 for (auto n1 : {nan_0123, mnan_4567, nan_89ab, mnan_cdef})941 for (auto n2 : {nan_0123, mnan_4567, nan_89ab, mnan_cdef}) {942 APFloat res = maximumnum(n1[0], n2[0]);943 EXPECT_TRUE(res.bitwiseIsEqual(n1[1]) || res.bitwiseIsEqual(n2[1]));944 EXPECT_FALSE(res.isSignaling());945 }946}947 948TEST(APFloatTest, Denormal) {949 APFloat::roundingMode rdmd = APFloat::rmNearestTiesToEven;950 951 // Test single precision952 {953 const char *MinNormalStr = "1.17549435082228750797e-38";954 EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), MinNormalStr).isDenormal());955 EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), 0).isDenormal());956 957 APFloat Val2(APFloat::IEEEsingle(), 2);958 APFloat T(APFloat::IEEEsingle(), MinNormalStr);959 T.divide(Val2, rdmd);960 EXPECT_TRUE(T.isDenormal());961 EXPECT_EQ(fcPosSubnormal, T.classify());962 963 964 const char *NegMinNormalStr = "-1.17549435082228750797e-38";965 EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), NegMinNormalStr).isDenormal());966 APFloat NegT(APFloat::IEEEsingle(), NegMinNormalStr);967 NegT.divide(Val2, rdmd);968 EXPECT_TRUE(NegT.isDenormal());969 EXPECT_EQ(fcNegSubnormal, NegT.classify());970 }971 972 // Test double precision973 {974 const char *MinNormalStr = "2.22507385850720138309e-308";975 EXPECT_FALSE(APFloat(APFloat::IEEEdouble(), MinNormalStr).isDenormal());976 EXPECT_FALSE(APFloat(APFloat::IEEEdouble(), 0).isDenormal());977 978 APFloat Val2(APFloat::IEEEdouble(), 2);979 APFloat T(APFloat::IEEEdouble(), MinNormalStr);980 T.divide(Val2, rdmd);981 EXPECT_TRUE(T.isDenormal());982 EXPECT_EQ(fcPosSubnormal, T.classify());983 }984 985 // Test Intel double-ext986 {987 const char *MinNormalStr = "3.36210314311209350626e-4932";988 EXPECT_FALSE(APFloat(APFloat::x87DoubleExtended(), MinNormalStr).isDenormal());989 EXPECT_FALSE(APFloat(APFloat::x87DoubleExtended(), 0).isDenormal());990 991 APFloat Val2(APFloat::x87DoubleExtended(), 2);992 APFloat T(APFloat::x87DoubleExtended(), MinNormalStr);993 T.divide(Val2, rdmd);994 EXPECT_TRUE(T.isDenormal());995 EXPECT_EQ(fcPosSubnormal, T.classify());996 }997 998 // Test quadruple precision999 {1000 const char *MinNormalStr = "3.36210314311209350626267781732175260e-4932";1001 EXPECT_FALSE(APFloat(APFloat::IEEEquad(), MinNormalStr).isDenormal());1002 EXPECT_FALSE(APFloat(APFloat::IEEEquad(), 0).isDenormal());1003 1004 APFloat Val2(APFloat::IEEEquad(), 2);1005 APFloat T(APFloat::IEEEquad(), MinNormalStr);1006 T.divide(Val2, rdmd);1007 EXPECT_TRUE(T.isDenormal());1008 EXPECT_EQ(fcPosSubnormal, T.classify());1009 }1010 1011 // Test TF321012 {1013 const char *MinNormalStr = "1.17549435082228750797e-38";1014 EXPECT_FALSE(APFloat(APFloat::FloatTF32(), MinNormalStr).isDenormal());1015 EXPECT_FALSE(APFloat(APFloat::FloatTF32(), 0).isDenormal());1016 1017 APFloat Val2(APFloat::FloatTF32(), 2);1018 APFloat T(APFloat::FloatTF32(), MinNormalStr);1019 T.divide(Val2, rdmd);1020 EXPECT_TRUE(T.isDenormal());1021 EXPECT_EQ(fcPosSubnormal, T.classify());1022 1023 const char *NegMinNormalStr = "-1.17549435082228750797e-38";1024 EXPECT_FALSE(APFloat(APFloat::FloatTF32(), NegMinNormalStr).isDenormal());1025 APFloat NegT(APFloat::FloatTF32(), NegMinNormalStr);1026 NegT.divide(Val2, rdmd);1027 EXPECT_TRUE(NegT.isDenormal());1028 EXPECT_EQ(fcNegSubnormal, NegT.classify());1029 }1030}1031 1032TEST(APFloatTest, IsSmallestNormalized) {1033 for (unsigned I = 0; I != APFloat::S_MaxSemantics + 1; ++I) {1034 const fltSemantics &Semantics =1035 APFloat::EnumToSemantics(static_cast<APFloat::Semantics>(I));1036 1037 // For Float8E8M0FNU format, the below cases are tested1038 // through Float8E8M0FNUSmallest and Float8E8M0FNUNext tests.1039 if (I == APFloat::S_Float8E8M0FNU)1040 continue;1041 1042 EXPECT_FALSE(APFloat::getZero(Semantics, false).isSmallestNormalized());1043 EXPECT_FALSE(APFloat::getZero(Semantics, true).isSmallestNormalized());1044 1045 if (APFloat::semanticsHasNaN(Semantics)) {1046 // Types that do not support Inf will return NaN when asked for Inf.1047 // (But only if they support NaN.)1048 EXPECT_FALSE(APFloat::getInf(Semantics, false).isSmallestNormalized());1049 EXPECT_FALSE(APFloat::getInf(Semantics, true).isSmallestNormalized());1050 1051 EXPECT_FALSE(APFloat::getQNaN(Semantics).isSmallestNormalized());1052 EXPECT_FALSE(APFloat::getSNaN(Semantics).isSmallestNormalized());1053 }1054 1055 EXPECT_FALSE(APFloat::getLargest(Semantics).isSmallestNormalized());1056 EXPECT_FALSE(APFloat::getLargest(Semantics, true).isSmallestNormalized());1057 1058 EXPECT_FALSE(APFloat::getSmallest(Semantics).isSmallestNormalized());1059 EXPECT_FALSE(APFloat::getSmallest(Semantics, true).isSmallestNormalized());1060 1061 EXPECT_FALSE(APFloat::getAllOnesValue(Semantics).isSmallestNormalized());1062 1063 APFloat PosSmallestNormalized =1064 APFloat::getSmallestNormalized(Semantics, false);1065 APFloat NegSmallestNormalized =1066 APFloat::getSmallestNormalized(Semantics, true);1067 EXPECT_TRUE(PosSmallestNormalized.isSmallestNormalized());1068 EXPECT_TRUE(NegSmallestNormalized.isSmallestNormalized());1069 EXPECT_EQ(fcPosNormal, PosSmallestNormalized.classify());1070 EXPECT_EQ(fcNegNormal, NegSmallestNormalized.classify());1071 1072 for (APFloat *Val : {&PosSmallestNormalized, &NegSmallestNormalized}) {1073 bool OldSign = Val->isNegative();1074 1075 // Step down, make sure it's still not smallest normalized.1076 EXPECT_EQ(APFloat::opOK, Val->next(false));1077 EXPECT_EQ(OldSign, Val->isNegative());1078 EXPECT_FALSE(Val->isSmallestNormalized());1079 EXPECT_EQ(OldSign, Val->isNegative());1080 1081 // Step back up should restore it to being smallest normalized.1082 EXPECT_EQ(APFloat::opOK, Val->next(true));1083 EXPECT_TRUE(Val->isSmallestNormalized());1084 EXPECT_EQ(OldSign, Val->isNegative());1085 1086 // Step beyond should no longer smallest normalized.1087 EXPECT_EQ(APFloat::opOK, Val->next(true));1088 EXPECT_FALSE(Val->isSmallestNormalized());1089 EXPECT_EQ(OldSign, Val->isNegative());1090 }1091 }1092}1093 1094TEST(APFloatTest, Zero) {1095 EXPECT_EQ(0.0f, APFloat(0.0f).convertToFloat());1096 EXPECT_EQ(-0.0f, APFloat(-0.0f).convertToFloat());1097 EXPECT_TRUE(APFloat(-0.0f).isNegative());1098 1099 EXPECT_EQ(0.0, APFloat(0.0).convertToDouble());1100 EXPECT_EQ(-0.0, APFloat(-0.0).convertToDouble());1101 EXPECT_TRUE(APFloat(-0.0).isNegative());1102 1103 EXPECT_EQ(fcPosZero, APFloat(0.0).classify());1104 EXPECT_EQ(fcNegZero, APFloat(-0.0).classify());1105}1106 1107TEST(APFloatTest, getOne) {1108 EXPECT_EQ(APFloat::getOne(APFloat::IEEEsingle(), false).convertToFloat(),1109 1.0f);1110 EXPECT_EQ(APFloat::getOne(APFloat::IEEEsingle(), true).convertToFloat(),1111 -1.0f);1112}1113 1114TEST(APFloatTest, DecimalStringsWithoutNullTerminators) {1115 // Make sure that we can parse strings without null terminators.1116 // rdar://14323230.1117 EXPECT_EQ(convertToDoubleFromString(StringRef("0.00", 3)), 0.0);1118 EXPECT_EQ(convertToDoubleFromString(StringRef("0.01", 3)), 0.0);1119 EXPECT_EQ(convertToDoubleFromString(StringRef("0.09", 3)), 0.0);1120 EXPECT_EQ(convertToDoubleFromString(StringRef("0.095", 4)), 0.09);1121 EXPECT_EQ(convertToDoubleFromString(StringRef("0.00e+3", 7)), 0.00);1122 EXPECT_EQ(convertToDoubleFromString(StringRef("0e+3", 4)), 0.00);1123}1124 1125TEST(APFloatTest, fromZeroDecimalString) {1126 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0").convertToDouble());1127 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0").convertToDouble());1128 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0").convertToDouble());1129 1130 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.").convertToDouble());1131 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.").convertToDouble());1132 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.").convertToDouble());1133 1134 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), ".0").convertToDouble());1135 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+.0").convertToDouble());1136 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-.0").convertToDouble());1137 1138 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.0").convertToDouble());1139 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.0").convertToDouble());1140 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.0").convertToDouble());1141 1142 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "00000.").convertToDouble());1143 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+00000.").convertToDouble());1144 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-00000.").convertToDouble());1145 1146 EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble(), ".00000").convertToDouble());1147 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+.00000").convertToDouble());1148 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-.00000").convertToDouble());1149 1150 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0000.00000").convertToDouble());1151 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0000.00000").convertToDouble());1152 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0000.00000").convertToDouble());1153}1154 1155TEST(APFloatTest, fromZeroDecimalSingleExponentString) {1156 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e1").convertToDouble());1157 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e1").convertToDouble());1158 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e1").convertToDouble());1159 1160 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e+1").convertToDouble());1161 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e+1").convertToDouble());1162 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e+1").convertToDouble());1163 1164 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e-1").convertToDouble());1165 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e-1").convertToDouble());1166 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e-1").convertToDouble());1167 1168 1169 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.e1").convertToDouble());1170 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.e1").convertToDouble());1171 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.e1").convertToDouble());1172 1173 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.e+1").convertToDouble());1174 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.e+1").convertToDouble());1175 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.e+1").convertToDouble());1176 1177 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.e-1").convertToDouble());1178 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.e-1").convertToDouble());1179 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.e-1").convertToDouble());1180 1181 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), ".0e1").convertToDouble());1182 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+.0e1").convertToDouble());1183 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-.0e1").convertToDouble());1184 1185 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), ".0e+1").convertToDouble());1186 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+.0e+1").convertToDouble());1187 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-.0e+1").convertToDouble());1188 1189 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), ".0e-1").convertToDouble());1190 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+.0e-1").convertToDouble());1191 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-.0e-1").convertToDouble());1192 1193 1194 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.0e1").convertToDouble());1195 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.0e1").convertToDouble());1196 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.0e1").convertToDouble());1197 1198 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.0e+1").convertToDouble());1199 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.0e+1").convertToDouble());1200 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.0e+1").convertToDouble());1201 1202 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0.0e-1").convertToDouble());1203 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0.0e-1").convertToDouble());1204 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0.0e-1").convertToDouble());1205 1206 1207 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "000.0000e1").convertToDouble());1208 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+000.0000e+1").convertToDouble());1209 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-000.0000e+1").convertToDouble());1210}1211 1212TEST(APFloatTest, fromZeroDecimalLargeExponentString) {1213 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e1234").convertToDouble());1214 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e1234").convertToDouble());1215 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e1234").convertToDouble());1216 1217 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e+1234").convertToDouble());1218 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e+1234").convertToDouble());1219 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e+1234").convertToDouble());1220 1221 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0e-1234").convertToDouble());1222 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0e-1234").convertToDouble());1223 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0e-1234").convertToDouble());1224 1225 EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble(), "000.0000e1234").convertToDouble());1226 EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble(), "000.0000e-1234").convertToDouble());1227 1228 EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble(), StringRef("0e1234" "\0" "2", 6)).convertToDouble());1229}1230 1231TEST(APFloatTest, fromZeroHexadecimalString) {1232 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0p1").convertToDouble());1233 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0p1").convertToDouble());1234 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0p1").convertToDouble());1235 1236 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0p+1").convertToDouble());1237 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0p+1").convertToDouble());1238 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0p+1").convertToDouble());1239 1240 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0p-1").convertToDouble());1241 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0p-1").convertToDouble());1242 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0p-1").convertToDouble());1243 1244 1245 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.p1").convertToDouble());1246 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.p1").convertToDouble());1247 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.p1").convertToDouble());1248 1249 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.p+1").convertToDouble());1250 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.p+1").convertToDouble());1251 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.p+1").convertToDouble());1252 1253 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.p-1").convertToDouble());1254 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.p-1").convertToDouble());1255 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.p-1").convertToDouble());1256 1257 1258 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x.0p1").convertToDouble());1259 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x.0p1").convertToDouble());1260 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x.0p1").convertToDouble());1261 1262 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x.0p+1").convertToDouble());1263 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x.0p+1").convertToDouble());1264 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x.0p+1").convertToDouble());1265 1266 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x.0p-1").convertToDouble());1267 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x.0p-1").convertToDouble());1268 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x.0p-1").convertToDouble());1269 1270 1271 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.0p1").convertToDouble());1272 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.0p1").convertToDouble());1273 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.0p1").convertToDouble());1274 1275 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.0p+1").convertToDouble());1276 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.0p+1").convertToDouble());1277 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.0p+1").convertToDouble());1278 1279 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.0p-1").convertToDouble());1280 EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble(), "+0x0.0p-1").convertToDouble());1281 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0.0p-1").convertToDouble());1282 1283 1284 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x00000.p1").convertToDouble());1285 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0000.00000p1").convertToDouble());1286 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x.00000p1").convertToDouble());1287 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.p1").convertToDouble());1288 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0p1234").convertToDouble());1289 EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble(), "-0x0p1234").convertToDouble());1290 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x00000.p1234").convertToDouble());1291 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0000.00000p1234").convertToDouble());1292 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x.00000p1234").convertToDouble());1293 EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble(), "0x0.p1234").convertToDouble());1294}1295 1296TEST(APFloatTest, fromDecimalString) {1297 EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1").convertToDouble());1298 EXPECT_EQ(2.0, APFloat(APFloat::IEEEdouble(), "2.").convertToDouble());1299 EXPECT_EQ(0.5, APFloat(APFloat::IEEEdouble(), ".5").convertToDouble());1300 EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1.0").convertToDouble());1301 EXPECT_EQ(-2.0, APFloat(APFloat::IEEEdouble(), "-2").convertToDouble());1302 EXPECT_EQ(-4.0, APFloat(APFloat::IEEEdouble(), "-4.").convertToDouble());1303 EXPECT_EQ(-0.5, APFloat(APFloat::IEEEdouble(), "-.5").convertToDouble());1304 EXPECT_EQ(-1.5, APFloat(APFloat::IEEEdouble(), "-1.5").convertToDouble());1305 EXPECT_EQ(1.25e12, APFloat(APFloat::IEEEdouble(), "1.25e12").convertToDouble());1306 EXPECT_EQ(1.25e+12, APFloat(APFloat::IEEEdouble(), "1.25e+12").convertToDouble());1307 EXPECT_EQ(1.25e-12, APFloat(APFloat::IEEEdouble(), "1.25e-12").convertToDouble());1308 EXPECT_EQ(1024.0, APFloat(APFloat::IEEEdouble(), "1024.").convertToDouble());1309 EXPECT_EQ(1024.05, APFloat(APFloat::IEEEdouble(), "1024.05000").convertToDouble());1310 EXPECT_EQ(0.05, APFloat(APFloat::IEEEdouble(), ".05000").convertToDouble());1311 EXPECT_EQ(2.0, APFloat(APFloat::IEEEdouble(), "2.").convertToDouble());1312 EXPECT_EQ(2.0e2, APFloat(APFloat::IEEEdouble(), "2.e2").convertToDouble());1313 EXPECT_EQ(2.0e+2, APFloat(APFloat::IEEEdouble(), "2.e+2").convertToDouble());1314 EXPECT_EQ(2.0e-2, APFloat(APFloat::IEEEdouble(), "2.e-2").convertToDouble());1315 EXPECT_EQ(2.05e2, APFloat(APFloat::IEEEdouble(), "002.05000e2").convertToDouble());1316 EXPECT_EQ(2.05e+2, APFloat(APFloat::IEEEdouble(), "002.05000e+2").convertToDouble());1317 EXPECT_EQ(2.05e-2, APFloat(APFloat::IEEEdouble(), "002.05000e-2").convertToDouble());1318 EXPECT_EQ(2.05e12, APFloat(APFloat::IEEEdouble(), "002.05000e12").convertToDouble());1319 EXPECT_EQ(2.05e+12, APFloat(APFloat::IEEEdouble(), "002.05000e+12").convertToDouble());1320 EXPECT_EQ(2.05e-12, APFloat(APFloat::IEEEdouble(), "002.05000e-12").convertToDouble());1321 1322 EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1e").convertToDouble());1323 EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "+1e").convertToDouble());1324 EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble(), "-1e").convertToDouble());1325 1326 EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1.e").convertToDouble());1327 EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "+1.e").convertToDouble());1328 EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble(), "-1.e").convertToDouble());1329 1330 EXPECT_EQ(0.1, APFloat(APFloat::IEEEdouble(), ".1e").convertToDouble());1331 EXPECT_EQ(0.1, APFloat(APFloat::IEEEdouble(), "+.1e").convertToDouble());1332 EXPECT_EQ(-0.1, APFloat(APFloat::IEEEdouble(), "-.1e").convertToDouble());1333 1334 EXPECT_EQ(1.1, APFloat(APFloat::IEEEdouble(), "1.1e").convertToDouble());1335 EXPECT_EQ(1.1, APFloat(APFloat::IEEEdouble(), "+1.1e").convertToDouble());1336 EXPECT_EQ(-1.1, APFloat(APFloat::IEEEdouble(), "-1.1e").convertToDouble());1337 1338 EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1e+").convertToDouble());1339 EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1e-").convertToDouble());1340 1341 EXPECT_EQ(0.1, APFloat(APFloat::IEEEdouble(), ".1e").convertToDouble());1342 EXPECT_EQ(0.1, APFloat(APFloat::IEEEdouble(), ".1e+").convertToDouble());1343 EXPECT_EQ(0.1, APFloat(APFloat::IEEEdouble(), ".1e-").convertToDouble());1344 1345 EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1.0e").convertToDouble());1346 EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1.0e+").convertToDouble());1347 EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "1.0e-").convertToDouble());1348 1349 // These are "carefully selected" to overflow the fast log-base1350 // calculations in APFloat.cpp1351 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "99e99999").isInfinity());1352 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-99e99999").isInfinity());1353 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "1e-99999").isPosZero());1354 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-1e-99999").isNegZero());1355 1356 EXPECT_EQ(2.71828, convertToDoubleFromString("2.71828"));1357}1358 1359TEST(APFloatTest, fromStringSpecials) {1360 const fltSemantics &Sem = APFloat::IEEEdouble();1361 const unsigned Precision = 53;1362 const unsigned PayloadBits = Precision - 2;1363 uint64_t PayloadMask = (uint64_t(1) << PayloadBits) - uint64_t(1);1364 1365 uint64_t NaNPayloads[] = {1366 0,1367 1,1368 123,1369 0xDEADBEEF,1370 uint64_t(-2),1371 uint64_t(1) << PayloadBits, // overflow bit1372 uint64_t(1) << (PayloadBits - 1), // signaling bit1373 uint64_t(1) << (PayloadBits - 2) // highest possible bit1374 };1375 1376 // Convert payload integer to decimal string representation.1377 std::string NaNPayloadDecStrings[std::size(NaNPayloads)];1378 for (size_t I = 0; I < std::size(NaNPayloads); ++I)1379 NaNPayloadDecStrings[I] = utostr(NaNPayloads[I]);1380 1381 // Convert payload integer to hexadecimal string representation.1382 std::string NaNPayloadHexStrings[std::size(NaNPayloads)];1383 for (size_t I = 0; I < std::size(NaNPayloads); ++I)1384 NaNPayloadHexStrings[I] = "0x" + utohexstr(NaNPayloads[I]);1385 1386 // Fix payloads to expected result.1387 for (uint64_t &Payload : NaNPayloads)1388 Payload &= PayloadMask;1389 1390 // Signaling NaN must have a non-zero payload. In case a zero payload is1391 // requested, a default arbitrary payload is set instead. Save this payload1392 // for testing.1393 const uint64_t SNaNDefaultPayload =1394 APFloat::getSNaN(Sem).bitcastToAPInt().getZExtValue() & PayloadMask;1395 1396 // Negative sign prefix (or none - for positive).1397 const char Signs[] = {0, '-'};1398 1399 // "Signaling" prefix (or none - for "Quiet").1400 const char NaNTypes[] = {0, 's', 'S'};1401 1402 const StringRef NaNStrings[] = {"nan", "NaN"};1403 for (StringRef NaNStr : NaNStrings)1404 for (char TypeChar : NaNTypes) {1405 bool Signaling = (TypeChar == 's' || TypeChar == 'S');1406 1407 for (size_t J = 0; J < std::size(NaNPayloads); ++J) {1408 uint64_t Payload = (Signaling && !NaNPayloads[J]) ? SNaNDefaultPayload1409 : NaNPayloads[J];1410 std::string &PayloadDec = NaNPayloadDecStrings[J];1411 std::string &PayloadHex = NaNPayloadHexStrings[J];1412 1413 for (char SignChar : Signs) {1414 bool Negative = (SignChar == '-');1415 1416 std::string TestStrings[5];1417 size_t NumTestStrings = 0;1418 1419 std::string Prefix;1420 if (SignChar)1421 Prefix += SignChar;1422 if (TypeChar)1423 Prefix += TypeChar;1424 Prefix += NaNStr;1425 1426 // Test without any paylod.1427 if (!Payload)1428 TestStrings[NumTestStrings++] = Prefix;1429 1430 // Test with the payload as a suffix.1431 TestStrings[NumTestStrings++] = Prefix + PayloadDec;1432 TestStrings[NumTestStrings++] = Prefix + PayloadHex;1433 1434 // Test with the payload inside parentheses.1435 TestStrings[NumTestStrings++] = Prefix + '(' + PayloadDec + ')';1436 TestStrings[NumTestStrings++] = Prefix + '(' + PayloadHex + ')';1437 1438 for (size_t K = 0; K < NumTestStrings; ++K) {1439 StringRef TestStr = TestStrings[K];1440 1441 APFloat F(Sem);1442 bool HasError = !F.convertFromString(1443 TestStr, llvm::APFloat::rmNearestTiesToEven);1444 EXPECT_FALSE(HasError);1445 EXPECT_TRUE(F.isNaN());1446 EXPECT_EQ(Signaling, F.isSignaling());1447 EXPECT_EQ(Negative, F.isNegative());1448 uint64_t PayloadResult =1449 F.bitcastToAPInt().getZExtValue() & PayloadMask;1450 EXPECT_EQ(Payload, PayloadResult);1451 }1452 }1453 }1454 }1455 1456 const StringRef InfStrings[] = {"inf", "INFINITY", "+Inf",1457 "-inf", "-INFINITY", "-Inf"};1458 for (StringRef InfStr : InfStrings) {1459 bool Negative = InfStr.front() == '-';1460 1461 APFloat F(Sem);1462 bool HasError =1463 !F.convertFromString(InfStr, llvm::APFloat::rmNearestTiesToEven);1464 EXPECT_FALSE(HasError);1465 EXPECT_TRUE(F.isInfinity());1466 EXPECT_EQ(Negative, F.isNegative());1467 uint64_t PayloadResult = F.bitcastToAPInt().getZExtValue() & PayloadMask;1468 EXPECT_EQ(UINT64_C(0), PayloadResult);1469 }1470}1471 1472TEST(APFloatTest, fromToStringSpecials) {1473 auto expects = [] (const char *first, const char *second) {1474 std::string roundtrip = convertToString(convertToDoubleFromString(second), 0, 3);1475 EXPECT_STREQ(first, roundtrip.c_str());1476 };1477 expects("+Inf", "+Inf");1478 expects("+Inf", "INFINITY");1479 expects("+Inf", "inf");1480 expects("-Inf", "-Inf");1481 expects("-Inf", "-INFINITY");1482 expects("-Inf", "-inf");1483 expects("NaN", "NaN");1484 expects("NaN", "nan");1485 expects("NaN", "-NaN");1486 expects("NaN", "-nan");1487}1488 1489TEST(APFloatTest, fromHexadecimalString) {1490 EXPECT_EQ( 1.0, APFloat(APFloat::IEEEdouble(), "0x1p0").convertToDouble());1491 EXPECT_EQ(+1.0, APFloat(APFloat::IEEEdouble(), "+0x1p0").convertToDouble());1492 EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble(), "-0x1p0").convertToDouble());1493 1494 EXPECT_EQ( 1.0, APFloat(APFloat::IEEEdouble(), "0x1p+0").convertToDouble());1495 EXPECT_EQ(+1.0, APFloat(APFloat::IEEEdouble(), "+0x1p+0").convertToDouble());1496 EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble(), "-0x1p+0").convertToDouble());1497 1498 EXPECT_EQ( 1.0, APFloat(APFloat::IEEEdouble(), "0x1p-0").convertToDouble());1499 EXPECT_EQ(+1.0, APFloat(APFloat::IEEEdouble(), "+0x1p-0").convertToDouble());1500 EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble(), "-0x1p-0").convertToDouble());1501 1502 1503 EXPECT_EQ( 2.0, APFloat(APFloat::IEEEdouble(), "0x1p1").convertToDouble());1504 EXPECT_EQ(+2.0, APFloat(APFloat::IEEEdouble(), "+0x1p1").convertToDouble());1505 EXPECT_EQ(-2.0, APFloat(APFloat::IEEEdouble(), "-0x1p1").convertToDouble());1506 1507 EXPECT_EQ( 2.0, APFloat(APFloat::IEEEdouble(), "0x1p+1").convertToDouble());1508 EXPECT_EQ(+2.0, APFloat(APFloat::IEEEdouble(), "+0x1p+1").convertToDouble());1509 EXPECT_EQ(-2.0, APFloat(APFloat::IEEEdouble(), "-0x1p+1").convertToDouble());1510 1511 EXPECT_EQ( 0.5, APFloat(APFloat::IEEEdouble(), "0x1p-1").convertToDouble());1512 EXPECT_EQ(+0.5, APFloat(APFloat::IEEEdouble(), "+0x1p-1").convertToDouble());1513 EXPECT_EQ(-0.5, APFloat(APFloat::IEEEdouble(), "-0x1p-1").convertToDouble());1514 1515 1516 EXPECT_EQ( 3.0, APFloat(APFloat::IEEEdouble(), "0x1.8p1").convertToDouble());1517 EXPECT_EQ(+3.0, APFloat(APFloat::IEEEdouble(), "+0x1.8p1").convertToDouble());1518 EXPECT_EQ(-3.0, APFloat(APFloat::IEEEdouble(), "-0x1.8p1").convertToDouble());1519 1520 EXPECT_EQ( 3.0, APFloat(APFloat::IEEEdouble(), "0x1.8p+1").convertToDouble());1521 EXPECT_EQ(+3.0, APFloat(APFloat::IEEEdouble(), "+0x1.8p+1").convertToDouble());1522 EXPECT_EQ(-3.0, APFloat(APFloat::IEEEdouble(), "-0x1.8p+1").convertToDouble());1523 1524 EXPECT_EQ( 0.75, APFloat(APFloat::IEEEdouble(), "0x1.8p-1").convertToDouble());1525 EXPECT_EQ(+0.75, APFloat(APFloat::IEEEdouble(), "+0x1.8p-1").convertToDouble());1526 EXPECT_EQ(-0.75, APFloat(APFloat::IEEEdouble(), "-0x1.8p-1").convertToDouble());1527 1528 1529 EXPECT_EQ( 8192.0, APFloat(APFloat::IEEEdouble(), "0x1000.000p1").convertToDouble());1530 EXPECT_EQ(+8192.0, APFloat(APFloat::IEEEdouble(), "+0x1000.000p1").convertToDouble());1531 EXPECT_EQ(-8192.0, APFloat(APFloat::IEEEdouble(), "-0x1000.000p1").convertToDouble());1532 1533 EXPECT_EQ( 8192.0, APFloat(APFloat::IEEEdouble(), "0x1000.000p+1").convertToDouble());1534 EXPECT_EQ(+8192.0, APFloat(APFloat::IEEEdouble(), "+0x1000.000p+1").convertToDouble());1535 EXPECT_EQ(-8192.0, APFloat(APFloat::IEEEdouble(), "-0x1000.000p+1").convertToDouble());1536 1537 EXPECT_EQ( 2048.0, APFloat(APFloat::IEEEdouble(), "0x1000.000p-1").convertToDouble());1538 EXPECT_EQ(+2048.0, APFloat(APFloat::IEEEdouble(), "+0x1000.000p-1").convertToDouble());1539 EXPECT_EQ(-2048.0, APFloat(APFloat::IEEEdouble(), "-0x1000.000p-1").convertToDouble());1540 1541 1542 EXPECT_EQ( 8192.0, APFloat(APFloat::IEEEdouble(), "0x1000p1").convertToDouble());1543 EXPECT_EQ(+8192.0, APFloat(APFloat::IEEEdouble(), "+0x1000p1").convertToDouble());1544 EXPECT_EQ(-8192.0, APFloat(APFloat::IEEEdouble(), "-0x1000p1").convertToDouble());1545 1546 EXPECT_EQ( 8192.0, APFloat(APFloat::IEEEdouble(), "0x1000p+1").convertToDouble());1547 EXPECT_EQ(+8192.0, APFloat(APFloat::IEEEdouble(), "+0x1000p+1").convertToDouble());1548 EXPECT_EQ(-8192.0, APFloat(APFloat::IEEEdouble(), "-0x1000p+1").convertToDouble());1549 1550 EXPECT_EQ( 2048.0, APFloat(APFloat::IEEEdouble(), "0x1000p-1").convertToDouble());1551 EXPECT_EQ(+2048.0, APFloat(APFloat::IEEEdouble(), "+0x1000p-1").convertToDouble());1552 EXPECT_EQ(-2048.0, APFloat(APFloat::IEEEdouble(), "-0x1000p-1").convertToDouble());1553 1554 1555 EXPECT_EQ( 16384.0, APFloat(APFloat::IEEEdouble(), "0x10p10").convertToDouble());1556 EXPECT_EQ(+16384.0, APFloat(APFloat::IEEEdouble(), "+0x10p10").convertToDouble());1557 EXPECT_EQ(-16384.0, APFloat(APFloat::IEEEdouble(), "-0x10p10").convertToDouble());1558 1559 EXPECT_EQ( 16384.0, APFloat(APFloat::IEEEdouble(), "0x10p+10").convertToDouble());1560 EXPECT_EQ(+16384.0, APFloat(APFloat::IEEEdouble(), "+0x10p+10").convertToDouble());1561 EXPECT_EQ(-16384.0, APFloat(APFloat::IEEEdouble(), "-0x10p+10").convertToDouble());1562 1563 EXPECT_EQ( 0.015625, APFloat(APFloat::IEEEdouble(), "0x10p-10").convertToDouble());1564 EXPECT_EQ(+0.015625, APFloat(APFloat::IEEEdouble(), "+0x10p-10").convertToDouble());1565 EXPECT_EQ(-0.015625, APFloat(APFloat::IEEEdouble(), "-0x10p-10").convertToDouble());1566 1567 EXPECT_EQ(1.0625, APFloat(APFloat::IEEEdouble(), "0x1.1p0").convertToDouble());1568 EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble(), "0x1p0").convertToDouble());1569 1570 EXPECT_EQ(convertToDoubleFromString("0x1p-150"),1571 convertToDoubleFromString("+0x800000000000000001.p-221"));1572 EXPECT_EQ(2251799813685248.5,1573 convertToDoubleFromString("0x80000000000004000000.010p-28"));1574}1575 1576TEST(APFloatTest, toString) {1577 ASSERT_EQ("10", convertToString(10.0, 6, 3));1578 ASSERT_EQ("1.0E+1", convertToString(10.0, 6, 0));1579 ASSERT_EQ("10100", convertToString(1.01E+4, 5, 2));1580 ASSERT_EQ("1.01E+4", convertToString(1.01E+4, 4, 2));1581 ASSERT_EQ("1.01E+4", convertToString(1.01E+4, 5, 1));1582 ASSERT_EQ("0.0101", convertToString(1.01E-2, 5, 2));1583 ASSERT_EQ("0.0101", convertToString(1.01E-2, 4, 2));1584 ASSERT_EQ("1.01E-2", convertToString(1.01E-2, 5, 1));1585 ASSERT_EQ("0.78539816339744828", convertToString(0.78539816339744830961, 0, 3));1586 ASSERT_EQ("4.9406564584124654E-324", convertToString(4.9406564584124654e-324, 0, 3));1587 ASSERT_EQ("873.18340000000001", convertToString(873.1834, 0, 1));1588 ASSERT_EQ("8.7318340000000001E+2", convertToString(873.1834, 0, 0));1589 ASSERT_EQ("1.7976931348623157E+308", convertToString(1.7976931348623157E+308, 0, 0));1590 ASSERT_EQ("10", convertToString(10.0, 6, 3, false));1591 ASSERT_EQ("1.000000e+01", convertToString(10.0, 6, 0, false));1592 ASSERT_EQ("10100", convertToString(1.01E+4, 5, 2, false));1593 ASSERT_EQ("1.0100e+04", convertToString(1.01E+4, 4, 2, false));1594 ASSERT_EQ("1.01000e+04", convertToString(1.01E+4, 5, 1, false));1595 ASSERT_EQ("0.0101", convertToString(1.01E-2, 5, 2, false));1596 ASSERT_EQ("0.0101", convertToString(1.01E-2, 4, 2, false));1597 ASSERT_EQ("1.01000e-02", convertToString(1.01E-2, 5, 1, false));1598 ASSERT_EQ("0.78539816339744828",1599 convertToString(0.78539816339744830961, 0, 3, false));1600 ASSERT_EQ("4.94065645841246540e-324",1601 convertToString(4.9406564584124654e-324, 0, 3, false));1602 ASSERT_EQ("873.18340000000001", convertToString(873.1834, 0, 1, false));1603 ASSERT_EQ("8.73183400000000010e+02", convertToString(873.1834, 0, 0, false));1604 ASSERT_EQ("1.79769313486231570e+308",1605 convertToString(1.7976931348623157E+308, 0, 0, false));1606 1607 {1608 SmallString<64> Str;1609 APFloat UnnormalZero(APFloat::x87DoubleExtended(), APInt(80, {0, 1}));1610 UnnormalZero.toString(Str);1611 ASSERT_EQ("NaN", Str);1612 }1613}1614 1615TEST(APFloatTest, toInteger) {1616 bool isExact = false;1617 APSInt result(5, /*isUnsigned=*/true);1618 1619 EXPECT_EQ(APFloat::opOK,1620 APFloat(APFloat::IEEEdouble(), "10")1621 .convertToInteger(result, APFloat::rmTowardZero, &isExact));1622 EXPECT_TRUE(isExact);1623 EXPECT_EQ(APSInt(APInt(5, 10), true), result);1624 1625 EXPECT_EQ(APFloat::opInvalidOp,1626 APFloat(APFloat::IEEEdouble(), "-10")1627 .convertToInteger(result, APFloat::rmTowardZero, &isExact));1628 EXPECT_FALSE(isExact);1629 EXPECT_EQ(APSInt::getMinValue(5, true), result);1630 1631 EXPECT_EQ(APFloat::opInvalidOp,1632 APFloat(APFloat::IEEEdouble(), "32")1633 .convertToInteger(result, APFloat::rmTowardZero, &isExact));1634 EXPECT_FALSE(isExact);1635 EXPECT_EQ(APSInt::getMaxValue(5, true), result);1636 1637 EXPECT_EQ(APFloat::opInexact,1638 APFloat(APFloat::IEEEdouble(), "7.9")1639 .convertToInteger(result, APFloat::rmTowardZero, &isExact));1640 EXPECT_FALSE(isExact);1641 EXPECT_EQ(APSInt(APInt(5, 7), true), result);1642 1643 result.setIsUnsigned(false);1644 EXPECT_EQ(APFloat::opOK,1645 APFloat(APFloat::IEEEdouble(), "-10")1646 .convertToInteger(result, APFloat::rmTowardZero, &isExact));1647 EXPECT_TRUE(isExact);1648 EXPECT_EQ(APSInt(APInt(5, -10, true), false), result);1649 1650 EXPECT_EQ(APFloat::opInvalidOp,1651 APFloat(APFloat::IEEEdouble(), "-17")1652 .convertToInteger(result, APFloat::rmTowardZero, &isExact));1653 EXPECT_FALSE(isExact);1654 EXPECT_EQ(APSInt::getMinValue(5, false), result);1655 1656 EXPECT_EQ(APFloat::opInvalidOp,1657 APFloat(APFloat::IEEEdouble(), "16")1658 .convertToInteger(result, APFloat::rmTowardZero, &isExact));1659 EXPECT_FALSE(isExact);1660 EXPECT_EQ(APSInt::getMaxValue(5, false), result);1661}1662 1663class APFloatConvertFromAPIntParamTest1664 : public ::testing::TestWithParam<const fltSemantics *> {1665protected:1666 // Helper to run a conversion and compare the integer result directly.1667 static void testConversionAndCompareInt(const APInt &InputValue,1668 const bool IsSigned,1669 APFloat::roundingMode RM,1670 const APInt &ExpectedIntValue) {1671 const fltSemantics &Sem = *GetParam();1672 APFloat F(Sem);1673 F.convertFromAPInt(InputValue, /*IsSigned=*/IsSigned, RM);1674 1675 APSInt ResultInt(InputValue.getBitWidth(), /*isUnsigned=*/!IsSigned);1676 bool IsExact;1677 F.convertToInteger(ResultInt, APFloat::rmTowardZero, &IsExact);1678 1679 EXPECT_TRUE(IsExact);1680 EXPECT_TRUE(ResultInt.eq(ExpectedIntValue))1681 << "InputValue: " << InputValue << "\n"1682 << ResultInt << " vs " << ExpectedIntValue << "\n";1683 }1684};1685 1686TEST_P(APFloatConvertFromAPIntParamTest, HalfwayRounding) {1687 const fltSemantics &Sem = *GetParam();1688 const unsigned Precision = APFloat::semanticsPrecision(Sem);1689 1690 if (Precision == 0)1691 GTEST_SKIP() << "Skipping test for semantics with no significand.";1692 1693 for (bool IsSigned : {false, true}) {1694 const unsigned BitWidth = Precision + 1 + (IsSigned ? 1 : 0);1695 1696 const APInt RoundedDownVal = APInt::getOneBitSet(BitWidth, Precision);1697 const APInt HalfwayVal = RoundedDownVal + 1;1698 const APInt RoundedUpVal = RoundedDownVal + 2;1699 1700 testConversionAndCompareInt(HalfwayVal, IsSigned,1701 APFloat::rmNearestTiesToEven, RoundedDownVal);1702 testConversionAndCompareInt(HalfwayVal, IsSigned,1703 APFloat::rmNearestTiesToAway, RoundedUpVal);1704 testConversionAndCompareInt(HalfwayVal, IsSigned, APFloat::rmTowardPositive,1705 RoundedUpVal);1706 testConversionAndCompareInt(HalfwayVal, IsSigned, APFloat::rmTowardNegative,1707 RoundedDownVal);1708 testConversionAndCompareInt(HalfwayVal, IsSigned, APFloat::rmTowardZero,1709 RoundedDownVal);1710 }1711}1712 1713TEST_P(APFloatConvertFromAPIntParamTest, MaxMagnitude) {1714 const fltSemantics &Sem = *GetParam();1715 const unsigned Precision = APFloat::semanticsPrecision(Sem);1716 1717 if (Precision == 0)1718 GTEST_SKIP() << "Skipping test for semantics with no significand.";1719 1720 const APFloat Largest = APFloat::getLargest(Sem, /*Negative=*/false);1721 const int Exp = ilogb(Largest);1722 for (bool IsSigned : {false, true}) {1723 const unsigned BitWidth = Exp + 1 + (IsSigned ? 1 : 0);1724 1725 bool IsExact;1726 APSInt LargestAsInt{BitWidth, /*IsUnsigned=*/!IsSigned};1727 const APFloat::opStatus ToIntStatus =1728 Largest.convertToInteger(LargestAsInt, APFloat::rmTowardZero, &IsExact);1729 EXPECT_EQ(ToIntStatus, APFloat::opOK);1730 1731 for (const APFloat::roundingMode RM :1732 {APFloat::rmNearestTiesToAway, APFloat::rmTowardNegative,1733 APFloat::rmTowardPositive, APFloat::rmTowardZero,1734 APFloat::rmNearestTiesToEven}) {1735 testConversionAndCompareInt(LargestAsInt, IsSigned, RM, LargestAsInt);1736 }1737 }1738}1739 1740INSTANTIATE_TEST_SUITE_P(IEEESemantics, APFloatConvertFromAPIntParamTest,1741 ::testing::Values(&APFloat::IEEEhalf(),1742 &APFloat::BFloat(),1743 &APFloat::IEEEsingle(),1744 &APFloat::IEEEdouble(),1745 &APFloat::IEEEquad()));1746 1747static APInt nanbitsFromAPInt(const fltSemantics &Sem, bool SNaN, bool Negative,1748 uint64_t payload) {1749 APInt appayload(64, payload);1750 if (SNaN)1751 return APFloat::getSNaN(Sem, Negative, &appayload).bitcastToAPInt();1752 else1753 return APFloat::getQNaN(Sem, Negative, &appayload).bitcastToAPInt();1754}1755 1756TEST(APFloatTest, makeNaN) {1757 const struct {1758 uint64_t expected;1759 const fltSemantics &semantics;1760 bool SNaN;1761 bool Negative;1762 uint64_t payload;1763 } tests[] = {1764 // clang-format off1765 /* expected semantics SNaN Neg payload */1766 { 0x7fc00000ULL, APFloat::IEEEsingle(), false, false, 0x00000000ULL },1767 { 0xffc00000ULL, APFloat::IEEEsingle(), false, true, 0x00000000ULL },1768 { 0x7fc0ae72ULL, APFloat::IEEEsingle(), false, false, 0x0000ae72ULL },1769 { 0x7fffae72ULL, APFloat::IEEEsingle(), false, false, 0xffffae72ULL },1770 { 0x7fdaae72ULL, APFloat::IEEEsingle(), false, false, 0x00daae72ULL },1771 { 0x7fa00000ULL, APFloat::IEEEsingle(), true, false, 0x00000000ULL },1772 { 0xffa00000ULL, APFloat::IEEEsingle(), true, true, 0x00000000ULL },1773 { 0x7f80ae72ULL, APFloat::IEEEsingle(), true, false, 0x0000ae72ULL },1774 { 0x7fbfae72ULL, APFloat::IEEEsingle(), true, false, 0xffffae72ULL },1775 { 0x7f9aae72ULL, APFloat::IEEEsingle(), true, false, 0x001aae72ULL },1776 { 0x7ff8000000000000ULL, APFloat::IEEEdouble(), false, false, 0x0000000000000000ULL },1777 { 0xfff8000000000000ULL, APFloat::IEEEdouble(), false, true, 0x0000000000000000ULL },1778 { 0x7ff800000000ae72ULL, APFloat::IEEEdouble(), false, false, 0x000000000000ae72ULL },1779 { 0x7fffffffffffae72ULL, APFloat::IEEEdouble(), false, false, 0xffffffffffffae72ULL },1780 { 0x7ffdaaaaaaaaae72ULL, APFloat::IEEEdouble(), false, false, 0x000daaaaaaaaae72ULL },1781 { 0x7ff4000000000000ULL, APFloat::IEEEdouble(), true, false, 0x0000000000000000ULL },1782 { 0xfff4000000000000ULL, APFloat::IEEEdouble(), true, true, 0x0000000000000000ULL },1783 { 0x7ff000000000ae72ULL, APFloat::IEEEdouble(), true, false, 0x000000000000ae72ULL },1784 { 0x7ff7ffffffffae72ULL, APFloat::IEEEdouble(), true, false, 0xffffffffffffae72ULL },1785 { 0x7ff1aaaaaaaaae72ULL, APFloat::IEEEdouble(), true, false, 0x0001aaaaaaaaae72ULL },1786 { 0x80ULL, APFloat::Float8E5M2FNUZ(), false, false, 0xaaULL },1787 { 0x80ULL, APFloat::Float8E5M2FNUZ(), false, true, 0xaaULL },1788 { 0x80ULL, APFloat::Float8E5M2FNUZ(), true, false, 0xaaULL },1789 { 0x80ULL, APFloat::Float8E5M2FNUZ(), true, true, 0xaaULL },1790 { 0x80ULL, APFloat::Float8E4M3FNUZ(), false, false, 0xaaULL },1791 { 0x80ULL, APFloat::Float8E4M3FNUZ(), false, true, 0xaaULL },1792 { 0x80ULL, APFloat::Float8E4M3FNUZ(), true, false, 0xaaULL },1793 { 0x80ULL, APFloat::Float8E4M3FNUZ(), true, true, 0xaaULL },1794 { 0x80ULL, APFloat::Float8E4M3B11FNUZ(), false, false, 0xaaULL },1795 { 0x80ULL, APFloat::Float8E4M3B11FNUZ(), false, true, 0xaaULL },1796 { 0x80ULL, APFloat::Float8E4M3B11FNUZ(), true, false, 0xaaULL },1797 { 0x80ULL, APFloat::Float8E4M3B11FNUZ(), true, true, 0xaaULL },1798 { 0x3fe00ULL, APFloat::FloatTF32(), false, false, 0x00000000ULL },1799 { 0x7fe00ULL, APFloat::FloatTF32(), false, true, 0x00000000ULL },1800 { 0x3feaaULL, APFloat::FloatTF32(), false, false, 0xaaULL },1801 { 0x3ffaaULL, APFloat::FloatTF32(), false, false, 0xdaaULL },1802 { 0x3ffaaULL, APFloat::FloatTF32(), false, false, 0xfdaaULL },1803 { 0x3fd00ULL, APFloat::FloatTF32(), true, false, 0x00000000ULL },1804 { 0x7fd00ULL, APFloat::FloatTF32(), true, true, 0x00000000ULL },1805 { 0x3fcaaULL, APFloat::FloatTF32(), true, false, 0xaaULL },1806 { 0x3fdaaULL, APFloat::FloatTF32(), true, false, 0xfaaULL },1807 { 0x3fdaaULL, APFloat::FloatTF32(), true, false, 0x1aaULL },1808 // clang-format on1809 };1810 1811 for (const auto &t : tests) {1812 ASSERT_EQ(t.expected, nanbitsFromAPInt(t.semantics, t.SNaN, t.Negative, t.payload));1813 }1814}1815 1816#ifdef GTEST_HAS_DEATH_TEST1817#ifndef NDEBUG1818TEST(APFloatTest, SemanticsDeath) {1819 EXPECT_DEATH(APFloat(APFloat::IEEEquad(), 0).convertToDouble(),1820 "Float semantics is not representable by IEEEdouble");1821 EXPECT_DEATH(APFloat(APFloat::IEEEdouble(), 0).convertToFloat(),1822 "Float semantics is not representable by IEEEsingle");1823}1824#endif1825#endif1826 1827TEST(APFloatTest, StringDecimalError) {1828 EXPECT_EQ("Invalid string length", convertToErrorFromString(""));1829 EXPECT_EQ("String has no digits", convertToErrorFromString("+"));1830 EXPECT_EQ("String has no digits", convertToErrorFromString("-"));1831 1832 EXPECT_EQ("Invalid character in significand", convertToErrorFromString(StringRef("\0", 1)));1833 EXPECT_EQ("Invalid character in significand", convertToErrorFromString(StringRef("1\0", 2)));1834 EXPECT_EQ("Invalid character in significand", convertToErrorFromString(StringRef("1" "\0" "2", 3)));1835 EXPECT_EQ("Invalid character in significand", convertToErrorFromString(StringRef("1" "\0" "2e1", 5)));1836 EXPECT_EQ("Invalid character in exponent", convertToErrorFromString(StringRef("1e\0", 3)));1837 EXPECT_EQ("Invalid character in exponent", convertToErrorFromString(StringRef("1e1\0", 4)));1838 EXPECT_EQ("Invalid character in exponent", convertToErrorFromString(StringRef("1e1" "\0" "2", 5)));1839 1840 EXPECT_EQ("Invalid character in significand", convertToErrorFromString("1.0f"));1841 1842 EXPECT_EQ("String contains multiple dots", convertToErrorFromString(".."));1843 EXPECT_EQ("String contains multiple dots", convertToErrorFromString("..0"));1844 EXPECT_EQ("String contains multiple dots", convertToErrorFromString("1.0.0"));1845}1846 1847TEST(APFloatTest, StringDecimalSignificandError) {1848 EXPECT_EQ("Significand has no digits", convertToErrorFromString( "."));1849 EXPECT_EQ("Significand has no digits", convertToErrorFromString("+."));1850 EXPECT_EQ("Significand has no digits", convertToErrorFromString("-."));1851 1852 1853 EXPECT_EQ("Significand has no digits", convertToErrorFromString( "e"));1854 EXPECT_EQ("Significand has no digits", convertToErrorFromString("+e"));1855 EXPECT_EQ("Significand has no digits", convertToErrorFromString("-e"));1856 1857 EXPECT_EQ("Significand has no digits", convertToErrorFromString( "e1"));1858 EXPECT_EQ("Significand has no digits", convertToErrorFromString("+e1"));1859 EXPECT_EQ("Significand has no digits", convertToErrorFromString("-e1"));1860 1861 EXPECT_EQ("Significand has no digits", convertToErrorFromString( ".e1"));1862 EXPECT_EQ("Significand has no digits", convertToErrorFromString("+.e1"));1863 EXPECT_EQ("Significand has no digits", convertToErrorFromString("-.e1"));1864 1865 1866 EXPECT_EQ("Significand has no digits", convertToErrorFromString( ".e"));1867 EXPECT_EQ("Significand has no digits", convertToErrorFromString("+.e"));1868 EXPECT_EQ("Significand has no digits", convertToErrorFromString("-.e"));1869}1870 1871TEST(APFloatTest, StringHexadecimalError) {1872 EXPECT_EQ("Invalid string", convertToErrorFromString( "0x"));1873 EXPECT_EQ("Invalid string", convertToErrorFromString("+0x"));1874 EXPECT_EQ("Invalid string", convertToErrorFromString("-0x"));1875 1876 EXPECT_EQ("Hex strings require an exponent", convertToErrorFromString( "0x0"));1877 EXPECT_EQ("Hex strings require an exponent", convertToErrorFromString("+0x0"));1878 EXPECT_EQ("Hex strings require an exponent", convertToErrorFromString("-0x0"));1879 1880 EXPECT_EQ("Hex strings require an exponent", convertToErrorFromString( "0x0."));1881 EXPECT_EQ("Hex strings require an exponent", convertToErrorFromString("+0x0."));1882 EXPECT_EQ("Hex strings require an exponent", convertToErrorFromString("-0x0."));1883 1884 EXPECT_EQ("Hex strings require an exponent", convertToErrorFromString( "0x.0"));1885 EXPECT_EQ("Hex strings require an exponent", convertToErrorFromString("+0x.0"));1886 EXPECT_EQ("Hex strings require an exponent", convertToErrorFromString("-0x.0"));1887 1888 EXPECT_EQ("Hex strings require an exponent", convertToErrorFromString( "0x0.0"));1889 EXPECT_EQ("Hex strings require an exponent", convertToErrorFromString("+0x0.0"));1890 EXPECT_EQ("Hex strings require an exponent", convertToErrorFromString("-0x0.0"));1891 1892 EXPECT_EQ("Invalid character in significand", convertToErrorFromString(StringRef("0x\0", 3)));1893 EXPECT_EQ("Invalid character in significand", convertToErrorFromString(StringRef("0x1\0", 4)));1894 EXPECT_EQ("Invalid character in significand", convertToErrorFromString(StringRef("0x1" "\0" "2", 5)));1895 EXPECT_EQ("Invalid character in significand", convertToErrorFromString(StringRef("0x1" "\0" "2p1", 7)));1896 EXPECT_EQ("Invalid character in exponent", convertToErrorFromString(StringRef("0x1p\0", 5)));1897 EXPECT_EQ("Invalid character in exponent", convertToErrorFromString(StringRef("0x1p1\0", 6)));1898 EXPECT_EQ("Invalid character in exponent", convertToErrorFromString(StringRef("0x1p1" "\0" "2", 7)));1899 1900 EXPECT_EQ("Invalid character in exponent", convertToErrorFromString("0x1p0f"));1901 1902 EXPECT_EQ("String contains multiple dots", convertToErrorFromString("0x..p1"));1903 EXPECT_EQ("String contains multiple dots", convertToErrorFromString("0x..0p1"));1904 EXPECT_EQ("String contains multiple dots", convertToErrorFromString("0x1.0.0p1"));1905}1906 1907TEST(APFloatTest, StringHexadecimalSignificandError) {1908 EXPECT_EQ("Significand has no digits", convertToErrorFromString( "0x."));1909 EXPECT_EQ("Significand has no digits", convertToErrorFromString("+0x."));1910 EXPECT_EQ("Significand has no digits", convertToErrorFromString("-0x."));1911 1912 EXPECT_EQ("Significand has no digits", convertToErrorFromString( "0xp"));1913 EXPECT_EQ("Significand has no digits", convertToErrorFromString("+0xp"));1914 EXPECT_EQ("Significand has no digits", convertToErrorFromString("-0xp"));1915 1916 EXPECT_EQ("Significand has no digits", convertToErrorFromString( "0xp+"));1917 EXPECT_EQ("Significand has no digits", convertToErrorFromString("+0xp+"));1918 EXPECT_EQ("Significand has no digits", convertToErrorFromString("-0xp+"));1919 1920 EXPECT_EQ("Significand has no digits", convertToErrorFromString( "0xp-"));1921 EXPECT_EQ("Significand has no digits", convertToErrorFromString("+0xp-"));1922 EXPECT_EQ("Significand has no digits", convertToErrorFromString("-0xp-"));1923 1924 1925 EXPECT_EQ("Significand has no digits", convertToErrorFromString( "0x.p"));1926 EXPECT_EQ("Significand has no digits", convertToErrorFromString("+0x.p"));1927 EXPECT_EQ("Significand has no digits", convertToErrorFromString("-0x.p"));1928 1929 EXPECT_EQ("Significand has no digits", convertToErrorFromString( "0x.p+"));1930 EXPECT_EQ("Significand has no digits", convertToErrorFromString("+0x.p+"));1931 EXPECT_EQ("Significand has no digits", convertToErrorFromString("-0x.p+"));1932 1933 EXPECT_EQ("Significand has no digits", convertToErrorFromString( "0x.p-"));1934 EXPECT_EQ("Significand has no digits", convertToErrorFromString("+0x.p-"));1935 EXPECT_EQ("Significand has no digits", convertToErrorFromString("-0x.p-"));1936}1937 1938TEST(APFloatTest, StringHexadecimalExponentError) {1939 EXPECT_EQ("Exponent has no digits", convertToErrorFromString( "0x1p"));1940 EXPECT_EQ("Exponent has no digits", convertToErrorFromString("+0x1p"));1941 EXPECT_EQ("Exponent has no digits", convertToErrorFromString("-0x1p"));1942 1943 EXPECT_EQ("Exponent has no digits", convertToErrorFromString( "0x1p+"));1944 EXPECT_EQ("Exponent has no digits", convertToErrorFromString("+0x1p+"));1945 EXPECT_EQ("Exponent has no digits", convertToErrorFromString("-0x1p+"));1946 1947 EXPECT_EQ("Exponent has no digits", convertToErrorFromString( "0x1p-"));1948 EXPECT_EQ("Exponent has no digits", convertToErrorFromString("+0x1p-"));1949 EXPECT_EQ("Exponent has no digits", convertToErrorFromString("-0x1p-"));1950 1951 1952 EXPECT_EQ("Exponent has no digits", convertToErrorFromString( "0x1.p"));1953 EXPECT_EQ("Exponent has no digits", convertToErrorFromString("+0x1.p"));1954 EXPECT_EQ("Exponent has no digits", convertToErrorFromString("-0x1.p"));1955 1956 EXPECT_EQ("Exponent has no digits", convertToErrorFromString( "0x1.p+"));1957 EXPECT_EQ("Exponent has no digits", convertToErrorFromString("+0x1.p+"));1958 EXPECT_EQ("Exponent has no digits", convertToErrorFromString("-0x1.p+"));1959 1960 EXPECT_EQ("Exponent has no digits", convertToErrorFromString( "0x1.p-"));1961 EXPECT_EQ("Exponent has no digits", convertToErrorFromString("+0x1.p-"));1962 EXPECT_EQ("Exponent has no digits", convertToErrorFromString("-0x1.p-"));1963 1964 1965 EXPECT_EQ("Exponent has no digits", convertToErrorFromString( "0x.1p"));1966 EXPECT_EQ("Exponent has no digits", convertToErrorFromString("+0x.1p"));1967 EXPECT_EQ("Exponent has no digits", convertToErrorFromString("-0x.1p"));1968 1969 EXPECT_EQ("Exponent has no digits", convertToErrorFromString( "0x.1p+"));1970 EXPECT_EQ("Exponent has no digits", convertToErrorFromString("+0x.1p+"));1971 EXPECT_EQ("Exponent has no digits", convertToErrorFromString("-0x.1p+"));1972 1973 EXPECT_EQ("Exponent has no digits", convertToErrorFromString( "0x.1p-"));1974 EXPECT_EQ("Exponent has no digits", convertToErrorFromString("+0x.1p-"));1975 EXPECT_EQ("Exponent has no digits", convertToErrorFromString("-0x.1p-"));1976 1977 1978 EXPECT_EQ("Exponent has no digits", convertToErrorFromString( "0x1.1p"));1979 EXPECT_EQ("Exponent has no digits", convertToErrorFromString("+0x1.1p"));1980 EXPECT_EQ("Exponent has no digits", convertToErrorFromString("-0x1.1p"));1981 1982 EXPECT_EQ("Exponent has no digits", convertToErrorFromString( "0x1.1p+"));1983 EXPECT_EQ("Exponent has no digits", convertToErrorFromString("+0x1.1p+"));1984 EXPECT_EQ("Exponent has no digits", convertToErrorFromString("-0x1.1p+"));1985 1986 EXPECT_EQ("Exponent has no digits", convertToErrorFromString( "0x1.1p-"));1987 EXPECT_EQ("Exponent has no digits", convertToErrorFromString("+0x1.1p-"));1988 EXPECT_EQ("Exponent has no digits", convertToErrorFromString("-0x1.1p-"));1989}1990 1991TEST(APFloatTest, exactInverse) {1992 APFloat inv(0.0f);1993 1994 // Trivial operation.1995 EXPECT_TRUE(APFloat(2.0).getExactInverse(&inv));1996 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(0.5)));1997 EXPECT_TRUE(APFloat(2.0f).getExactInverse(&inv));1998 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(0.5f)));1999 EXPECT_TRUE(APFloat(APFloat::IEEEquad(), "2.0").getExactInverse(&inv));2000 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(APFloat::IEEEquad(), "0.5")));2001 EXPECT_TRUE(APFloat(APFloat::PPCDoubleDouble(), "2.0").getExactInverse(&inv));2002 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(APFloat::PPCDoubleDouble(), "0.5")));2003 EXPECT_TRUE(APFloat(APFloat::x87DoubleExtended(), "2.0").getExactInverse(&inv));2004 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(APFloat::x87DoubleExtended(), "0.5")));2005 // 0x1p1022 has a normal inverse for IEEE 754 binary64: 0x1p-1022.2006 EXPECT_TRUE(APFloat(0x1p1022).getExactInverse(&inv));2007 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(0x1p-1022)));2008 // With regards to getExactInverse, IEEEdouble and PPCDoubleDouble should2009 // behave the same.2010 EXPECT_TRUE(2011 APFloat(APFloat::PPCDoubleDouble(), "0x1p1022").getExactInverse(&inv));2012 EXPECT_TRUE(2013 inv.bitwiseIsEqual(APFloat(APFloat::PPCDoubleDouble(), "0x1p-1022")));2014 2015 // FLT_MIN2016 EXPECT_TRUE(APFloat(1.17549435e-38f).getExactInverse(&inv));2017 EXPECT_TRUE(inv.bitwiseIsEqual(APFloat(8.5070592e+37f)));2018 2019 // Large float, inverse is a denormal.2020 EXPECT_FALSE(APFloat(1.7014118e38f).getExactInverse(nullptr));2021 // Zero2022 EXPECT_FALSE(APFloat(0.0).getExactInverse(nullptr));2023 // Denormalized float2024 EXPECT_FALSE(APFloat(1.40129846e-45f).getExactInverse(nullptr));2025 // Largest subnormal2026 EXPECT_FALSE(APFloat(0x1p-127f).getExactInverse(nullptr));2027}2028 2029TEST(APFloatTest, roundToIntegral) {2030 APFloat T(-0.5), S(3.14), R(APFloat::getLargest(APFloat::IEEEdouble())), P(0.0);2031 2032 P = T;2033 P.roundToIntegral(APFloat::rmTowardZero);2034 EXPECT_EQ(-0.0, P.convertToDouble());2035 P = T;2036 P.roundToIntegral(APFloat::rmTowardNegative);2037 EXPECT_EQ(-1.0, P.convertToDouble());2038 P = T;2039 P.roundToIntegral(APFloat::rmTowardPositive);2040 EXPECT_EQ(-0.0, P.convertToDouble());2041 P = T;2042 P.roundToIntegral(APFloat::rmNearestTiesToEven);2043 EXPECT_EQ(-0.0, P.convertToDouble());2044 2045 P = S;2046 P.roundToIntegral(APFloat::rmTowardZero);2047 EXPECT_EQ(3.0, P.convertToDouble());2048 P = S;2049 P.roundToIntegral(APFloat::rmTowardNegative);2050 EXPECT_EQ(3.0, P.convertToDouble());2051 P = S;2052 P.roundToIntegral(APFloat::rmTowardPositive);2053 EXPECT_EQ(4.0, P.convertToDouble());2054 P = S;2055 P.roundToIntegral(APFloat::rmNearestTiesToEven);2056 EXPECT_EQ(3.0, P.convertToDouble());2057 2058 P = R;2059 P.roundToIntegral(APFloat::rmTowardZero);2060 EXPECT_EQ(R.convertToDouble(), P.convertToDouble());2061 P = R;2062 P.roundToIntegral(APFloat::rmTowardNegative);2063 EXPECT_EQ(R.convertToDouble(), P.convertToDouble());2064 P = R;2065 P.roundToIntegral(APFloat::rmTowardPositive);2066 EXPECT_EQ(R.convertToDouble(), P.convertToDouble());2067 P = R;2068 P.roundToIntegral(APFloat::rmNearestTiesToEven);2069 EXPECT_EQ(R.convertToDouble(), P.convertToDouble());2070 2071 P = APFloat::getZero(APFloat::IEEEdouble());2072 P.roundToIntegral(APFloat::rmTowardZero);2073 EXPECT_EQ(0.0, P.convertToDouble());2074 P = APFloat::getZero(APFloat::IEEEdouble(), true);2075 P.roundToIntegral(APFloat::rmTowardZero);2076 EXPECT_EQ(-0.0, P.convertToDouble());2077 P = APFloat::getNaN(APFloat::IEEEdouble());2078 P.roundToIntegral(APFloat::rmTowardZero);2079 EXPECT_TRUE(std::isnan(P.convertToDouble()));2080 P = APFloat::getInf(APFloat::IEEEdouble());2081 P.roundToIntegral(APFloat::rmTowardZero);2082 EXPECT_TRUE(std::isinf(P.convertToDouble()) && P.convertToDouble() > 0.0);2083 P = APFloat::getInf(APFloat::IEEEdouble(), true);2084 P.roundToIntegral(APFloat::rmTowardZero);2085 EXPECT_TRUE(std::isinf(P.convertToDouble()) && P.convertToDouble() < 0.0);2086 2087 APFloat::opStatus St;2088 2089 P = APFloat::getNaN(APFloat::IEEEdouble());2090 St = P.roundToIntegral(APFloat::rmTowardZero);2091 EXPECT_TRUE(P.isNaN());2092 EXPECT_FALSE(P.isNegative());2093 EXPECT_EQ(APFloat::opOK, St);2094 2095 P = APFloat::getNaN(APFloat::IEEEdouble(), true);2096 St = P.roundToIntegral(APFloat::rmTowardZero);2097 EXPECT_TRUE(P.isNaN());2098 EXPECT_TRUE(P.isNegative());2099 EXPECT_EQ(APFloat::opOK, St);2100 2101 P = APFloat::getSNaN(APFloat::IEEEdouble());2102 St = P.roundToIntegral(APFloat::rmTowardZero);2103 EXPECT_TRUE(P.isNaN());2104 EXPECT_FALSE(P.isSignaling());2105 EXPECT_FALSE(P.isNegative());2106 EXPECT_EQ(APFloat::opInvalidOp, St);2107 2108 P = APFloat::getSNaN(APFloat::IEEEdouble(), true);2109 St = P.roundToIntegral(APFloat::rmTowardZero);2110 EXPECT_TRUE(P.isNaN());2111 EXPECT_FALSE(P.isSignaling());2112 EXPECT_TRUE(P.isNegative());2113 EXPECT_EQ(APFloat::opInvalidOp, St);2114 2115 P = APFloat::getInf(APFloat::IEEEdouble());2116 St = P.roundToIntegral(APFloat::rmTowardZero);2117 EXPECT_TRUE(P.isInfinity());2118 EXPECT_FALSE(P.isNegative());2119 EXPECT_EQ(APFloat::opOK, St);2120 2121 P = APFloat::getInf(APFloat::IEEEdouble(), true);2122 St = P.roundToIntegral(APFloat::rmTowardZero);2123 EXPECT_TRUE(P.isInfinity());2124 EXPECT_TRUE(P.isNegative());2125 EXPECT_EQ(APFloat::opOK, St);2126 2127 P = APFloat::getZero(APFloat::IEEEdouble(), false);2128 St = P.roundToIntegral(APFloat::rmTowardZero);2129 EXPECT_TRUE(P.isZero());2130 EXPECT_FALSE(P.isNegative());2131 EXPECT_EQ(APFloat::opOK, St);2132 2133 P = APFloat::getZero(APFloat::IEEEdouble(), false);2134 St = P.roundToIntegral(APFloat::rmTowardNegative);2135 EXPECT_TRUE(P.isZero());2136 EXPECT_FALSE(P.isNegative());2137 EXPECT_EQ(APFloat::opOK, St);2138 2139 P = APFloat::getZero(APFloat::IEEEdouble(), true);2140 St = P.roundToIntegral(APFloat::rmTowardZero);2141 EXPECT_TRUE(P.isZero());2142 EXPECT_TRUE(P.isNegative());2143 EXPECT_EQ(APFloat::opOK, St);2144 2145 P = APFloat::getZero(APFloat::IEEEdouble(), true);2146 St = P.roundToIntegral(APFloat::rmTowardNegative);2147 EXPECT_TRUE(P.isZero());2148 EXPECT_TRUE(P.isNegative());2149 EXPECT_EQ(APFloat::opOK, St);2150 2151 P = APFloat(1E-100);2152 St = P.roundToIntegral(APFloat::rmTowardNegative);2153 EXPECT_TRUE(P.isZero());2154 EXPECT_FALSE(P.isNegative());2155 EXPECT_EQ(APFloat::opInexact, St);2156 2157 P = APFloat(1E-100);2158 St = P.roundToIntegral(APFloat::rmTowardPositive);2159 EXPECT_EQ(1.0, P.convertToDouble());2160 EXPECT_FALSE(P.isNegative());2161 EXPECT_EQ(APFloat::opInexact, St);2162 2163 P = APFloat(-1E-100);2164 St = P.roundToIntegral(APFloat::rmTowardNegative);2165 EXPECT_TRUE(P.isNegative());2166 EXPECT_EQ(-1.0, P.convertToDouble());2167 EXPECT_EQ(APFloat::opInexact, St);2168 2169 P = APFloat(-1E-100);2170 St = P.roundToIntegral(APFloat::rmTowardPositive);2171 EXPECT_TRUE(P.isZero());2172 EXPECT_TRUE(P.isNegative());2173 EXPECT_EQ(APFloat::opInexact, St);2174 2175 P = APFloat(10.0);2176 St = P.roundToIntegral(APFloat::rmTowardZero);2177 EXPECT_EQ(10.0, P.convertToDouble());2178 EXPECT_EQ(APFloat::opOK, St);2179 2180 P = APFloat(10.5);2181 St = P.roundToIntegral(APFloat::rmTowardZero);2182 EXPECT_EQ(10.0, P.convertToDouble());2183 EXPECT_EQ(APFloat::opInexact, St);2184 2185 P = APFloat(10.5);2186 St = P.roundToIntegral(APFloat::rmTowardPositive);2187 EXPECT_EQ(11.0, P.convertToDouble());2188 EXPECT_EQ(APFloat::opInexact, St);2189 2190 P = APFloat(10.5);2191 St = P.roundToIntegral(APFloat::rmTowardNegative);2192 EXPECT_EQ(10.0, P.convertToDouble());2193 EXPECT_EQ(APFloat::opInexact, St);2194 2195 P = APFloat(10.5);2196 St = P.roundToIntegral(APFloat::rmNearestTiesToAway);2197 EXPECT_EQ(11.0, P.convertToDouble());2198 EXPECT_EQ(APFloat::opInexact, St);2199 2200 P = APFloat(10.5);2201 St = P.roundToIntegral(APFloat::rmNearestTiesToEven);2202 EXPECT_EQ(10.0, P.convertToDouble());2203 EXPECT_EQ(APFloat::opInexact, St);2204}2205 2206TEST(APFloatTest, isInteger) {2207 APFloat T(-0.0);2208 EXPECT_TRUE(T.isInteger());2209 T = APFloat(3.14159);2210 EXPECT_FALSE(T.isInteger());2211 T = APFloat::getNaN(APFloat::IEEEdouble());2212 EXPECT_FALSE(T.isInteger());2213 T = APFloat::getInf(APFloat::IEEEdouble());2214 EXPECT_FALSE(T.isInteger());2215 T = APFloat::getInf(APFloat::IEEEdouble(), true);2216 EXPECT_FALSE(T.isInteger());2217 T = APFloat::getLargest(APFloat::IEEEdouble());2218 EXPECT_TRUE(T.isInteger());2219}2220 2221TEST(DoubleAPFloatTest, isInteger) {2222 APFloat F1(-0.0);2223 APFloat F2(-0.0);2224 llvm::detail::DoubleAPFloat T(APFloat::PPCDoubleDouble(), std::move(F1),2225 std::move(F2));2226 EXPECT_TRUE(T.isInteger());2227 APFloat F3(3.14159);2228 APFloat F4(-0.0);2229 llvm::detail::DoubleAPFloat T2(APFloat::PPCDoubleDouble(), std::move(F3),2230 std::move(F4));2231 EXPECT_FALSE(T2.isInteger());2232 APFloat F5(-0.0);2233 APFloat F6(3.14159);2234 llvm::detail::DoubleAPFloat T3(APFloat::PPCDoubleDouble(), std::move(F5),2235 std::move(F6));2236 EXPECT_FALSE(T3.isInteger());2237}2238 2239// Test to check if the full range of Float8E8M0FNU2240// values are being represented correctly.2241TEST(APFloatTest, Float8E8M0FNUValues) {2242 // High end of the range2243 auto test = APFloat(APFloat::Float8E8M0FNU(), "0x1.0p127");2244 EXPECT_EQ(0x1.0p127, test.convertToDouble());2245 2246 test = APFloat(APFloat::Float8E8M0FNU(), "0x1.0p126");2247 EXPECT_EQ(0x1.0p126, test.convertToDouble());2248 2249 test = APFloat(APFloat::Float8E8M0FNU(), "0x1.0p125");2250 EXPECT_EQ(0x1.0p125, test.convertToDouble());2251 2252 // tests the fix in makeLargest()2253 test = APFloat::getLargest(APFloat::Float8E8M0FNU());2254 EXPECT_EQ(0x1.0p127, test.convertToDouble());2255 2256 // tests overflow to nan2257 APFloat nan = APFloat(APFloat::Float8E8M0FNU(), "nan");2258 test = APFloat(APFloat::Float8E8M0FNU(), "0x1.0p128");2259 EXPECT_TRUE(test.bitwiseIsEqual(nan));2260 2261 // Mid of the range2262 test = APFloat(APFloat::Float8E8M0FNU(), "0x1.0p0");2263 EXPECT_EQ(1.0, test.convertToDouble());2264 2265 test = APFloat(APFloat::Float8E8M0FNU(), "0x1.0p1");2266 EXPECT_EQ(2.0, test.convertToDouble());2267 2268 test = APFloat(APFloat::Float8E8M0FNU(), "0x1.0p2");2269 EXPECT_EQ(4.0, test.convertToDouble());2270 2271 // Low end of the range2272 test = APFloat(APFloat::Float8E8M0FNU(), "0x1.0p-125");2273 EXPECT_EQ(0x1.0p-125, test.convertToDouble());2274 2275 test = APFloat(APFloat::Float8E8M0FNU(), "0x1.0p-126");2276 EXPECT_EQ(0x1.0p-126, test.convertToDouble());2277 2278 test = APFloat(APFloat::Float8E8M0FNU(), "0x1.0p-127");2279 EXPECT_EQ(0x1.0p-127, test.convertToDouble());2280 2281 // Smallest value2282 test = APFloat::getSmallest(APFloat::Float8E8M0FNU());2283 EXPECT_EQ(0x1.0p-127, test.convertToDouble());2284 2285 // Value below the smallest, but clamped to the smallest2286 test = APFloat(APFloat::Float8E8M0FNU(), "0x1.0p-128");2287 EXPECT_EQ(0x1.0p-127, test.convertToDouble());2288}2289 2290TEST(APFloatTest, getLargest) {2291 EXPECT_EQ(3.402823466e+38f, APFloat::getLargest(APFloat::IEEEsingle()).convertToFloat());2292 EXPECT_EQ(1.7976931348623158e+308, APFloat::getLargest(APFloat::IEEEdouble()).convertToDouble());2293 EXPECT_EQ(448, APFloat::getLargest(APFloat::Float8E4M3FN()).convertToDouble());2294 EXPECT_EQ(240,2295 APFloat::getLargest(APFloat::Float8E4M3FNUZ()).convertToDouble());2296 EXPECT_EQ(57344,2297 APFloat::getLargest(APFloat::Float8E5M2FNUZ()).convertToDouble());2298 EXPECT_EQ(2299 30, APFloat::getLargest(APFloat::Float8E4M3B11FNUZ()).convertToDouble());2300 EXPECT_EQ(3.40116213421e+38f,2301 APFloat::getLargest(APFloat::FloatTF32()).convertToFloat());2302 EXPECT_EQ(1.701411834e+38f,2303 APFloat::getLargest(APFloat::Float8E8M0FNU()).convertToDouble());2304 EXPECT_EQ(28, APFloat::getLargest(APFloat::Float6E3M2FN()).convertToDouble());2305 EXPECT_EQ(7.5,2306 APFloat::getLargest(APFloat::Float6E2M3FN()).convertToDouble());2307 EXPECT_EQ(6, APFloat::getLargest(APFloat::Float4E2M1FN()).convertToDouble());2308}2309 2310TEST(APFloatTest, getSmallest) {2311 APFloat test = APFloat::getSmallest(APFloat::IEEEsingle(), false);2312 APFloat expected = APFloat(APFloat::IEEEsingle(), "0x0.000002p-126");2313 EXPECT_FALSE(test.isNegative());2314 EXPECT_TRUE(test.isFiniteNonZero());2315 EXPECT_TRUE(test.isDenormal());2316 EXPECT_TRUE(test.bitwiseIsEqual(expected));2317 2318 test = APFloat::getSmallest(APFloat::IEEEsingle(), true);2319 expected = APFloat(APFloat::IEEEsingle(), "-0x0.000002p-126");2320 EXPECT_TRUE(test.isNegative());2321 EXPECT_TRUE(test.isFiniteNonZero());2322 EXPECT_TRUE(test.isDenormal());2323 EXPECT_TRUE(test.bitwiseIsEqual(expected));2324 2325 test = APFloat::getSmallest(APFloat::IEEEquad(), false);2326 expected = APFloat(APFloat::IEEEquad(), "0x0.0000000000000000000000000001p-16382");2327 EXPECT_FALSE(test.isNegative());2328 EXPECT_TRUE(test.isFiniteNonZero());2329 EXPECT_TRUE(test.isDenormal());2330 EXPECT_TRUE(test.bitwiseIsEqual(expected));2331 2332 test = APFloat::getSmallest(APFloat::IEEEquad(), true);2333 expected = APFloat(APFloat::IEEEquad(), "-0x0.0000000000000000000000000001p-16382");2334 EXPECT_TRUE(test.isNegative());2335 EXPECT_TRUE(test.isFiniteNonZero());2336 EXPECT_TRUE(test.isDenormal());2337 EXPECT_TRUE(test.bitwiseIsEqual(expected));2338 2339 test = APFloat::getSmallest(APFloat::Float8E5M2FNUZ(), false);2340 expected = APFloat(APFloat::Float8E5M2FNUZ(), "0x0.4p-15");2341 EXPECT_FALSE(test.isNegative());2342 EXPECT_TRUE(test.isFiniteNonZero());2343 EXPECT_TRUE(test.isDenormal());2344 EXPECT_TRUE(test.bitwiseIsEqual(expected));2345 2346 test = APFloat::getSmallest(APFloat::Float8E4M3FNUZ(), false);2347 expected = APFloat(APFloat::Float8E4M3FNUZ(), "0x0.2p-7");2348 EXPECT_FALSE(test.isNegative());2349 EXPECT_TRUE(test.isFiniteNonZero());2350 EXPECT_TRUE(test.isDenormal());2351 EXPECT_TRUE(test.bitwiseIsEqual(expected));2352 2353 test = APFloat::getSmallest(APFloat::Float8E4M3B11FNUZ(), false);2354 expected = APFloat(APFloat::Float8E4M3B11FNUZ(), "0x0.2p-10");2355 EXPECT_FALSE(test.isNegative());2356 EXPECT_TRUE(test.isFiniteNonZero());2357 EXPECT_TRUE(test.isDenormal());2358 EXPECT_TRUE(test.bitwiseIsEqual(expected));2359 2360 test = APFloat::getSmallest(APFloat::FloatTF32(), true);2361 expected = APFloat(APFloat::FloatTF32(), "-0x0.004p-126");2362 EXPECT_TRUE(test.isNegative());2363 EXPECT_TRUE(test.isFiniteNonZero());2364 EXPECT_TRUE(test.isDenormal());2365 EXPECT_TRUE(test.bitwiseIsEqual(expected));2366 2367 test = APFloat::getSmallest(APFloat::Float6E3M2FN(), false);2368 expected = APFloat(APFloat::Float6E3M2FN(), "0x0.1p0");2369 EXPECT_FALSE(test.isNegative());2370 EXPECT_TRUE(test.isFiniteNonZero());2371 EXPECT_TRUE(test.isDenormal());2372 EXPECT_TRUE(test.bitwiseIsEqual(expected));2373 2374 test = APFloat::getSmallest(APFloat::Float6E2M3FN(), false);2375 expected = APFloat(APFloat::Float6E2M3FN(), "0x0.2p0");2376 EXPECT_FALSE(test.isNegative());2377 EXPECT_TRUE(test.isFiniteNonZero());2378 EXPECT_TRUE(test.isDenormal());2379 EXPECT_TRUE(test.bitwiseIsEqual(expected));2380 2381 test = APFloat::getSmallest(APFloat::Float4E2M1FN(), false);2382 expected = APFloat(APFloat::Float4E2M1FN(), "0x0.8p0");2383 EXPECT_FALSE(test.isNegative());2384 EXPECT_TRUE(test.isFiniteNonZero());2385 EXPECT_TRUE(test.isDenormal());2386 EXPECT_TRUE(test.bitwiseIsEqual(expected));2387 2388 test = APFloat::getSmallest(APFloat::Float8E8M0FNU());2389 expected = APFloat(APFloat::Float8E8M0FNU(), "0x1.0p-127");2390 EXPECT_FALSE(test.isNegative());2391 EXPECT_TRUE(test.isFiniteNonZero());2392 EXPECT_FALSE(test.isDenormal());2393 EXPECT_TRUE(test.bitwiseIsEqual(expected));2394}2395 2396TEST(APFloatTest, getSmallestNormalized) {2397 APFloat test = APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);2398 APFloat expected = APFloat(APFloat::IEEEsingle(), "0x1p-126");2399 EXPECT_FALSE(test.isNegative());2400 EXPECT_TRUE(test.isFiniteNonZero());2401 EXPECT_FALSE(test.isDenormal());2402 EXPECT_TRUE(test.bitwiseIsEqual(expected));2403 EXPECT_TRUE(test.isSmallestNormalized());2404 2405 test = APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);2406 expected = APFloat(APFloat::IEEEsingle(), "-0x1p-126");2407 EXPECT_TRUE(test.isNegative());2408 EXPECT_TRUE(test.isFiniteNonZero());2409 EXPECT_FALSE(test.isDenormal());2410 EXPECT_TRUE(test.bitwiseIsEqual(expected));2411 EXPECT_TRUE(test.isSmallestNormalized());2412 2413 test = APFloat::getSmallestNormalized(APFloat::IEEEdouble(), false);2414 expected = APFloat(APFloat::IEEEdouble(), "0x1p-1022");2415 EXPECT_FALSE(test.isNegative());2416 EXPECT_TRUE(test.isFiniteNonZero());2417 EXPECT_FALSE(test.isDenormal());2418 EXPECT_TRUE(test.bitwiseIsEqual(expected));2419 EXPECT_TRUE(test.isSmallestNormalized());2420 2421 test = APFloat::getSmallestNormalized(APFloat::IEEEdouble(), true);2422 expected = APFloat(APFloat::IEEEdouble(), "-0x1p-1022");2423 EXPECT_TRUE(test.isNegative());2424 EXPECT_TRUE(test.isFiniteNonZero());2425 EXPECT_FALSE(test.isDenormal());2426 EXPECT_TRUE(test.bitwiseIsEqual(expected));2427 EXPECT_TRUE(test.isSmallestNormalized());2428 2429 test = APFloat::getSmallestNormalized(APFloat::IEEEquad(), false);2430 expected = APFloat(APFloat::IEEEquad(), "0x1p-16382");2431 EXPECT_FALSE(test.isNegative());2432 EXPECT_TRUE(test.isFiniteNonZero());2433 EXPECT_FALSE(test.isDenormal());2434 EXPECT_TRUE(test.bitwiseIsEqual(expected));2435 EXPECT_TRUE(test.isSmallestNormalized());2436 2437 test = APFloat::getSmallestNormalized(APFloat::IEEEquad(), true);2438 expected = APFloat(APFloat::IEEEquad(), "-0x1p-16382");2439 EXPECT_TRUE(test.isNegative());2440 EXPECT_TRUE(test.isFiniteNonZero());2441 EXPECT_FALSE(test.isDenormal());2442 EXPECT_TRUE(test.bitwiseIsEqual(expected));2443 EXPECT_TRUE(test.isSmallestNormalized());2444 2445 test = APFloat::getSmallestNormalized(APFloat::Float8E5M2FNUZ(), false);2446 expected = APFloat(APFloat::Float8E5M2FNUZ(), "0x1.0p-15");2447 EXPECT_FALSE(test.isNegative());2448 EXPECT_TRUE(test.isFiniteNonZero());2449 EXPECT_FALSE(test.isDenormal());2450 EXPECT_TRUE(test.bitwiseIsEqual(expected));2451 EXPECT_TRUE(test.isSmallestNormalized());2452 2453 test = APFloat::getSmallestNormalized(APFloat::Float8E4M3FNUZ(), false);2454 expected = APFloat(APFloat::Float8E4M3FNUZ(), "0x1.0p-7");2455 EXPECT_FALSE(test.isNegative());2456 EXPECT_TRUE(test.isFiniteNonZero());2457 EXPECT_FALSE(test.isDenormal());2458 EXPECT_TRUE(test.bitwiseIsEqual(expected));2459 EXPECT_TRUE(test.isSmallestNormalized());2460 2461 test = APFloat::getSmallestNormalized(APFloat::Float8E4M3B11FNUZ(), false);2462 expected = APFloat(APFloat::Float8E4M3B11FNUZ(), "0x1.0p-10");2463 EXPECT_FALSE(test.isNegative());2464 EXPECT_TRUE(test.isFiniteNonZero());2465 EXPECT_FALSE(test.isDenormal());2466 EXPECT_TRUE(test.bitwiseIsEqual(expected));2467 EXPECT_TRUE(test.isSmallestNormalized());2468 2469 test = APFloat::getSmallestNormalized(APFloat::FloatTF32(), false);2470 expected = APFloat(APFloat::FloatTF32(), "0x1p-126");2471 EXPECT_FALSE(test.isNegative());2472 EXPECT_TRUE(test.isFiniteNonZero());2473 EXPECT_FALSE(test.isDenormal());2474 EXPECT_TRUE(test.bitwiseIsEqual(expected));2475 EXPECT_TRUE(test.isSmallestNormalized());2476 2477 test = APFloat::getSmallestNormalized(APFloat::Float6E3M2FN(), false);2478 expected = APFloat(APFloat::Float6E3M2FN(), "0x1p-2");2479 EXPECT_FALSE(test.isNegative());2480 EXPECT_TRUE(test.isFiniteNonZero());2481 EXPECT_FALSE(test.isDenormal());2482 EXPECT_TRUE(test.bitwiseIsEqual(expected));2483 EXPECT_TRUE(test.isSmallestNormalized());2484 2485 test = APFloat::getSmallestNormalized(APFloat::Float4E2M1FN(), false);2486 expected = APFloat(APFloat::Float4E2M1FN(), "0x1p0");2487 EXPECT_FALSE(test.isNegative());2488 EXPECT_TRUE(test.isFiniteNonZero());2489 EXPECT_FALSE(test.isDenormal());2490 EXPECT_TRUE(test.bitwiseIsEqual(expected));2491 EXPECT_TRUE(test.isSmallestNormalized());2492 2493 test = APFloat::getSmallestNormalized(APFloat::Float6E2M3FN(), false);2494 expected = APFloat(APFloat::Float6E2M3FN(), "0x1p0");2495 EXPECT_FALSE(test.isNegative());2496 EXPECT_TRUE(test.isFiniteNonZero());2497 EXPECT_FALSE(test.isDenormal());2498 EXPECT_TRUE(test.bitwiseIsEqual(expected));2499 EXPECT_TRUE(test.isSmallestNormalized());2500 2501 test = APFloat::getSmallestNormalized(APFloat::Float8E8M0FNU(), false);2502 expected = APFloat(APFloat::Float8E8M0FNU(), "0x1.0p-127");2503 EXPECT_FALSE(test.isNegative());2504 EXPECT_TRUE(test.isFiniteNonZero());2505 EXPECT_FALSE(test.isDenormal());2506 EXPECT_TRUE(test.bitwiseIsEqual(expected));2507 EXPECT_TRUE(test.isSmallestNormalized());2508}2509 2510TEST(APFloatTest, getZero) {2511 struct {2512 const fltSemantics *semantics;2513 const bool sign;2514 const bool signedZero;2515 const unsigned long long bitPattern[2];2516 const unsigned bitPatternLength;2517 } const GetZeroTest[] = {2518 {&APFloat::IEEEhalf(), false, true, {0, 0}, 1},2519 {&APFloat::IEEEhalf(), true, true, {0x8000ULL, 0}, 1},2520 {&APFloat::IEEEsingle(), false, true, {0, 0}, 1},2521 {&APFloat::IEEEsingle(), true, true, {0x80000000ULL, 0}, 1},2522 {&APFloat::IEEEdouble(), false, true, {0, 0}, 1},2523 {&APFloat::IEEEdouble(), true, true, {0x8000000000000000ULL, 0}, 1},2524 {&APFloat::IEEEquad(), false, true, {0, 0}, 2},2525 {&APFloat::IEEEquad(), true, true, {0, 0x8000000000000000ULL}, 2},2526 {&APFloat::PPCDoubleDouble(), false, true, {0, 0}, 2},2527 {&APFloat::PPCDoubleDouble(), true, true, {0x8000000000000000ULL, 0}, 2},2528 {&APFloat::x87DoubleExtended(), false, true, {0, 0}, 2},2529 {&APFloat::x87DoubleExtended(), true, true, {0, 0x8000ULL}, 2},2530 {&APFloat::Float8E5M2(), false, true, {0, 0}, 1},2531 {&APFloat::Float8E5M2(), true, true, {0x80ULL, 0}, 1},2532 {&APFloat::Float8E5M2FNUZ(), false, false, {0, 0}, 1},2533 {&APFloat::Float8E5M2FNUZ(), true, false, {0, 0}, 1},2534 {&APFloat::Float8E4M3(), false, true, {0, 0}, 1},2535 {&APFloat::Float8E4M3(), true, true, {0x80ULL, 0}, 1},2536 {&APFloat::Float8E4M3FN(), false, true, {0, 0}, 1},2537 {&APFloat::Float8E4M3FN(), true, true, {0x80ULL, 0}, 1},2538 {&APFloat::Float8E4M3FNUZ(), false, false, {0, 0}, 1},2539 {&APFloat::Float8E4M3FNUZ(), true, false, {0, 0}, 1},2540 {&APFloat::Float8E4M3B11FNUZ(), false, false, {0, 0}, 1},2541 {&APFloat::Float8E4M3B11FNUZ(), true, false, {0, 0}, 1},2542 {&APFloat::Float8E3M4(), false, true, {0, 0}, 1},2543 {&APFloat::Float8E3M4(), true, true, {0x80ULL, 0}, 1},2544 {&APFloat::FloatTF32(), false, true, {0, 0}, 1},2545 {&APFloat::FloatTF32(), true, true, {0x40000ULL, 0}, 1},2546 {&APFloat::Float6E3M2FN(), false, true, {0, 0}, 1},2547 {&APFloat::Float6E3M2FN(), true, true, {0x20ULL, 0}, 1},2548 {&APFloat::Float6E2M3FN(), false, true, {0, 0}, 1},2549 {&APFloat::Float6E2M3FN(), true, true, {0x20ULL, 0}, 1},2550 {&APFloat::Float4E2M1FN(), false, true, {0, 0}, 1},2551 {&APFloat::Float4E2M1FN(), true, true, {0x8ULL, 0}, 1}};2552 const unsigned NumGetZeroTests = std::size(GetZeroTest);2553 for (unsigned i = 0; i < NumGetZeroTests; ++i) {2554 APFloat test = APFloat::getZero(*GetZeroTest[i].semantics,2555 GetZeroTest[i].sign);2556 const char *pattern = GetZeroTest[i].sign? "-0x0p+0" : "0x0p+0";2557 APFloat expected = APFloat(*GetZeroTest[i].semantics,2558 pattern);2559 EXPECT_TRUE(test.isZero());2560 if (GetZeroTest[i].signedZero)2561 EXPECT_TRUE(GetZeroTest[i].sign ? test.isNegative() : !test.isNegative());2562 else2563 EXPECT_TRUE(!test.isNegative());2564 EXPECT_TRUE(test.bitwiseIsEqual(expected));2565 for (unsigned j = 0, je = GetZeroTest[i].bitPatternLength; j < je; ++j) {2566 EXPECT_EQ(GetZeroTest[i].bitPattern[j],2567 test.bitcastToAPInt().getRawData()[j]);2568 }2569 }2570}2571 2572TEST(APFloatTest, copySign) {2573 EXPECT_TRUE(APFloat(-42.0).bitwiseIsEqual(2574 APFloat::copySign(APFloat(42.0), APFloat(-1.0))));2575 EXPECT_TRUE(APFloat(42.0).bitwiseIsEqual(2576 APFloat::copySign(APFloat(-42.0), APFloat(1.0))));2577 EXPECT_TRUE(APFloat(-42.0).bitwiseIsEqual(2578 APFloat::copySign(APFloat(-42.0), APFloat(-1.0))));2579 EXPECT_TRUE(APFloat(42.0).bitwiseIsEqual(2580 APFloat::copySign(APFloat(42.0), APFloat(1.0))));2581 // For floating-point formats with unsigned 0, copySign() to a zero is a noop2582 for (APFloat::Semantics S :2583 {APFloat::S_Float8E4M3FNUZ, APFloat::S_Float8E4M3B11FNUZ}) {2584 const llvm::fltSemantics &Sem = APFloat::EnumToSemantics(S);2585 EXPECT_TRUE(APFloat::getZero(Sem).bitwiseIsEqual(2586 APFloat::copySign(APFloat::getZero(Sem), APFloat(-1.0))));2587 EXPECT_TRUE(APFloat::getNaN(Sem, true).bitwiseIsEqual(2588 APFloat::copySign(APFloat::getNaN(Sem, true), APFloat(1.0))));2589 }2590}2591 2592TEST(APFloatTest, convert) {2593 bool losesInfo;2594 APFloat test(APFloat::IEEEdouble(), "1.0");2595 test.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &losesInfo);2596 EXPECT_EQ(1.0f, test.convertToFloat());2597 EXPECT_FALSE(losesInfo);2598 2599 test = APFloat(APFloat::x87DoubleExtended(), "0x1p-53");2600 test.add(APFloat(APFloat::x87DoubleExtended(), "1.0"), APFloat::rmNearestTiesToEven);2601 test.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &losesInfo);2602 EXPECT_EQ(1.0, test.convertToDouble());2603 EXPECT_TRUE(losesInfo);2604 2605 test = APFloat(APFloat::IEEEquad(), "0x1p-53");2606 test.add(APFloat(APFloat::IEEEquad(), "1.0"), APFloat::rmNearestTiesToEven);2607 test.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &losesInfo);2608 EXPECT_EQ(1.0, test.convertToDouble());2609 EXPECT_TRUE(losesInfo);2610 2611 test = APFloat(APFloat::x87DoubleExtended(), "0xf.fffffffp+28");2612 test.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &losesInfo);2613 EXPECT_EQ(4294967295.0, test.convertToDouble());2614 EXPECT_FALSE(losesInfo);2615 2616 test = APFloat::getSNaN(APFloat::IEEEsingle());2617 APFloat::opStatus status = test.convert(APFloat::x87DoubleExtended(), APFloat::rmNearestTiesToEven, &losesInfo);2618 // Conversion quiets the SNAN, so now 2 bits of the 64-bit significand should be set.2619 APInt topTwoBits(64, 0x6000000000000000);2620 EXPECT_TRUE(test.bitwiseIsEqual(APFloat::getQNaN(APFloat::x87DoubleExtended(), false, &topTwoBits)));2621 EXPECT_FALSE(losesInfo);2622 EXPECT_EQ(status, APFloat::opInvalidOp);2623 2624 test = APFloat::getQNaN(APFloat::IEEEsingle());2625 APFloat X87QNaN = APFloat::getQNaN(APFloat::x87DoubleExtended());2626 test.convert(APFloat::x87DoubleExtended(), APFloat::rmNearestTiesToEven,2627 &losesInfo);2628 EXPECT_TRUE(test.bitwiseIsEqual(X87QNaN));2629 EXPECT_FALSE(losesInfo);2630 2631 test = APFloat::getSNaN(APFloat::x87DoubleExtended());2632 test.convert(APFloat::x87DoubleExtended(), APFloat::rmNearestTiesToEven,2633 &losesInfo);2634 APFloat X87SNaN = APFloat::getSNaN(APFloat::x87DoubleExtended());2635 EXPECT_TRUE(test.bitwiseIsEqual(X87SNaN));2636 EXPECT_FALSE(losesInfo);2637 2638 test = APFloat::getQNaN(APFloat::x87DoubleExtended());2639 test.convert(APFloat::x87DoubleExtended(), APFloat::rmNearestTiesToEven,2640 &losesInfo);2641 EXPECT_TRUE(test.bitwiseIsEqual(X87QNaN));2642 EXPECT_FALSE(losesInfo);2643 2644 // The payload is lost in truncation, but we retain NaN by setting the quiet bit.2645 APInt payload(52, 1);2646 test = APFloat::getSNaN(APFloat::IEEEdouble(), false, &payload);2647 status = test.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &losesInfo);2648 EXPECT_EQ(0x7fc00000, test.bitcastToAPInt());2649 EXPECT_TRUE(losesInfo);2650 EXPECT_EQ(status, APFloat::opInvalidOp);2651 2652 // The payload is lost in truncation. QNaN remains QNaN.2653 test = APFloat::getQNaN(APFloat::IEEEdouble(), false, &payload);2654 status = test.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &losesInfo);2655 EXPECT_EQ(0x7fc00000, test.bitcastToAPInt());2656 EXPECT_TRUE(losesInfo);2657 EXPECT_EQ(status, APFloat::opOK);2658 2659 // Test that subnormals are handled correctly in double to float conversion2660 test = APFloat(APFloat::IEEEdouble(), "0x0.0000010000000p-1022");2661 test.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &losesInfo);2662 EXPECT_EQ(0.0f, test.convertToFloat());2663 EXPECT_TRUE(losesInfo);2664 2665 test = APFloat(APFloat::IEEEdouble(), "0x0.0000010000001p-1022");2666 test.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &losesInfo);2667 EXPECT_EQ(0.0f, test.convertToFloat());2668 EXPECT_TRUE(losesInfo);2669 2670 test = APFloat(APFloat::IEEEdouble(), "-0x0.0000010000001p-1022");2671 test.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &losesInfo);2672 EXPECT_EQ(0.0f, test.convertToFloat());2673 EXPECT_TRUE(losesInfo);2674 2675 test = APFloat(APFloat::IEEEdouble(), "0x0.0000020000000p-1022");2676 test.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &losesInfo);2677 EXPECT_EQ(0.0f, test.convertToFloat());2678 EXPECT_TRUE(losesInfo);2679 2680 test = APFloat(APFloat::IEEEdouble(), "0x0.0000020000001p-1022");2681 test.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &losesInfo);2682 EXPECT_EQ(0.0f, test.convertToFloat());2683 EXPECT_TRUE(losesInfo);2684 2685 // Test subnormal conversion to bfloat2686 test = APFloat(APFloat::IEEEsingle(), "0x0.01p-126");2687 test.convert(APFloat::BFloat(), APFloat::rmNearestTiesToEven, &losesInfo);2688 EXPECT_EQ(0.0f, test.convertToFloat());2689 EXPECT_TRUE(losesInfo);2690 2691 test = APFloat(APFloat::IEEEsingle(), "0x0.02p-126");2692 test.convert(APFloat::BFloat(), APFloat::rmNearestTiesToEven, &losesInfo);2693 EXPECT_EQ(0x01, test.bitcastToAPInt());2694 EXPECT_FALSE(losesInfo);2695 2696 test = APFloat(APFloat::IEEEsingle(), "0x0.01p-126");2697 test.convert(APFloat::BFloat(), APFloat::rmNearestTiesToAway, &losesInfo);2698 EXPECT_EQ(0x01, test.bitcastToAPInt());2699 EXPECT_TRUE(losesInfo);2700}2701 2702TEST(APFloatTest, Float8UZConvert) {2703 bool losesInfo = false;2704 std::pair<APFloat, APFloat::opStatus> toNaNTests[] = {2705 {APFloat::getQNaN(APFloat::IEEEsingle(), false), APFloat::opOK},2706 {APFloat::getQNaN(APFloat::IEEEsingle(), true), APFloat::opOK},2707 {APFloat::getSNaN(APFloat::IEEEsingle(), false), APFloat::opInvalidOp},2708 {APFloat::getSNaN(APFloat::IEEEsingle(), true), APFloat::opInvalidOp},2709 {APFloat::getInf(APFloat::IEEEsingle(), false), APFloat::opInexact},2710 {APFloat::getInf(APFloat::IEEEsingle(), true), APFloat::opInexact}};2711 for (APFloat::Semantics S :2712 {APFloat::S_Float8E5M2FNUZ, APFloat::S_Float8E4M3FNUZ,2713 APFloat::S_Float8E4M3B11FNUZ}) {2714 const llvm::fltSemantics &Sem = APFloat::EnumToSemantics(S);2715 SCOPED_TRACE("Semantics = " + std::to_string(S));2716 for (auto [toTest, expectedRes] : toNaNTests) {2717 llvm::SmallString<16> value;2718 toTest.toString(value);2719 SCOPED_TRACE("toTest = " + value);2720 losesInfo = false;2721 APFloat test = toTest;2722 EXPECT_EQ(test.convert(Sem, APFloat::rmNearestTiesToAway, &losesInfo),2723 expectedRes);2724 EXPECT_TRUE(test.isNaN());2725 EXPECT_TRUE(test.isNegative());2726 EXPECT_FALSE(test.isSignaling());2727 EXPECT_FALSE(test.isInfinity());2728 EXPECT_EQ(0x80, test.bitcastToAPInt());2729 EXPECT_TRUE(losesInfo);2730 }2731 2732 // Negative zero conversions are information losing.2733 losesInfo = false;2734 APFloat test = APFloat::getZero(APFloat::IEEEsingle(), true);2735 EXPECT_EQ(test.convert(Sem, APFloat::rmNearestTiesToAway, &losesInfo),2736 APFloat::opInexact);2737 EXPECT_TRUE(test.isZero());2738 EXPECT_FALSE(test.isNegative());2739 EXPECT_TRUE(losesInfo);2740 EXPECT_EQ(0x0, test.bitcastToAPInt());2741 2742 losesInfo = true;2743 test = APFloat::getZero(APFloat::IEEEsingle(), false);2744 EXPECT_EQ(test.convert(Sem, APFloat::rmNearestTiesToAway, &losesInfo),2745 APFloat::opOK);2746 EXPECT_TRUE(test.isZero());2747 EXPECT_FALSE(test.isNegative());2748 EXPECT_FALSE(losesInfo);2749 EXPECT_EQ(0x0, test.bitcastToAPInt());2750 2751 // Except in casts between ourselves.2752 losesInfo = true;2753 test = APFloat::getZero(Sem);2754 EXPECT_EQ(test.convert(Sem, APFloat::rmNearestTiesToAway, &losesInfo),2755 APFloat::opOK);2756 EXPECT_FALSE(losesInfo);2757 EXPECT_EQ(0x0, test.bitcastToAPInt());2758 }2759}2760 2761struct DD {2762 double Hi;2763 double Lo;2764};2765 2766template <typename T, typename U>2767static APFloat makeDoubleAPFloat(T Hi, U Lo) {2768 APFloat HiFloat{APFloat::IEEEdouble(), APFloat::uninitialized};2769 if constexpr (std::is_same_v<decltype(Hi), APFloat>) {2770 HiFloat = Hi;2771 } else if constexpr (std::is_same_v<decltype(Hi), double>) {2772 HiFloat = APFloat{Hi};2773 } else {2774 HiFloat = {APFloat::IEEEdouble(), Hi};2775 }2776 2777 APFloat LoFloat{APFloat::IEEEdouble(), APFloat::uninitialized};2778 if constexpr (std::is_same_v<decltype(Lo), APFloat>) {2779 LoFloat = Lo;2780 } else if constexpr (std::is_same_v<decltype(Lo), double>) {2781 LoFloat = APFloat{Lo};2782 } else {2783 LoFloat = {APFloat::IEEEdouble(), Lo};2784 }2785 2786 APInt Bits = LoFloat.bitcastToAPInt().concat(HiFloat.bitcastToAPInt());2787 return APFloat(APFloat::PPCDoubleDouble(), Bits);2788}2789 2790static APFloat makeDoubleAPFloat(DD X) { return makeDoubleAPFloat(X.Hi, X.Lo); }2791 2792TEST(APFloatTest, PPCDoubleDouble) {2793 APFloat test(APFloat::PPCDoubleDouble(), "1.0");2794 EXPECT_EQ(0x3ff0000000000000ull, test.bitcastToAPInt().getRawData()[0]);2795 EXPECT_EQ(0x0000000000000000ull, test.bitcastToAPInt().getRawData()[1]);2796 2797 // LDBL_MAX2798 test = APFloat(APFloat::PPCDoubleDouble(), "1.79769313486231580793728971405301e+308");2799 EXPECT_EQ(0x7fefffffffffffffull, test.bitcastToAPInt().getRawData()[0]);2800 EXPECT_EQ(0x7c8ffffffffffffeull, test.bitcastToAPInt().getRawData()[1]);2801 2802 // LDBL_MIN2803 test = APFloat(APFloat::PPCDoubleDouble(), "2.00416836000897277799610805135016e-292");2804 EXPECT_EQ(0x0360000000000000ull, test.bitcastToAPInt().getRawData()[0]);2805 EXPECT_EQ(0x0000000000000000ull, test.bitcastToAPInt().getRawData()[1]);2806 2807 // PR308692808 {2809 auto Result = APFloat(APFloat::PPCDoubleDouble(), "1.0") +2810 APFloat(APFloat::PPCDoubleDouble(), "1.0");2811 EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics());2812 2813 Result = APFloat(APFloat::PPCDoubleDouble(), "1.0") -2814 APFloat(APFloat::PPCDoubleDouble(), "1.0");2815 EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics());2816 2817 Result = APFloat(APFloat::PPCDoubleDouble(), "1.0") *2818 APFloat(APFloat::PPCDoubleDouble(), "1.0");2819 EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics());2820 2821 Result = APFloat(APFloat::PPCDoubleDouble(), "1.0") /2822 APFloat(APFloat::PPCDoubleDouble(), "1.0");2823 EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics());2824 2825 int Exp;2826 Result = frexp(APFloat(APFloat::PPCDoubleDouble(), "1.0"), Exp,2827 APFloat::rmNearestTiesToEven);2828 EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics());2829 2830 Result = scalbn(APFloat(APFloat::PPCDoubleDouble(), "1.0"), 1,2831 APFloat::rmNearestTiesToEven);2832 EXPECT_EQ(&APFloat::PPCDoubleDouble(), &Result.getSemantics());2833 }2834}2835 2836TEST(APFloatTest, isNegative) {2837 APFloat t(APFloat::IEEEsingle(), "0x1p+0");2838 EXPECT_FALSE(t.isNegative());2839 t = APFloat(APFloat::IEEEsingle(), "-0x1p+0");2840 EXPECT_TRUE(t.isNegative());2841 2842 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), false).isNegative());2843 EXPECT_TRUE(APFloat::getInf(APFloat::IEEEsingle(), true).isNegative());2844 2845 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), false).isNegative());2846 EXPECT_TRUE(APFloat::getZero(APFloat::IEEEsingle(), true).isNegative());2847 2848 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), false).isNegative());2849 EXPECT_TRUE(APFloat::getNaN(APFloat::IEEEsingle(), true).isNegative());2850 2851 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isNegative());2852 EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle(), true).isNegative());2853}2854 2855TEST(APFloatTest, isNormal) {2856 APFloat t(APFloat::IEEEsingle(), "0x1p+0");2857 EXPECT_TRUE(t.isNormal());2858 2859 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), false).isNormal());2860 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), false).isNormal());2861 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), false).isNormal());2862 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isNormal());2863 EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), "0x1p-149").isNormal());2864}2865 2866TEST(APFloatTest, isFinite) {2867 APFloat t(APFloat::IEEEsingle(), "0x1p+0");2868 EXPECT_TRUE(t.isFinite());2869 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), false).isFinite());2870 EXPECT_TRUE(APFloat::getZero(APFloat::IEEEsingle(), false).isFinite());2871 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), false).isFinite());2872 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isFinite());2873 EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "0x1p-149").isFinite());2874}2875 2876TEST(APFloatTest, isInfinity) {2877 APFloat t(APFloat::IEEEsingle(), "0x1p+0");2878 EXPECT_FALSE(t.isInfinity());2879 2880 APFloat PosInf = APFloat::getInf(APFloat::IEEEsingle(), false);2881 APFloat NegInf = APFloat::getInf(APFloat::IEEEsingle(), true);2882 2883 EXPECT_TRUE(PosInf.isInfinity());2884 EXPECT_TRUE(PosInf.isPosInfinity());2885 EXPECT_FALSE(PosInf.isNegInfinity());2886 EXPECT_EQ(fcPosInf, PosInf.classify());2887 2888 EXPECT_TRUE(NegInf.isInfinity());2889 EXPECT_FALSE(NegInf.isPosInfinity());2890 EXPECT_TRUE(NegInf.isNegInfinity());2891 EXPECT_EQ(fcNegInf, NegInf.classify());2892 2893 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), false).isInfinity());2894 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), false).isInfinity());2895 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isInfinity());2896 EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), "0x1p-149").isInfinity());2897 2898 for (unsigned I = 0; I != APFloat::S_MaxSemantics + 1; ++I) {2899 const fltSemantics &Semantics =2900 APFloat::EnumToSemantics(static_cast<APFloat::Semantics>(I));2901 if (APFloat::semanticsHasInf(Semantics)) {2902 EXPECT_TRUE(APFloat::getInf(Semantics).isInfinity());2903 }2904 }2905}2906 2907TEST(APFloatTest, isNaN) {2908 APFloat t(APFloat::IEEEsingle(), "0x1p+0");2909 EXPECT_FALSE(t.isNaN());2910 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), false).isNaN());2911 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), false).isNaN());2912 EXPECT_TRUE(APFloat::getNaN(APFloat::IEEEsingle(), false).isNaN());2913 EXPECT_TRUE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isNaN());2914 EXPECT_FALSE(APFloat(APFloat::IEEEsingle(), "0x1p-149").isNaN());2915 2916 for (unsigned I = 0; I != APFloat::S_MaxSemantics + 1; ++I) {2917 const fltSemantics &Semantics =2918 APFloat::EnumToSemantics(static_cast<APFloat::Semantics>(I));2919 if (APFloat::semanticsHasNaN(Semantics)) {2920 EXPECT_TRUE(APFloat::getNaN(Semantics).isNaN());2921 }2922 }2923}2924 2925TEST(APFloatTest, isFiniteNonZero) {2926 // Test positive/negative normal value.2927 EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "0x1p+0").isFiniteNonZero());2928 EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "-0x1p+0").isFiniteNonZero());2929 2930 // Test positive/negative denormal value.2931 EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "0x1p-149").isFiniteNonZero());2932 EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "-0x1p-149").isFiniteNonZero());2933 2934 // Test +/- Infinity.2935 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), false).isFiniteNonZero());2936 EXPECT_FALSE(APFloat::getInf(APFloat::IEEEsingle(), true).isFiniteNonZero());2937 2938 // Test +/- Zero.2939 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), false).isFiniteNonZero());2940 EXPECT_FALSE(APFloat::getZero(APFloat::IEEEsingle(), true).isFiniteNonZero());2941 2942 // Test +/- qNaN. +/- dont mean anything with qNaN but paranoia can't hurt in2943 // this instance.2944 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), false).isFiniteNonZero());2945 EXPECT_FALSE(APFloat::getNaN(APFloat::IEEEsingle(), true).isFiniteNonZero());2946 2947 // Test +/- sNaN. +/- dont mean anything with sNaN but paranoia can't hurt in2948 // this instance.2949 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), false).isFiniteNonZero());2950 EXPECT_FALSE(APFloat::getSNaN(APFloat::IEEEsingle(), true).isFiniteNonZero());2951}2952 2953TEST(APFloatTest, add) {2954 // Test Special Cases against each other and normal values.2955 2956 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle(), false);2957 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle(), true);2958 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle(), false);2959 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle(), true);2960 APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);2961 APFloat SNaN = APFloat(APFloat::IEEEsingle(), "snan123");2962 APFloat PNormalValue = APFloat(APFloat::IEEEsingle(), "0x1p+0");2963 APFloat MNormalValue = APFloat(APFloat::IEEEsingle(), "-0x1p+0");2964 APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), false);2965 APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), true);2966 APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), false);2967 APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), true);2968 APFloat PSmallestNormalized =2969 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);2970 APFloat MSmallestNormalized =2971 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);2972 2973 const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact;2974 2975 struct {2976 APFloat x;2977 APFloat y;2978 const char *result;2979 int status;2980 int category;2981 } SpecialCaseTests[] = {2982 { PInf, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },2983 { PInf, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },2984 { PInf, PZero, "inf", APFloat::opOK, APFloat::fcInfinity },2985 { PInf, MZero, "inf", APFloat::opOK, APFloat::fcInfinity },2986 { PInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },2987 { PInf, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },2988 { PInf, PNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },2989 { PInf, MNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },2990 { PInf, PLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },2991 { PInf, MLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },2992 { PInf, PSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },2993 { PInf, MSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },2994 { PInf, PSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },2995 { PInf, MSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },2996 { MInf, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },2997 { MInf, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },2998 { MInf, PZero, "-inf", APFloat::opOK, APFloat::fcInfinity },2999 { MInf, MZero, "-inf", APFloat::opOK, APFloat::fcInfinity },3000 { MInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3001 { MInf, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3002 { MInf, PNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },3003 { MInf, MNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },3004 { MInf, PLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },3005 { MInf, MLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },3006 { MInf, PSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },3007 { MInf, MSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },3008 { MInf, PSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },3009 { MInf, MSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },3010 { PZero, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },3011 { PZero, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3012 { PZero, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },3013 { PZero, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },3014 { PZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3015 { PZero, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3016 { PZero, PNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },3017 { PZero, MNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },3018 { PZero, PLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },3019 { PZero, MLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },3020 { PZero, PSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },3021 { PZero, MSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },3022 { PZero, PSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },3023 { PZero, MSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },3024 { MZero, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },3025 { MZero, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3026 { MZero, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },3027 { MZero, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3028 { MZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3029 { MZero, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3030 { MZero, PNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },3031 { MZero, MNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },3032 { MZero, PLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },3033 { MZero, MLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },3034 { MZero, PSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },3035 { MZero, MSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },3036 { MZero, PSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },3037 { MZero, MSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },3038 { QNaN, PInf, "nan", APFloat::opOK, APFloat::fcNaN },3039 { QNaN, MInf, "nan", APFloat::opOK, APFloat::fcNaN },3040 { QNaN, PZero, "nan", APFloat::opOK, APFloat::fcNaN },3041 { QNaN, MZero, "nan", APFloat::opOK, APFloat::fcNaN },3042 { QNaN, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3043 { QNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },3044 { QNaN, PNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },3045 { QNaN, MNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },3046 { QNaN, PLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },3047 { QNaN, MLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },3048 { QNaN, PSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },3049 { QNaN, MSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },3050 { QNaN, PSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },3051 { QNaN, MSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },3052 { SNaN, PInf, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3053 { SNaN, MInf, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3054 { SNaN, PZero, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3055 { SNaN, MZero, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3056 { SNaN, QNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3057 { SNaN, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3058 { SNaN, PNormalValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3059 { SNaN, MNormalValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3060 { SNaN, PLargestValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3061 { SNaN, MLargestValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3062 { SNaN, PSmallestValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3063 { SNaN, MSmallestValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3064 { SNaN, PSmallestNormalized, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3065 { SNaN, MSmallestNormalized, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3066 { PNormalValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },3067 { PNormalValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3068 { PNormalValue, PZero, "0x1p+0", APFloat::opOK, APFloat::fcNormal },3069 { PNormalValue, MZero, "0x1p+0", APFloat::opOK, APFloat::fcNormal },3070 { PNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3071 { PNormalValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3072 { PNormalValue, PNormalValue, "0x1p+1", APFloat::opOK, APFloat::fcNormal },3073 { PNormalValue, MNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },3074 { PNormalValue, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3075 { PNormalValue, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3076 { PNormalValue, PSmallestValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },3077 { PNormalValue, MSmallestValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },3078 { PNormalValue, PSmallestNormalized, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },3079 { PNormalValue, MSmallestNormalized, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },3080 { MNormalValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },3081 { MNormalValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3082 { MNormalValue, PZero, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },3083 { MNormalValue, MZero, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },3084 { MNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3085 { MNormalValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3086 { MNormalValue, PNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },3087 { MNormalValue, MNormalValue, "-0x1p+1", APFloat::opOK, APFloat::fcNormal },3088 { MNormalValue, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3089 { MNormalValue, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3090 { MNormalValue, PSmallestValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },3091 { MNormalValue, MSmallestValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },3092 { MNormalValue, PSmallestNormalized, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },3093 { MNormalValue, MSmallestNormalized, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },3094 { PLargestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },3095 { PLargestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3096 { PLargestValue, PZero, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },3097 { PLargestValue, MZero, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },3098 { PLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3099 { PLargestValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3100 { PLargestValue, PNormalValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3101 { PLargestValue, MNormalValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3102 { PLargestValue, PLargestValue, "inf", OverflowStatus, APFloat::fcInfinity },3103 { PLargestValue, MLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },3104 { PLargestValue, PSmallestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3105 { PLargestValue, MSmallestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3106 { PLargestValue, PSmallestNormalized, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3107 { PLargestValue, MSmallestNormalized, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3108 { MLargestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },3109 { MLargestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3110 { MLargestValue, PZero, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },3111 { MLargestValue, MZero, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },3112 { MLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3113 { MLargestValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3114 { MLargestValue, PNormalValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3115 { MLargestValue, MNormalValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3116 { MLargestValue, PLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },3117 { MLargestValue, MLargestValue, "-inf", OverflowStatus, APFloat::fcInfinity },3118 { MLargestValue, PSmallestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3119 { MLargestValue, MSmallestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3120 { MLargestValue, PSmallestNormalized, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3121 { MLargestValue, MSmallestNormalized, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3122 { PSmallestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },3123 { PSmallestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3124 { PSmallestValue, PZero, "0x1p-149", APFloat::opOK, APFloat::fcNormal },3125 { PSmallestValue, MZero, "0x1p-149", APFloat::opOK, APFloat::fcNormal },3126 { PSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3127 { PSmallestValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3128 { PSmallestValue, PNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },3129 { PSmallestValue, MNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },3130 { PSmallestValue, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3131 { PSmallestValue, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3132 { PSmallestValue, PSmallestValue, "0x1p-148", APFloat::opOK, APFloat::fcNormal },3133 { PSmallestValue, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },3134 { PSmallestValue, PSmallestNormalized, "0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },3135 { PSmallestValue, MSmallestNormalized, "-0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },3136 { MSmallestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },3137 { MSmallestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3138 { MSmallestValue, PZero, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },3139 { MSmallestValue, MZero, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },3140 { MSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3141 { MSmallestValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3142 { MSmallestValue, PNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },3143 { MSmallestValue, MNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },3144 { MSmallestValue, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3145 { MSmallestValue, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3146 { MSmallestValue, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },3147 { MSmallestValue, MSmallestValue, "-0x1p-148", APFloat::opOK, APFloat::fcNormal },3148 { MSmallestValue, PSmallestNormalized, "0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },3149 { MSmallestValue, MSmallestNormalized, "-0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },3150 { PSmallestNormalized, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },3151 { PSmallestNormalized, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3152 { PSmallestNormalized, PZero, "0x1p-126", APFloat::opOK, APFloat::fcNormal },3153 { PSmallestNormalized, MZero, "0x1p-126", APFloat::opOK, APFloat::fcNormal },3154 { PSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3155 { PSmallestNormalized, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3156 { PSmallestNormalized, PNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },3157 { PSmallestNormalized, MNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },3158 { PSmallestNormalized, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3159 { PSmallestNormalized, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3160 { PSmallestNormalized, PSmallestValue, "0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },3161 { PSmallestNormalized, MSmallestValue, "0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },3162 { PSmallestNormalized, PSmallestNormalized, "0x1p-125", APFloat::opOK, APFloat::fcNormal },3163 { PSmallestNormalized, MSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },3164 { MSmallestNormalized, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },3165 { MSmallestNormalized, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3166 { MSmallestNormalized, PZero, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },3167 { MSmallestNormalized, MZero, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },3168 { MSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3169 { MSmallestNormalized, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3170 { MSmallestNormalized, PNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },3171 { MSmallestNormalized, MNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },3172 { MSmallestNormalized, PLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3173 { MSmallestNormalized, MLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3174 { MSmallestNormalized, PSmallestValue, "-0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },3175 { MSmallestNormalized, MSmallestValue, "-0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },3176 { MSmallestNormalized, PSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },3177 { MSmallestNormalized, MSmallestNormalized, "-0x1p-125", APFloat::opOK, APFloat::fcNormal }3178 };3179 3180 for (size_t i = 0; i < std::size(SpecialCaseTests); ++i) {3181 APFloat x(SpecialCaseTests[i].x);3182 APFloat y(SpecialCaseTests[i].y);3183 APFloat::opStatus status = x.add(y, APFloat::rmNearestTiesToEven);3184 3185 APFloat result(APFloat::IEEEsingle(), SpecialCaseTests[i].result);3186 3187 EXPECT_TRUE(result.bitwiseIsEqual(x));3188 EXPECT_EQ(SpecialCaseTests[i].status, (int)status);3189 EXPECT_EQ(SpecialCaseTests[i].category, (int)x.getCategory());3190 }3191}3192 3193TEST(APFloatTest, subtract) {3194 // Test Special Cases against each other and normal values.3195 3196 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle(), false);3197 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle(), true);3198 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle(), false);3199 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle(), true);3200 APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);3201 APFloat SNaN = APFloat(APFloat::IEEEsingle(), "snan123");3202 APFloat PNormalValue = APFloat(APFloat::IEEEsingle(), "0x1p+0");3203 APFloat MNormalValue = APFloat(APFloat::IEEEsingle(), "-0x1p+0");3204 APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), false);3205 APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), true);3206 APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), false);3207 APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), true);3208 APFloat PSmallestNormalized =3209 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);3210 APFloat MSmallestNormalized =3211 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);3212 3213 const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact;3214 3215 struct {3216 APFloat x;3217 APFloat y;3218 const char *result;3219 int status;3220 int category;3221 } SpecialCaseTests[] = {3222 { PInf, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },3223 { PInf, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },3224 { PInf, PZero, "inf", APFloat::opOK, APFloat::fcInfinity },3225 { PInf, MZero, "inf", APFloat::opOK, APFloat::fcInfinity },3226 { PInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3227 { PInf, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3228 { PInf, PNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },3229 { PInf, MNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },3230 { PInf, PLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },3231 { PInf, MLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },3232 { PInf, PSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },3233 { PInf, MSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },3234 { PInf, PSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },3235 { PInf, MSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },3236 { MInf, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3237 { MInf, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },3238 { MInf, PZero, "-inf", APFloat::opOK, APFloat::fcInfinity },3239 { MInf, MZero, "-inf", APFloat::opOK, APFloat::fcInfinity },3240 { MInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3241 { MInf, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3242 { MInf, PNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },3243 { MInf, MNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },3244 { MInf, PLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },3245 { MInf, MLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },3246 { MInf, PSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },3247 { MInf, MSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },3248 { MInf, PSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },3249 { MInf, MSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },3250 { PZero, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3251 { PZero, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },3252 { PZero, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },3253 { PZero, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },3254 { PZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3255 { PZero, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3256 { PZero, PNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },3257 { PZero, MNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },3258 { PZero, PLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },3259 { PZero, MLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },3260 { PZero, PSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },3261 { PZero, MSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },3262 { PZero, PSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },3263 { PZero, MSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },3264 { MZero, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3265 { MZero, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },3266 { MZero, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3267 { MZero, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },3268 { MZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3269 { MZero, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3270 { MZero, PNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },3271 { MZero, MNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },3272 { MZero, PLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },3273 { MZero, MLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },3274 { MZero, PSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },3275 { MZero, MSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },3276 { MZero, PSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },3277 { MZero, MSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },3278 { QNaN, PInf, "nan", APFloat::opOK, APFloat::fcNaN },3279 { QNaN, MInf, "nan", APFloat::opOK, APFloat::fcNaN },3280 { QNaN, PZero, "nan", APFloat::opOK, APFloat::fcNaN },3281 { QNaN, MZero, "nan", APFloat::opOK, APFloat::fcNaN },3282 { QNaN, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3283 { QNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },3284 { QNaN, PNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },3285 { QNaN, MNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },3286 { QNaN, PLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },3287 { QNaN, MLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },3288 { QNaN, PSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },3289 { QNaN, MSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },3290 { QNaN, PSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },3291 { QNaN, MSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },3292 { SNaN, PInf, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3293 { SNaN, MInf, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3294 { SNaN, PZero, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3295 { SNaN, MZero, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3296 { SNaN, QNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3297 { SNaN, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3298 { SNaN, PNormalValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3299 { SNaN, MNormalValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3300 { SNaN, PLargestValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3301 { SNaN, MLargestValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3302 { SNaN, PSmallestValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3303 { SNaN, MSmallestValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3304 { SNaN, PSmallestNormalized, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3305 { SNaN, MSmallestNormalized, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3306 { PNormalValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3307 { PNormalValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },3308 { PNormalValue, PZero, "0x1p+0", APFloat::opOK, APFloat::fcNormal },3309 { PNormalValue, MZero, "0x1p+0", APFloat::opOK, APFloat::fcNormal },3310 { PNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3311 { PNormalValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3312 { PNormalValue, PNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },3313 { PNormalValue, MNormalValue, "0x1p+1", APFloat::opOK, APFloat::fcNormal },3314 { PNormalValue, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3315 { PNormalValue, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3316 { PNormalValue, PSmallestValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },3317 { PNormalValue, MSmallestValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },3318 { PNormalValue, PSmallestNormalized, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },3319 { PNormalValue, MSmallestNormalized, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },3320 { MNormalValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3321 { MNormalValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },3322 { MNormalValue, PZero, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },3323 { MNormalValue, MZero, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },3324 { MNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3325 { MNormalValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3326 { MNormalValue, PNormalValue, "-0x1p+1", APFloat::opOK, APFloat::fcNormal },3327 { MNormalValue, MNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },3328 { MNormalValue, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3329 { MNormalValue, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3330 { MNormalValue, PSmallestValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },3331 { MNormalValue, MSmallestValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },3332 { MNormalValue, PSmallestNormalized, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },3333 { MNormalValue, MSmallestNormalized, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },3334 { PLargestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3335 { PLargestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },3336 { PLargestValue, PZero, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },3337 { PLargestValue, MZero, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },3338 { PLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3339 { PLargestValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3340 { PLargestValue, PNormalValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3341 { PLargestValue, MNormalValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3342 { PLargestValue, PLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },3343 { PLargestValue, MLargestValue, "inf", OverflowStatus, APFloat::fcInfinity },3344 { PLargestValue, PSmallestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3345 { PLargestValue, MSmallestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3346 { PLargestValue, PSmallestNormalized, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3347 { PLargestValue, MSmallestNormalized, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3348 { MLargestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3349 { MLargestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },3350 { MLargestValue, PZero, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },3351 { MLargestValue, MZero, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },3352 { MLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3353 { MLargestValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3354 { MLargestValue, PNormalValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3355 { MLargestValue, MNormalValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3356 { MLargestValue, PLargestValue, "-inf", OverflowStatus, APFloat::fcInfinity },3357 { MLargestValue, MLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },3358 { MLargestValue, PSmallestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3359 { MLargestValue, MSmallestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3360 { MLargestValue, PSmallestNormalized, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3361 { MLargestValue, MSmallestNormalized, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3362 { PSmallestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3363 { PSmallestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },3364 { PSmallestValue, PZero, "0x1p-149", APFloat::opOK, APFloat::fcNormal },3365 { PSmallestValue, MZero, "0x1p-149", APFloat::opOK, APFloat::fcNormal },3366 { PSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3367 { PSmallestValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3368 { PSmallestValue, PNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },3369 { PSmallestValue, MNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },3370 { PSmallestValue, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3371 { PSmallestValue, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3372 { PSmallestValue, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },3373 { PSmallestValue, MSmallestValue, "0x1p-148", APFloat::opOK, APFloat::fcNormal },3374 { PSmallestValue, PSmallestNormalized, "-0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },3375 { PSmallestValue, MSmallestNormalized, "0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },3376 { MSmallestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3377 { MSmallestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },3378 { MSmallestValue, PZero, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },3379 { MSmallestValue, MZero, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },3380 { MSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3381 { MSmallestValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3382 { MSmallestValue, PNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },3383 { MSmallestValue, MNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },3384 { MSmallestValue, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3385 { MSmallestValue, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3386 { MSmallestValue, PSmallestValue, "-0x1p-148", APFloat::opOK, APFloat::fcNormal },3387 { MSmallestValue, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },3388 { MSmallestValue, PSmallestNormalized, "-0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },3389 { MSmallestValue, MSmallestNormalized, "0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },3390 { PSmallestNormalized, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3391 { PSmallestNormalized, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },3392 { PSmallestNormalized, PZero, "0x1p-126", APFloat::opOK, APFloat::fcNormal },3393 { PSmallestNormalized, MZero, "0x1p-126", APFloat::opOK, APFloat::fcNormal },3394 { PSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3395 { PSmallestNormalized, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3396 { PSmallestNormalized, PNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },3397 { PSmallestNormalized, MNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },3398 { PSmallestNormalized, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3399 { PSmallestNormalized, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3400 { PSmallestNormalized, PSmallestValue, "0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },3401 { PSmallestNormalized, MSmallestValue, "0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },3402 { PSmallestNormalized, PSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },3403 { PSmallestNormalized, MSmallestNormalized, "0x1p-125", APFloat::opOK, APFloat::fcNormal },3404 { MSmallestNormalized, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3405 { MSmallestNormalized, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },3406 { MSmallestNormalized, PZero, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },3407 { MSmallestNormalized, MZero, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },3408 { MSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3409 { MSmallestNormalized, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3410 { MSmallestNormalized, PNormalValue, "-0x1p+0", APFloat::opInexact, APFloat::fcNormal },3411 { MSmallestNormalized, MNormalValue, "0x1p+0", APFloat::opInexact, APFloat::fcNormal },3412 { MSmallestNormalized, PLargestValue, "-0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3413 { MSmallestNormalized, MLargestValue, "0x1.fffffep+127", APFloat::opInexact, APFloat::fcNormal },3414 { MSmallestNormalized, PSmallestValue, "-0x1.000002p-126", APFloat::opOK, APFloat::fcNormal },3415 { MSmallestNormalized, MSmallestValue, "-0x1.fffffcp-127", APFloat::opOK, APFloat::fcNormal },3416 { MSmallestNormalized, PSmallestNormalized, "-0x1p-125", APFloat::opOK, APFloat::fcNormal },3417 { MSmallestNormalized, MSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero }3418 };3419 3420 for (size_t i = 0; i < std::size(SpecialCaseTests); ++i) {3421 APFloat x(SpecialCaseTests[i].x);3422 APFloat y(SpecialCaseTests[i].y);3423 APFloat::opStatus status = x.subtract(y, APFloat::rmNearestTiesToEven);3424 3425 APFloat result(APFloat::IEEEsingle(), SpecialCaseTests[i].result);3426 3427 EXPECT_TRUE(result.bitwiseIsEqual(x));3428 EXPECT_EQ(SpecialCaseTests[i].status, (int)status);3429 EXPECT_EQ(SpecialCaseTests[i].category, (int)x.getCategory());3430 }3431}3432 3433TEST(APFloatTest, multiply) {3434 // Test Special Cases against each other and normal values.3435 3436 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle(), false);3437 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle(), true);3438 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle(), false);3439 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle(), true);3440 APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);3441 APFloat SNaN = APFloat(APFloat::IEEEsingle(), "snan123");3442 APFloat PNormalValue = APFloat(APFloat::IEEEsingle(), "0x1p+0");3443 APFloat MNormalValue = APFloat(APFloat::IEEEsingle(), "-0x1p+0");3444 APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), false);3445 APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), true);3446 APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), false);3447 APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), true);3448 APFloat PSmallestNormalized =3449 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);3450 APFloat MSmallestNormalized =3451 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);3452 3453 APFloat MaxQuad(APFloat::IEEEquad(),3454 "0x1.ffffffffffffffffffffffffffffp+16383");3455 APFloat MinQuad(APFloat::IEEEquad(),3456 "0x0.0000000000000000000000000001p-16382");3457 APFloat NMinQuad(APFloat::IEEEquad(),3458 "-0x0.0000000000000000000000000001p-16382");3459 3460 const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact;3461 const int UnderflowStatus = APFloat::opUnderflow | APFloat::opInexact;3462 3463 struct {3464 APFloat x;3465 APFloat y;3466 const char *result;3467 int status;3468 int category;3469 APFloat::roundingMode roundingMode = APFloat::rmNearestTiesToEven;3470 } SpecialCaseTests[] = {3471 { PInf, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },3472 { PInf, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3473 { PInf, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },3474 { PInf, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },3475 { PInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3476 { PInf, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3477 { PInf, PNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },3478 { PInf, MNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },3479 { PInf, PLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },3480 { PInf, MLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },3481 { PInf, PSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },3482 { PInf, MSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },3483 { PInf, PSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },3484 { PInf, MSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },3485 { MInf, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3486 { MInf, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },3487 { MInf, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },3488 { MInf, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },3489 { MInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3490 { MInf, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3491 { MInf, PNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },3492 { MInf, MNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },3493 { MInf, PLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },3494 { MInf, MLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },3495 { MInf, PSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },3496 { MInf, MSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },3497 { MInf, PSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },3498 { MInf, MSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },3499 { PZero, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },3500 { PZero, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },3501 { PZero, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },3502 { PZero, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3503 { PZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3504 { PZero, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3505 { PZero, PNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },3506 { PZero, MNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3507 { PZero, PLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },3508 { PZero, MLargestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3509 { PZero, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },3510 { PZero, MSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3511 { PZero, PSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },3512 { PZero, MSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3513 { MZero, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },3514 { MZero, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },3515 { MZero, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3516 { MZero, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },3517 { MZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3518 { MZero, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3519 { MZero, PNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3520 { MZero, MNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },3521 { MZero, PLargestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3522 { MZero, MLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },3523 { MZero, PSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3524 { MZero, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },3525 { MZero, PSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3526 { MZero, MSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },3527 { QNaN, PInf, "nan", APFloat::opOK, APFloat::fcNaN },3528 { QNaN, MInf, "nan", APFloat::opOK, APFloat::fcNaN },3529 { QNaN, PZero, "nan", APFloat::opOK, APFloat::fcNaN },3530 { QNaN, MZero, "nan", APFloat::opOK, APFloat::fcNaN },3531 { QNaN, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3532 { QNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },3533 { QNaN, PNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },3534 { QNaN, MNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },3535 { QNaN, PLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },3536 { QNaN, MLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },3537 { QNaN, PSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },3538 { QNaN, MSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },3539 { QNaN, PSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },3540 { QNaN, MSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },3541 { SNaN, PInf, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3542 { SNaN, MInf, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3543 { SNaN, PZero, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3544 { SNaN, MZero, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3545 { SNaN, QNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3546 { SNaN, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3547 { SNaN, PNormalValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3548 { SNaN, MNormalValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3549 { SNaN, PLargestValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3550 { SNaN, MLargestValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3551 { SNaN, PSmallestValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3552 { SNaN, MSmallestValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3553 { SNaN, PSmallestNormalized, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3554 { SNaN, MSmallestNormalized, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3555 { PNormalValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },3556 { PNormalValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3557 { PNormalValue, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },3558 { PNormalValue, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3559 { PNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3560 { PNormalValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3561 { PNormalValue, PNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },3562 { PNormalValue, MNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },3563 { PNormalValue, PLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },3564 { PNormalValue, MLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },3565 { PNormalValue, PSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },3566 { PNormalValue, MSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },3567 { PNormalValue, PSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },3568 { PNormalValue, MSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },3569 { MNormalValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3570 { MNormalValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },3571 { MNormalValue, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3572 { MNormalValue, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },3573 { MNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3574 { MNormalValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3575 { MNormalValue, PNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },3576 { MNormalValue, MNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },3577 { MNormalValue, PLargestValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },3578 { MNormalValue, MLargestValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },3579 { MNormalValue, PSmallestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },3580 { MNormalValue, MSmallestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },3581 { MNormalValue, PSmallestNormalized, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },3582 { MNormalValue, MSmallestNormalized, "0x1p-126", APFloat::opOK, APFloat::fcNormal },3583 { PLargestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },3584 { PLargestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3585 { PLargestValue, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },3586 { PLargestValue, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3587 { PLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3588 { PLargestValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3589 { PLargestValue, PNormalValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },3590 { PLargestValue, MNormalValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },3591 { PLargestValue, PLargestValue, "inf", OverflowStatus, APFloat::fcInfinity },3592 { PLargestValue, MLargestValue, "-inf", OverflowStatus, APFloat::fcInfinity },3593 { PLargestValue, PSmallestValue, "0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },3594 { PLargestValue, MSmallestValue, "-0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },3595 { PLargestValue, PSmallestNormalized, "0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },3596 { PLargestValue, MSmallestNormalized, "-0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },3597 { MLargestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3598 { MLargestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },3599 { MLargestValue, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3600 { MLargestValue, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },3601 { MLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3602 { MLargestValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3603 { MLargestValue, PNormalValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },3604 { MLargestValue, MNormalValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },3605 { MLargestValue, PLargestValue, "-inf", OverflowStatus, APFloat::fcInfinity },3606 { MLargestValue, MLargestValue, "inf", OverflowStatus, APFloat::fcInfinity },3607 { MLargestValue, PSmallestValue, "-0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },3608 { MLargestValue, MSmallestValue, "0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },3609 { MLargestValue, PSmallestNormalized, "-0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },3610 { MLargestValue, MSmallestNormalized, "0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },3611 { PSmallestValue, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },3612 { PSmallestValue, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3613 { PSmallestValue, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },3614 { PSmallestValue, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3615 { PSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3616 { PSmallestValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3617 { PSmallestValue, PNormalValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },3618 { PSmallestValue, MNormalValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },3619 { PSmallestValue, PLargestValue, "0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },3620 { PSmallestValue, MLargestValue, "-0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },3621 { PSmallestValue, PSmallestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },3622 { PSmallestValue, MSmallestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },3623 { PSmallestValue, PSmallestNormalized, "0x0p+0", UnderflowStatus, APFloat::fcZero },3624 { PSmallestValue, MSmallestNormalized, "-0x0p+0", UnderflowStatus, APFloat::fcZero },3625 { MSmallestValue, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3626 { MSmallestValue, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },3627 { MSmallestValue, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3628 { MSmallestValue, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },3629 { MSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3630 { MSmallestValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3631 { MSmallestValue, PNormalValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },3632 { MSmallestValue, MNormalValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },3633 { MSmallestValue, PLargestValue, "-0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },3634 { MSmallestValue, MLargestValue, "0x1.fffffep-22", APFloat::opOK, APFloat::fcNormal },3635 { MSmallestValue, PSmallestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },3636 { MSmallestValue, MSmallestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },3637 { MSmallestValue, PSmallestNormalized, "-0x0p+0", UnderflowStatus, APFloat::fcZero },3638 { MSmallestValue, MSmallestNormalized, "0x0p+0", UnderflowStatus, APFloat::fcZero },3639 { PSmallestNormalized, PInf, "inf", APFloat::opOK, APFloat::fcInfinity },3640 { PSmallestNormalized, MInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3641 { PSmallestNormalized, PZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },3642 { PSmallestNormalized, MZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3643 { PSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3644 { PSmallestNormalized, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3645 { PSmallestNormalized, PNormalValue, "0x1p-126", APFloat::opOK, APFloat::fcNormal },3646 { PSmallestNormalized, MNormalValue, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },3647 { PSmallestNormalized, PLargestValue, "0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },3648 { PSmallestNormalized, MLargestValue, "-0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },3649 { PSmallestNormalized, PSmallestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },3650 { PSmallestNormalized, MSmallestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },3651 { PSmallestNormalized, PSmallestNormalized, "0x0p+0", UnderflowStatus, APFloat::fcZero },3652 { PSmallestNormalized, MSmallestNormalized, "-0x0p+0", UnderflowStatus, APFloat::fcZero },3653 { MSmallestNormalized, PInf, "-inf", APFloat::opOK, APFloat::fcInfinity },3654 { MSmallestNormalized, MInf, "inf", APFloat::opOK, APFloat::fcInfinity },3655 { MSmallestNormalized, PZero, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3656 { MSmallestNormalized, MZero, "0x0p+0", APFloat::opOK, APFloat::fcZero },3657 { MSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3658 { MSmallestNormalized, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3659 { MSmallestNormalized, PNormalValue, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },3660 { MSmallestNormalized, MNormalValue, "0x1p-126", APFloat::opOK, APFloat::fcNormal },3661 { MSmallestNormalized, PLargestValue, "-0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },3662 { MSmallestNormalized, MLargestValue, "0x1.fffffep+1", APFloat::opOK, APFloat::fcNormal },3663 { MSmallestNormalized, PSmallestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },3664 { MSmallestNormalized, MSmallestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },3665 { MSmallestNormalized, PSmallestNormalized, "-0x0p+0", UnderflowStatus, APFloat::fcZero },3666 { MSmallestNormalized, MSmallestNormalized, "0x0p+0", UnderflowStatus, APFloat::fcZero },3667 3668 {MaxQuad, MinQuad, "0x1.ffffffffffffffffffffffffffffp-111", APFloat::opOK,3669 APFloat::fcNormal, APFloat::rmNearestTiesToEven},3670 {MaxQuad, MinQuad, "0x1.ffffffffffffffffffffffffffffp-111", APFloat::opOK,3671 APFloat::fcNormal, APFloat::rmTowardPositive},3672 {MaxQuad, MinQuad, "0x1.ffffffffffffffffffffffffffffp-111", APFloat::opOK,3673 APFloat::fcNormal, APFloat::rmTowardNegative},3674 {MaxQuad, MinQuad, "0x1.ffffffffffffffffffffffffffffp-111", APFloat::opOK,3675 APFloat::fcNormal, APFloat::rmTowardZero},3676 {MaxQuad, MinQuad, "0x1.ffffffffffffffffffffffffffffp-111", APFloat::opOK,3677 APFloat::fcNormal, APFloat::rmNearestTiesToAway},3678 3679 {MaxQuad, NMinQuad, "-0x1.ffffffffffffffffffffffffffffp-111", APFloat::opOK,3680 APFloat::fcNormal, APFloat::rmNearestTiesToEven},3681 {MaxQuad, NMinQuad, "-0x1.ffffffffffffffffffffffffffffp-111", APFloat::opOK,3682 APFloat::fcNormal, APFloat::rmTowardPositive},3683 {MaxQuad, NMinQuad, "-0x1.ffffffffffffffffffffffffffffp-111", APFloat::opOK,3684 APFloat::fcNormal, APFloat::rmTowardNegative},3685 {MaxQuad, NMinQuad, "-0x1.ffffffffffffffffffffffffffffp-111", APFloat::opOK,3686 APFloat::fcNormal, APFloat::rmTowardZero},3687 {MaxQuad, NMinQuad, "-0x1.ffffffffffffffffffffffffffffp-111", APFloat::opOK,3688 APFloat::fcNormal, APFloat::rmNearestTiesToAway},3689 3690 {MaxQuad, MaxQuad, "inf", OverflowStatus, APFloat::fcInfinity,3691 APFloat::rmNearestTiesToEven},3692 {MaxQuad, MaxQuad, "inf", OverflowStatus, APFloat::fcInfinity,3693 APFloat::rmTowardPositive},3694 {MaxQuad, MaxQuad, "0x1.ffffffffffffffffffffffffffffp+16383",3695 APFloat::opInexact, APFloat::fcNormal, APFloat::rmTowardNegative},3696 {MaxQuad, MaxQuad, "0x1.ffffffffffffffffffffffffffffp+16383",3697 APFloat::opInexact, APFloat::fcNormal, APFloat::rmTowardZero},3698 {MaxQuad, MaxQuad, "inf", OverflowStatus, APFloat::fcInfinity,3699 APFloat::rmNearestTiesToAway},3700 3701 {MinQuad, MinQuad, "0", UnderflowStatus, APFloat::fcZero,3702 APFloat::rmNearestTiesToEven},3703 {MinQuad, MinQuad, "0x0.0000000000000000000000000001p-16382",3704 UnderflowStatus, APFloat::fcNormal, APFloat::rmTowardPositive},3705 {MinQuad, MinQuad, "0", UnderflowStatus, APFloat::fcZero,3706 APFloat::rmTowardNegative},3707 {MinQuad, MinQuad, "0", UnderflowStatus, APFloat::fcZero,3708 APFloat::rmTowardZero},3709 {MinQuad, MinQuad, "0", UnderflowStatus, APFloat::fcZero,3710 APFloat::rmNearestTiesToAway},3711 3712 {MinQuad, NMinQuad, "-0", UnderflowStatus, APFloat::fcZero,3713 APFloat::rmNearestTiesToEven},3714 {MinQuad, NMinQuad, "-0", UnderflowStatus, APFloat::fcZero,3715 APFloat::rmTowardPositive},3716 {MinQuad, NMinQuad, "-0x0.0000000000000000000000000001p-16382",3717 UnderflowStatus, APFloat::fcNormal, APFloat::rmTowardNegative},3718 {MinQuad, NMinQuad, "-0", UnderflowStatus, APFloat::fcZero,3719 APFloat::rmTowardZero},3720 {MinQuad, NMinQuad, "-0", UnderflowStatus, APFloat::fcZero,3721 APFloat::rmNearestTiesToAway},3722 };3723 3724 for (size_t i = 0; i < std::size(SpecialCaseTests); ++i) {3725 APFloat x(SpecialCaseTests[i].x);3726 APFloat y(SpecialCaseTests[i].y);3727 APFloat::opStatus status = x.multiply(y, SpecialCaseTests[i].roundingMode);3728 3729 APFloat result(x.getSemantics(), SpecialCaseTests[i].result);3730 3731 EXPECT_TRUE(result.bitwiseIsEqual(x));3732 EXPECT_EQ(SpecialCaseTests[i].status, (int)status);3733 EXPECT_EQ(SpecialCaseTests[i].category, (int)x.getCategory());3734 }3735}3736 3737TEST(APFloatTest, divide) {3738 // Test Special Cases against each other and normal values.3739 3740 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle(), false);3741 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle(), true);3742 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle(), false);3743 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle(), true);3744 APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);3745 APFloat SNaN = APFloat(APFloat::IEEEsingle(), "snan123");3746 APFloat PNormalValue = APFloat(APFloat::IEEEsingle(), "0x1p+0");3747 APFloat MNormalValue = APFloat(APFloat::IEEEsingle(), "-0x1p+0");3748 APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), false);3749 APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), true);3750 APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), false);3751 APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), true);3752 APFloat PSmallestNormalized =3753 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);3754 APFloat MSmallestNormalized =3755 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);3756 3757 APFloat MaxQuad(APFloat::IEEEquad(),3758 "0x1.ffffffffffffffffffffffffffffp+16383");3759 APFloat MinQuad(APFloat::IEEEquad(),3760 "0x0.0000000000000000000000000001p-16382");3761 APFloat NMinQuad(APFloat::IEEEquad(),3762 "-0x0.0000000000000000000000000001p-16382");3763 3764 const int OverflowStatus = APFloat::opOverflow | APFloat::opInexact;3765 const int UnderflowStatus = APFloat::opUnderflow | APFloat::opInexact;3766 3767 struct {3768 APFloat x;3769 APFloat y;3770 const char *result;3771 int status;3772 int category;3773 APFloat::roundingMode roundingMode = APFloat::rmNearestTiesToEven;3774 } SpecialCaseTests[] = {3775 { PInf, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },3776 { PInf, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },3777 { PInf, PZero, "inf", APFloat::opOK, APFloat::fcInfinity },3778 { PInf, MZero, "-inf", APFloat::opOK, APFloat::fcInfinity },3779 { PInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3780 { PInf, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3781 { PInf, PNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },3782 { PInf, MNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },3783 { PInf, PLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },3784 { PInf, MLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },3785 { PInf, PSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },3786 { PInf, MSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },3787 { PInf, PSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },3788 { PInf, MSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },3789 { MInf, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },3790 { MInf, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },3791 { MInf, PZero, "-inf", APFloat::opOK, APFloat::fcInfinity },3792 { MInf, MZero, "inf", APFloat::opOK, APFloat::fcInfinity },3793 { MInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3794 { MInf, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3795 { MInf, PNormalValue, "-inf", APFloat::opOK, APFloat::fcInfinity },3796 { MInf, MNormalValue, "inf", APFloat::opOK, APFloat::fcInfinity },3797 { MInf, PLargestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },3798 { MInf, MLargestValue, "inf", APFloat::opOK, APFloat::fcInfinity },3799 { MInf, PSmallestValue, "-inf", APFloat::opOK, APFloat::fcInfinity },3800 { MInf, MSmallestValue, "inf", APFloat::opOK, APFloat::fcInfinity },3801 { MInf, PSmallestNormalized, "-inf", APFloat::opOK, APFloat::fcInfinity },3802 { MInf, MSmallestNormalized, "inf", APFloat::opOK, APFloat::fcInfinity },3803 { PZero, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },3804 { PZero, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3805 { PZero, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },3806 { PZero, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },3807 { PZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3808 { PZero, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3809 { PZero, PNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },3810 { PZero, MNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3811 { PZero, PLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },3812 { PZero, MLargestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3813 { PZero, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },3814 { PZero, MSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3815 { PZero, PSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },3816 { PZero, MSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3817 { MZero, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3818 { MZero, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },3819 { MZero, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },3820 { MZero, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },3821 { MZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3822 { MZero, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3823 { MZero, PNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3824 { MZero, MNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },3825 { MZero, PLargestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3826 { MZero, MLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },3827 { MZero, PSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3828 { MZero, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },3829 { MZero, PSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3830 { MZero, MSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },3831 { QNaN, PInf, "nan", APFloat::opOK, APFloat::fcNaN },3832 { QNaN, MInf, "nan", APFloat::opOK, APFloat::fcNaN },3833 { QNaN, PZero, "nan", APFloat::opOK, APFloat::fcNaN },3834 { QNaN, MZero, "nan", APFloat::opOK, APFloat::fcNaN },3835 { QNaN, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3836 { QNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },3837 { QNaN, PNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },3838 { QNaN, MNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },3839 { QNaN, PLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },3840 { QNaN, MLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },3841 { QNaN, PSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },3842 { QNaN, MSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },3843 { QNaN, PSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },3844 { QNaN, MSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },3845 { SNaN, PInf, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3846 { SNaN, MInf, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3847 { SNaN, PZero, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3848 { SNaN, MZero, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3849 { SNaN, QNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3850 { SNaN, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3851 { SNaN, PNormalValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3852 { SNaN, MNormalValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3853 { SNaN, PLargestValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3854 { SNaN, MLargestValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3855 { SNaN, PSmallestValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3856 { SNaN, MSmallestValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3857 { SNaN, PSmallestNormalized, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3858 { SNaN, MSmallestNormalized, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3859 { PNormalValue, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },3860 { PNormalValue, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3861 { PNormalValue, PZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },3862 { PNormalValue, MZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },3863 { PNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3864 { PNormalValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3865 { PNormalValue, PNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },3866 { PNormalValue, MNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },3867 { PNormalValue, PLargestValue, "0x1p-128", UnderflowStatus, APFloat::fcNormal },3868 { PNormalValue, MLargestValue, "-0x1p-128", UnderflowStatus, APFloat::fcNormal },3869 { PNormalValue, PSmallestValue, "inf", OverflowStatus, APFloat::fcInfinity },3870 { PNormalValue, MSmallestValue, "-inf", OverflowStatus, APFloat::fcInfinity },3871 { PNormalValue, PSmallestNormalized, "0x1p+126", APFloat::opOK, APFloat::fcNormal },3872 { PNormalValue, MSmallestNormalized, "-0x1p+126", APFloat::opOK, APFloat::fcNormal },3873 { MNormalValue, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3874 { MNormalValue, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },3875 { MNormalValue, PZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },3876 { MNormalValue, MZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },3877 { MNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3878 { MNormalValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3879 { MNormalValue, PNormalValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },3880 { MNormalValue, MNormalValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },3881 { MNormalValue, PLargestValue, "-0x1p-128", UnderflowStatus, APFloat::fcNormal },3882 { MNormalValue, MLargestValue, "0x1p-128", UnderflowStatus, APFloat::fcNormal },3883 { MNormalValue, PSmallestValue, "-inf", OverflowStatus, APFloat::fcInfinity },3884 { MNormalValue, MSmallestValue, "inf", OverflowStatus, APFloat::fcInfinity },3885 { MNormalValue, PSmallestNormalized, "-0x1p+126", APFloat::opOK, APFloat::fcNormal },3886 { MNormalValue, MSmallestNormalized, "0x1p+126", APFloat::opOK, APFloat::fcNormal },3887 { PLargestValue, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },3888 { PLargestValue, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3889 { PLargestValue, PZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },3890 { PLargestValue, MZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },3891 { PLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3892 { PLargestValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3893 { PLargestValue, PNormalValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },3894 { PLargestValue, MNormalValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },3895 { PLargestValue, PLargestValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },3896 { PLargestValue, MLargestValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },3897 { PLargestValue, PSmallestValue, "inf", OverflowStatus, APFloat::fcInfinity },3898 { PLargestValue, MSmallestValue, "-inf", OverflowStatus, APFloat::fcInfinity },3899 { PLargestValue, PSmallestNormalized, "inf", OverflowStatus, APFloat::fcInfinity },3900 { PLargestValue, MSmallestNormalized, "-inf", OverflowStatus, APFloat::fcInfinity },3901 { MLargestValue, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3902 { MLargestValue, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },3903 { MLargestValue, PZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },3904 { MLargestValue, MZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },3905 { MLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3906 { MLargestValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3907 { MLargestValue, PNormalValue, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },3908 { MLargestValue, MNormalValue, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },3909 { MLargestValue, PLargestValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },3910 { MLargestValue, MLargestValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },3911 { MLargestValue, PSmallestValue, "-inf", OverflowStatus, APFloat::fcInfinity },3912 { MLargestValue, MSmallestValue, "inf", OverflowStatus, APFloat::fcInfinity },3913 { MLargestValue, PSmallestNormalized, "-inf", OverflowStatus, APFloat::fcInfinity },3914 { MLargestValue, MSmallestNormalized, "inf", OverflowStatus, APFloat::fcInfinity },3915 { PSmallestValue, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },3916 { PSmallestValue, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3917 { PSmallestValue, PZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },3918 { PSmallestValue, MZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },3919 { PSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3920 { PSmallestValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3921 { PSmallestValue, PNormalValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },3922 { PSmallestValue, MNormalValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },3923 { PSmallestValue, PLargestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },3924 { PSmallestValue, MLargestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },3925 { PSmallestValue, PSmallestValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },3926 { PSmallestValue, MSmallestValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },3927 { PSmallestValue, PSmallestNormalized, "0x1p-23", APFloat::opOK, APFloat::fcNormal },3928 { PSmallestValue, MSmallestNormalized, "-0x1p-23", APFloat::opOK, APFloat::fcNormal },3929 { MSmallestValue, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3930 { MSmallestValue, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },3931 { MSmallestValue, PZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },3932 { MSmallestValue, MZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },3933 { MSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3934 { MSmallestValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3935 { MSmallestValue, PNormalValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },3936 { MSmallestValue, MNormalValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },3937 { MSmallestValue, PLargestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },3938 { MSmallestValue, MLargestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },3939 { MSmallestValue, PSmallestValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },3940 { MSmallestValue, MSmallestValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },3941 { MSmallestValue, PSmallestNormalized, "-0x1p-23", APFloat::opOK, APFloat::fcNormal },3942 { MSmallestValue, MSmallestNormalized, "0x1p-23", APFloat::opOK, APFloat::fcNormal },3943 { PSmallestNormalized, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },3944 { PSmallestNormalized, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3945 { PSmallestNormalized, PZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },3946 { PSmallestNormalized, MZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },3947 { PSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3948 { PSmallestNormalized, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3949 { PSmallestNormalized, PNormalValue, "0x1p-126", APFloat::opOK, APFloat::fcNormal },3950 { PSmallestNormalized, MNormalValue, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },3951 { PSmallestNormalized, PLargestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },3952 { PSmallestNormalized, MLargestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },3953 { PSmallestNormalized, PSmallestValue, "0x1p+23", APFloat::opOK, APFloat::fcNormal },3954 { PSmallestNormalized, MSmallestValue, "-0x1p+23", APFloat::opOK, APFloat::fcNormal },3955 { PSmallestNormalized, PSmallestNormalized, "0x1p+0", APFloat::opOK, APFloat::fcNormal },3956 { PSmallestNormalized, MSmallestNormalized, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },3957 { MSmallestNormalized, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },3958 { MSmallestNormalized, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },3959 { MSmallestNormalized, PZero, "-inf", APFloat::opDivByZero, APFloat::fcInfinity },3960 { MSmallestNormalized, MZero, "inf", APFloat::opDivByZero, APFloat::fcInfinity },3961 { MSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },3962 { MSmallestNormalized, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },3963 { MSmallestNormalized, PNormalValue, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },3964 { MSmallestNormalized, MNormalValue, "0x1p-126", APFloat::opOK, APFloat::fcNormal },3965 { MSmallestNormalized, PLargestValue, "-0x0p+0", UnderflowStatus, APFloat::fcZero },3966 { MSmallestNormalized, MLargestValue, "0x0p+0", UnderflowStatus, APFloat::fcZero },3967 { MSmallestNormalized, PSmallestValue, "-0x1p+23", APFloat::opOK, APFloat::fcNormal },3968 { MSmallestNormalized, MSmallestValue, "0x1p+23", APFloat::opOK, APFloat::fcNormal },3969 { MSmallestNormalized, PSmallestNormalized, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },3970 { MSmallestNormalized, MSmallestNormalized, "0x1p+0", APFloat::opOK, APFloat::fcNormal },3971 3972 {MaxQuad, NMinQuad, "-inf", OverflowStatus, APFloat::fcInfinity,3973 APFloat::rmNearestTiesToEven},3974 {MaxQuad, NMinQuad, "-0x1.ffffffffffffffffffffffffffffp+16383",3975 APFloat::opInexact, APFloat::fcNormal, APFloat::rmTowardPositive},3976 {MaxQuad, NMinQuad, "-inf", OverflowStatus, APFloat::fcInfinity,3977 APFloat::rmTowardNegative},3978 {MaxQuad, NMinQuad, "-0x1.ffffffffffffffffffffffffffffp+16383",3979 APFloat::opInexact, APFloat::fcNormal, APFloat::rmTowardZero},3980 {MaxQuad, NMinQuad, "-inf", OverflowStatus, APFloat::fcInfinity,3981 APFloat::rmNearestTiesToAway},3982 3983 {MinQuad, MaxQuad, "0", UnderflowStatus, APFloat::fcZero,3984 APFloat::rmNearestTiesToEven},3985 {MinQuad, MaxQuad, "0x0.0000000000000000000000000001p-16382",3986 UnderflowStatus, APFloat::fcNormal, APFloat::rmTowardPositive},3987 {MinQuad, MaxQuad, "0", UnderflowStatus, APFloat::fcZero,3988 APFloat::rmTowardNegative},3989 {MinQuad, MaxQuad, "0", UnderflowStatus, APFloat::fcZero,3990 APFloat::rmTowardZero},3991 {MinQuad, MaxQuad, "0", UnderflowStatus, APFloat::fcZero,3992 APFloat::rmNearestTiesToAway},3993 3994 {NMinQuad, MaxQuad, "-0", UnderflowStatus, APFloat::fcZero,3995 APFloat::rmNearestTiesToEven},3996 {NMinQuad, MaxQuad, "-0", UnderflowStatus, APFloat::fcZero,3997 APFloat::rmTowardPositive},3998 {NMinQuad, MaxQuad, "-0x0.0000000000000000000000000001p-16382",3999 UnderflowStatus, APFloat::fcNormal, APFloat::rmTowardNegative},4000 {NMinQuad, MaxQuad, "-0", UnderflowStatus, APFloat::fcZero,4001 APFloat::rmTowardZero},4002 {NMinQuad, MaxQuad, "-0", UnderflowStatus, APFloat::fcZero,4003 APFloat::rmNearestTiesToAway},4004 };4005 4006 for (size_t i = 0; i < std::size(SpecialCaseTests); ++i) {4007 APFloat x(SpecialCaseTests[i].x);4008 APFloat y(SpecialCaseTests[i].y);4009 APFloat::opStatus status = x.divide(y, SpecialCaseTests[i].roundingMode);4010 4011 APFloat result(x.getSemantics(), SpecialCaseTests[i].result);4012 4013 EXPECT_TRUE(result.bitwiseIsEqual(x));4014 EXPECT_EQ(SpecialCaseTests[i].status, (int)status);4015 EXPECT_EQ(SpecialCaseTests[i].category, (int)x.getCategory());4016 }4017}4018 4019TEST(APFloatTest, operatorOverloads) {4020 // This is mostly testing that these operator overloads compile.4021 APFloat One = APFloat(APFloat::IEEEsingle(), "0x1p+0");4022 APFloat Two = APFloat(APFloat::IEEEsingle(), "0x2p+0");4023 EXPECT_TRUE(Two.bitwiseIsEqual(One + One));4024 EXPECT_TRUE(One.bitwiseIsEqual(Two - One));4025 EXPECT_TRUE(Two.bitwiseIsEqual(One * Two));4026 EXPECT_TRUE(One.bitwiseIsEqual(Two / Two));4027}4028 4029TEST(APFloatTest, Comparisons) {4030 enum {MNan, MInf, MBig, MOne, MZer, PZer, POne, PBig, PInf, PNan, NumVals};4031 APFloat Vals[NumVals] = {4032 APFloat::getNaN(APFloat::IEEEsingle(), true),4033 APFloat::getInf(APFloat::IEEEsingle(), true),4034 APFloat::getLargest(APFloat::IEEEsingle(), true),4035 APFloat(APFloat::IEEEsingle(), "-0x1p+0"),4036 APFloat::getZero(APFloat::IEEEsingle(), true),4037 APFloat::getZero(APFloat::IEEEsingle(), false),4038 APFloat(APFloat::IEEEsingle(), "0x1p+0"),4039 APFloat::getLargest(APFloat::IEEEsingle(), false),4040 APFloat::getInf(APFloat::IEEEsingle(), false),4041 APFloat::getNaN(APFloat::IEEEsingle(), false),4042 };4043 using Relation = void (*)(const APFloat &, const APFloat &);4044 Relation LT = [](const APFloat &LHS, const APFloat &RHS) {4045 EXPECT_FALSE(LHS == RHS);4046 EXPECT_TRUE(LHS != RHS);4047 EXPECT_TRUE(LHS < RHS);4048 EXPECT_FALSE(LHS > RHS);4049 EXPECT_TRUE(LHS <= RHS);4050 EXPECT_FALSE(LHS >= RHS);4051 };4052 Relation EQ = [](const APFloat &LHS, const APFloat &RHS) {4053 EXPECT_TRUE(LHS == RHS);4054 EXPECT_FALSE(LHS != RHS);4055 EXPECT_FALSE(LHS < RHS);4056 EXPECT_FALSE(LHS > RHS);4057 EXPECT_TRUE(LHS <= RHS);4058 EXPECT_TRUE(LHS >= RHS);4059 };4060 Relation GT = [](const APFloat &LHS, const APFloat &RHS) {4061 EXPECT_FALSE(LHS == RHS);4062 EXPECT_TRUE(LHS != RHS);4063 EXPECT_FALSE(LHS < RHS);4064 EXPECT_TRUE(LHS > RHS);4065 EXPECT_FALSE(LHS <= RHS);4066 EXPECT_TRUE(LHS >= RHS);4067 };4068 Relation UN = [](const APFloat &LHS, const APFloat &RHS) {4069 EXPECT_FALSE(LHS == RHS);4070 EXPECT_TRUE(LHS != RHS);4071 EXPECT_FALSE(LHS < RHS);4072 EXPECT_FALSE(LHS > RHS);4073 EXPECT_FALSE(LHS <= RHS);4074 EXPECT_FALSE(LHS >= RHS);4075 };4076 Relation Relations[NumVals][NumVals] = {4077 // -N -I -B -1 -0 +0 +1 +B +I +N4078 /* MNan */ {UN, UN, UN, UN, UN, UN, UN, UN, UN, UN},4079 /* MInf */ {UN, EQ, LT, LT, LT, LT, LT, LT, LT, UN},4080 /* MBig */ {UN, GT, EQ, LT, LT, LT, LT, LT, LT, UN},4081 /* MOne */ {UN, GT, GT, EQ, LT, LT, LT, LT, LT, UN},4082 /* MZer */ {UN, GT, GT, GT, EQ, EQ, LT, LT, LT, UN},4083 /* PZer */ {UN, GT, GT, GT, EQ, EQ, LT, LT, LT, UN},4084 /* POne */ {UN, GT, GT, GT, GT, GT, EQ, LT, LT, UN},4085 /* PBig */ {UN, GT, GT, GT, GT, GT, GT, EQ, LT, UN},4086 /* PInf */ {UN, GT, GT, GT, GT, GT, GT, GT, EQ, UN},4087 /* PNan */ {UN, UN, UN, UN, UN, UN, UN, UN, UN, UN},4088 };4089 for (unsigned I = 0; I < NumVals; ++I)4090 for (unsigned J = 0; J < NumVals; ++J)4091 Relations[I][J](Vals[I], Vals[J]);4092}4093 4094TEST(APFloatTest, abs) {4095 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle(), false);4096 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle(), true);4097 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle(), false);4098 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle(), true);4099 APFloat PQNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);4100 APFloat MQNaN = APFloat::getNaN(APFloat::IEEEsingle(), true);4101 APFloat PSNaN = APFloat::getSNaN(APFloat::IEEEsingle(), false);4102 APFloat MSNaN = APFloat::getSNaN(APFloat::IEEEsingle(), true);4103 APFloat PNormalValue = APFloat(APFloat::IEEEsingle(), "0x1p+0");4104 APFloat MNormalValue = APFloat(APFloat::IEEEsingle(), "-0x1p+0");4105 APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), false);4106 APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), true);4107 APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), false);4108 APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), true);4109 APFloat PSmallestNormalized =4110 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);4111 APFloat MSmallestNormalized =4112 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);4113 4114 EXPECT_TRUE(PInf.bitwiseIsEqual(abs(PInf)));4115 EXPECT_TRUE(PInf.bitwiseIsEqual(abs(MInf)));4116 EXPECT_TRUE(PZero.bitwiseIsEqual(abs(PZero)));4117 EXPECT_TRUE(PZero.bitwiseIsEqual(abs(MZero)));4118 EXPECT_TRUE(PQNaN.bitwiseIsEqual(abs(PQNaN)));4119 EXPECT_TRUE(PQNaN.bitwiseIsEqual(abs(MQNaN)));4120 EXPECT_TRUE(PSNaN.bitwiseIsEqual(abs(PSNaN)));4121 EXPECT_TRUE(PSNaN.bitwiseIsEqual(abs(MSNaN)));4122 EXPECT_TRUE(PNormalValue.bitwiseIsEqual(abs(PNormalValue)));4123 EXPECT_TRUE(PNormalValue.bitwiseIsEqual(abs(MNormalValue)));4124 EXPECT_TRUE(PLargestValue.bitwiseIsEqual(abs(PLargestValue)));4125 EXPECT_TRUE(PLargestValue.bitwiseIsEqual(abs(MLargestValue)));4126 EXPECT_TRUE(PSmallestValue.bitwiseIsEqual(abs(PSmallestValue)));4127 EXPECT_TRUE(PSmallestValue.bitwiseIsEqual(abs(MSmallestValue)));4128 EXPECT_TRUE(PSmallestNormalized.bitwiseIsEqual(abs(PSmallestNormalized)));4129 EXPECT_TRUE(PSmallestNormalized.bitwiseIsEqual(abs(MSmallestNormalized)));4130}4131 4132TEST(APFloatTest, neg) {4133 APFloat One = APFloat(APFloat::IEEEsingle(), "1.0");4134 APFloat NegOne = APFloat(APFloat::IEEEsingle(), "-1.0");4135 APFloat Zero = APFloat::getZero(APFloat::IEEEsingle(), false);4136 APFloat NegZero = APFloat::getZero(APFloat::IEEEsingle(), true);4137 APFloat Inf = APFloat::getInf(APFloat::IEEEsingle(), false);4138 APFloat NegInf = APFloat::getInf(APFloat::IEEEsingle(), true);4139 APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);4140 APFloat NegQNaN = APFloat::getNaN(APFloat::IEEEsingle(), true);4141 4142 EXPECT_TRUE(NegOne.bitwiseIsEqual(neg(One)));4143 EXPECT_TRUE(One.bitwiseIsEqual(neg(NegOne)));4144 EXPECT_TRUE(NegZero.bitwiseIsEqual(neg(Zero)));4145 EXPECT_TRUE(Zero.bitwiseIsEqual(neg(NegZero)));4146 EXPECT_TRUE(NegInf.bitwiseIsEqual(neg(Inf)));4147 EXPECT_TRUE(Inf.bitwiseIsEqual(neg(NegInf)));4148 EXPECT_TRUE(NegInf.bitwiseIsEqual(neg(Inf)));4149 EXPECT_TRUE(Inf.bitwiseIsEqual(neg(NegInf)));4150 EXPECT_TRUE(NegQNaN.bitwiseIsEqual(neg(QNaN)));4151 EXPECT_TRUE(QNaN.bitwiseIsEqual(neg(NegQNaN)));4152 4153 EXPECT_TRUE(NegOne.bitwiseIsEqual(-One));4154 EXPECT_TRUE(One.bitwiseIsEqual(-NegOne));4155 EXPECT_TRUE(NegZero.bitwiseIsEqual(-Zero));4156 EXPECT_TRUE(Zero.bitwiseIsEqual(-NegZero));4157 EXPECT_TRUE(NegInf.bitwiseIsEqual(-Inf));4158 EXPECT_TRUE(Inf.bitwiseIsEqual(-NegInf));4159 EXPECT_TRUE(NegInf.bitwiseIsEqual(-Inf));4160 EXPECT_TRUE(Inf.bitwiseIsEqual(-NegInf));4161 EXPECT_TRUE(NegQNaN.bitwiseIsEqual(-QNaN));4162 EXPECT_TRUE(QNaN.bitwiseIsEqual(-NegQNaN));4163}4164 4165TEST(APFloatTest, ilogb) {4166 EXPECT_EQ(-1074, ilogb(APFloat::getSmallest(APFloat::IEEEdouble(), false)));4167 EXPECT_EQ(-1074, ilogb(APFloat::getSmallest(APFloat::IEEEdouble(), true)));4168 EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1024")));4169 EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1023")));4170 EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble(), "-0x1.ffffffffffffep-1023")));4171 EXPECT_EQ(-51, ilogb(APFloat(APFloat::IEEEdouble(), "0x1p-51")));4172 EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp-1023")));4173 EXPECT_EQ(-2, ilogb(APFloat(APFloat::IEEEdouble(), "0x0.ffffp-1")));4174 EXPECT_EQ(-1023, ilogb(APFloat(APFloat::IEEEdouble(), "0x1.fffep-1023")));4175 EXPECT_EQ(1023, ilogb(APFloat::getLargest(APFloat::IEEEdouble(), false)));4176 EXPECT_EQ(1023, ilogb(APFloat::getLargest(APFloat::IEEEdouble(), true)));4177 4178 4179 EXPECT_EQ(0, ilogb(APFloat(APFloat::IEEEsingle(), "0x1p+0")));4180 EXPECT_EQ(0, ilogb(APFloat(APFloat::IEEEsingle(), "-0x1p+0")));4181 EXPECT_EQ(42, ilogb(APFloat(APFloat::IEEEsingle(), "0x1p+42")));4182 EXPECT_EQ(-42, ilogb(APFloat(APFloat::IEEEsingle(), "0x1p-42")));4183 4184 EXPECT_EQ(APFloat::IEK_Inf,4185 ilogb(APFloat::getInf(APFloat::IEEEsingle(), false)));4186 EXPECT_EQ(APFloat::IEK_Inf,4187 ilogb(APFloat::getInf(APFloat::IEEEsingle(), true)));4188 EXPECT_EQ(APFloat::IEK_Zero,4189 ilogb(APFloat::getZero(APFloat::IEEEsingle(), false)));4190 EXPECT_EQ(APFloat::IEK_Zero,4191 ilogb(APFloat::getZero(APFloat::IEEEsingle(), true)));4192 EXPECT_EQ(APFloat::IEK_NaN,4193 ilogb(APFloat::getNaN(APFloat::IEEEsingle(), false)));4194 EXPECT_EQ(APFloat::IEK_NaN,4195 ilogb(APFloat::getSNaN(APFloat::IEEEsingle(), false)));4196 4197 EXPECT_EQ(127, ilogb(APFloat::getLargest(APFloat::IEEEsingle(), false)));4198 EXPECT_EQ(127, ilogb(APFloat::getLargest(APFloat::IEEEsingle(), true)));4199 4200 EXPECT_EQ(-149, ilogb(APFloat::getSmallest(APFloat::IEEEsingle(), false)));4201 EXPECT_EQ(-149, ilogb(APFloat::getSmallest(APFloat::IEEEsingle(), true)));4202 EXPECT_EQ(-126,4203 ilogb(APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false)));4204 EXPECT_EQ(-126,4205 ilogb(APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true)));4206}4207 4208TEST(APFloatTest, scalbn) {4209 4210 const APFloat::roundingMode RM = APFloat::rmNearestTiesToEven;4211 EXPECT_TRUE(4212 APFloat(APFloat::IEEEsingle(), "0x1p+0")4213 .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEsingle(), "0x1p+0"), 0, RM)));4214 EXPECT_TRUE(4215 APFloat(APFloat::IEEEsingle(), "0x1p+42")4216 .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEsingle(), "0x1p+0"), 42, RM)));4217 EXPECT_TRUE(4218 APFloat(APFloat::IEEEsingle(), "0x1p-42")4219 .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEsingle(), "0x1p+0"), -42, RM)));4220 4221 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle(), false);4222 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle(), true);4223 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle(), false);4224 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle(), true);4225 APFloat QPNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);4226 APFloat QMNaN = APFloat::getNaN(APFloat::IEEEsingle(), true);4227 APFloat SNaN = APFloat::getSNaN(APFloat::IEEEsingle(), false);4228 4229 EXPECT_TRUE(PInf.bitwiseIsEqual(scalbn(PInf, 0, RM)));4230 EXPECT_TRUE(MInf.bitwiseIsEqual(scalbn(MInf, 0, RM)));4231 EXPECT_TRUE(PZero.bitwiseIsEqual(scalbn(PZero, 0, RM)));4232 EXPECT_TRUE(MZero.bitwiseIsEqual(scalbn(MZero, 0, RM)));4233 EXPECT_TRUE(QPNaN.bitwiseIsEqual(scalbn(QPNaN, 0, RM)));4234 EXPECT_TRUE(QMNaN.bitwiseIsEqual(scalbn(QMNaN, 0, RM)));4235 EXPECT_FALSE(scalbn(SNaN, 0, RM).isSignaling());4236 4237 APFloat ScalbnSNaN = scalbn(SNaN, 1, RM);4238 EXPECT_TRUE(ScalbnSNaN.isNaN() && !ScalbnSNaN.isSignaling());4239 4240 // Make sure highest bit of payload is preserved.4241 const APInt Payload(64, (UINT64_C(1) << 50) |4242 (UINT64_C(1) << 49) |4243 (UINT64_C(1234) << 32) |4244 1);4245 4246 APFloat SNaNWithPayload = APFloat::getSNaN(APFloat::IEEEdouble(), false,4247 &Payload);4248 APFloat QuietPayload = scalbn(SNaNWithPayload, 1, RM);4249 EXPECT_TRUE(QuietPayload.isNaN() && !QuietPayload.isSignaling());4250 EXPECT_EQ(Payload, QuietPayload.bitcastToAPInt().getLoBits(51));4251 4252 EXPECT_TRUE(PInf.bitwiseIsEqual(4253 scalbn(APFloat(APFloat::IEEEsingle(), "0x1p+0"), 128, RM)));4254 EXPECT_TRUE(MInf.bitwiseIsEqual(4255 scalbn(APFloat(APFloat::IEEEsingle(), "-0x1p+0"), 128, RM)));4256 EXPECT_TRUE(PInf.bitwiseIsEqual(4257 scalbn(APFloat(APFloat::IEEEsingle(), "0x1p+127"), 1, RM)));4258 EXPECT_TRUE(PZero.bitwiseIsEqual(4259 scalbn(APFloat(APFloat::IEEEsingle(), "0x1p-127"), -127, RM)));4260 EXPECT_TRUE(MZero.bitwiseIsEqual(4261 scalbn(APFloat(APFloat::IEEEsingle(), "-0x1p-127"), -127, RM)));4262 EXPECT_TRUE(APFloat(APFloat::IEEEsingle(), "-0x1p-149").bitwiseIsEqual(4263 scalbn(APFloat(APFloat::IEEEsingle(), "-0x1p-127"), -22, RM)));4264 EXPECT_TRUE(PZero.bitwiseIsEqual(4265 scalbn(APFloat(APFloat::IEEEsingle(), "0x1p-126"), -24, RM)));4266 4267 4268 APFloat SmallestF64 = APFloat::getSmallest(APFloat::IEEEdouble(), false);4269 APFloat NegSmallestF64 = APFloat::getSmallest(APFloat::IEEEdouble(), true);4270 4271 APFloat LargestF64 = APFloat::getLargest(APFloat::IEEEdouble(), false);4272 APFloat NegLargestF64 = APFloat::getLargest(APFloat::IEEEdouble(), true);4273 4274 APFloat SmallestNormalizedF644275 = APFloat::getSmallestNormalized(APFloat::IEEEdouble(), false);4276 APFloat NegSmallestNormalizedF644277 = APFloat::getSmallestNormalized(APFloat::IEEEdouble(), true);4278 4279 APFloat LargestDenormalF64(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1023");4280 APFloat NegLargestDenormalF64(APFloat::IEEEdouble(), "-0x1.ffffffffffffep-1023");4281 4282 4283 EXPECT_TRUE(SmallestF64.bitwiseIsEqual(4284 scalbn(APFloat(APFloat::IEEEdouble(), "0x1p-1074"), 0, RM)));4285 EXPECT_TRUE(NegSmallestF64.bitwiseIsEqual(4286 scalbn(APFloat(APFloat::IEEEdouble(), "-0x1p-1074"), 0, RM)));4287 4288 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p+1023")4289 .bitwiseIsEqual(scalbn(SmallestF64, 2097, RM)));4290 4291 EXPECT_TRUE(scalbn(SmallestF64, -2097, RM).isPosZero());4292 EXPECT_TRUE(scalbn(SmallestF64, -2098, RM).isPosZero());4293 EXPECT_TRUE(scalbn(SmallestF64, -2099, RM).isPosZero());4294 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p+1022")4295 .bitwiseIsEqual(scalbn(SmallestF64, 2096, RM)));4296 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p+1023")4297 .bitwiseIsEqual(scalbn(SmallestF64, 2097, RM)));4298 EXPECT_TRUE(scalbn(SmallestF64, 2098, RM).isInfinity());4299 EXPECT_TRUE(scalbn(SmallestF64, 2099, RM).isInfinity());4300 4301 // Test for integer overflows when adding to exponent.4302 EXPECT_TRUE(scalbn(SmallestF64, -INT_MAX, RM).isPosZero());4303 EXPECT_TRUE(scalbn(LargestF64, INT_MAX, RM).isInfinity());4304 4305 EXPECT_TRUE(LargestDenormalF644306 .bitwiseIsEqual(scalbn(LargestDenormalF64, 0, RM)));4307 EXPECT_TRUE(NegLargestDenormalF644308 .bitwiseIsEqual(scalbn(NegLargestDenormalF64, 0, RM)));4309 4310 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1022")4311 .bitwiseIsEqual(scalbn(LargestDenormalF64, 1, RM)));4312 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1.ffffffffffffep-1021")4313 .bitwiseIsEqual(scalbn(NegLargestDenormalF64, 2, RM)));4314 4315 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep+1")4316 .bitwiseIsEqual(scalbn(LargestDenormalF64, 1024, RM)));4317 EXPECT_TRUE(scalbn(LargestDenormalF64, -1023, RM).isPosZero());4318 EXPECT_TRUE(scalbn(LargestDenormalF64, -1024, RM).isPosZero());4319 EXPECT_TRUE(scalbn(LargestDenormalF64, -2048, RM).isPosZero());4320 EXPECT_TRUE(scalbn(LargestDenormalF64, 2047, RM).isInfinity());4321 EXPECT_TRUE(scalbn(LargestDenormalF64, 2098, RM).isInfinity());4322 EXPECT_TRUE(scalbn(LargestDenormalF64, 2099, RM).isInfinity());4323 4324 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-2")4325 .bitwiseIsEqual(scalbn(LargestDenormalF64, 1021, RM)));4326 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1")4327 .bitwiseIsEqual(scalbn(LargestDenormalF64, 1022, RM)));4328 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep+0")4329 .bitwiseIsEqual(scalbn(LargestDenormalF64, 1023, RM)));4330 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep+1023")4331 .bitwiseIsEqual(scalbn(LargestDenormalF64, 2046, RM)));4332 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p+974")4333 .bitwiseIsEqual(scalbn(SmallestF64, 2048, RM)));4334 4335 APFloat RandomDenormalF64(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp+51");4336 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp-972")4337 .bitwiseIsEqual(scalbn(RandomDenormalF64, -1023, RM)));4338 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp-1")4339 .bitwiseIsEqual(scalbn(RandomDenormalF64, -52, RM)));4340 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp-2")4341 .bitwiseIsEqual(scalbn(RandomDenormalF64, -53, RM)));4342 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp+0")4343 .bitwiseIsEqual(scalbn(RandomDenormalF64, -51, RM)));4344 4345 EXPECT_TRUE(scalbn(RandomDenormalF64, -2097, RM).isPosZero());4346 EXPECT_TRUE(scalbn(RandomDenormalF64, -2090, RM).isPosZero());4347 4348 4349 EXPECT_TRUE(4350 APFloat(APFloat::IEEEdouble(), "-0x1p-1073")4351 .bitwiseIsEqual(scalbn(NegLargestF64, -2097, RM)));4352 4353 EXPECT_TRUE(4354 APFloat(APFloat::IEEEdouble(), "-0x1p-1024")4355 .bitwiseIsEqual(scalbn(NegLargestF64, -2048, RM)));4356 4357 EXPECT_TRUE(4358 APFloat(APFloat::IEEEdouble(), "0x1p-1073")4359 .bitwiseIsEqual(scalbn(LargestF64, -2097, RM)));4360 4361 EXPECT_TRUE(4362 APFloat(APFloat::IEEEdouble(), "0x1p-1074")4363 .bitwiseIsEqual(scalbn(LargestF64, -2098, RM)));4364 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1p-1074")4365 .bitwiseIsEqual(scalbn(NegLargestF64, -2098, RM)));4366 EXPECT_TRUE(scalbn(NegLargestF64, -2099, RM).isNegZero());4367 EXPECT_TRUE(scalbn(LargestF64, 1, RM).isInfinity());4368 4369 4370 EXPECT_TRUE(4371 APFloat(APFloat::IEEEdouble(), "0x1p+0")4372 .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEdouble(), "0x1p+52"), -52, RM)));4373 4374 EXPECT_TRUE(4375 APFloat(APFloat::IEEEdouble(), "0x1p-103")4376 .bitwiseIsEqual(scalbn(APFloat(APFloat::IEEEdouble(), "0x1p-51"), -52, RM)));4377}4378 4379TEST(APFloatTest, frexp) {4380 const APFloat::roundingMode RM = APFloat::rmNearestTiesToEven;4381 4382 APFloat PZero = APFloat::getZero(APFloat::IEEEdouble(), false);4383 APFloat MZero = APFloat::getZero(APFloat::IEEEdouble(), true);4384 APFloat One(1.0);4385 APFloat MOne(-1.0);4386 APFloat Two(2.0);4387 APFloat MTwo(-2.0);4388 4389 APFloat LargestDenormal(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1023");4390 APFloat NegLargestDenormal(APFloat::IEEEdouble(), "-0x1.ffffffffffffep-1023");4391 4392 APFloat Smallest = APFloat::getSmallest(APFloat::IEEEdouble(), false);4393 APFloat NegSmallest = APFloat::getSmallest(APFloat::IEEEdouble(), true);4394 4395 APFloat Largest = APFloat::getLargest(APFloat::IEEEdouble(), false);4396 APFloat NegLargest = APFloat::getLargest(APFloat::IEEEdouble(), true);4397 4398 APFloat PInf = APFloat::getInf(APFloat::IEEEdouble(), false);4399 APFloat MInf = APFloat::getInf(APFloat::IEEEdouble(), true);4400 4401 APFloat QPNaN = APFloat::getNaN(APFloat::IEEEdouble(), false);4402 APFloat QMNaN = APFloat::getNaN(APFloat::IEEEdouble(), true);4403 APFloat SNaN = APFloat::getSNaN(APFloat::IEEEdouble(), false);4404 4405 // Make sure highest bit of payload is preserved.4406 const APInt Payload(64, (UINT64_C(1) << 50) |4407 (UINT64_C(1) << 49) |4408 (UINT64_C(1234) << 32) |4409 1);4410 4411 APFloat SNaNWithPayload = APFloat::getSNaN(APFloat::IEEEdouble(), false,4412 &Payload);4413 4414 APFloat SmallestNormalized4415 = APFloat::getSmallestNormalized(APFloat::IEEEdouble(), false);4416 APFloat NegSmallestNormalized4417 = APFloat::getSmallestNormalized(APFloat::IEEEdouble(), true);4418 4419 int Exp;4420 APFloat Frac(APFloat::IEEEdouble());4421 4422 4423 Frac = frexp(PZero, Exp, RM);4424 EXPECT_EQ(0, Exp);4425 EXPECT_TRUE(Frac.isPosZero());4426 4427 Frac = frexp(MZero, Exp, RM);4428 EXPECT_EQ(0, Exp);4429 EXPECT_TRUE(Frac.isNegZero());4430 4431 4432 Frac = frexp(One, Exp, RM);4433 EXPECT_EQ(1, Exp);4434 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p-1").bitwiseIsEqual(Frac));4435 4436 Frac = frexp(MOne, Exp, RM);4437 EXPECT_EQ(1, Exp);4438 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1p-1").bitwiseIsEqual(Frac));4439 4440 Frac = frexp(LargestDenormal, Exp, RM);4441 EXPECT_EQ(-1022, Exp);4442 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.ffffffffffffep-1").bitwiseIsEqual(Frac));4443 4444 Frac = frexp(NegLargestDenormal, Exp, RM);4445 EXPECT_EQ(-1022, Exp);4446 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1.ffffffffffffep-1").bitwiseIsEqual(Frac));4447 4448 4449 Frac = frexp(Smallest, Exp, RM);4450 EXPECT_EQ(-1073, Exp);4451 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p-1").bitwiseIsEqual(Frac));4452 4453 Frac = frexp(NegSmallest, Exp, RM);4454 EXPECT_EQ(-1073, Exp);4455 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1p-1").bitwiseIsEqual(Frac));4456 4457 4458 Frac = frexp(Largest, Exp, RM);4459 EXPECT_EQ(1024, Exp);4460 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.fffffffffffffp-1").bitwiseIsEqual(Frac));4461 4462 Frac = frexp(NegLargest, Exp, RM);4463 EXPECT_EQ(1024, Exp);4464 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "-0x1.fffffffffffffp-1").bitwiseIsEqual(Frac));4465 4466 4467 Frac = frexp(PInf, Exp, RM);4468 EXPECT_EQ(INT_MAX, Exp);4469 EXPECT_TRUE(Frac.isInfinity() && !Frac.isNegative());4470 4471 Frac = frexp(MInf, Exp, RM);4472 EXPECT_EQ(INT_MAX, Exp);4473 EXPECT_TRUE(Frac.isInfinity() && Frac.isNegative());4474 4475 Frac = frexp(QPNaN, Exp, RM);4476 EXPECT_EQ(INT_MIN, Exp);4477 EXPECT_TRUE(Frac.isNaN());4478 4479 Frac = frexp(QMNaN, Exp, RM);4480 EXPECT_EQ(INT_MIN, Exp);4481 EXPECT_TRUE(Frac.isNaN());4482 4483 Frac = frexp(SNaN, Exp, RM);4484 EXPECT_EQ(INT_MIN, Exp);4485 EXPECT_TRUE(Frac.isNaN() && !Frac.isSignaling());4486 4487 Frac = frexp(SNaNWithPayload, Exp, RM);4488 EXPECT_EQ(INT_MIN, Exp);4489 EXPECT_TRUE(Frac.isNaN() && !Frac.isSignaling());4490 EXPECT_EQ(Payload, Frac.bitcastToAPInt().getLoBits(51));4491 4492 Frac = frexp(APFloat(APFloat::IEEEdouble(), "0x0.ffffp-1"), Exp, RM);4493 EXPECT_EQ(-1, Exp);4494 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.fffep-1").bitwiseIsEqual(Frac));4495 4496 Frac = frexp(APFloat(APFloat::IEEEdouble(), "0x1p-51"), Exp, RM);4497 EXPECT_EQ(-50, Exp);4498 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1p-1").bitwiseIsEqual(Frac));4499 4500 Frac = frexp(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp+51"), Exp, RM);4501 EXPECT_EQ(52, Exp);4502 EXPECT_TRUE(APFloat(APFloat::IEEEdouble(), "0x1.c60f120d9f87cp-1").bitwiseIsEqual(Frac));4503}4504 4505TEST(APFloatTest, mod) {4506 {4507 APFloat f1(APFloat::IEEEdouble(), "1.5");4508 APFloat f2(APFloat::IEEEdouble(), "1.0");4509 APFloat expected(APFloat::IEEEdouble(), "0.5");4510 EXPECT_EQ(f1.mod(f2), APFloat::opOK);4511 EXPECT_TRUE(f1.bitwiseIsEqual(expected));4512 }4513 {4514 APFloat f1(APFloat::IEEEdouble(), "0.5");4515 APFloat f2(APFloat::IEEEdouble(), "1.0");4516 APFloat expected(APFloat::IEEEdouble(), "0.5");4517 EXPECT_EQ(f1.mod(f2), APFloat::opOK);4518 EXPECT_TRUE(f1.bitwiseIsEqual(expected));4519 }4520 {4521 APFloat f1(APFloat::IEEEdouble(), "0x1.3333333333333p-2"); // 0.34522 APFloat f2(APFloat::IEEEdouble(), "0x1.47ae147ae147bp-7"); // 0.014523 APFloat expected(APFloat::IEEEdouble(),4524 "0x1.47ae147ae1471p-7"); // 0.0099999999999999834525 EXPECT_EQ(f1.mod(f2), APFloat::opOK);4526 EXPECT_TRUE(f1.bitwiseIsEqual(expected));4527 }4528 {4529 APFloat f1(APFloat::IEEEdouble(), "0x1p64"); // 1.8446744073709552e194530 APFloat f2(APFloat::IEEEdouble(), "1.5");4531 APFloat expected(APFloat::IEEEdouble(), "1.0");4532 EXPECT_EQ(f1.mod(f2), APFloat::opOK);4533 EXPECT_TRUE(f1.bitwiseIsEqual(expected));4534 }4535 {4536 APFloat f1(APFloat::IEEEdouble(), "0x1p1000");4537 APFloat f2(APFloat::IEEEdouble(), "0x1p-1000");4538 APFloat expected(APFloat::IEEEdouble(), "0.0");4539 EXPECT_EQ(f1.mod(f2), APFloat::opOK);4540 EXPECT_TRUE(f1.bitwiseIsEqual(expected));4541 }4542 {4543 APFloat f1(APFloat::IEEEdouble(), "0.0");4544 APFloat f2(APFloat::IEEEdouble(), "1.0");4545 APFloat expected(APFloat::IEEEdouble(), "0.0");4546 EXPECT_EQ(f1.mod(f2), APFloat::opOK);4547 EXPECT_TRUE(f1.bitwiseIsEqual(expected));4548 }4549 {4550 APFloat f1(APFloat::IEEEdouble(), "1.0");4551 APFloat f2(APFloat::IEEEdouble(), "0.0");4552 EXPECT_EQ(f1.mod(f2), APFloat::opInvalidOp);4553 EXPECT_TRUE(f1.isNaN());4554 }4555 {4556 APFloat f1(APFloat::IEEEdouble(), "0.0");4557 APFloat f2(APFloat::IEEEdouble(), "0.0");4558 EXPECT_EQ(f1.mod(f2), APFloat::opInvalidOp);4559 EXPECT_TRUE(f1.isNaN());4560 }4561 {4562 APFloat f1 = APFloat::getInf(APFloat::IEEEdouble(), false);4563 APFloat f2(APFloat::IEEEdouble(), "1.0");4564 EXPECT_EQ(f1.mod(f2), APFloat::opInvalidOp);4565 EXPECT_TRUE(f1.isNaN());4566 }4567 {4568 APFloat f1(APFloat::IEEEdouble(), "-4.0");4569 APFloat f2(APFloat::IEEEdouble(), "-2.0");4570 APFloat expected(APFloat::IEEEdouble(), "-0.0");4571 EXPECT_EQ(f1.mod(f2), APFloat::opOK);4572 EXPECT_TRUE(f1.bitwiseIsEqual(expected));4573 }4574 {4575 APFloat f1(APFloat::IEEEdouble(), "-4.0");4576 APFloat f2(APFloat::IEEEdouble(), "2.0");4577 APFloat expected(APFloat::IEEEdouble(), "-0.0");4578 EXPECT_EQ(f1.mod(f2), APFloat::opOK);4579 EXPECT_TRUE(f1.bitwiseIsEqual(expected));4580 }4581 {4582 // Test E4M3FN mod where the LHS exponent is maxExponent (8) and the RHS is4583 // the max value whose exponent is minExponent (-6). This requires special4584 // logic in the mod implementation to prevent overflow to NaN.4585 APFloat f1(APFloat::Float8E4M3FN(), "0x1p8"); // 2564586 APFloat f2(APFloat::Float8E4M3FN(), "0x1.ep-6"); // 0.0292968754587 APFloat expected(APFloat::Float8E4M3FN(), "0x1p-8"); // 0.003906254588 EXPECT_EQ(f1.mod(f2), APFloat::opOK);4589 EXPECT_TRUE(f1.bitwiseIsEqual(expected));4590 }4591}4592 4593TEST(APFloatTest, remainder) {4594 // Test Special Cases against each other and normal values.4595 4596 APFloat PInf = APFloat::getInf(APFloat::IEEEsingle(), false);4597 APFloat MInf = APFloat::getInf(APFloat::IEEEsingle(), true);4598 APFloat PZero = APFloat::getZero(APFloat::IEEEsingle(), false);4599 APFloat MZero = APFloat::getZero(APFloat::IEEEsingle(), true);4600 APFloat QNaN = APFloat::getNaN(APFloat::IEEEsingle(), false);4601 APFloat SNaN = APFloat(APFloat::IEEEsingle(), "snan123");4602 APFloat PNormalValue = APFloat(APFloat::IEEEsingle(), "0x1p+0");4603 APFloat MNormalValue = APFloat(APFloat::IEEEsingle(), "-0x1p+0");4604 APFloat PLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), false);4605 APFloat MLargestValue = APFloat::getLargest(APFloat::IEEEsingle(), true);4606 APFloat PSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), false);4607 APFloat MSmallestValue = APFloat::getSmallest(APFloat::IEEEsingle(), true);4608 APFloat PSmallestNormalized =4609 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);4610 APFloat MSmallestNormalized =4611 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);4612 4613 APFloat PVal1(APFloat::IEEEsingle(), "0x1.fffffep+126");4614 APFloat MVal1(APFloat::IEEEsingle(), "-0x1.fffffep+126");4615 APFloat PVal2(APFloat::IEEEsingle(), "0x1.fffffep-126");4616 APFloat MVal2(APFloat::IEEEsingle(), "-0x1.fffffep-126");4617 APFloat PVal3(APFloat::IEEEsingle(), "0x1p-125");4618 APFloat MVal3(APFloat::IEEEsingle(), "-0x1p-125");4619 APFloat PVal4(APFloat::IEEEsingle(), "0x1p+127");4620 APFloat MVal4(APFloat::IEEEsingle(), "-0x1p+127");4621 APFloat PVal5(APFloat::IEEEsingle(), "1.5");4622 APFloat MVal5(APFloat::IEEEsingle(), "-1.5");4623 APFloat PVal6(APFloat::IEEEsingle(), "1");4624 APFloat MVal6(APFloat::IEEEsingle(), "-1");4625 4626 struct {4627 APFloat x;4628 APFloat y;4629 const char *result;4630 int status;4631 int category;4632 } SpecialCaseTests[] = {4633 { PInf, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4634 { PInf, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4635 { PInf, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4636 { PInf, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4637 { PInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },4638 { PInf, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },4639 { PInf, PNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4640 { PInf, MNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4641 { PInf, PLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4642 { PInf, MLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4643 { PInf, PSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4644 { PInf, MSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4645 { PInf, PSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4646 { PInf, MSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4647 { MInf, PInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4648 { MInf, MInf, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4649 { MInf, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4650 { MInf, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4651 { MInf, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },4652 { MInf, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },4653 { MInf, PNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4654 { MInf, MNormalValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4655 { MInf, PLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4656 { MInf, MLargestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4657 { MInf, PSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4658 { MInf, MSmallestValue, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4659 { MInf, PSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4660 { MInf, MSmallestNormalized, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4661 { PZero, PInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },4662 { PZero, MInf, "0x0p+0", APFloat::opOK, APFloat::fcZero },4663 { PZero, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4664 { PZero, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4665 { PZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },4666 { PZero, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },4667 { PZero, PNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },4668 { PZero, MNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },4669 { PZero, PLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },4670 { PZero, MLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },4671 { PZero, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },4672 { PZero, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },4673 { PZero, PSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },4674 { PZero, MSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },4675 { MZero, PInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4676 { MZero, MInf, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4677 { MZero, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4678 { MZero, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4679 { MZero, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },4680 { MZero, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },4681 { MZero, PNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4682 { MZero, MNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4683 { MZero, PLargestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4684 { MZero, MLargestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4685 { MZero, PSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4686 { MZero, MSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4687 { MZero, PSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4688 { MZero, MSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4689 { QNaN, PInf, "nan", APFloat::opOK, APFloat::fcNaN },4690 { QNaN, MInf, "nan", APFloat::opOK, APFloat::fcNaN },4691 { QNaN, PZero, "nan", APFloat::opOK, APFloat::fcNaN },4692 { QNaN, MZero, "nan", APFloat::opOK, APFloat::fcNaN },4693 { QNaN, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },4694 { QNaN, SNaN, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4695 { QNaN, PNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },4696 { QNaN, MNormalValue, "nan", APFloat::opOK, APFloat::fcNaN },4697 { QNaN, PLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },4698 { QNaN, MLargestValue, "nan", APFloat::opOK, APFloat::fcNaN },4699 { QNaN, PSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },4700 { QNaN, MSmallestValue, "nan", APFloat::opOK, APFloat::fcNaN },4701 { QNaN, PSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },4702 { QNaN, MSmallestNormalized, "nan", APFloat::opOK, APFloat::fcNaN },4703 { SNaN, PInf, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },4704 { SNaN, MInf, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },4705 { SNaN, PZero, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },4706 { SNaN, MZero, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },4707 { SNaN, QNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },4708 { SNaN, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },4709 { SNaN, PNormalValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },4710 { SNaN, MNormalValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },4711 { SNaN, PLargestValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },4712 { SNaN, MLargestValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },4713 { SNaN, PSmallestValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },4714 { SNaN, MSmallestValue, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },4715 { SNaN, PSmallestNormalized, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },4716 { SNaN, MSmallestNormalized, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },4717 { PNormalValue, PInf, "0x1p+0", APFloat::opOK, APFloat::fcNormal },4718 { PNormalValue, MInf, "0x1p+0", APFloat::opOK, APFloat::fcNormal },4719 { PNormalValue, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4720 { PNormalValue, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4721 { PNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },4722 { PNormalValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },4723 { PNormalValue, PNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },4724 { PNormalValue, MNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },4725 { PNormalValue, PLargestValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },4726 { PNormalValue, MLargestValue, "0x1p+0", APFloat::opOK, APFloat::fcNormal },4727 { PNormalValue, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },4728 { PNormalValue, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },4729 { PNormalValue, PSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },4730 { PNormalValue, MSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },4731 { MNormalValue, PInf, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },4732 { MNormalValue, MInf, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },4733 { MNormalValue, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4734 { MNormalValue, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4735 { MNormalValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },4736 { MNormalValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },4737 { MNormalValue, PNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4738 { MNormalValue, MNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4739 { MNormalValue, PLargestValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },4740 { MNormalValue, MLargestValue, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },4741 { MNormalValue, PSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4742 { MNormalValue, MSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4743 { MNormalValue, PSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4744 { MNormalValue, MSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4745 { PLargestValue, PInf, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },4746 { PLargestValue, MInf, "0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },4747 { PLargestValue, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4748 { PLargestValue, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4749 { PLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },4750 { PLargestValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },4751 { PLargestValue, PNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },4752 { PLargestValue, MNormalValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },4753 { PLargestValue, PLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },4754 { PLargestValue, MLargestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },4755 { PLargestValue, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },4756 { PLargestValue, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },4757 { PLargestValue, PSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },4758 { PLargestValue, MSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },4759 { MLargestValue, PInf, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },4760 { MLargestValue, MInf, "-0x1.fffffep+127", APFloat::opOK, APFloat::fcNormal },4761 { MLargestValue, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4762 { MLargestValue, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4763 { MLargestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },4764 { MLargestValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },4765 { MLargestValue, PNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4766 { MLargestValue, MNormalValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4767 { MLargestValue, PLargestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4768 { MLargestValue, MLargestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4769 { MLargestValue, PSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4770 { MLargestValue, MSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4771 { MLargestValue, PSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4772 { MLargestValue, MSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4773 { PSmallestValue, PInf, "0x1p-149", APFloat::opOK, APFloat::fcNormal },4774 { PSmallestValue, MInf, "0x1p-149", APFloat::opOK, APFloat::fcNormal },4775 { PSmallestValue, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4776 { PSmallestValue, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4777 { PSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },4778 { PSmallestValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },4779 { PSmallestValue, PNormalValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },4780 { PSmallestValue, MNormalValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },4781 { PSmallestValue, PLargestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },4782 { PSmallestValue, MLargestValue, "0x1p-149", APFloat::opOK, APFloat::fcNormal },4783 { PSmallestValue, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },4784 { PSmallestValue, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },4785 { PSmallestValue, PSmallestNormalized, "0x1p-149", APFloat::opOK, APFloat::fcNormal },4786 { PSmallestValue, MSmallestNormalized, "0x1p-149", APFloat::opOK, APFloat::fcNormal },4787 { MSmallestValue, PInf, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },4788 { MSmallestValue, MInf, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },4789 { MSmallestValue, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4790 { MSmallestValue, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4791 { MSmallestValue, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },4792 { MSmallestValue, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },4793 { MSmallestValue, PNormalValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },4794 { MSmallestValue, MNormalValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },4795 { MSmallestValue, PLargestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },4796 { MSmallestValue, MLargestValue, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },4797 { MSmallestValue, PSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4798 { MSmallestValue, MSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4799 { MSmallestValue, PSmallestNormalized, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },4800 { MSmallestValue, MSmallestNormalized, "-0x1p-149", APFloat::opOK, APFloat::fcNormal },4801 { PSmallestNormalized, PInf, "0x1p-126", APFloat::opOK, APFloat::fcNormal },4802 { PSmallestNormalized, MInf, "0x1p-126", APFloat::opOK, APFloat::fcNormal },4803 { PSmallestNormalized, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4804 { PSmallestNormalized, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4805 { PSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },4806 { PSmallestNormalized, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },4807 { PSmallestNormalized, PNormalValue, "0x1p-126", APFloat::opOK, APFloat::fcNormal },4808 { PSmallestNormalized, MNormalValue, "0x1p-126", APFloat::opOK, APFloat::fcNormal },4809 { PSmallestNormalized, PLargestValue, "0x1p-126", APFloat::opOK, APFloat::fcNormal },4810 { PSmallestNormalized, MLargestValue, "0x1p-126", APFloat::opOK, APFloat::fcNormal },4811 { PSmallestNormalized, PSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },4812 { PSmallestNormalized, MSmallestValue, "0x0p+0", APFloat::opOK, APFloat::fcZero },4813 { PSmallestNormalized, PSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },4814 { PSmallestNormalized, MSmallestNormalized, "0x0p+0", APFloat::opOK, APFloat::fcZero },4815 { MSmallestNormalized, PInf, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },4816 { MSmallestNormalized, MInf, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },4817 { MSmallestNormalized, PZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4818 { MSmallestNormalized, MZero, "nan", APFloat::opInvalidOp, APFloat::fcNaN },4819 { MSmallestNormalized, QNaN, "nan", APFloat::opOK, APFloat::fcNaN },4820 { MSmallestNormalized, SNaN, "nan123", APFloat::opInvalidOp, APFloat::fcNaN },4821 { MSmallestNormalized, PNormalValue, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },4822 { MSmallestNormalized, MNormalValue, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },4823 { MSmallestNormalized, PLargestValue, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },4824 { MSmallestNormalized, MLargestValue, "-0x1p-126", APFloat::opOK, APFloat::fcNormal },4825 { MSmallestNormalized, PSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4826 { MSmallestNormalized, MSmallestValue, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4827 { MSmallestNormalized, PSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4828 { MSmallestNormalized, MSmallestNormalized, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4829 4830 { PVal1, PVal1, "0x0p+0", APFloat::opOK, APFloat::fcZero },4831 { PVal1, MVal1, "0x0p+0", APFloat::opOK, APFloat::fcZero },4832 { PVal1, PVal2, "0x0p+0", APFloat::opOK, APFloat::fcZero },4833 { PVal1, MVal2, "0x0p+0", APFloat::opOK, APFloat::fcZero },4834 { PVal1, PVal3, "0x0p+0", APFloat::opOK, APFloat::fcZero },4835 { PVal1, MVal3, "0x0p+0", APFloat::opOK, APFloat::fcZero },4836 { PVal1, PVal4, "-0x1p+103", APFloat::opOK, APFloat::fcNormal },4837 { PVal1, MVal4, "-0x1p+103", APFloat::opOK, APFloat::fcNormal },4838 { PVal1, PVal5, "0x0p+0", APFloat::opOK, APFloat::fcZero },4839 { PVal1, MVal5, "0x0p+0", APFloat::opOK, APFloat::fcZero },4840 { PVal1, PVal6, "0x0p+0", APFloat::opOK, APFloat::fcZero },4841 { PVal1, MVal6, "0x0p+0", APFloat::opOK, APFloat::fcZero },4842 { MVal1, PVal1, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4843 { MVal1, MVal1, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4844 { MVal1, PVal2, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4845 { MVal1, MVal2, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4846 { MVal1, PVal3, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4847 { MVal1, MVal3, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4848 { MVal1, PVal4, "0x1p+103", APFloat::opOK, APFloat::fcNormal },4849 { MVal1, MVal4, "0x1p+103", APFloat::opOK, APFloat::fcNormal },4850 { MVal1, PVal5, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4851 { MVal1, MVal5, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4852 { MVal1, PVal6, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4853 { MVal1, MVal6, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4854 { PVal2, PVal1, "0x1.fffffep-126", APFloat::opOK, APFloat::fcNormal },4855 { PVal2, MVal1, "0x1.fffffep-126", APFloat::opOK, APFloat::fcNormal },4856 { PVal2, PVal2, "0x0p+0", APFloat::opOK, APFloat::fcZero },4857 { PVal2, MVal2, "0x0p+0", APFloat::opOK, APFloat::fcZero },4858 { PVal2, PVal3, "-0x0.000002p-126", APFloat::opOK, APFloat::fcNormal },4859 { PVal2, MVal3, "-0x0.000002p-126", APFloat::opOK, APFloat::fcNormal },4860 { PVal2, PVal4, "0x1.fffffep-126", APFloat::opOK, APFloat::fcNormal },4861 { PVal2, MVal4, "0x1.fffffep-126", APFloat::opOK, APFloat::fcNormal },4862 { PVal2, PVal5, "0x1.fffffep-126", APFloat::opOK, APFloat::fcNormal },4863 { PVal2, MVal5, "0x1.fffffep-126", APFloat::opOK, APFloat::fcNormal },4864 { PVal2, PVal6, "0x1.fffffep-126", APFloat::opOK, APFloat::fcNormal },4865 { PVal2, MVal6, "0x1.fffffep-126", APFloat::opOK, APFloat::fcNormal },4866 { MVal2, PVal1, "-0x1.fffffep-126", APFloat::opOK, APFloat::fcNormal },4867 { MVal2, MVal1, "-0x1.fffffep-126", APFloat::opOK, APFloat::fcNormal },4868 { MVal2, PVal2, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4869 { MVal2, MVal2, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4870 { MVal2, PVal3, "0x0.000002p-126", APFloat::opOK, APFloat::fcNormal },4871 { MVal2, MVal3, "0x0.000002p-126", APFloat::opOK, APFloat::fcNormal },4872 { MVal2, PVal4, "-0x1.fffffep-126", APFloat::opOK, APFloat::fcNormal },4873 { MVal2, MVal4, "-0x1.fffffep-126", APFloat::opOK, APFloat::fcNormal },4874 { MVal2, PVal5, "-0x1.fffffep-126", APFloat::opOK, APFloat::fcNormal },4875 { MVal2, MVal5, "-0x1.fffffep-126", APFloat::opOK, APFloat::fcNormal },4876 { MVal2, PVal6, "-0x1.fffffep-126", APFloat::opOK, APFloat::fcNormal },4877 { MVal2, MVal6, "-0x1.fffffep-126", APFloat::opOK, APFloat::fcNormal },4878 { PVal3, PVal1, "0x1p-125", APFloat::opOK, APFloat::fcNormal },4879 { PVal3, MVal1, "0x1p-125", APFloat::opOK, APFloat::fcNormal },4880 { PVal3, PVal2, "0x0.000002p-126", APFloat::opOK, APFloat::fcNormal },4881 { PVal3, MVal2, "0x0.000002p-126", APFloat::opOK, APFloat::fcNormal },4882 { PVal3, PVal3, "0x0p+0", APFloat::opOK, APFloat::fcZero },4883 { PVal3, MVal3, "0x0p+0", APFloat::opOK, APFloat::fcZero },4884 { PVal3, PVal4, "0x1p-125", APFloat::opOK, APFloat::fcNormal },4885 { PVal3, MVal4, "0x1p-125", APFloat::opOK, APFloat::fcNormal },4886 { PVal3, PVal5, "0x1p-125", APFloat::opOK, APFloat::fcNormal },4887 { PVal3, MVal5, "0x1p-125", APFloat::opOK, APFloat::fcNormal },4888 { PVal3, PVal6, "0x1p-125", APFloat::opOK, APFloat::fcNormal },4889 { PVal3, MVal6, "0x1p-125", APFloat::opOK, APFloat::fcNormal },4890 { MVal3, PVal1, "-0x1p-125", APFloat::opOK, APFloat::fcNormal },4891 { MVal3, MVal1, "-0x1p-125", APFloat::opOK, APFloat::fcNormal },4892 { MVal3, PVal2, "-0x0.000002p-126", APFloat::opOK, APFloat::fcNormal },4893 { MVal3, MVal2, "-0x0.000002p-126", APFloat::opOK, APFloat::fcNormal },4894 { MVal3, PVal3, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4895 { MVal3, MVal3, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4896 { MVal3, PVal4, "-0x1p-125", APFloat::opOK, APFloat::fcNormal },4897 { MVal3, MVal4, "-0x1p-125", APFloat::opOK, APFloat::fcNormal },4898 { MVal3, PVal5, "-0x1p-125", APFloat::opOK, APFloat::fcNormal },4899 { MVal3, MVal5, "-0x1p-125", APFloat::opOK, APFloat::fcNormal },4900 { MVal3, PVal6, "-0x1p-125", APFloat::opOK, APFloat::fcNormal },4901 { MVal3, MVal6, "-0x1p-125", APFloat::opOK, APFloat::fcNormal },4902 { PVal4, PVal1, "0x1p+103", APFloat::opOK, APFloat::fcNormal },4903 { PVal4, MVal1, "0x1p+103", APFloat::opOK, APFloat::fcNormal },4904 { PVal4, PVal2, "0x0.002p-126", APFloat::opOK, APFloat::fcNormal },4905 { PVal4, MVal2, "0x0.002p-126", APFloat::opOK, APFloat::fcNormal },4906 { PVal4, PVal3, "0x0p+0", APFloat::opOK, APFloat::fcZero },4907 { PVal4, MVal3, "0x0p+0", APFloat::opOK, APFloat::fcZero },4908 { PVal4, PVal4, "0x0p+0", APFloat::opOK, APFloat::fcZero },4909 { PVal4, MVal4, "0x0p+0", APFloat::opOK, APFloat::fcZero },4910 { PVal4, PVal5, "0.5", APFloat::opOK, APFloat::fcNormal },4911 { PVal4, MVal5, "0.5", APFloat::opOK, APFloat::fcNormal },4912 { PVal4, PVal6, "0x0p+0", APFloat::opOK, APFloat::fcZero },4913 { PVal4, MVal6, "0x0p+0", APFloat::opOK, APFloat::fcZero },4914 { MVal4, PVal1, "-0x1p+103", APFloat::opOK, APFloat::fcNormal },4915 { MVal4, MVal1, "-0x1p+103", APFloat::opOK, APFloat::fcNormal },4916 { MVal4, PVal2, "-0x0.002p-126", APFloat::opOK, APFloat::fcNormal },4917 { MVal4, MVal2, "-0x0.002p-126", APFloat::opOK, APFloat::fcNormal },4918 { MVal4, PVal3, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4919 { MVal4, MVal3, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4920 { MVal4, PVal4, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4921 { MVal4, MVal4, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4922 { MVal4, PVal5, "-0.5", APFloat::opOK, APFloat::fcNormal },4923 { MVal4, MVal5, "-0.5", APFloat::opOK, APFloat::fcNormal },4924 { MVal4, PVal6, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4925 { MVal4, MVal6, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4926 { PVal5, PVal1, "1.5", APFloat::opOK, APFloat::fcNormal },4927 { PVal5, MVal1, "1.5", APFloat::opOK, APFloat::fcNormal },4928 { PVal5, PVal2, "0x0.00006p-126", APFloat::opOK, APFloat::fcNormal },4929 { PVal5, MVal2, "0x0.00006p-126", APFloat::opOK, APFloat::fcNormal },4930 { PVal5, PVal3, "0x0p+0", APFloat::opOK, APFloat::fcZero },4931 { PVal5, MVal3, "0x0p+0", APFloat::opOK, APFloat::fcZero },4932 { PVal5, PVal4, "1.5", APFloat::opOK, APFloat::fcNormal },4933 { PVal5, MVal4, "1.5", APFloat::opOK, APFloat::fcNormal },4934 { PVal5, PVal5, "0x0p+0", APFloat::opOK, APFloat::fcZero },4935 { PVal5, MVal5, "0x0p+0", APFloat::opOK, APFloat::fcZero },4936 { PVal5, PVal6, "-0.5", APFloat::opOK, APFloat::fcNormal },4937 { PVal5, MVal6, "-0.5", APFloat::opOK, APFloat::fcNormal },4938 { MVal5, PVal1, "-1.5", APFloat::opOK, APFloat::fcNormal },4939 { MVal5, MVal1, "-1.5", APFloat::opOK, APFloat::fcNormal },4940 { MVal5, PVal2, "-0x0.00006p-126", APFloat::opOK, APFloat::fcNormal },4941 { MVal5, MVal2, "-0x0.00006p-126", APFloat::opOK, APFloat::fcNormal },4942 { MVal5, PVal3, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4943 { MVal5, MVal3, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4944 { MVal5, PVal4, "-1.5", APFloat::opOK, APFloat::fcNormal },4945 { MVal5, MVal4, "-1.5", APFloat::opOK, APFloat::fcNormal },4946 { MVal5, PVal5, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4947 { MVal5, MVal5, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4948 { MVal5, PVal6, "0.5", APFloat::opOK, APFloat::fcNormal },4949 { MVal5, MVal6, "0.5", APFloat::opOK, APFloat::fcNormal },4950 { PVal6, PVal1, "0x1p+0", APFloat::opOK, APFloat::fcNormal },4951 { PVal6, MVal1, "0x1p+0", APFloat::opOK, APFloat::fcNormal },4952 { PVal6, PVal2, "0x0.00004p-126", APFloat::opOK, APFloat::fcNormal },4953 { PVal6, MVal2, "0x0.00004p-126", APFloat::opOK, APFloat::fcNormal },4954 { PVal6, PVal3, "0x0p+0", APFloat::opOK, APFloat::fcZero },4955 { PVal6, MVal3, "0x0p+0", APFloat::opOK, APFloat::fcZero },4956 { PVal6, PVal4, "0x1p+0", APFloat::opOK, APFloat::fcNormal },4957 { PVal6, MVal4, "0x1p+0", APFloat::opOK, APFloat::fcNormal },4958 { PVal6, PVal5, "-0.5", APFloat::opOK, APFloat::fcNormal },4959 { PVal6, MVal5, "-0.5", APFloat::opOK, APFloat::fcNormal },4960 { PVal6, PVal6, "0x0p+0", APFloat::opOK, APFloat::fcZero },4961 { PVal6, MVal6, "0x0p+0", APFloat::opOK, APFloat::fcZero },4962 { MVal6, PVal1, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },4963 { MVal6, MVal1, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },4964 { MVal6, PVal2, "-0x0.00004p-126", APFloat::opOK, APFloat::fcNormal },4965 { MVal6, MVal2, "-0x0.00004p-126", APFloat::opOK, APFloat::fcNormal },4966 { MVal6, PVal3, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4967 { MVal6, MVal3, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4968 { MVal6, PVal4, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },4969 { MVal6, MVal4, "-0x1p+0", APFloat::opOK, APFloat::fcNormal },4970 { MVal6, PVal5, "0.5", APFloat::opOK, APFloat::fcNormal },4971 { MVal6, MVal5, "0.5", APFloat::opOK, APFloat::fcNormal },4972 { MVal6, PVal6, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4973 { MVal6, MVal6, "-0x0p+0", APFloat::opOK, APFloat::fcZero },4974 };4975 4976 for (size_t i = 0; i < std::size(SpecialCaseTests); ++i) {4977 APFloat x(SpecialCaseTests[i].x);4978 APFloat y(SpecialCaseTests[i].y);4979 APFloat::opStatus status = x.remainder(y);4980 4981 APFloat result(x.getSemantics(), SpecialCaseTests[i].result);4982 4983 EXPECT_TRUE(result.bitwiseIsEqual(x));4984 EXPECT_EQ(SpecialCaseTests[i].status, (int)status);4985 EXPECT_EQ(SpecialCaseTests[i].category, (int)x.getCategory());4986 }4987 4988 {4989 APFloat f1(APFloat::IEEEdouble(), "0x1.3333333333333p-2"); // 0.34990 APFloat f2(APFloat::IEEEdouble(), "0x1.47ae147ae147bp-7"); // 0.014991 APFloat expected(APFloat::IEEEdouble(), "-0x1.4p-56");4992 EXPECT_EQ(APFloat::opOK, f1.remainder(f2));4993 EXPECT_TRUE(f1.bitwiseIsEqual(expected));4994 }4995 {4996 APFloat f1(APFloat::IEEEdouble(), "0x1p64"); // 1.8446744073709552e194997 APFloat f2(APFloat::IEEEdouble(), "1.5");4998 APFloat expected(APFloat::IEEEdouble(), "-0.5");4999 EXPECT_EQ(APFloat::opOK, f1.remainder(f2));5000 EXPECT_TRUE(f1.bitwiseIsEqual(expected));5001 }5002 {5003 APFloat f1(APFloat::IEEEdouble(), "0x1p1000");5004 APFloat f2(APFloat::IEEEdouble(), "0x1p-1000");5005 APFloat expected(APFloat::IEEEdouble(), "0.0");5006 EXPECT_EQ(APFloat::opOK, f1.remainder(f2));5007 EXPECT_TRUE(f1.bitwiseIsEqual(expected));5008 }5009 {5010 APFloat f1 = APFloat::getInf(APFloat::IEEEdouble(), false);5011 APFloat f2(APFloat::IEEEdouble(), "1.0");5012 EXPECT_EQ(f1.remainder(f2), APFloat::opInvalidOp);5013 EXPECT_TRUE(f1.isNaN());5014 }5015 {5016 APFloat f1(APFloat::IEEEdouble(), "-4.0");5017 APFloat f2(APFloat::IEEEdouble(), "-2.0");5018 APFloat expected(APFloat::IEEEdouble(), "-0.0");5019 EXPECT_EQ(APFloat::opOK, f1.remainder(f2));5020 EXPECT_TRUE(f1.bitwiseIsEqual(expected));5021 }5022 {5023 APFloat f1(APFloat::IEEEdouble(), "-4.0");5024 APFloat f2(APFloat::IEEEdouble(), "2.0");5025 APFloat expected(APFloat::IEEEdouble(), "-0.0");5026 EXPECT_EQ(APFloat::opOK, f1.remainder(f2));5027 EXPECT_TRUE(f1.bitwiseIsEqual(expected));5028 }5029}5030 5031TEST(APFloatTest, PPCDoubleDoubleAddSpecial) {5032 using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t,5033 APFloat::fltCategory, APFloat::roundingMode>;5034 DataType Data[] = {5035 // (1 + 0) + (-1 + 0) = fcZero5036 std::make_tuple(0x3ff0000000000000ull, 0, 0xbff0000000000000ull, 0,5037 APFloat::fcZero, APFloat::rmNearestTiesToEven),5038 // LDBL_MAX + (1.1 >> (1023 - 106) + 0)) = fcInfinity5039 std::make_tuple(0x7fefffffffffffffull, 0x7c8ffffffffffffeull,5040 0x7948000000000000ull, 0ull, APFloat::fcInfinity,5041 APFloat::rmNearestTiesToEven),5042 // TODO: change the 4th 0x75effffffffffffe to 0x75efffffffffffff when5043 // semPPCDoubleDoubleLegacy is gone.5044 // LDBL_MAX + (1.011111... >> (1023 - 106) + (1.1111111...0 >> (1023 -5045 // 160))) = fcNormal5046 std::make_tuple(0x7fefffffffffffffull, 0x7c8ffffffffffffeull,5047 0x7947ffffffffffffull, 0x75effffffffffffeull,5048 APFloat::fcNormal, APFloat::rmNearestTiesToEven),5049 // LDBL_MAX + (1.1 >> (1023 - 106) + 0)) = fcInfinity5050 std::make_tuple(0x7fefffffffffffffull, 0x7c8ffffffffffffeull,5051 0x7fefffffffffffffull, 0x7c8ffffffffffffeull,5052 APFloat::fcInfinity, APFloat::rmNearestTiesToEven),5053 // NaN + (1 + 0) = fcNaN5054 std::make_tuple(0x7ff8000000000000ull, 0, 0x3ff0000000000000ull, 0,5055 APFloat::fcNaN, APFloat::rmNearestTiesToEven),5056 };5057 5058 for (auto Tp : Data) {5059 uint64_t Op1[2], Op2[2];5060 APFloat::fltCategory Expected;5061 APFloat::roundingMode RM;5062 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected, RM) = Tp;5063 5064 {5065 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, Op1));5066 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, Op2));5067 A1.add(A2, RM);5068 5069 EXPECT_EQ(Expected, A1.getCategory())5070 << formatv("({0:x} + {1:x}) + ({2:x} + {3:x})", Op1[0], Op1[1],5071 Op2[0], Op2[1])5072 .str();5073 }5074 {5075 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, Op1));5076 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, Op2));5077 A2.add(A1, RM);5078 5079 EXPECT_EQ(Expected, A2.getCategory())5080 << formatv("({0:x} + {1:x}) + ({2:x} + {3:x})", Op2[0], Op2[1],5081 Op1[0], Op1[1])5082 .str();5083 }5084 }5085}5086 5087TEST(APFloatTest, PPCDoubleDoubleAdd) {5088 using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,5089 uint64_t, APFloat::roundingMode>;5090 DataType Data[] = {5091 // (1 + 0) + (1e-105 + 0) = (1 + 1e-105)5092 std::make_tuple(0x3ff0000000000000ull, 0, 0x3960000000000000ull, 0,5093 0x3ff0000000000000ull, 0x3960000000000000ull,5094 APFloat::rmNearestTiesToEven),5095 // (1 + 0) + (1e-106 + 0) = (1 + 1e-106)5096 std::make_tuple(0x3ff0000000000000ull, 0, 0x3950000000000000ull, 0,5097 0x3ff0000000000000ull, 0x3950000000000000ull,5098 APFloat::rmNearestTiesToEven),5099 // (1 + 1e-106) + (1e-106 + 0) = (1 + 1e-105)5100 std::make_tuple(0x3ff0000000000000ull, 0x3950000000000000ull,5101 0x3950000000000000ull, 0, 0x3ff0000000000000ull,5102 0x3960000000000000ull, APFloat::rmNearestTiesToEven),5103 // (1 + 0) + (epsilon + 0) = (1 + epsilon)5104 std::make_tuple(0x3ff0000000000000ull, 0, 0x0000000000000001ull, 0,5105 0x3ff0000000000000ull, 0x0000000000000001ull,5106 APFloat::rmNearestTiesToEven),5107 // TODO: change 0xf950000000000000 to 0xf940000000000000, when5108 // semPPCDoubleDoubleLegacy is gone.5109 // (DBL_MAX - 1 << (1023 - 105)) + (1 << (1023 - 53) + 0) = DBL_MAX +5110 // 1.11111... << (1023 - 52)5111 std::make_tuple(0x7fefffffffffffffull, 0xf950000000000000ull,5112 0x7c90000000000000ull, 0, 0x7fefffffffffffffull,5113 0x7c8ffffffffffffeull, APFloat::rmNearestTiesToEven),5114 // TODO: change 0xf950000000000000 to 0xf940000000000000, when5115 // semPPCDoubleDoubleLegacy is gone.5116 // (1 << (1023 - 53) + 0) + (DBL_MAX - 1 << (1023 - 105)) = DBL_MAX +5117 // 1.11111... << (1023 - 52)5118 std::make_tuple(0x7c90000000000000ull, 0, 0x7fefffffffffffffull,5119 0xf950000000000000ull, 0x7fefffffffffffffull,5120 0x7c8ffffffffffffeull, APFloat::rmNearestTiesToEven),5121 };5122 5123 for (auto Tp : Data) {5124 uint64_t Op1[2], Op2[2], Expected[2];5125 APFloat::roundingMode RM;5126 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected[0], Expected[1], RM) = Tp;5127 5128 {5129 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, Op1));5130 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, Op2));5131 A1.add(A2, RM);5132 5133 EXPECT_EQ(Expected[0], A1.bitcastToAPInt().getRawData()[0])5134 << formatv("({0:x} + {1:x}) + ({2:x} + {3:x})", Op1[0], Op1[1],5135 Op2[0], Op2[1])5136 .str();5137 EXPECT_EQ(Expected[1], A1.bitcastToAPInt().getRawData()[1])5138 << formatv("({0:x} + {1:x}) + ({2:x} + {3:x})", Op1[0], Op1[1],5139 Op2[0], Op2[1])5140 .str();5141 }5142 {5143 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, Op1));5144 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, Op2));5145 A2.add(A1, RM);5146 5147 EXPECT_EQ(Expected[0], A2.bitcastToAPInt().getRawData()[0])5148 << formatv("({0:x} + {1:x}) + ({2:x} + {3:x})", Op2[0], Op2[1],5149 Op1[0], Op1[1])5150 .str();5151 EXPECT_EQ(Expected[1], A2.bitcastToAPInt().getRawData()[1])5152 << formatv("({0:x} + {1:x}) + ({2:x} + {3:x})", Op2[0], Op2[1],5153 Op1[0], Op1[1])5154 .str();5155 }5156 }5157}5158 5159TEST(APFloatTest, PPCDoubleDoubleSubtract) {5160 using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,5161 uint64_t, APFloat::roundingMode>;5162 DataType Data[] = {5163 // (1 + 0) - (-1e-105 + 0) = (1 + 1e-105)5164 std::make_tuple(0x3ff0000000000000ull, 0, 0xb960000000000000ull, 0,5165 0x3ff0000000000000ull, 0x3960000000000000ull,5166 APFloat::rmNearestTiesToEven),5167 // (1 + 0) - (-1e-106 + 0) = (1 + 1e-106)5168 std::make_tuple(0x3ff0000000000000ull, 0, 0xb950000000000000ull, 0,5169 0x3ff0000000000000ull, 0x3950000000000000ull,5170 APFloat::rmNearestTiesToEven),5171 };5172 5173 for (auto Tp : Data) {5174 uint64_t Op1[2], Op2[2], Expected[2];5175 APFloat::roundingMode RM;5176 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected[0], Expected[1], RM) = Tp;5177 5178 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, Op1));5179 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, Op2));5180 A1.subtract(A2, RM);5181 5182 EXPECT_EQ(Expected[0], A1.bitcastToAPInt().getRawData()[0])5183 << formatv("({0:x} + {1:x}) - ({2:x} + {3:x})", Op1[0], Op1[1], Op2[0],5184 Op2[1])5185 .str();5186 EXPECT_EQ(Expected[1], A1.bitcastToAPInt().getRawData()[1])5187 << formatv("({0:x} + {1:x}) - ({2:x} + {3:x})", Op1[0], Op1[1], Op2[0],5188 Op2[1])5189 .str();5190 }5191}5192 5193TEST(APFloatTest, PPCDoubleDoubleMultiplySpecial) {5194 using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t,5195 APFloat::fltCategory, APFloat::roundingMode>;5196 DataType Data[] = {5197 // fcNaN * fcNaN = fcNaN5198 std::make_tuple(0x7ff8000000000000ull, 0, 0x7ff8000000000000ull, 0,5199 APFloat::fcNaN, APFloat::rmNearestTiesToEven),5200 // fcNaN * fcZero = fcNaN5201 std::make_tuple(0x7ff8000000000000ull, 0, 0, 0, APFloat::fcNaN,5202 APFloat::rmNearestTiesToEven),5203 // fcNaN * fcInfinity = fcNaN5204 std::make_tuple(0x7ff8000000000000ull, 0, 0x7ff0000000000000ull, 0,5205 APFloat::fcNaN, APFloat::rmNearestTiesToEven),5206 // fcNaN * fcNormal = fcNaN5207 std::make_tuple(0x7ff8000000000000ull, 0, 0x3ff0000000000000ull, 0,5208 APFloat::fcNaN, APFloat::rmNearestTiesToEven),5209 // fcInfinity * fcInfinity = fcInfinity5210 std::make_tuple(0x7ff0000000000000ull, 0, 0x7ff0000000000000ull, 0,5211 APFloat::fcInfinity, APFloat::rmNearestTiesToEven),5212 // fcInfinity * fcZero = fcNaN5213 std::make_tuple(0x7ff0000000000000ull, 0, 0, 0, APFloat::fcNaN,5214 APFloat::rmNearestTiesToEven),5215 // fcInfinity * fcNormal = fcInfinity5216 std::make_tuple(0x7ff0000000000000ull, 0, 0x3ff0000000000000ull, 0,5217 APFloat::fcInfinity, APFloat::rmNearestTiesToEven),5218 // fcZero * fcZero = fcZero5219 std::make_tuple(0, 0, 0, 0, APFloat::fcZero,5220 APFloat::rmNearestTiesToEven),5221 // fcZero * fcNormal = fcZero5222 std::make_tuple(0, 0, 0x3ff0000000000000ull, 0, APFloat::fcZero,5223 APFloat::rmNearestTiesToEven),5224 };5225 5226 for (auto Tp : Data) {5227 uint64_t Op1[2], Op2[2];5228 APFloat::fltCategory Expected;5229 APFloat::roundingMode RM;5230 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected, RM) = Tp;5231 5232 {5233 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, Op1));5234 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, Op2));5235 A1.multiply(A2, RM);5236 5237 EXPECT_EQ(Expected, A1.getCategory())5238 << formatv("({0:x} + {1:x}) * ({2:x} + {3:x})", Op1[0], Op1[1],5239 Op2[0], Op2[1])5240 .str();5241 }5242 {5243 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, Op1));5244 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, Op2));5245 A2.multiply(A1, RM);5246 5247 EXPECT_EQ(Expected, A2.getCategory())5248 << formatv("({0:x} + {1:x}) * ({2:x} + {3:x})", Op2[0], Op2[1],5249 Op1[0], Op1[1])5250 .str();5251 }5252 }5253}5254 5255TEST(APFloatTest, PPCDoubleDoubleMultiply) {5256 using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,5257 uint64_t, APFloat::roundingMode>;5258 DataType Data[] = {5259 // 1/3 * 3 = 1.05260 std::make_tuple(0x3fd5555555555555ull, 0x3c75555555555556ull,5261 0x4008000000000000ull, 0, 0x3ff0000000000000ull, 0,5262 APFloat::rmNearestTiesToEven),5263 // (1 + epsilon) * (1 + 0) = fcZero5264 std::make_tuple(0x3ff0000000000000ull, 0x0000000000000001ull,5265 0x3ff0000000000000ull, 0, 0x3ff0000000000000ull,5266 0x0000000000000001ull, APFloat::rmNearestTiesToEven),5267 // (1 + epsilon) * (1 + epsilon) = 1 + 2 * epsilon5268 std::make_tuple(0x3ff0000000000000ull, 0x0000000000000001ull,5269 0x3ff0000000000000ull, 0x0000000000000001ull,5270 0x3ff0000000000000ull, 0x0000000000000002ull,5271 APFloat::rmNearestTiesToEven),5272 // -(1 + epsilon) * (1 + epsilon) = -15273 std::make_tuple(0xbff0000000000000ull, 0x0000000000000001ull,5274 0x3ff0000000000000ull, 0x0000000000000001ull,5275 0xbff0000000000000ull, 0, APFloat::rmNearestTiesToEven),5276 // (0.5 + 0) * (1 + 2 * epsilon) = 0.5 + epsilon5277 std::make_tuple(0x3fe0000000000000ull, 0, 0x3ff0000000000000ull,5278 0x0000000000000002ull, 0x3fe0000000000000ull,5279 0x0000000000000001ull, APFloat::rmNearestTiesToEven),5280 // (0.5 + 0) * (1 + epsilon) = 0.55281 std::make_tuple(0x3fe0000000000000ull, 0, 0x3ff0000000000000ull,5282 0x0000000000000001ull, 0x3fe0000000000000ull, 0,5283 APFloat::rmNearestTiesToEven),5284 // __LDBL_MAX__ * (1 + 1 << 106) = inf5285 std::make_tuple(0x7fefffffffffffffull, 0x7c8ffffffffffffeull,5286 0x3ff0000000000000ull, 0x3950000000000000ull,5287 0x7ff0000000000000ull, 0, APFloat::rmNearestTiesToEven),5288 // __LDBL_MAX__ * (1 + 1 << 107) > __LDBL_MAX__, but not inf, yes =_=|||5289 std::make_tuple(0x7fefffffffffffffull, 0x7c8ffffffffffffeull,5290 0x3ff0000000000000ull, 0x3940000000000000ull,5291 0x7fefffffffffffffull, 0x7c8fffffffffffffull,5292 APFloat::rmNearestTiesToEven),5293 // __LDBL_MAX__ * (1 + 1 << 108) = __LDBL_MAX__5294 std::make_tuple(0x7fefffffffffffffull, 0x7c8ffffffffffffeull,5295 0x3ff0000000000000ull, 0x3930000000000000ull,5296 0x7fefffffffffffffull, 0x7c8ffffffffffffeull,5297 APFloat::rmNearestTiesToEven),5298 };5299 5300 for (auto Tp : Data) {5301 uint64_t Op1[2], Op2[2], Expected[2];5302 APFloat::roundingMode RM;5303 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected[0], Expected[1], RM) = Tp;5304 5305 {5306 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, Op1));5307 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, Op2));5308 A1.multiply(A2, RM);5309 5310 EXPECT_EQ(Expected[0], A1.bitcastToAPInt().getRawData()[0])5311 << formatv("({0:x} + {1:x}) * ({2:x} + {3:x})", Op1[0], Op1[1],5312 Op2[0], Op2[1])5313 .str();5314 EXPECT_EQ(Expected[1], A1.bitcastToAPInt().getRawData()[1])5315 << formatv("({0:x} + {1:x}) * ({2:x} + {3:x})", Op1[0], Op1[1],5316 Op2[0], Op2[1])5317 .str();5318 }5319 {5320 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, Op1));5321 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, Op2));5322 A2.multiply(A1, RM);5323 5324 EXPECT_EQ(Expected[0], A2.bitcastToAPInt().getRawData()[0])5325 << formatv("({0:x} + {1:x}) * ({2:x} + {3:x})", Op2[0], Op2[1],5326 Op1[0], Op1[1])5327 .str();5328 EXPECT_EQ(Expected[1], A2.bitcastToAPInt().getRawData()[1])5329 << formatv("({0:x} + {1:x}) * ({2:x} + {3:x})", Op2[0], Op2[1],5330 Op1[0], Op1[1])5331 .str();5332 }5333 }5334}5335 5336TEST(APFloatTest, PPCDoubleDoubleDivide) {5337 using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, uint64_t,5338 uint64_t, APFloat::roundingMode>;5339 // TODO: Only a sanity check for now. Add more edge cases when the5340 // double-double algorithm is implemented.5341 DataType Data[] = {5342 // 1 / 3 = 1/35343 std::make_tuple(0x3ff0000000000000ull, 0, 0x4008000000000000ull, 0,5344 0x3fd5555555555555ull, 0x3c75555555555556ull,5345 APFloat::rmNearestTiesToEven),5346 };5347 5348 for (auto Tp : Data) {5349 uint64_t Op1[2], Op2[2], Expected[2];5350 APFloat::roundingMode RM;5351 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected[0], Expected[1], RM) = Tp;5352 5353 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, Op1));5354 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, Op2));5355 A1.divide(A2, RM);5356 5357 EXPECT_EQ(Expected[0], A1.bitcastToAPInt().getRawData()[0])5358 << formatv("({0:x} + {1:x}) / ({2:x} + {3:x})", Op1[0], Op1[1], Op2[0],5359 Op2[1])5360 .str();5361 EXPECT_EQ(Expected[1], A1.bitcastToAPInt().getRawData()[1])5362 << formatv("({0:x} + {1:x}) / ({2:x} + {3:x})", Op1[0], Op1[1], Op2[0],5363 Op2[1])5364 .str();5365 }5366}5367 5368TEST(APFloatTest, PPCDoubleDoubleRemainder) {5369 using DataType =5370 std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t>;5371 DataType Data[] = {5372 // remainder(3.0 + 3.0 << 53, 1.25 + 1.25 << 53) = (0.5 + 0.5 << 53)5373 std::make_tuple(0x4008000000000000ull, 0x3cb8000000000000ull,5374 0x3ff4000000000000ull, 0x3ca4000000000000ull,5375 0x3fe0000000000000ull, 0x3c90000000000000ull),5376 // remainder(3.0 + 3.0 << 53, 1.75 + 1.75 << 53) = (-0.5 - 0.5 << 53)5377 std::make_tuple(0x4008000000000000ull, 0x3cb8000000000000ull,5378 0x3ffc000000000000ull, 0x3cac000000000000ull,5379 0xbfe0000000000000ull, 0xbc90000000000000ull),5380 };5381 5382 for (auto Tp : Data) {5383 uint64_t Op1[2], Op2[2], Expected[2];5384 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected[0], Expected[1]) = Tp;5385 5386 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, Op1));5387 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, Op2));5388 A1.remainder(A2);5389 5390 EXPECT_EQ(Expected[0], A1.bitcastToAPInt().getRawData()[0])5391 << formatv("remainder({0:x} + {1:x}), ({2:x} + {3:x}))", Op1[0], Op1[1],5392 Op2[0], Op2[1])5393 .str();5394 EXPECT_EQ(Expected[1], A1.bitcastToAPInt().getRawData()[1])5395 << formatv("remainder(({0:x} + {1:x}), ({2:x} + {3:x}))", Op1[0],5396 Op1[1], Op2[0], Op2[1])5397 .str();5398 }5399}5400 5401TEST(APFloatTest, PPCDoubleDoubleMod) {5402 using DataType =5403 std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t>;5404 DataType Data[] = {5405 // mod(3.0 + 3.0 << 53, 1.25 + 1.25 << 53) = (0.5 + 0.5 << 53)5406 std::make_tuple(0x4008000000000000ull, 0x3cb8000000000000ull,5407 0x3ff4000000000000ull, 0x3ca4000000000000ull,5408 0x3fe0000000000000ull, 0x3c90000000000000ull),5409 // mod(3.0 + 3.0 << 53, 1.75 + 1.75 << 53) = (1.25 + 1.25 << 53)5410 // 0xbc98000000000000 doesn't seem right, but it's what we currently have.5411 // TODO: investigate5412 std::make_tuple(0x4008000000000000ull, 0x3cb8000000000000ull,5413 0x3ffc000000000000ull, 0x3cac000000000000ull,5414 0x3ff4000000000001ull, 0xbc98000000000000ull),5415 };5416 5417 for (auto Tp : Data) {5418 uint64_t Op1[2], Op2[2], Expected[2];5419 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected[0], Expected[1]) = Tp;5420 5421 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, Op1));5422 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, Op2));5423 A1.mod(A2);5424 5425 EXPECT_EQ(Expected[0], A1.bitcastToAPInt().getRawData()[0])5426 << formatv("fmod(({0:x} + {1:x}), ({2:x} + {3:x}))", Op1[0], Op1[1],5427 Op2[0], Op2[1])5428 .str();5429 EXPECT_EQ(Expected[1], A1.bitcastToAPInt().getRawData()[1])5430 << formatv("fmod(({0:x} + {1:x}), ({2:x} + {3:x}))", Op1[0], Op1[1],5431 Op2[0], Op2[1])5432 .str();5433 }5434}5435 5436TEST(APFloatTest, PPCDoubleDoubleFMA) {5437 // Sanity check for now.5438 APFloat A(APFloat::PPCDoubleDouble(), "2");5439 A.fusedMultiplyAdd(APFloat(APFloat::PPCDoubleDouble(), "3"),5440 APFloat(APFloat::PPCDoubleDouble(), "4"),5441 APFloat::rmNearestTiesToEven);5442 EXPECT_EQ(APFloat::cmpEqual,5443 APFloat(APFloat::PPCDoubleDouble(), "10").compare(A));5444}5445 5446struct PPCDoubleDoubleRoundToIntegralTestCase {5447 DD Input;5448 DD Rounded[5] = {};5449 constexpr PPCDoubleDoubleRoundToIntegralTestCase &5450 withRounded(DD R, APFloat::roundingMode RM) {5451 Rounded[static_cast<std::underlying_type_t<APFloat::roundingMode>>(RM)] = R;5452 return *this;5453 }5454};5455 5456auto ppcDoubleDoubleRoundToIntegralTests() {5457 constexpr double Eps = std::numeric_limits<double>::epsilon();5458 constexpr double HalfEps = Eps / 2.0;5459 constexpr double QuarterEps = Eps / 4.0;5460 constexpr double SmallestNormal = std::numeric_limits<double>::min();5461 constexpr double EvenIntegerThreshold{uint64_t{1}5462 << std::numeric_limits<double>::digits};5463 constexpr double Inf = std::numeric_limits<double>::infinity();5464 constexpr double QNaN = std::numeric_limits<double>::quiet_NaN();5465 using TestCase = PPCDoubleDoubleRoundToIntegralTestCase;5466 static constexpr auto TestCases = std::array{5467 // 1. Zeros and Basic Integers5468 // Input: Positive Zero (0.0, 0.0)5469 TestCase({{0.0, 0.0}})5470 .withRounded({0.0, 0.0}, APFloat::rmTowardZero)5471 .withRounded({0.0, 0.0}, APFloat::rmTowardNegative)5472 .withRounded({0.0, 0.0}, APFloat::rmTowardPositive)5473 .withRounded({0.0, 0.0}, APFloat::rmNearestTiesToAway)5474 .withRounded({0.0, 0.0}, APFloat::rmNearestTiesToEven),5475 5476 // Input: Negative Zero (-0.0, 0.0)5477 TestCase({{-0.0, 0.0}})5478 .withRounded({-0.0, 0.0}, APFloat::rmTowardZero)5479 .withRounded({-0.0, 0.0}, APFloat::rmTowardNegative)5480 .withRounded({-0.0, 0.0}, APFloat::rmTowardPositive)5481 .withRounded({-0.0, 0.0}, APFloat::rmNearestTiesToAway)5482 .withRounded({-0.0, 0.0}, APFloat::rmNearestTiesToEven),5483 5484 // Input: Positive Even (2.0, 0.0)5485 TestCase({{2.0, 0.0}})5486 .withRounded({2.0, 0.0}, APFloat::rmTowardZero)5487 .withRounded({2.0, 0.0}, APFloat::rmTowardNegative)5488 .withRounded({2.0, 0.0}, APFloat::rmTowardPositive)5489 .withRounded({2.0, 0.0}, APFloat::rmNearestTiesToAway)5490 .withRounded({2.0, 0.0}, APFloat::rmNearestTiesToEven),5491 5492 // Input: Positive Odd (3.0, 0.0)5493 TestCase({{3.0, 0.0}})5494 .withRounded({3.0, 0.0}, APFloat::rmTowardZero)5495 .withRounded({3.0, 0.0}, APFloat::rmTowardNegative)5496 .withRounded({3.0, 0.0}, APFloat::rmTowardPositive)5497 .withRounded({3.0, 0.0}, APFloat::rmNearestTiesToAway)5498 .withRounded({3.0, 0.0}, APFloat::rmNearestTiesToEven),5499 5500 // Input: Negative Even (-2.0, 0.0)5501 TestCase({{-2.0, 0.0}})5502 .withRounded({-2.0, 0.0}, APFloat::rmTowardZero)5503 .withRounded({-2.0, 0.0}, APFloat::rmTowardNegative)5504 .withRounded({-2.0, 0.0}, APFloat::rmTowardPositive)5505 .withRounded({-2.0, 0.0}, APFloat::rmNearestTiesToAway)5506 .withRounded({-2.0, 0.0}, APFloat::rmNearestTiesToEven),5507 5508 // 2. General Fractions (Non-Ties)5509 // Input: 2.35510 TestCase({{2.3, 0.0}})5511 .withRounded({2.0, 0.0}, APFloat::rmTowardZero)5512 .withRounded({2.0, 0.0}, APFloat::rmTowardNegative)5513 .withRounded({3.0, 0.0}, APFloat::rmTowardPositive)5514 .withRounded({2.0, 0.0}, APFloat::rmNearestTiesToAway)5515 .withRounded({2.0, 0.0}, APFloat::rmNearestTiesToEven),5516 5517 // Input: 2.75518 TestCase({{2.7, 0.0}})5519 .withRounded({2.0, 0.0}, APFloat::rmTowardZero)5520 .withRounded({2.0, 0.0}, APFloat::rmTowardNegative)5521 .withRounded({3.0, 0.0}, APFloat::rmTowardPositive)5522 .withRounded({3.0, 0.0}, APFloat::rmNearestTiesToAway)5523 .withRounded({3.0, 0.0}, APFloat::rmNearestTiesToEven),5524 5525 // Input: -2.35526 TestCase({{-2.3, 0.0}})5527 .withRounded({-2.0, 0.0}, APFloat::rmTowardZero)5528 .withRounded({-3.0, 0.0}, APFloat::rmTowardNegative)5529 .withRounded({-2.0, 0.0}, APFloat::rmTowardPositive)5530 .withRounded({-2.0, 0.0}, APFloat::rmNearestTiesToAway)5531 .withRounded({-2.0, 0.0}, APFloat::rmNearestTiesToEven),5532 5533 // Input: -2.75534 TestCase({{-2.7, 0.0}})5535 .withRounded({-2.0, 0.0}, APFloat::rmTowardZero)5536 .withRounded({-3.0, 0.0}, APFloat::rmTowardNegative)5537 .withRounded({-2.0, 0.0}, APFloat::rmTowardPositive)5538 .withRounded({-3.0, 0.0}, APFloat::rmNearestTiesToAway)5539 .withRounded({-3.0, 0.0}, APFloat::rmNearestTiesToEven),5540 5541 // Input: 2.3 + Tiny5542 TestCase({{2.3, SmallestNormal}})5543 .withRounded({2.0, 0.0}, APFloat::rmTowardZero)5544 .withRounded({2.0, 0.0}, APFloat::rmTowardNegative)5545 .withRounded({3.0, 0.0}, APFloat::rmTowardPositive)5546 .withRounded({2.0, 0.0}, APFloat::rmNearestTiesToAway)5547 .withRounded({2.0, 0.0}, APFloat::rmNearestTiesToEven),5548 5549 // 3. Exact Midpoints (Ties at N.5)5550 // Input: 0.55551 TestCase({{0.5, 0.0}})5552 .withRounded({0.0, 0.0}, APFloat::rmTowardZero)5553 .withRounded({0.0, 0.0}, APFloat::rmTowardNegative)5554 .withRounded({1.0, 0.0}, APFloat::rmTowardPositive)5555 .withRounded({1.0, 0.0}, APFloat::rmNearestTiesToAway)5556 .withRounded({0.0, 0.0}, APFloat::rmNearestTiesToEven),5557 5558 // Input: 1.5 (Odd base)5559 TestCase({{1.5, 0.0}})5560 .withRounded({1.0, 0.0}, APFloat::rmTowardZero)5561 .withRounded({1.0, 0.0}, APFloat::rmTowardNegative)5562 .withRounded({2.0, 0.0}, APFloat::rmTowardPositive)5563 .withRounded({2.0, 0.0}, APFloat::rmNearestTiesToAway)5564 .withRounded({2.0, 0.0}, APFloat::rmNearestTiesToEven),5565 5566 // Input: 2.5 (Even base)5567 TestCase({{2.5, 0.0}})5568 .withRounded({2.0, 0.0}, APFloat::rmTowardZero)5569 .withRounded({2.0, 0.0}, APFloat::rmTowardNegative)5570 .withRounded({3.0, 0.0}, APFloat::rmTowardPositive)5571 .withRounded({3.0, 0.0}, APFloat::rmNearestTiesToAway)5572 .withRounded({2.0, 0.0}, APFloat::rmNearestTiesToEven),5573 5574 // Input: -0.55575 TestCase({{-0.5, 0.0}})5576 .withRounded({-0.0, 0.0}, APFloat::rmTowardZero)5577 .withRounded({-1.0, 0.0}, APFloat::rmTowardNegative)5578 .withRounded({-0.0, 0.0}, APFloat::rmTowardPositive)5579 .withRounded({-1.0, 0.0}, APFloat::rmNearestTiesToAway)5580 .withRounded({-0.0, 0.0}, APFloat::rmNearestTiesToEven),5581 5582 // Input: -1.5 (Odd base)5583 TestCase({{-1.5, 0.0}})5584 .withRounded({-1.0, 0.0}, APFloat::rmTowardZero)5585 .withRounded({-2.0, 0.0}, APFloat::rmTowardNegative)5586 .withRounded({-1.0, 0.0}, APFloat::rmTowardPositive)5587 .withRounded({-2.0, 0.0}, APFloat::rmNearestTiesToAway)5588 .withRounded({-2.0, 0.0}, APFloat::rmNearestTiesToEven),5589 5590 // Input: -2.5 (Even base)5591 TestCase({{-2.5, 0.0}})5592 .withRounded({-2.0, 0.0}, APFloat::rmTowardZero)5593 .withRounded({-3.0, 0.0}, APFloat::rmTowardNegative)5594 .withRounded({-2.0, 0.0}, APFloat::rmTowardPositive)5595 .withRounded({-3.0, 0.0}, APFloat::rmNearestTiesToAway)5596 .withRounded({-2.0, 0.0}, APFloat::rmNearestTiesToEven),5597 5598 // 4. Near Midpoints (lo breaks the tie)5599 // Input: Slightly > 2.55600 TestCase({{2.5, SmallestNormal}})5601 .withRounded({2.0, 0.0}, APFloat::rmTowardZero)5602 .withRounded({2.0, 0.0}, APFloat::rmTowardNegative)5603 .withRounded({3.0, 0.0}, APFloat::rmTowardPositive)5604 .withRounded({3.0, 0.0}, APFloat::rmNearestTiesToAway)5605 .withRounded({3.0, 0.0}, APFloat::rmNearestTiesToEven),5606 5607 // Input: Slightly < 2.55608 TestCase({{2.5, -SmallestNormal}})5609 .withRounded({2.0, 0.0}, APFloat::rmTowardZero)5610 .withRounded({2.0, 0.0}, APFloat::rmTowardNegative)5611 .withRounded({3.0, 0.0}, APFloat::rmTowardPositive)5612 .withRounded({2.0, 0.0}, APFloat::rmNearestTiesToAway)5613 .withRounded({2.0, 0.0}, APFloat::rmNearestTiesToEven),5614 5615 // Input: Slightly > 1.55616 TestCase({{1.5, SmallestNormal}})5617 .withRounded({1.0, 0.0}, APFloat::rmTowardZero)5618 .withRounded({1.0, 0.0}, APFloat::rmTowardNegative)5619 .withRounded({2.0, 0.0}, APFloat::rmTowardPositive)5620 .withRounded({2.0, 0.0}, APFloat::rmNearestTiesToAway)5621 .withRounded({2.0, 0.0}, APFloat::rmNearestTiesToEven),5622 5623 // Input: Slightly < 1.55624 TestCase({{1.5, -SmallestNormal}})5625 .withRounded({1.0, 0.0}, APFloat::rmTowardZero)5626 .withRounded({1.0, 0.0}, APFloat::rmTowardNegative)5627 .withRounded({2.0, 0.0}, APFloat::rmTowardPositive)5628 .withRounded({1.0, 0.0}, APFloat::rmNearestTiesToAway)5629 .withRounded({1.0, 0.0}, APFloat::rmNearestTiesToEven),5630 5631 // Input: Slightly > -2.5 (closer to 0)5632 TestCase({{-2.5, SmallestNormal}})5633 .withRounded({-2.0, 0.0}, APFloat::rmTowardZero)5634 .withRounded({-3.0, 0.0}, APFloat::rmTowardNegative)5635 .withRounded({-2.0, 0.0}, APFloat::rmTowardPositive)5636 .withRounded({-2.0, 0.0}, APFloat::rmNearestTiesToAway)5637 .withRounded({-2.0, 0.0}, APFloat::rmNearestTiesToEven),5638 5639 // Input: Slightly < -2.5 (further from 0)5640 TestCase({{-2.5, -SmallestNormal}})5641 .withRounded({-2.0, 0.0}, APFloat::rmTowardZero)5642 .withRounded({-3.0, 0.0}, APFloat::rmTowardNegative)5643 .withRounded({-2.0, 0.0}, APFloat::rmTowardPositive)5644 .withRounded({-3.0, 0.0}, APFloat::rmNearestTiesToAway)5645 .withRounded({-3.0, 0.0}, APFloat::rmNearestTiesToEven),5646 5647 // 5. Near Integers (lo crosses the integer boundary)5648 // Input: Slightly > 2.05649 TestCase({{2.0, SmallestNormal}})5650 .withRounded({2.0, 0.0}, APFloat::rmTowardZero)5651 .withRounded({2.0, 0.0}, APFloat::rmTowardNegative)5652 .withRounded({3.0, 0.0}, APFloat::rmTowardPositive)5653 .withRounded({2.0, 0.0}, APFloat::rmNearestTiesToAway)5654 .withRounded({2.0, 0.0}, APFloat::rmNearestTiesToEven),5655 5656 // Input: Slightly < 2.0 (1.99...)5657 TestCase({{2.0, -SmallestNormal}})5658 .withRounded({1.0, 0.0}, APFloat::rmTowardZero)5659 .withRounded({1.0, 0.0}, APFloat::rmTowardNegative)5660 .withRounded({2.0, 0.0}, APFloat::rmTowardPositive)5661 .withRounded({2.0, 0.0}, APFloat::rmNearestTiesToAway)5662 .withRounded({2.0, 0.0}, APFloat::rmNearestTiesToEven),5663 5664 // Input: Slightly > -2.0 (-1.99...)5665 TestCase({{-2.0, SmallestNormal}})5666 .withRounded({-1.0, 0.0}, APFloat::rmTowardZero)5667 .withRounded({-2.0, 0.0}, APFloat::rmTowardNegative)5668 .withRounded({-1.0, 0.0}, APFloat::rmTowardPositive)5669 .withRounded({-2.0, 0.0}, APFloat::rmNearestTiesToAway)5670 .withRounded({-2.0, 0.0}, APFloat::rmNearestTiesToEven),5671 5672 // Input: Slightly < -2.05673 TestCase({{-2.0, -SmallestNormal}})5674 .withRounded({-2.0, 0.0}, APFloat::rmTowardZero)5675 .withRounded({-3.0, 0.0}, APFloat::rmTowardNegative)5676 .withRounded({-2.0, 0.0}, APFloat::rmTowardPositive)5677 .withRounded({-2.0, 0.0}, APFloat::rmNearestTiesToAway)5678 .withRounded({-2.0, 0.0}, APFloat::rmNearestTiesToEven),5679 5680 // Input: Slightly > 0.05681 TestCase({{SmallestNormal, 0.0}})5682 .withRounded({0.0, 0.0}, APFloat::rmTowardZero)5683 .withRounded({0.0, 0.0}, APFloat::rmTowardNegative)5684 .withRounded({1.0, 0.0}, APFloat::rmTowardPositive)5685 .withRounded({0.0, 0.0}, APFloat::rmNearestTiesToAway)5686 .withRounded({0.0, 0.0}, APFloat::rmNearestTiesToEven),5687 5688 // Input: Slightly < 0.05689 TestCase({{-SmallestNormal, 0.0}})5690 .withRounded({-0.0, 0.0}, APFloat::rmTowardZero)5691 .withRounded({-1.0, 0.0}, APFloat::rmTowardNegative)5692 .withRounded({-0.0, 0.0}, APFloat::rmTowardPositive)5693 .withRounded({-0.0, 0.0}, APFloat::rmNearestTiesToAway)5694 .withRounded({-0.0, 0.0}, APFloat::rmNearestTiesToEven),5695 5696 // 6. Boundary of Canonicalization (Maximum lo)5697 // Input: 1.0 + Max lo (1 + 2^-53)5698 TestCase({{1.0, HalfEps}})5699 .withRounded({1.0, 0.0}, APFloat::rmTowardZero)5700 .withRounded({1.0, 0.0}, APFloat::rmTowardNegative)5701 .withRounded({2.0, 0.0}, APFloat::rmTowardPositive)5702 .withRounded({1.0, 0.0}, APFloat::rmNearestTiesToAway)5703 .withRounded({1.0, 0.0}, APFloat::rmNearestTiesToEven),5704 5705 // Input: 1.0 - Max lo (1 - 2^-54)5706 TestCase({{1.0, -QuarterEps}})5707 .withRounded({0.0, 0.0}, APFloat::rmTowardZero)5708 .withRounded({0.0, 0.0}, APFloat::rmTowardNegative)5709 .withRounded({1.0, 0.0}, APFloat::rmTowardPositive)5710 .withRounded({1.0, 0.0}, APFloat::rmNearestTiesToAway)5711 .withRounded({1.0, 0.0}, APFloat::rmNearestTiesToEven),5712 5713 // 7. Large Magnitudes (Beyond 2^53). N = EvenIntegerThreshold (Even)5714 // Input: EvenIntegerThreshold (Exact)5715 TestCase({{EvenIntegerThreshold, 0.0}})5716 .withRounded({EvenIntegerThreshold, 0.0}, APFloat::rmTowardZero)5717 .withRounded({EvenIntegerThreshold, 0.0}, APFloat::rmTowardNegative)5718 .withRounded({EvenIntegerThreshold, 0.0}, APFloat::rmTowardPositive)5719 .withRounded({EvenIntegerThreshold, 0.0},5720 APFloat::rmNearestTiesToAway)5721 .withRounded({EvenIntegerThreshold, 0.0},5722 APFloat::rmNearestTiesToEven),5723 5724 // Input: EvenIntegerThreshold+1 (Exact)5725 TestCase({{EvenIntegerThreshold, 1.0}})5726 .withRounded({EvenIntegerThreshold, 1.0}, APFloat::rmTowardZero)5727 .withRounded({EvenIntegerThreshold, 1.0}, APFloat::rmTowardNegative)5728 .withRounded({EvenIntegerThreshold, 1.0}, APFloat::rmTowardPositive)5729 .withRounded({EvenIntegerThreshold, 1.0},5730 APFloat::rmNearestTiesToAway)5731 .withRounded({EvenIntegerThreshold, 1.0},5732 APFloat::rmNearestTiesToEven),5733 5734 // Fractions5735 // Input: EvenIntegerThreshold+0.255736 TestCase({{EvenIntegerThreshold, 0.25}})5737 .withRounded({EvenIntegerThreshold, 0.0}, APFloat::rmTowardZero)5738 .withRounded({EvenIntegerThreshold, 0.0}, APFloat::rmTowardNegative)5739 .withRounded({EvenIntegerThreshold, 1.0}, APFloat::rmTowardPositive)5740 .withRounded({EvenIntegerThreshold, 0.0},5741 APFloat::rmNearestTiesToAway)5742 .withRounded({EvenIntegerThreshold, 0.0},5743 APFloat::rmNearestTiesToEven),5744 5745 // Input: EvenIntegerThreshold+0.755746 TestCase({{EvenIntegerThreshold, 0.75}})5747 .withRounded({EvenIntegerThreshold, 0.0}, APFloat::rmTowardZero)5748 .withRounded({EvenIntegerThreshold, 0.0}, APFloat::rmTowardNegative)5749 .withRounded({EvenIntegerThreshold, 1.0}, APFloat::rmTowardPositive)5750 .withRounded({EvenIntegerThreshold, 1.0},5751 APFloat::rmNearestTiesToAway)5752 .withRounded({EvenIntegerThreshold, 1.0},5753 APFloat::rmNearestTiesToEven),5754 5755 // Ties (Midpoints)5756 // Input: EvenIntegerThreshold-0.55757 TestCase({{EvenIntegerThreshold, -0.5}})5758 .withRounded({EvenIntegerThreshold - 1.0, 0.0}, APFloat::rmTowardZero)5759 .withRounded({EvenIntegerThreshold - 1.0, 0.0},5760 APFloat::rmTowardNegative)5761 .withRounded({EvenIntegerThreshold, 0.0}, APFloat::rmTowardPositive)5762 .withRounded({EvenIntegerThreshold, 0.0},5763 APFloat::rmNearestTiesToAway)5764 .withRounded({EvenIntegerThreshold, 0.0},5765 APFloat::rmNearestTiesToEven),5766 5767 // Input: EvenIntegerThreshold+0.55768 TestCase({{EvenIntegerThreshold, 0.5}})5769 .withRounded({EvenIntegerThreshold, 0.0}, APFloat::rmTowardZero)5770 .withRounded({EvenIntegerThreshold, 0.0}, APFloat::rmTowardNegative)5771 .withRounded({EvenIntegerThreshold, 1.0}, APFloat::rmTowardPositive)5772 .withRounded({EvenIntegerThreshold, 1.0},5773 APFloat::rmNearestTiesToAway)5774 .withRounded({EvenIntegerThreshold, 0.0},5775 APFloat::rmNearestTiesToEven),5776 5777 // Input: EvenIntegerThreshold+1.55778 TestCase({{EvenIntegerThreshold + 2.0, -0.5}})5779 .withRounded({EvenIntegerThreshold, 1.0}, APFloat::rmTowardZero)5780 .withRounded({EvenIntegerThreshold, 1.0}, APFloat::rmTowardNegative)5781 .withRounded({EvenIntegerThreshold + 2.0, 0.0},5782 APFloat::rmTowardPositive)5783 .withRounded({EvenIntegerThreshold + 2.0, 0.0},5784 APFloat::rmNearestTiesToAway)5785 .withRounded({EvenIntegerThreshold + 2.0, 0.0},5786 APFloat::rmNearestTiesToEven),5787 5788 // Input: EvenIntegerThreshold+2.55789 TestCase({{EvenIntegerThreshold + 2.0, 0.5}})5790 .withRounded({EvenIntegerThreshold + 2.0, 0.0}, APFloat::rmTowardZero)5791 .withRounded({EvenIntegerThreshold + 2.0, 0.0},5792 APFloat::rmTowardNegative)5793 .withRounded({EvenIntegerThreshold + 4.0, -1.0},5794 APFloat::rmTowardPositive)5795 .withRounded({EvenIntegerThreshold + 4.0, -1.0},5796 APFloat::rmNearestTiesToAway)5797 .withRounded({EvenIntegerThreshold + 2.0, 0.0},5798 APFloat::rmNearestTiesToEven),5799 5800 // Near Ties5801 // Input: EvenIntegerThreshold+0.5+HalfEps5802 TestCase({{EvenIntegerThreshold, 0.5 + HalfEps}})5803 .withRounded({EvenIntegerThreshold, 0.0}, APFloat::rmTowardZero)5804 .withRounded({EvenIntegerThreshold, 0.0}, APFloat::rmTowardNegative)5805 .withRounded({EvenIntegerThreshold, 1.0}, APFloat::rmTowardPositive)5806 .withRounded({EvenIntegerThreshold, 1.0},5807 APFloat::rmNearestTiesToAway)5808 .withRounded({EvenIntegerThreshold, 1.0},5809 APFloat::rmNearestTiesToEven),5810 5811 // Input: EvenIntegerThreshold+0.5-QuarterEps5812 TestCase({{EvenIntegerThreshold, 0.5 - QuarterEps}})5813 .withRounded({EvenIntegerThreshold, 0.0}, APFloat::rmTowardZero)5814 .withRounded({EvenIntegerThreshold, 0.0}, APFloat::rmTowardNegative)5815 .withRounded({EvenIntegerThreshold, 1.0}, APFloat::rmTowardPositive)5816 .withRounded({EvenIntegerThreshold, 0.0},5817 APFloat::rmNearestTiesToAway)5818 .withRounded({EvenIntegerThreshold, 0.0},5819 APFloat::rmNearestTiesToEven),5820 5821 // Canonical Boundary (Max lo for EvenIntegerThreshold is 1.0)5822 // Input: EvenIntegerThreshold+1.05823 TestCase({{EvenIntegerThreshold, 1.0}})5824 .withRounded({EvenIntegerThreshold, 1.0}, APFloat::rmTowardZero)5825 .withRounded({EvenIntegerThreshold, 1.0}, APFloat::rmTowardNegative)5826 .withRounded({EvenIntegerThreshold, 1.0}, APFloat::rmTowardPositive)5827 .withRounded({EvenIntegerThreshold, 1.0},5828 APFloat::rmNearestTiesToAway)5829 .withRounded({EvenIntegerThreshold, 1.0},5830 APFloat::rmNearestTiesToEven),5831 5832 // 8. Special Values5833 // Input: +Inf5834 TestCase({{Inf, 0.0}})5835 .withRounded({Inf, 0.0}, APFloat::rmTowardZero)5836 .withRounded({Inf, 0.0}, APFloat::rmTowardNegative)5837 .withRounded({Inf, 0.0}, APFloat::rmTowardPositive)5838 .withRounded({Inf, 0.0}, APFloat::rmNearestTiesToAway)5839 .withRounded({Inf, 0.0}, APFloat::rmNearestTiesToEven),5840 5841 // Input: -Inf5842 TestCase({{-Inf, 0.0}})5843 .withRounded({-Inf, 0.0}, APFloat::rmTowardZero)5844 .withRounded({-Inf, 0.0}, APFloat::rmTowardNegative)5845 .withRounded({-Inf, 0.0}, APFloat::rmTowardPositive)5846 .withRounded({-Inf, 0.0}, APFloat::rmNearestTiesToAway)5847 .withRounded({-Inf, 0.0}, APFloat::rmNearestTiesToEven),5848 5849 // Input: NaN input hi. Expected output canonical (NaN, 0.0).5850 TestCase({{QNaN, 0.0}})5851 .withRounded({QNaN, 0.0}, APFloat::rmTowardZero)5852 .withRounded({QNaN, 0.0}, APFloat::rmTowardNegative)5853 .withRounded({QNaN, 0.0}, APFloat::rmTowardPositive)5854 .withRounded({QNaN, 0.0}, APFloat::rmNearestTiesToAway)5855 .withRounded({QNaN, 0.0}, APFloat::rmNearestTiesToEven),5856 };5857 return TestCases;5858}5859 5860class PPCDoubleDoubleRoundToIntegralValueTest5861 : public testing::Test,5862 public ::testing::WithParamInterface<5863 PPCDoubleDoubleRoundToIntegralTestCase> {};5864 5865INSTANTIATE_TEST_SUITE_P(5866 PPCDoubleDoubleRoundToIntegralValueParamTests,5867 PPCDoubleDoubleRoundToIntegralValueTest,5868 ::testing::ValuesIn(ppcDoubleDoubleRoundToIntegralTests()));5869 5870TEST_P(PPCDoubleDoubleRoundToIntegralValueTest,5871 PPCDoubleDoubleRoundToIntegral) {5872 const PPCDoubleDoubleRoundToIntegralTestCase TestCase = GetParam();5873 const APFloat Input = makeDoubleAPFloat(TestCase.Input);5874 EXPECT_FALSE(Input.isDenormal())5875 << TestCase.Input.Hi << " + " << TestCase.Input.Lo;5876 for (size_t I = 0, E = std::size(TestCase.Rounded); I != E; ++I) {5877 const auto RM = static_cast<APFloat::roundingMode>(I);5878 const APFloat Expected = makeDoubleAPFloat(TestCase.Rounded[I]);5879 EXPECT_FALSE(Expected.isDenormal())5880 << TestCase.Rounded[I].Hi << " + " << TestCase.Input.Lo;5881 APFloat Actual = Input;5882 Actual.roundToIntegral(RM);5883 if (Actual.isNaN())5884 EXPECT_TRUE(Actual.isNaN());5885 else5886 EXPECT_EQ(Actual.compare(Expected), APFloat::cmpEqual)5887 << "RM: " << RM << " Input.Hi: " << TestCase.Input.Hi5888 << " Input.Lo: " << TestCase.Input.Lo << " Actual: " << Actual5889 << " Expected.Hi: " << TestCase.Rounded[I].Hi5890 << " Expected.Lo: " << TestCase.Rounded[I].Lo5891 << " Expected: " << Expected;5892 }5893}5894 5895namespace PPCDoubleDoubleConvertToIntegerTestDetails {5896// Define the rounding modes for easier readability.5897static constexpr auto RNE = APFloat::rmNearestTiesToEven;5898static constexpr auto RNA = APFloat::rmNearestTiesToAway;5899static constexpr auto RTZ = APFloat::rmTowardZero;5900static constexpr auto RUP = APFloat::rmTowardPositive;5901static constexpr auto RDN = APFloat::rmTowardNegative;5902 5903struct TestCase {5904 // Structure to hold the expected result of a conversion5905 struct ExpectedConversion {5906 // The expected integer value represented as a string (decimal).5907 // We use a string to easily represent arbitrary precision values in5908 // constexpr. The test runner should parse this into an APSInt matching the5909 // test configuration.5910 const char *ExpectedIntStr;5911 APFloat::opStatus Status;5912 };5913 5914 DD Input;5915 unsigned IntegerWidth;5916 bool IsSigned;5917 // Array indexed by the rounding mode enum value.5918 std::array<ExpectedConversion, 5> Rounded = {};5919 5920 // Helper to define the expected results for a specific rounding mode.5921 constexpr TestCase &with(APFloat::roundingMode RM, const char *ExpectedStr,5922 APFloat::opStatus Status) {5923 Rounded[static_cast<std::underlying_type_t<APFloat::roundingMode>>(RM)] = {5924 ExpectedStr,5925 Status,5926 };5927 return *this;5928 }5929 5930 // Helper to define the same result for all rounding modes.5931 constexpr TestCase &withAll(const char *ExpectedStr,5932 APFloat::opStatus Status) {5933 return with(RNE, ExpectedStr, Status)5934 .with(RNA, ExpectedStr, Status)5935 .with(RTZ, ExpectedStr, Status)5936 .with(RUP, ExpectedStr, Status)5937 .with(RDN, ExpectedStr, Status);5938 }5939};5940 5941auto testCases() {5942 // Define the status codes.5943 constexpr auto OK = llvm::APFloat::opOK;5944 constexpr auto Inexact = llvm::APFloat::opInexact;5945 // The API specifies opInvalidOp for out-of-range (overflow/underflow) and5946 // NaN.5947 constexpr auto Invalid = llvm::APFloat::opInvalidOp;5948 5949 // Helper constants for constructing specific DD values.5950 constexpr double Infinity = std::numeric_limits<double>::infinity();5951 constexpr double NaN = std::numeric_limits<double>::quiet_NaN();5952 constexpr double DMAX = std::numeric_limits<double>::max();5953 5954 // Powers of 25955 constexpr double P53 = 0x1p53;5956 constexpr double P63 = 0x1p63;5957 constexpr double P64 = 0x1p64;5958 // 2^-100 (A very small delta demonstrating extended precision)5959 constexpr double PM100 = 0x1p-100;5960 5961 static constexpr auto ConvertToIntegerTestCases = std::array{5962 // 1. Zeros, NaNs, and Infinities (Target: 64-bit Signed)5963 // INT64_MAX = 92233720368547758075964 // INT64_MIN = -92233720368547758085965 5966 // Input: Positive Zero (0.0, 0.0)5967 TestCase{{0.0, 0.0}, 64, true}.withAll("0", OK),5968 5969 // Input: Negative Zero (-0.0, 0.0)5970 TestCase{{-0.0, 0.0}, 64, true}.withAll("0", OK),5971 5972 // Input: NaN. Expected behavior: Invalid, deterministic result of 0.5973 TestCase{{NaN, 0.0}, 64, true}.withAll("0", Invalid),5974 5975 // Input: +Infinity. Expected behavior: Invalid, deterministic result of5976 // INT64_MAX.5977 TestCase{{Infinity, 0.0}, 64, true}.withAll("9223372036854775807",5978 Invalid),5979 5980 // Input: -Infinity. Expected behavior: Invalid, deterministic result of5981 // INT64_MIN.5982 TestCase{{-Infinity, 0.0}, 64, true}.withAll("-9223372036854775808",5983 Invalid),5984 5985 // 2. Basic Rounding and Tie-Breaking (Target: 32-bit Signed)5986 5987 // Input: 2.5 (Tie, preceding integer is Even)5988 TestCase{{2.5, 0.0}, 32, true}5989 .with(RTZ, "2", Inexact)5990 .with(RDN, "2", Inexact)5991 .with(RUP, "3", Inexact)5992 .with(RNA, "3", Inexact)5993 .with(RNE, "2", Inexact),5994 5995 // Input: 3.5 (Tie, preceding integer is Odd)5996 TestCase{{3.5, 0.0}, 32, true}5997 .with(RTZ, "3", Inexact)5998 .with(RDN, "3", Inexact)5999 .with(RUP, "4", Inexact)6000 .with(RNA, "4", Inexact)6001 .with(RNE, "4", Inexact),6002 6003 // Input: -2.5 (Tie, preceding integer is Even)6004 TestCase{{-2.5, 0.0}, 32, true}6005 .with(RTZ, "-2", Inexact)6006 .with(RDN, "-3", Inexact)6007 .with(RUP, "-2", Inexact)6008 .with(RNA, "-3", Inexact)6009 .with(RNE, "-2", Inexact),6010 6011 // 3. Double-Double Precision (The role of 'lo')6012 // Testing how extended precision affects rounding decisions.6013 6014 // Input: 2.5 + Epsilon (Slightly above tie)6015 TestCase{{2.5, PM100}, 32, true}6016 .with(RTZ, "2", Inexact)6017 .with(RDN, "2", Inexact)6018 .with(RUP, "3", Inexact)6019 .with(RNA, "3", Inexact)6020 .with(RNE, "3", Inexact),6021 6022 // Input: 2.5 - Epsilon (Slightly below tie)6023 TestCase{{2.5, -PM100}, 32, true}6024 .with(RTZ, "2", Inexact)6025 .with(RDN, "2", Inexact)6026 .with(RUP, "3", Inexact)6027 .with(RNA, "2", Inexact)6028 .with(RNE, "2", Inexact),6029 6030 // Input: 1.0 + Epsilon (Just above 1.0, e.g., 1.00...1)6031 TestCase{{1.0, PM100}, 32, true}6032 .with(RTZ, "1", Inexact)6033 .with(RDN, "1", Inexact)6034 .with(RUP, "2", Inexact)6035 .with(RNA, "1", Inexact)6036 .with(RNE, "1", Inexact),6037 6038 // Input: 1.0 - Epsilon (Just below 1.0, e.g. 0.999...)6039 TestCase{{1.0, -PM100}, 32, true}6040 .with(RTZ, "0", Inexact)6041 .with(RDN, "0", Inexact)6042 .with(RUP, "1", Inexact)6043 .with(RNA, "1", Inexact)6044 .with(RNE, "1", Inexact),6045 6046 // Input: Large number tie-breaking (Crucial test for DD implementation)6047 // Input: 2^53 + 1.5.6048 // A standard double(2^53 + 1.5) rounds to 2^53 + 2.0.6049 // The DD representation must precisely hold 2^53 + 1.5.6050 // The canonical DD representation is {2^53 + 2.0, -0.5}.6051 // Value is 9007199254740993.56052 TestCase{{P53 + 2.0, -0.5}, 64, true}6053 .with(RTZ, "9007199254740993", Inexact)6054 .with(RDN, "9007199254740993", Inexact)6055 .with(RUP, "9007199254740994", Inexact)6056 .with(RNA, "9007199254740994", Inexact)6057 .with(RNE, "9007199254740994", Inexact),6058 6059 // 4. Overflow Boundaries (Signed)6060 6061 // Input: Exactly INT64_MAX. (2^63 - 1)6062 // Represented precisely as (2^63, -1.0)6063 TestCase{{P63, -1.0}, 64, true}.withAll("9223372036854775807", OK),6064 6065 // Input: INT64_MAX + 0.3.6066 // Represented as (2^63, -0.7)6067 TestCase{{P63, -0.7}, 64, true}6068 .with(RTZ, "9223372036854775807", Inexact)6069 .with(RDN, "9223372036854775807", Inexact)6070 .with(RNA, "9223372036854775807", Inexact)6071 .with(RNE, "9223372036854775807", Inexact)6072 .with(RUP, "9223372036854775807", Invalid),6073 6074 // Input: INT64_MAX + 0.5 (Tie at the boundary)6075 // Represented as (2^63, -0.5). Target integers are MAX (odd) and 2^636076 // (even).6077 TestCase{{P63, -0.5}, 64, true}6078 .with(RTZ, "9223372036854775807", Inexact)6079 .with(RDN, "9223372036854775807", Inexact)6080 .with(RUP, "9223372036854775807", Invalid)6081 .with(RNA, "9223372036854775807", Invalid)6082 .with(RNE, "9223372036854775807", Invalid),6083 6084 // Input: 2^55 - 2^1 - 2^-52 to signed integer.6085 // Represented as (2^55 - 2^2, 2^1 - 2^-1).6086 TestCase{{0x1.fffffffffffffp+54, 0x1.8p0}, 56, true}6087 .with(RTZ, "36028797018963965", Inexact)6088 .with(RDN, "36028797018963965", Inexact)6089 .with(RUP, "36028797018963966", Inexact)6090 .with(RNA, "36028797018963966", Inexact)6091 .with(RNE, "36028797018963966", Inexact),6092 6093 // Input: 2^55 - 2^1 - 2^-52 to signed integer.6094 // Represented as (2^55 - 2^2, 2^1 - 2^-52).6095 TestCase{{0x1.fffffffffffffp+54, 0x1.fffffffffffffp0}, 56, true}6096 .with(RTZ, "36028797018963965", Inexact)6097 .with(RDN, "36028797018963965", Inexact)6098 .with(RUP, "36028797018963966", Inexact)6099 .with(RNA, "36028797018963966", Inexact)6100 .with(RNE, "36028797018963966", Inexact),6101 6102 // Input: Exactly 2^63 (One past INT64_MAX)6103 TestCase{{P63, 0.0}, 64, true}.withAll("9223372036854775807", Invalid),6104 6105 // Input: Exactly INT64_MIN (-2^63)6106 TestCase{{-P63, 0.0}, 64, true}.withAll("-9223372036854775808", OK),6107 6108 // Input: INT64_MIN - 0.5 (Tie at the lower boundary)6109 // Target integers are -2^63-1 (odd) and MIN (even).6110 TestCase{{-P63, -0.5}, 64, true}6111 .with(RTZ, "-9223372036854775808", Inexact)6112 .with(RUP, "-9223372036854775808", Inexact)6113 // RDN rounds down, causing overflow.6114 .with(RDN, "-9223372036854775808", Invalid)6115 // RNA rounds away (down), causing overflow.6116 .with(RNA, "-9223372036854775808", Invalid)6117 // RNE rounds to even (up to -2^63), which is OK.6118 .with(RNE, "-9223372036854775808", Inexact),6119 6120 // 5. Overflow Boundaries (Unsigned)6121 // UINT64_MAX = 18446744073709551615 (2^64 - 1)6122 6123 // Input: Exactly UINT64_MAX. (2^64 - 1)6124 // Represented precisely as (2^64, -1.0)6125 TestCase{{P64, -1.0}, 64, false}.withAll("18446744073709551615", OK),6126 6127 // Input: UINT64_MAX + 0.5 (Tie at the boundary)6128 // Represented as (2^64, -0.5)6129 TestCase{{P64, -0.5}, 64, false}6130 .with(RTZ, "18446744073709551615", Inexact)6131 .with(RDN, "18446744073709551615", Inexact)6132 // RUP rounds up (2^64), causing overflow.6133 .with(RUP, "18446744073709551615", Invalid)6134 // RNA rounds away (up), causing overflow.6135 .with(RNA, "18446744073709551615", Invalid)6136 // RNE rounds to even (up to 2^64), causing overflow.6137 .with(RNE, "18446744073709551615", Invalid),6138 6139 // Input: 2^55 - 2^1 - 2^-52 to unsigned integer.6140 // Represented as (2^55 - 2^2, 2^1 - 2^-1).6141 TestCase{{0x1.fffffffffffffp+54, 0x1.8p0}, 55, false}6142 .with(RTZ, "36028797018963965", Inexact)6143 .with(RDN, "36028797018963965", Inexact)6144 .with(RUP, "36028797018963966", Inexact)6145 .with(RNA, "36028797018963966", Inexact)6146 .with(RNE, "36028797018963966", Inexact),6147 6148 // Input: 2^55 - 2^1 - 2^-52 to unsigned integer.6149 // Represented as (2^55 - 2^2, 2^1 - 2^-52).6150 TestCase{{0x1.fffffffffffffp+54, 0x1.fffffffffffffp0}, 55, false}6151 .with(RTZ, "36028797018963965", Inexact)6152 .with(RDN, "36028797018963965", Inexact)6153 .with(RUP, "36028797018963966", Inexact)6154 .with(RNA, "36028797018963966", Inexact)6155 .with(RNE, "36028797018963966", Inexact),6156 6157 // Input: -0.3 (Slightly below zero)6158 TestCase{{-0.3, 0.0}, 64, false}6159 .with(RTZ, "0", Inexact)6160 .with(RUP, "0", Inexact)6161 .with(RNA, "0", Inexact)6162 .with(RNE, "0", Inexact)6163 .with(RDN, "0", Invalid),6164 6165 // Input: -0.5 (Tie at zero)6166 TestCase{{-0.5, 0.0}, 64, false}6167 .with(RTZ, "0", Inexact)6168 .with(RUP, "0", Inexact)6169 // RNE rounds to even (0).6170 .with(RNE, "0", Inexact)6171 .with(RDN, "0", Invalid)6172 // RNA rounds away (-1), causing overflow.6173 .with(RNA, "0", Invalid),6174 6175 // Input: -1.0 (Negative integer)6176 TestCase{{-1.0, 0.0}, 64, false}.withAll("0", Invalid),6177 6178 // 6. High Precision Integers (Target: 128-bit Signed)6179 // INT128_MAX = 1701411834604692317316873037158841057276180 6181 // Input: 2^100 (Exactly representable in DD)6182 // 2^100 = 1267650600228229401496703205376.06183 TestCase{{1267650600228229401496703205376.0, 0.0}, 128, true}.withAll(6184 "1267650600228229401496703205376", OK),6185 6186 // Input: DMAX. (Approx 1.8e308).6187 // This is vastly larger than INT128_MAX (Approx 1.7e38).6188 TestCase{{DMAX, 0.0}, 128, true}.withAll(6189 "170141183460469231731687303715884105727", Invalid),6190 6191 // Input: Largest semPPCDoubleDoubleLegacy6192 TestCase{{DMAX, 0x1.ffffffffffffep+969}, 128, true}.withAll(6193 "170141183460469231731687303715884105727", Invalid),6194 6195 // 7. Round to negative -06196 TestCase{{-PM100, 0.0}, 32, true}6197 .with(RTZ, "0", Inexact)6198 .with(RUP, "0", Inexact)6199 .with(RNA, "0", Inexact)6200 .with(RNE, "0", Inexact)6201 .with(RDN, "-1", Inexact),6202 };6203 return ConvertToIntegerTestCases;6204}6205} // namespace PPCDoubleDoubleConvertToIntegerTestDetails6206 6207class PPCDoubleDoubleConvertToIntegerValueTest6208 : public testing::Test,6209 public ::testing::WithParamInterface<6210 PPCDoubleDoubleConvertToIntegerTestDetails::TestCase> {};6211 6212INSTANTIATE_TEST_SUITE_P(6213 PPCDoubleDoubleConvertToIntegerValueParamTests,6214 PPCDoubleDoubleConvertToIntegerValueTest,6215 ::testing::ValuesIn(6216 PPCDoubleDoubleConvertToIntegerTestDetails::testCases()));6217 6218TEST_P(PPCDoubleDoubleConvertToIntegerValueTest,6219 PPCDoubleDoubleConvertToInteger) {6220 const PPCDoubleDoubleConvertToIntegerTestDetails::TestCase Params =6221 GetParam();6222 const APFloat Input = makeDoubleAPFloat(Params.Input);6223 EXPECT_FALSE(Input.isDenormal())6224 << Params.Input.Hi << " + " << Params.Input.Lo;6225 6226 for (size_t I = 0, E = std::size(Params.Rounded); I != E; ++I) {6227 const auto RM = static_cast<APFloat::roundingMode>(I);6228 const auto &Expected = Params.Rounded[I];6229 APSInt ActualInteger(Params.IntegerWidth, /*isUnsigned=*/!Params.IsSigned);6230 6231 APSInt ExpectedInteger{Expected.ExpectedIntStr};6232 EXPECT_LE(ExpectedInteger.getBitWidth(), Params.IntegerWidth);6233 ExpectedInteger = ExpectedInteger.extend(Params.IntegerWidth);6234 if (ExpectedInteger.isUnsigned() && Params.IsSigned) {6235 ExpectedInteger.setIsSigned(Params.IsSigned);6236 EXPECT_FALSE(ExpectedInteger.isNegative());6237 }6238 6239 const bool NegativeUnderflow =6240 ExpectedInteger.isZero() && Input.isNegative();6241 const bool ExpectedIsExact =6242 Expected.Status == APFloat::opOK && !NegativeUnderflow;6243 bool ActualIsExact;6244 const auto ActualStatus =6245 Input.convertToInteger(ActualInteger, RM, &ActualIsExact);6246 EXPECT_EQ(ActualStatus, Expected.Status);6247 EXPECT_EQ(ActualIsExact, ExpectedIsExact);6248 EXPECT_EQ(ActualInteger, ExpectedInteger);6249 }6250}6251 6252TEST(APFloatTest, PPCDoubleDoubleCompare) {6253 using DataType =6254 std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, APFloat::cmpResult>;6255 6256 DataType Data[] = {6257 // (1 + 0) = (1 + 0)6258 std::make_tuple(0x3ff0000000000000ull, 0, 0x3ff0000000000000ull, 0,6259 APFloat::cmpEqual),6260 // (1 + 0) < (1.00...1 + 0)6261 std::make_tuple(0x3ff0000000000000ull, 0, 0x3ff0000000000001ull, 0,6262 APFloat::cmpLessThan),6263 // (1.00...1 + 0) > (1 + 0)6264 std::make_tuple(0x3ff0000000000001ull, 0, 0x3ff0000000000000ull, 0,6265 APFloat::cmpGreaterThan),6266 // (1 + 0) < (1 + epsilon)6267 std::make_tuple(0x3ff0000000000000ull, 0, 0x3ff0000000000001ull,6268 0x0000000000000001ull, APFloat::cmpLessThan),6269 // NaN != NaN6270 std::make_tuple(0x7ff8000000000000ull, 0, 0x7ff8000000000000ull, 0,6271 APFloat::cmpUnordered),6272 // (1 + 0) != NaN6273 std::make_tuple(0x3ff0000000000000ull, 0, 0x7ff8000000000000ull, 0,6274 APFloat::cmpUnordered),6275 // Inf = Inf6276 std::make_tuple(0x7ff0000000000000ull, 0, 0x7ff0000000000000ull, 0,6277 APFloat::cmpEqual),6278 };6279 6280 for (auto Tp : Data) {6281 uint64_t Op1[2], Op2[2];6282 APFloat::cmpResult Expected;6283 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected) = Tp;6284 6285 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, Op1));6286 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, Op2));6287 EXPECT_EQ(Expected, A1.compare(A2))6288 << formatv("compare(({0:x} + {1:x}), ({2:x} + {3:x}))", Op1[0], Op1[1],6289 Op2[0], Op2[1])6290 .str();6291 }6292}6293 6294namespace PPCDoubleDoubleCompareAbsoluteValueTestDetails {6295struct TestCase {6296 DD LHS;6297 DD RHS;6298 APFloat::cmpResult Result;6299};6300 6301auto testCases() {6302 static constexpr auto CompareAbsoluteValueTestCases = std::array{6303 TestCase{6304 {1.0, 0.0},6305 {1.0, 0.0},6306 APFloat::cmpEqual,6307 },6308 TestCase{6309 {1.0, -0.0},6310 {1.0, +0.0},6311 APFloat::cmpEqual,6312 },6313 TestCase{6314 {1.0, 0.0},6315 {0x1.0000000000001p+0, 0.0},6316 APFloat::cmpLessThan,6317 },6318 TestCase{6319 {0x1.0000000000001p+0, 0.0},6320 {1.0, 0.0},6321 APFloat::cmpGreaterThan,6322 },6323 TestCase{6324 {0x1.0000000000001p+0, +0x1p-1074},6325 {1.0, -0x1p-1074},6326 APFloat::cmpGreaterThan,6327 },6328 TestCase{6329 {0x1.0000000000001p+0, -0x1p-1074},6330 {1.0, +0x1p-1074},6331 APFloat::cmpGreaterThan,6332 },6333 TestCase{6334 {1.0, 0.0},6335 {1.0, -0x1p-1074},6336 APFloat::cmpGreaterThan,6337 },6338 TestCase{6339 {1.0, 0.0},6340 {1.0, +0x1p-1074},6341 APFloat::cmpLessThan,6342 },6343 TestCase{6344 {1.0, +0x1p-1073},6345 {1.0, -0x1p-1074},6346 APFloat::cmpGreaterThan,6347 },6348 TestCase{6349 {1.0, +0x1p-1074},6350 {1.0, -0x1p-1074},6351 APFloat::cmpGreaterThan,6352 },6353 };6354 return CompareAbsoluteValueTestCases;6355}6356} // namespace PPCDoubleDoubleCompareAbsoluteValueTestDetails6357 6358class PPCDoubleDoubleCompareAbsoluteValueValueTest6359 : public testing::Test,6360 public ::testing::WithParamInterface<6361 PPCDoubleDoubleCompareAbsoluteValueTestDetails::TestCase> {};6362 6363INSTANTIATE_TEST_SUITE_P(6364 PPCDoubleDoubleCompareAbsoluteValueValueParamTests,6365 PPCDoubleDoubleCompareAbsoluteValueValueTest,6366 ::testing::ValuesIn(6367 PPCDoubleDoubleCompareAbsoluteValueTestDetails::testCases()));6368 6369TEST_P(PPCDoubleDoubleCompareAbsoluteValueValueTest,6370 PPCDoubleDoubleCompareAbsoluteValue) {6371 auto Param = GetParam();6372 for (bool LHSNegate : {false, true}) {6373 auto LHS = llvm::detail::DoubleAPFloat{APFloat::PPCDoubleDouble(),6374 APFloat{Param.LHS.Hi},6375 APFloat{Param.LHS.Lo}};6376 if (LHSNegate)6377 LHS.changeSign();6378 for (bool RHSNegate : {false, true}) {6379 auto RHS = llvm::detail::DoubleAPFloat{APFloat::PPCDoubleDouble(),6380 APFloat{Param.RHS.Hi},6381 APFloat{Param.RHS.Lo}};6382 if (RHSNegate)6383 RHS.changeSign();6384 6385 EXPECT_EQ(LHS.compareAbsoluteValue(RHS), Param.Result);6386 }6387 }6388}6389 6390TEST(APFloatTest, PPCDoubleDoubleBitwiseIsEqual) {6391 using DataType = std::tuple<uint64_t, uint64_t, uint64_t, uint64_t, bool>;6392 6393 DataType Data[] = {6394 // (1 + 0) = (1 + 0)6395 std::make_tuple(0x3ff0000000000000ull, 0, 0x3ff0000000000000ull, 0, true),6396 // (1 + 0) != (1.00...1 + 0)6397 std::make_tuple(0x3ff0000000000000ull, 0, 0x3ff0000000000001ull, 0,6398 false),6399 // NaN = NaN6400 std::make_tuple(0x7ff8000000000000ull, 0, 0x7ff8000000000000ull, 0, true),6401 // NaN != NaN with a different bit pattern6402 std::make_tuple(0x7ff8000000000000ull, 0, 0x7ff8000000000000ull,6403 0x3ff0000000000000ull, false),6404 // Inf = Inf6405 std::make_tuple(0x7ff0000000000000ull, 0, 0x7ff0000000000000ull, 0, true),6406 };6407 6408 for (auto Tp : Data) {6409 uint64_t Op1[2], Op2[2];6410 bool Expected;6411 std::tie(Op1[0], Op1[1], Op2[0], Op2[1], Expected) = Tp;6412 6413 APFloat A1(APFloat::PPCDoubleDouble(), APInt(128, Op1));6414 APFloat A2(APFloat::PPCDoubleDouble(), APInt(128, Op2));6415 EXPECT_EQ(Expected, A1.bitwiseIsEqual(A2))6416 << formatv("({0:x} + {1:x}) = ({2:x} + {3:x})", Op1[0], Op1[1], Op2[0],6417 Op2[1])6418 .str();6419 }6420}6421 6422TEST(APFloatTest, PPCDoubleDoubleHashValue) {6423 uint64_t Data1[] = {0x3ff0000000000001ull, 0x0000000000000001ull};6424 uint64_t Data2[] = {0x3ff0000000000001ull, 0};6425 // The hash values are *hopefully* different.6426 EXPECT_NE(hash_value(APFloat(APFloat::PPCDoubleDouble(), APInt(128, Data1))),6427 hash_value(APFloat(APFloat::PPCDoubleDouble(), APInt(128, Data2))));6428}6429 6430TEST(APFloatTest, PPCDoubleDoubleChangeSign) {6431 uint64_t Data[] = {6432 0x400f000000000000ull, 0xbcb0000000000000ull,6433 };6434 APFloat Float(APFloat::PPCDoubleDouble(), APInt(128, Data));6435 {6436 APFloat Actual =6437 APFloat::copySign(Float, APFloat(APFloat::IEEEdouble(), "1"));6438 EXPECT_EQ(0x400f000000000000ull, Actual.bitcastToAPInt().getRawData()[0]);6439 EXPECT_EQ(0xbcb0000000000000ull, Actual.bitcastToAPInt().getRawData()[1]);6440 }6441 {6442 APFloat Actual =6443 APFloat::copySign(Float, APFloat(APFloat::IEEEdouble(), "-1"));6444 EXPECT_EQ(0xc00f000000000000ull, Actual.bitcastToAPInt().getRawData()[0]);6445 EXPECT_EQ(0x3cb0000000000000ull, Actual.bitcastToAPInt().getRawData()[1]);6446 }6447}6448 6449TEST(APFloatTest, PPCDoubleDoubleFactories) {6450 {6451 uint64_t Data[] = {6452 0, 0,6453 };6454 EXPECT_EQ(APInt(128, Data),6455 APFloat::getZero(APFloat::PPCDoubleDouble()).bitcastToAPInt());6456 }6457 {6458 uint64_t Data[] = {6459 0x7fefffffffffffffull, 0x7c8ffffffffffffeull,6460 };6461 EXPECT_EQ(APInt(128, Data),6462 APFloat::getLargest(APFloat::PPCDoubleDouble()).bitcastToAPInt());6463 }6464 {6465 uint64_t Data[] = {6466 0x0000000000000001ull, 0,6467 };6468 EXPECT_EQ(6469 APInt(128, Data),6470 APFloat::getSmallest(APFloat::PPCDoubleDouble()).bitcastToAPInt());6471 }6472 {6473 uint64_t Data[] = {0x0360000000000000ull, 0};6474 EXPECT_EQ(APInt(128, Data),6475 APFloat::getSmallestNormalized(APFloat::PPCDoubleDouble())6476 .bitcastToAPInt());6477 }6478 {6479 uint64_t Data[] = {6480 0x8000000000000000ull, 0x0000000000000000ull,6481 };6482 EXPECT_EQ(6483 APInt(128, Data),6484 APFloat::getZero(APFloat::PPCDoubleDouble(), true).bitcastToAPInt());6485 }6486 {6487 uint64_t Data[] = {6488 0xffefffffffffffffull, 0xfc8ffffffffffffeull,6489 };6490 EXPECT_EQ(6491 APInt(128, Data),6492 APFloat::getLargest(APFloat::PPCDoubleDouble(), true).bitcastToAPInt());6493 }6494 {6495 uint64_t Data[] = {6496 0x8000000000000001ull, 0x0000000000000000ull,6497 };6498 EXPECT_EQ(APInt(128, Data),6499 APFloat::getSmallest(APFloat::PPCDoubleDouble(), true)6500 .bitcastToAPInt());6501 }6502 {6503 uint64_t Data[] = {6504 0x8360000000000000ull, 0x0000000000000000ull,6505 };6506 EXPECT_EQ(APInt(128, Data),6507 APFloat::getSmallestNormalized(APFloat::PPCDoubleDouble(), true)6508 .bitcastToAPInt());6509 }6510 EXPECT_TRUE(APFloat::getSmallest(APFloat::PPCDoubleDouble()).isSmallest());6511 EXPECT_TRUE(APFloat::getLargest(APFloat::PPCDoubleDouble()).isLargest());6512}6513 6514TEST(APFloatTest, PPCDoubleDoubleIsDenormal) {6515 EXPECT_TRUE(APFloat::getSmallest(APFloat::PPCDoubleDouble()).isDenormal());6516 EXPECT_FALSE(APFloat::getLargest(APFloat::PPCDoubleDouble()).isDenormal());6517 EXPECT_FALSE(6518 APFloat::getSmallestNormalized(APFloat::PPCDoubleDouble()).isDenormal());6519 {6520 // (4 + 3) is not normalized6521 uint64_t Data[] = {6522 0x4010000000000000ull, 0x4008000000000000ull,6523 };6524 EXPECT_TRUE(6525 APFloat(APFloat::PPCDoubleDouble(), APInt(128, Data)).isDenormal());6526 }6527}6528 6529TEST(APFloatTest, PPCDoubleDoubleScalbn) {6530 // 3.0 + 3.0 << 536531 uint64_t Input[] = {6532 0x4008000000000000ull, 0x3cb8000000000000ull,6533 };6534 APFloat Result =6535 scalbn(APFloat(APFloat::PPCDoubleDouble(), APInt(128, Input)), 1,6536 APFloat::rmNearestTiesToEven);6537 // 6.0 + 6.0 << 536538 EXPECT_EQ(0x4018000000000000ull, Result.bitcastToAPInt().getRawData()[0]);6539 EXPECT_EQ(0x3cc8000000000000ull, Result.bitcastToAPInt().getRawData()[1]);6540}6541 6542namespace PPCDoubleDoubleFrexpTestDetails {6543// Define the rounding modes for easier readability.6544static constexpr auto RNE = APFloat::rmNearestTiesToEven;6545static constexpr auto RNA = APFloat::rmNearestTiesToAway;6546static constexpr auto RTZ = APFloat::rmTowardZero;6547static constexpr auto RUP = APFloat::rmTowardPositive;6548static constexpr auto RDN = APFloat::rmTowardNegative;6549 6550struct TestCase {6551 // Structure to hold the expected result of a conversion6552 struct ExpectedFractionExponent {6553 DD Fraction;6554 int Exponent;6555 friend APFloat::cmpResult compare(const ExpectedFractionExponent &Lhs,6556 const ExpectedFractionExponent &Rhs) {6557 const APFloat LhsFraction = makeDoubleAPFloat(Lhs.Fraction);6558 const APFloat RhsFraction = makeDoubleAPFloat(Rhs.Fraction);6559 const APFloat::cmpResult FractionRelation =6560 LhsFraction.compare(RhsFraction);6561 if (FractionRelation == APFloat::cmpUnordered)6562 return APFloat::cmpUnordered;6563 if (LhsFraction.isZero() && RhsFraction.isZero())6564 return APFloat::cmpEqual;6565 if (!LhsFraction.isNegative() &&6566 (RhsFraction.isNegative() || RhsFraction.isZero()))6567 return APFloat::cmpGreaterThan;6568 if (!RhsFraction.isNegative() &&6569 (LhsFraction.isNegative() || LhsFraction.isZero()))6570 return APFloat::cmpLessThan;6571 if (Lhs.Exponent > Rhs.Exponent)6572 return LhsFraction.isNegative() ? APFloat::cmpLessThan6573 : APFloat::cmpGreaterThan;6574 if (Lhs.Exponent < Rhs.Exponent)6575 return RhsFraction.isNegative() ? APFloat::cmpGreaterThan6576 : APFloat::cmpLessThan;6577 return FractionRelation;6578 }6579 };6580 6581 DD Input;6582 // Array indexed by the rounding mode enum value.6583 std::array<ExpectedFractionExponent, 5> Rounded = {};6584 6585 // Helper to define the expected results for a specific rounding mode.6586 constexpr TestCase &with(APFloat::roundingMode RM, DD ExpectedDD,6587 int ExpectedExponent) {6588 Rounded[static_cast<std::underlying_type_t<APFloat::roundingMode>>(RM)] = {6589 ExpectedDD,6590 ExpectedExponent,6591 };6592 return *this;6593 }6594 6595 // Helper to define the same result for all rounding modes.6596 constexpr TestCase &withAll(DD ExpectedDD, int ExpectedExponent) {6597 return with(RNE, ExpectedDD, ExpectedExponent)6598 .with(RNA, ExpectedDD, ExpectedExponent)6599 .with(RTZ, ExpectedDD, ExpectedExponent)6600 .with(RUP, ExpectedDD, ExpectedExponent)6601 .with(RDN, ExpectedDD, ExpectedExponent);6602 }6603};6604 6605auto testCases() {6606 static constexpr auto FrexpTestCases = std::array{6607 // Input: +infinity6608 TestCase{{std::numeric_limits<double>::infinity(), 0.0}}.withAll(6609 {std::numeric_limits<double>::infinity(), 0.0}, INT_MAX),6610 6611 // Input: -infinity6612 TestCase{{-std::numeric_limits<double>::infinity(), 0.0}}.withAll(6613 {-std::numeric_limits<double>::infinity(), 0.0}, INT_MAX),6614 6615 // Input: NaN6616 TestCase{{std::numeric_limits<double>::quiet_NaN(), 0.0}}.withAll(6617 {std::numeric_limits<double>::quiet_NaN(), 0.0}, INT_MIN),6618 6619 // Input: 2^-10746620 TestCase{{0x1p-1074, 0.0}}.withAll({0x1p-1, 0.0}, -1073),6621 TestCase{{-0x1p-1074, 0.0}}.withAll({-0x1p-1, 0.0}, -1073),6622 6623 // Input: (2^1, -2^-1073 + -2^-1074)6624 TestCase{{0x1p1, -0x1.8p-1073}}6625 .withAll({0x1p0, -0x1p-1073}, 1)6626 .with(RNA, {0x1p0, -0x1p-1074}, 1)6627 .with(RUP, {0x1p0, -0x1p-1074}, 1),6628 TestCase{{-0x1p1, 0x1.8p-1073}}6629 .withAll({-0x1p0, 0x1p-1073}, 1)6630 .with(RNA, {-0x1p0, 0x1p-1074}, 1)6631 .with(RDN, {-0x1p0, 0x1p-1074}, 1),6632 6633 // Input: (2^1, -2^-1073)6634 TestCase{{0x1p1, -0x1p-1073}}.withAll({0x1p0, -0x1p-1074}, 1),6635 6636 // Input: (2^1, -2^-1074)6637 TestCase{{0x1p1, -0x1p-1074}}6638 .withAll({0x1p-1, -0.0}, 2)6639 .with(RDN, {0x1p0, -0x1p-1074}, 1)6640 .with(RTZ, {0x1p0, -0x1p-1074}, 1),6641 6642 // Input: (2^2, -2^-1072 + -2^-1073 + -2^-1074)6643 TestCase{{0x1p2, -0x1.cp-1072}}6644 .withAll({0x1p0, -0x1p-1073}, 2)6645 .with(RUP, {0x1p0, -0x1p-1074}, 2),6646 6647 // Input: (2^2, -2^-1072 + -2^-1073)6648 TestCase{{0x1p2, -0x1.8p-1072}}6649 .withAll({0x1p0, -0x1p-1073}, 2)6650 .with(RNA, {0x1p0, -0x1p-1074}, 2)6651 .with(RUP, {0x1p0, -0x1p-1074}, 2),6652 TestCase{{-0x1p2, 0x1.8p-1072}}6653 .withAll({-0x1p0, 0x1p-1073}, 2)6654 .with(RNA, {-0x1p0, 0x1p-1074}, 2)6655 .with(RDN, {-0x1p0, 0x1p-1074}, 2),6656 6657 // Input: (2^2, -2^-1072 + -2^-1074)6658 TestCase{{0x1p2, -0x1.4cp-1072}}6659 .withAll({0x1p0, -0x1p-1074}, 2)6660 .with(RDN, {0x1p0, -0x1p-1073}, 2)6661 .with(RTZ, {0x1p0, -0x1p-1073}, 2),6662 6663 // Input: (2^2, -2^-1072)6664 TestCase{{0x1p2, -0x1p-1072}}.withAll({0x1p0, -0x1p-1074}, 2),6665 6666 // Input: (2^2, -2^-1073 + -2^-1074)6667 TestCase{{0x1p2, -0x1.8p-1073}}6668 .withAll({0x1p0, -0x1p-1074}, 2)6669 .with(RUP, {0x1p-1, -0.0}, 3),6670 6671 // Input: (2^2, -2^-1073)6672 TestCase{{0x1p2, -0x1p-1073}}6673 .withAll({0x1p-1, -0.0}, 3)6674 .with(RDN, {0x1p0, -0x1p-1074}, 2)6675 .with(RTZ, {0x1p0, -0x1p-1074}, 2),6676 6677 // Input: (2^2, -2^-1074)6678 TestCase{{0x1p2, -0x1p-1074}}6679 .withAll({0x1p-1, -0.0}, 3)6680 .with(RDN, {0x1p0, -0x1p-1074}, 2)6681 .with(RTZ, {0x1p0, -0x1p-1074}, 2),6682 6683 // Input: 3+3*2^-53 canonicalized to (3+2^-51, -2^-53)6684 // Output: 0.75+0.75*2^-53 canonicalized to (.75+2^-53, -2^-55)6685 TestCase{{0x1.8000000000001p1, -0x1p-53}}.withAll(6686 {0x1.8000000000001p-1, -0x1p-55}, 2),6687 TestCase{{-0x1.8000000000001p1, 0x1p-53}}.withAll(6688 {-0x1.8000000000001p-1, 0x1p-55}, 2),6689 6690 // Input: (2^1021+2^969, 2^968-2^915)6691 TestCase{{0x1.0000000000001p1021, 0x1.fffffffffffffp967}}.withAll(6692 {0x1.0000000000001p-1, 0x1.fffffffffffffp-55}, 1022),6693 TestCase{{-0x1.0000000000001p1021, -0x1.fffffffffffffp967}}.withAll(6694 {-0x1.0000000000001p-1, -0x1.fffffffffffffp-55}, 1022),6695 6696 // Input: (2^1023, -2^-1)6697 TestCase{{0x1p+1023, -0x1p-1}}.withAll({0x1p0, -0x1p-1024}, 1023),6698 TestCase{{-0x1p+1023, 0x1p-1}}.withAll({-0x1p0, 0x1p-1024}, 1023),6699 6700 // Input: (2^1023, -2^-51)6701 TestCase{{0x1p+1023, -0x1p-51}}.withAll({0x1p0, -0x1p-1074}, 1023),6702 TestCase{{-0x1p+1023, 0x1p-51}}.withAll({-0x1p0, 0x1p-1074}, 1023),6703 6704 // Input: (2^1023, -2^-52)6705 TestCase{{0x1p+1023, -0x1p-52}}6706 .withAll({0x1p-1, -0x0p0}, 1024)6707 .with(RDN, {0x1p0, -0x1p-1074}, 1023)6708 .with(RTZ, {0x1p0, -0x1p-1074}, 1023),6709 TestCase{{-0x1p+1023, 0x1p-52}}6710 .withAll({-0x1p-1, 0x0p0}, 1024)6711 .with(RUP, {-0x1p0, 0x1p-1074}, 1023)6712 .with(RTZ, {-0x1p0, 0x1p-1074}, 1023),6713 6714 // Input: (2^1023, 2^-1074)6715 TestCase{{0x1p+1023, 0x1p-1074}}6716 .withAll({0x1p-1, 0x0p+0}, 1024)6717 .with(RUP, {0x1p-1, 0x1p-1074}, 1024),6718 TestCase{{-0x1p+1023, -0x1p-1074}}6719 .withAll({-0x1p-1, -0x0p+0}, 1024)6720 .with(RDN, {-0x1p-1, -0x1p-1074}, 1024),6721 6722 // Input: (2^1024-2^971, 2^970-2^918)6723 TestCase{{0x1.fffffffffffffp+1023, 0x1.ffffffffffffep+969}}.withAll(6724 {0x1.fffffffffffffp-1, 0x1.ffffffffffffep-55}, 1024),6725 TestCase{{-0x1.fffffffffffffp+1023, -0x1.ffffffffffffep+969}}.withAll(6726 {-0x1.fffffffffffffp-1, -0x1.ffffffffffffep-55}, 1024),6727 };6728 return FrexpTestCases;6729}6730} // namespace PPCDoubleDoubleFrexpTestDetails6731 6732class PPCDoubleDoubleFrexpValueTest6733 : public testing::Test,6734 public ::testing::WithParamInterface<6735 PPCDoubleDoubleFrexpTestDetails::TestCase> {};6736 6737INSTANTIATE_TEST_SUITE_P(6738 PPCDoubleDoubleFrexpValueParamTests, PPCDoubleDoubleFrexpValueTest,6739 ::testing::ValuesIn(PPCDoubleDoubleFrexpTestDetails::testCases()));6740 6741TEST_P(PPCDoubleDoubleFrexpValueTest, PPCDoubleDoubleFrexp) {6742 const PPCDoubleDoubleFrexpTestDetails::TestCase Params = GetParam();6743 const APFloat Input = makeDoubleAPFloat(Params.Input);6744 auto RmToIdx = [](APFloat::roundingMode RM) {6745 return static_cast<std::underlying_type_t<APFloat::roundingMode>>(RM);6746 };6747 // First, make sure our expected results are consistent with each other before6748 // bothering to test the implementation.6749 if (Input.isFinite()) {6750 // Make sure the input is canonical.6751 EXPECT_EQ(APFloat{Params.Input.Hi},6752 APFloat{Params.Input.Hi} + APFloat{Params.Input.Lo})6753 << Params.Input.Hi << " + " << Params.Input.Lo;6754 6755 const auto Dn = Params.Rounded[RmToIdx(APFloat::rmTowardNegative)];6756 const auto Up = Params.Rounded[RmToIdx(APFloat::rmTowardPositive)];6757 const auto Tz = Params.Rounded[RmToIdx(APFloat::rmTowardZero)];6758 const auto Ne = Params.Rounded[RmToIdx(APFloat::rmNearestTiesToEven)];6759 const auto Na = Params.Rounded[RmToIdx(APFloat::rmNearestTiesToAway)];6760 6761 // The rdn result must be no larger than the rup result.6762 const APFloat::cmpResult DnVsUp = compare(Dn, Up);6763 EXPECT_TRUE(DnVsUp == APFloat::cmpLessThan || DnVsUp == APFloat::cmpEqual);6764 6765 for (size_t I = 0, E = std::size(Params.Rounded); I != E; ++I) {6766 const APFloat RoundedFraction =6767 makeDoubleAPFloat(Params.Rounded[I].Fraction);6768 // All possible results should be bracketed by [Dn, Up].6769 const APFloat::cmpResult VsDn = compare(Params.Rounded[I], Dn);6770 EXPECT_TRUE(VsDn == APFloat::cmpGreaterThan || VsDn == APFloat::cmpEqual);6771 const APFloat::cmpResult VsUp = compare(Params.Rounded[I], Up);6772 EXPECT_TRUE(VsUp == APFloat::cmpLessThan || VsUp == APFloat::cmpEqual);6773 // A rounding result is either equal to the rup or rdn result.6774 EXPECT_TRUE(VsUp == APFloat::cmpEqual || VsDn == APFloat::cmpEqual);6775 // frexp returns a result whose magnitude is in in [.5, 1) so its exponent6776 // should be -1.6777 if (!RoundedFraction.isZero())6778 EXPECT_EQ(ilogb(RoundedFraction), -1)6779 << static_cast<APFloat::roundingMode>(I);6780 // Decomposition preserves sign.6781 EXPECT_EQ(RoundedFraction.isNegative(), Input.isNegative());6782 // A rounding result must be canonical.6783 EXPECT_EQ(APFloat{Params.Rounded[I].Fraction.Hi},6784 APFloat{Params.Rounded[I].Fraction.Hi} +6785 APFloat{Params.Rounded[I].Fraction.Lo})6786 << Params.Rounded[I].Fraction.Hi << " + "6787 << Params.Rounded[I].Fraction.Lo;6788 }6789 6790 // The rtz result must be either rup or rdn depending on the sign.6791 if (Input.isNegative()) {6792 const APFloat::cmpResult TzVsUp = compare(Tz, Up);6793 EXPECT_EQ(TzVsUp, APFloat::cmpEqual);6794 } else {6795 const APFloat::cmpResult TzVsDn = compare(Tz, Dn);6796 EXPECT_EQ(TzVsDn, APFloat::cmpEqual);6797 }6798 6799 // The recomposed up should be at least as big as the input.6800 const APFloat RecomposedUp =6801 scalbn(makeDoubleAPFloat(Up.Fraction), Up.Exponent,6802 APFloat::rmNearestTiesToEven);6803 EXPECT_TRUE(RecomposedUp >= Input);6804 // The recomposed down can't be larger than the input.6805 const APFloat RecomposedDn =6806 scalbn(makeDoubleAPFloat(Dn.Fraction), Dn.Exponent,6807 APFloat::rmNearestTiesToEven);6808 EXPECT_TRUE(RecomposedDn <= Input);6809 // The recomposed tz must have a smaller magnitude.6810 const APFloat RecomposedTz =6811 scalbn(makeDoubleAPFloat(Tz.Fraction), Tz.Exponent,6812 APFloat::rmNearestTiesToEven);6813 EXPECT_TRUE(abs(RecomposedTz) <= abs(Input));6814 // Either both or neither of the recomposed round-to-nearest results are6815 // equal to the input.6816 const APFloat RecomposedNe =6817 scalbn(makeDoubleAPFloat(Ne.Fraction), Ne.Exponent,6818 APFloat::rmNearestTiesToEven);6819 const APFloat RecomposedNa =6820 scalbn(makeDoubleAPFloat(Na.Fraction), Na.Exponent,6821 APFloat::rmNearestTiesToEven);6822 EXPECT_EQ(RecomposedNe == Input, RecomposedNa == Input);6823 // Either the ne result equals the na result or the na result has a bigger6824 // magnitude.6825 const APFloat::cmpResult NeVsNa =6826 abs(RecomposedNe).compare(abs(RecomposedNa));6827 EXPECT_TRUE(NeVsNa == APFloat::cmpLessThan || NeVsNa == APFloat::cmpEqual);6828 // ne and na may only disagree if they broke a tie differently.6829 if (NeVsNa == APFloat::cmpLessThan) {6830 // ne's magnitude should be lower than input.6831 const APFloat::cmpResult NeVsInput =6832 abs(RecomposedNe).compare(abs(Input));6833 EXPECT_EQ(NeVsInput, APFloat::cmpLessThan);6834 // na's magnitude should be greater than input.6835 const APFloat::cmpResult NaVsInput =6836 abs(RecomposedNa).compare(abs(Input));6837 EXPECT_EQ(NaVsInput, APFloat::cmpGreaterThan);6838 }6839 // If up or down perfectly reconstructs the input, the round-to-nearest6840 // results should too.6841 if (RecomposedUp == Input || RecomposedDn == Input) {6842 EXPECT_EQ(RecomposedNe, Input);6843 EXPECT_EQ(RecomposedNa, Input);6844 }6845 }6846 6847 for (size_t I = 0, E = std::size(Params.Rounded); I != E; ++I) {6848 const auto RM = static_cast<APFloat::roundingMode>(I);6849 const auto &Expected = Params.Rounded[I];6850 const APFloat ExpectedFraction = makeDoubleAPFloat(Expected.Fraction);6851 6852 int ActualExponent;6853 const APFloat ActualFraction = frexp(Input, ActualExponent, RM);6854 if (ExpectedFraction.isNaN())6855 EXPECT_TRUE(ActualFraction.isNaN());6856 else6857 EXPECT_EQ(ActualFraction.compare(ExpectedFraction), APFloat::cmpEqual)6858 << ActualFraction << " vs " << ExpectedFraction << " for input "6859 << Params.Input.Hi << " + " << Params.Input.Lo << " RM " << RM;6860 EXPECT_EQ(ActualExponent, Expected.Exponent)6861 << "for input " << Params.Input.Hi << " + " << Params.Input.Lo6862 << " RM " << RM;6863 }6864}6865 6866TEST(APFloatTest, PPCDoubleDoubleNext) {6867 auto NextUp = [](APFloat X) {6868 X.next(/*nextDown=*/false);6869 return X;6870 };6871 6872 auto NextDown = [](APFloat X) {6873 X.next(/*nextDown=*/true);6874 return X;6875 };6876 6877 auto Zero = [] { return APFloat::getZero(APFloat::IEEEdouble()); };6878 6879 auto One = [] { return APFloat::getOne(APFloat::IEEEdouble()); };6880 6881 // 0x1p-10746882 auto MinSubnormal = [] {6883 return APFloat::getSmallest(APFloat::IEEEdouble());6884 };6885 6886 // 2^-526887 auto Eps = [&] {6888 const fltSemantics &Sem = APFloat::IEEEdouble();6889 return scalbn(One(), 1 - APFloat::semanticsPrecision(Sem),6890 APFloat::rmNearestTiesToEven);6891 };6892 6893 // 2^-536894 auto EpsNeg = [&] { return scalbn(Eps(), -1, APFloat::rmNearestTiesToEven); };6895 6896 APFloat Test(APFloat::PPCDoubleDouble(), APFloat::uninitialized);6897 APFloat Expected(APFloat::PPCDoubleDouble(), APFloat::uninitialized);6898 6899 // 1. Test Special Cases Values.6900 //6901 // Test all special values for nextUp and nextDown prescribed by IEEE-754R6902 // 2008. These are:6903 // 1. +inf6904 // 2. -inf6905 // 3. getLargest()6906 // 4. -getLargest()6907 // 5. getSmallest()6908 // 6. -getSmallest()6909 // 7. qNaN6910 // 8. sNaN6911 // 9. +06912 // 10. -06913 6914 // nextUp(+inf) = +inf.6915 Test = APFloat::getInf(APFloat::PPCDoubleDouble(), false);6916 EXPECT_EQ(Test.next(false), APFloat::opOK);6917 EXPECT_TRUE(Test.isPosInfinity());6918 EXPECT_TRUE(!Test.isNegative());6919 6920 // nextDown(+inf) = -nextUp(-inf) = -(-getLargest()) = getLargest()6921 Test = APFloat::getInf(APFloat::PPCDoubleDouble(), false);6922 EXPECT_EQ(Test.next(true), APFloat::opOK);6923 EXPECT_FALSE(Test.isNegative());6924 EXPECT_TRUE(Test.isLargest());6925 6926 // nextUp(-inf) = -getLargest()6927 Test = APFloat::getInf(APFloat::PPCDoubleDouble(), true);6928 Expected = APFloat::getLargest(APFloat::PPCDoubleDouble(), true);6929 EXPECT_EQ(Test.next(false), APFloat::opOK);6930 EXPECT_TRUE(Test.isNegative());6931 EXPECT_TRUE(Test.isLargest());6932 EXPECT_TRUE(Test.bitwiseIsEqual(Expected));6933 6934 // nextDown(-inf) = -nextUp(+inf) = -(+inf) = -inf.6935 Test = APFloat::getInf(APFloat::PPCDoubleDouble(), true);6936 Expected = APFloat::getInf(APFloat::PPCDoubleDouble(), true);6937 EXPECT_EQ(Test.next(true), APFloat::opOK);6938 EXPECT_TRUE(Test.isNegInfinity());6939 EXPECT_TRUE(Test.bitwiseIsEqual(Expected));6940 6941 // nextUp(getLargest()) = +inf6942 Test = APFloat::getLargest(APFloat::PPCDoubleDouble(), false);6943 Expected = APFloat::getInf(APFloat::PPCDoubleDouble(), false);6944 EXPECT_EQ(Test.next(false), APFloat::opOK);6945 EXPECT_TRUE(Test.isPosInfinity());6946 EXPECT_TRUE(Test.bitwiseIsEqual(Expected));6947 6948 // nextUp(-getSmallest()) = -0.6949 Test = APFloat::getSmallest(Test.getSemantics(), /*Neg=*/true);6950 Expected = APFloat::getZero(APFloat::PPCDoubleDouble(), true);6951 EXPECT_EQ(Test.next(false), APFloat::opOK);6952 EXPECT_TRUE(Test.isNegZero());6953 EXPECT_TRUE(Test.bitwiseIsEqual(Expected));6954 6955 // nextDown(getSmallest()) = -nextUp(-getSmallest()) = -(-0) = +0.6956 Test = APFloat::getSmallest(Test.getSemantics(), /*Neg=*/false);6957 EXPECT_EQ(Test.next(true), APFloat::opOK);6958 EXPECT_TRUE(Test.isPosZero());6959 6960 // nextDown(-getLargest()) = -nextUp(getLargest()) = -(inf) = -inf.6961 Test = APFloat::getLargest(APFloat::PPCDoubleDouble(), true);6962 EXPECT_EQ(Test.next(true), APFloat::opOK);6963 EXPECT_TRUE(Test.isNegInfinity());6964 6965 // nextUp(qNaN) = qNaN6966 Test = APFloat::getQNaN(APFloat::PPCDoubleDouble(), false);6967 EXPECT_EQ(Test.next(false), APFloat::opOK);6968 EXPECT_TRUE(Test.isNaN());6969 EXPECT_FALSE(Test.isSignaling());6970 6971 // nextDown(qNaN) = qNaN6972 Test = APFloat::getQNaN(APFloat::PPCDoubleDouble(), false);6973 EXPECT_EQ(Test.next(true), APFloat::opOK);6974 EXPECT_TRUE(Test.isNaN());6975 EXPECT_FALSE(Test.isSignaling());6976 6977 // nextUp(sNaN) = qNaN6978 Test = APFloat::getSNaN(APFloat::PPCDoubleDouble(), false);6979 EXPECT_EQ(Test.next(false), APFloat::opInvalidOp);6980 EXPECT_TRUE(Test.isNaN());6981 EXPECT_FALSE(Test.isSignaling());6982 6983 // nextDown(sNaN) = qNaN6984 Test = APFloat::getSNaN(APFloat::PPCDoubleDouble(), false);6985 EXPECT_EQ(Test.next(true), APFloat::opInvalidOp);6986 EXPECT_TRUE(Test.isNaN());6987 EXPECT_FALSE(Test.isSignaling());6988 6989 // nextUp(+0) = +getSmallest()6990 Test = APFloat::getZero(APFloat::PPCDoubleDouble(), false);6991 EXPECT_EQ(Test.next(false), APFloat::opOK);6992 EXPECT_FALSE(Test.isNegative());6993 EXPECT_TRUE(Test.isSmallest());6994 6995 // nextDown(+0) = -nextUp(-0) = -getSmallest()6996 Test = APFloat::getZero(APFloat::PPCDoubleDouble(), false);6997 EXPECT_EQ(Test.next(true), APFloat::opOK);6998 EXPECT_TRUE(Test.isNegative());6999 EXPECT_TRUE(Test.isSmallest());7000 7001 // nextUp(-0) = +getSmallest()7002 Test = APFloat::getZero(APFloat::PPCDoubleDouble(), true);7003 EXPECT_EQ(Test.next(false), APFloat::opOK);7004 EXPECT_FALSE(Test.isNegative());7005 EXPECT_TRUE(Test.isSmallest());7006 7007 // nextDown(-0) = -nextUp(0) = -getSmallest()7008 Test = APFloat::getZero(APFloat::PPCDoubleDouble(), true);7009 EXPECT_EQ(Test.next(true), APFloat::opOK);7010 EXPECT_TRUE(Test.isNegative());7011 EXPECT_TRUE(Test.isSmallest());7012 7013 // 2. Cases where the lo APFloat is zero.7014 7015 // 2a. |hi| < 2*DBL_MIN_NORMAL (DD precision == D precision)7016 Test = APFloat(APFloat::PPCDoubleDouble(), "0x1.fffffffffffffp-1022");7017 Expected = APFloat(APFloat::PPCDoubleDouble(), "0x1p-1021");7018 EXPECT_EQ(Test.next(false), APFloat::opOK);7019 EXPECT_EQ(Test.compare(Expected), APFloat::cmpEqual);7020 7021 // 2b. |hi| >= 2*DBL_MIN_NORMAL (DD precision > D precision)7022 // Test at hi = 1.0, lo = 0.7023 Test = makeDoubleAPFloat(One(), Zero());7024 Expected = makeDoubleAPFloat(One(), MinSubnormal());7025 EXPECT_EQ(Test.next(false), APFloat::opOK);7026 EXPECT_TRUE(Test.bitwiseIsEqual(Expected));7027 7028 // Test at hi = -1.0. delta = 2^-1074 (positive, moving towards +Inf).7029 Test = makeDoubleAPFloat(-One(), Zero());7030 Expected = makeDoubleAPFloat(-One(), MinSubnormal());7031 EXPECT_EQ(Test.next(false), APFloat::opOK);7032 EXPECT_TRUE(Test.bitwiseIsEqual(Expected));7033 7034 // Testing the boundary where calculated delta equals DBL_TRUE_MIN.7035 // Requires ilogb(hi) = E = -968.7036 // delta = 2^(-968 - 106) = 2^-1074 = DBL_TRUE_MIN.7037 Test = makeDoubleAPFloat("0x1p-968", Zero());7038 Expected = makeDoubleAPFloat("0x1p-968", MinSubnormal());7039 EXPECT_EQ(Test.next(false), APFloat::opOK);7040 EXPECT_TRUE(Test.bitwiseIsEqual(Expected));7041 7042 // Testing below the boundary (E < -968). Delta clamps to DBL_TRUE_MIN.7043 Test = makeDoubleAPFloat("0x1p-969", Zero());7044 Expected = makeDoubleAPFloat("0x1p-969", MinSubnormal());7045 EXPECT_EQ(Test.next(false), APFloat::opOK);7046 EXPECT_TRUE(Test.bitwiseIsEqual(Expected));7047 7048 // 3. Standard Increment (No rollover)7049 // hi=1.0, lo=2^-1074.7050 Test = makeDoubleAPFloat(One(), MinSubnormal());7051 Expected = makeDoubleAPFloat(One(), NextUp(MinSubnormal()));7052 EXPECT_EQ(Test.next(false), APFloat::opOK);7053 EXPECT_TRUE(Test.bitwiseIsEqual(Expected));7054 7055 // Incrementing negative lo.7056 Test = makeDoubleAPFloat(One(), -MinSubnormal());7057 Expected = makeDoubleAPFloat(One(), Zero());7058 EXPECT_EQ(Test.next(false), APFloat::opOK);7059 EXPECT_EQ(Test.compare(Expected), APFloat::cmpEqual);7060 7061 // Crossing lo=0.7062 Test = makeDoubleAPFloat(One(), -MinSubnormal());7063 Expected = makeDoubleAPFloat(One(), Zero());7064 EXPECT_EQ(Test.next(false), APFloat::opOK);7065 EXPECT_EQ(Test.compare(Expected), APFloat::cmpEqual);7066 7067 // 4. Rollover Cases around 1.0 (Positive hi)7068 // hi=1.0, lo=nextDown(2^-53).7069 Test = makeDoubleAPFloat(One(), NextDown(EpsNeg()));7070 EXPECT_FALSE(Test.isDenormal());7071 Expected = makeDoubleAPFloat(One(), EpsNeg());7072 EXPECT_FALSE(Test.isDenormal());7073 EXPECT_EQ(Test.next(false), APFloat::opOK);7074 EXPECT_TRUE(Test.bitwiseIsEqual(Expected));7075 7076 // Input: (1, ulp(1)/2). nextUp(lo)=next(H). V>Midpoint. Rollover occurs7077 // Can't naively increment lo:7078 // RTNE(0x1p+0 + 0x1.0000000000001p-53) == 0x1.0000000000001p+0.7079 // Can't naively TwoSum(0x1p+0, nextUp(0x1p-53)):7080 // It gives {nextUp(0x1p+0), nextUp(nextUp(-0x1p-53))} but the next7081 // number should be {nextUp(0x1p+0), nextUp(-0x1p-53)}.7082 Test = makeDoubleAPFloat(One(), EpsNeg());7083 EXPECT_FALSE(Test.isDenormal());7084 Expected = makeDoubleAPFloat(NextUp(One()), NextUp(-EpsNeg()));7085 EXPECT_EQ(Test.next(false), APFloat::opOK);7086 EXPECT_TRUE(Test.bitwiseIsEqual(Expected));7087 EXPECT_FALSE(Test.isDenormal());7088 7089 // hi = nextDown(1), lo = nextDown(0x1p-54)7090 Test = makeDoubleAPFloat(NextDown(One()), NextDown(APFloat(0x1p-54)));7091 EXPECT_FALSE(Test.isDenormal());7092 Expected = makeDoubleAPFloat(One(), APFloat(-0x1p-54));7093 EXPECT_EQ(Test.next(false), APFloat::opOK);7094 EXPECT_TRUE(Test.bitwiseIsEqual(Expected));7095 EXPECT_FALSE(Test.isDenormal());7096 7097 // 5. Negative Rollover (Moving towards Zero / +Inf)7098 7099 // hi = -1, lo = nextDown(0x1p-54)7100 Test = makeDoubleAPFloat(APFloat(-1.0), NextDown(APFloat(0x1p-54)));7101 EXPECT_FALSE(Test.isDenormal());7102 Expected = makeDoubleAPFloat(APFloat(-1.0), APFloat(0x1p-54));7103 EXPECT_EQ(Test.next(false), APFloat::opOK);7104 EXPECT_TRUE(Test.bitwiseIsEqual(Expected));7105 EXPECT_FALSE(Test.isDenormal());7106 7107 // hi = -1, lo = 0x1p-547108 Test = makeDoubleAPFloat(APFloat(-1.0), APFloat(0x1p-54));7109 EXPECT_FALSE(Test.isDenormal());7110 Expected =7111 makeDoubleAPFloat(NextUp(APFloat(-1.0)), NextUp(APFloat(-0x1p-54)));7112 EXPECT_EQ(Test.next(false), APFloat::opOK);7113 EXPECT_TRUE(Test.bitwiseIsEqual(Expected));7114 EXPECT_FALSE(Test.isDenormal());7115 7116 // 6. Rollover across Power of 2 boundary (Exponent change)7117 Test = makeDoubleAPFloat(NextDown(APFloat(2.0)), NextDown(EpsNeg()));7118 EXPECT_FALSE(Test.isDenormal());7119 Expected = makeDoubleAPFloat(APFloat(2.0), -EpsNeg());7120 EXPECT_EQ(Test.next(false), APFloat::opOK);7121 EXPECT_TRUE(Test.bitwiseIsEqual(Expected));7122 EXPECT_FALSE(Test.isDenormal());7123}7124 7125TEST(APFloatTest, PPCDoubleDoubleConvertFromAPIntInexact) {7126 // Create an integer which would not be exactly representable in7127 // PPCDoubleDoubleLegacy.7128 for (bool IsSigned : {false, true}) {7129 const unsigned BitWidth =7130 APFloat::semanticsPrecision(APFloat::IEEEdouble()) * 3 +7131 (IsSigned ? 1 : 0);7132 7133 for (bool Negative :7134 IsSigned ? std::vector{false, true} : std::vector{false}) {7135 APInt Huge = APInt{BitWidth, 0};7136 // Set the highest bit without making Huge negative..7137 Huge.setBit(BitWidth - (IsSigned ? 2 : 1));7138 // Set the low bit.7139 Huge.setBit(0);7140 if (Negative)7141 Huge.negate();7142 for (const APFloat::roundingMode RM :7143 {APFloat::rmNearestTiesToAway, APFloat::rmTowardNegative,7144 APFloat::rmTowardPositive, APFloat::rmTowardZero,7145 APFloat::rmNearestTiesToEven}) {7146 APFloat F{APFloat::PPCDoubleDouble()};7147 const APFloat::opStatus ConvertFromStatus =7148 F.convertFromAPInt(Huge, /*IsSigned=*/IsSigned, RM);7149 EXPECT_EQ(ConvertFromStatus, APFloat::opOK);7150 7151 bool IsExact;7152 APSInt ResultInt{Huge.getBitWidth(), /*isUnsigned=*/!IsSigned};7153 const APFloat::opStatus ConvertToStatus =7154 F.convertToInteger(ResultInt, APFloat::rmTowardZero, &IsExact);7155 7156 EXPECT_TRUE(IsExact) << "RM: " << RM;7157 EXPECT_TRUE(ResultInt.eq(Huge)) << ResultInt << " vs " << Huge << "\n";7158 EXPECT_EQ(ConvertToStatus, APFloat::opOK);7159 }7160 }7161 }7162}7163 7164TEST(APFloatTest, PPCDoubleDoubleConvertFromAPIntBoundary) {7165 const unsigned Binary64Precision =7166 APFloat::semanticsPrecision(APFloat::IEEEdouble());7167 APSInt Boundary =7168 APSInt::getMaxValue(Binary64Precision + 1, /*Unsigned=*/true);7169 for (const APFloat::roundingMode RM :7170 {APFloat::rmNearestTiesToAway, APFloat::rmTowardNegative,7171 APFloat::rmTowardPositive, APFloat::rmTowardZero,7172 APFloat::rmNearestTiesToEven}) {7173 const APFloat Exact = makeDoubleAPFloat(0x1p54, -0x1p0);7174 APFloat F{APFloat::PPCDoubleDouble()};7175 const APFloat::opStatus ConvertFromStatus =7176 F.convertFromAPInt(Boundary, /*IsSigned=*/false, RM);7177 EXPECT_EQ(ConvertFromStatus, APFloat::opOK);7178 EXPECT_EQ(F, Exact);7179 }7180 7181 Boundary = APSInt{APInt::getHighBitsSet(/*numBits=*/128,7182 /*hiBitsSet=*/Binary64Precision + 1),7183 /*isUnsigned=*/true};7184 for (const APFloat::roundingMode RM :7185 {APFloat::rmNearestTiesToAway, APFloat::rmTowardNegative,7186 APFloat::rmTowardPositive, APFloat::rmTowardZero,7187 APFloat::rmNearestTiesToEven}) {7188 const APFloat Exact = makeDoubleAPFloat(0x1p128, -0x1p74);7189 APFloat F{APFloat::PPCDoubleDouble()};7190 const APFloat::opStatus ConvertFromStatus =7191 F.convertFromAPInt(Boundary, /*IsSigned=*/false, RM);7192 EXPECT_EQ(ConvertFromStatus, APFloat::opOK);7193 EXPECT_EQ(F, Exact);7194 }7195}7196 7197TEST(APFloatTest, PPCDoubleDoubleConvertFromAPIntEnormous) {7198 APFloat Largest = APFloat::getLargest(APFloat::PPCDoubleDouble());7199 int Exponent = ilogb(Largest);7200 unsigned BitWidth = Exponent + 1;7201 APSInt HugeInt{BitWidth, /*isUnsigned=*/true};7202 bool IsExact;7203 APFloat::opStatus Status =7204 Largest.convertToInteger(HugeInt, APFloat::rmTowardPositive, &IsExact);7205 ASSERT_EQ(Status, APFloat::opOK);7206 ASSERT_TRUE(IsExact);7207 7208 for (const APFloat::roundingMode RM :7209 {APFloat::rmNearestTiesToAway, APFloat::rmTowardNegative,7210 APFloat::rmTowardPositive, APFloat::rmTowardZero,7211 APFloat::rmNearestTiesToEven}) {7212 APFloat F{APFloat::PPCDoubleDouble()};7213 const APFloat::opStatus ConvertFromStatus =7214 F.convertFromAPInt(HugeInt, /*IsSigned=*/false, RM);7215 EXPECT_EQ(ConvertFromStatus, APFloat::opOK);7216 EXPECT_EQ(F, Largest);7217 }7218 7219 const unsigned MaxExponent =7220 APFloat::semanticsMaxExponent(APFloat::IEEEdouble());7221 const unsigned Binary64Precision =7222 APFloat::semanticsPrecision(APFloat::IEEEdouble());7223 const unsigned UlpOfLargest = MaxExponent - (2 * Binary64Precision);7224 const unsigned HalfUlpOfLargest = UlpOfLargest - 1;7225 7226 // Add just under a half-ulp. This should never overflow for7227 // round-ties-to-nearest modes.7228 HugeInt.setLowBits(HalfUlpOfLargest);7229 for (const APFloat::roundingMode RM :7230 {APFloat::rmNearestTiesToAway, APFloat::rmTowardNegative,7231 APFloat::rmTowardPositive, APFloat::rmTowardZero,7232 APFloat::rmNearestTiesToEven}) {7233 APFloat F{APFloat::PPCDoubleDouble()};7234 const APFloat::opStatus ConvertFromStatus =7235 F.convertFromAPInt(HugeInt, /*IsSigned=*/false, RM);7236 if (RM == APFloat::rmTowardPositive) {7237 EXPECT_TRUE(F.isPosInfinity()) << F;7238 EXPECT_EQ(ConvertFromStatus, APFloat::opInexact | APFloat::opOverflow);7239 } else {7240 EXPECT_EQ(F, Largest);7241 EXPECT_EQ(ConvertFromStatus, APFloat::opInexact);7242 }7243 }7244 7245 // Now test adding a half-ulp. This should cause overflow for ties-to-away.7246 // ties-to-even will not overflow if the max finite value has a clear low bit.7247 ++HugeInt;7248 for (const APFloat::roundingMode RM :7249 {APFloat::rmNearestTiesToAway, APFloat::rmTowardNegative,7250 APFloat::rmTowardPositive, APFloat::rmTowardZero,7251 APFloat::rmNearestTiesToEven}) {7252 APFloat F{APFloat::PPCDoubleDouble()};7253 const APFloat::opStatus ConvertFromStatus =7254 F.convertFromAPInt(HugeInt, /*IsSigned=*/false, RM);7255 const bool Overflow =7256 RM == APFloat::rmTowardPositive || RM == APFloat::rmNearestTiesToAway ||7257 (RM == APFloat::rmNearestTiesToEven && HugeInt[UlpOfLargest]);7258 if (Overflow) {7259 EXPECT_TRUE(F.isPosInfinity()) << F;7260 EXPECT_EQ(ConvertFromStatus, APFloat::opInexact | APFloat::opOverflow);7261 } else {7262 EXPECT_EQ(F, Largest);7263 EXPECT_EQ(ConvertFromStatus, APFloat::opInexact);7264 }7265 }7266 7267 // Now test adding just over a half-ulp. This should break all ties.7268 ++HugeInt;7269 for (const APFloat::roundingMode RM :7270 {APFloat::rmNearestTiesToAway, APFloat::rmTowardNegative,7271 APFloat::rmTowardPositive, APFloat::rmTowardZero,7272 APFloat::rmNearestTiesToEven}) {7273 APFloat F{APFloat::PPCDoubleDouble()};7274 const APFloat::opStatus ConvertFromStatus =7275 F.convertFromAPInt(HugeInt, /*IsSigned=*/false, RM);7276 const bool Overflow = RM == APFloat::rmTowardPositive ||7277 RM == APFloat::rmNearestTiesToAway ||7278 RM == APFloat::rmNearestTiesToEven;7279 if (Overflow) {7280 EXPECT_TRUE(F.isPosInfinity()) << F;7281 EXPECT_EQ(ConvertFromStatus, APFloat::opInexact | APFloat::opOverflow);7282 } else {7283 EXPECT_EQ(F, Largest);7284 EXPECT_EQ(ConvertFromStatus, APFloat::opInexact);7285 }7286 }7287 7288 HugeInt.setAllBits();7289 for (const APFloat::roundingMode RM :7290 {APFloat::rmNearestTiesToAway, APFloat::rmTowardNegative,7291 APFloat::rmTowardPositive, APFloat::rmTowardZero,7292 APFloat::rmNearestTiesToEven}) {7293 APFloat F{APFloat::PPCDoubleDouble()};7294 const APFloat::opStatus ConvertFromStatus =7295 F.convertFromAPInt(HugeInt, /*IsSigned=*/false, RM);7296 const bool Overflow = RM == APFloat::rmTowardPositive ||7297 RM == APFloat::rmNearestTiesToAway ||7298 RM == APFloat::rmNearestTiesToEven;7299 if (Overflow) {7300 EXPECT_TRUE(F.isPosInfinity()) << F;7301 EXPECT_EQ(ConvertFromStatus, APFloat::opInexact | APFloat::opOverflow);7302 } else {7303 EXPECT_EQ(F, Largest);7304 EXPECT_EQ(ConvertFromStatus, APFloat::opInexact);7305 }7306 }7307 7308 HugeInt.clearAllBits();7309 HugeInt.setBit(2 * Binary64Precision + 1);7310 HugeInt.setLowBits(Binary64Precision + 1);7311 for (const APFloat::roundingMode RM :7312 {APFloat::rmNearestTiesToAway, APFloat::rmTowardNegative,7313 APFloat::rmTowardPositive, APFloat::rmTowardZero,7314 APFloat::rmNearestTiesToEven}) {7315 const APFloat RoundUp = makeDoubleAPFloat(0x1p107, 0x1p54);7316 const APFloat RoundDown = makeDoubleAPFloat(0x1p107, 0x1.fffffffffffffp53);7317 APFloat F{APFloat::PPCDoubleDouble()};7318 const APFloat::opStatus ConvertFromStatus =7319 F.convertFromAPInt(HugeInt, /*IsSigned=*/false, RM);7320 EXPECT_EQ(ConvertFromStatus, APFloat::opInexact);7321 7322 if (RM == APFloat::rmNearestTiesToEven ||7323 RM == APFloat::rmNearestTiesToAway || RM == APFloat::rmTowardPositive)7324 EXPECT_EQ(F, RoundUp);7325 else7326 EXPECT_EQ(F, RoundDown);7327 }7328 7329 ++HugeInt;7330 // 162259276829213381405976519770112 can be represented exactly.7331 for (const APFloat::roundingMode RM :7332 {APFloat::rmNearestTiesToAway, APFloat::rmTowardNegative,7333 APFloat::rmTowardPositive, APFloat::rmTowardZero,7334 APFloat::rmNearestTiesToEven}) {7335 const APFloat Exact = makeDoubleAPFloat(0x1p107, 0x1p54);7336 APFloat F{APFloat::PPCDoubleDouble()};7337 const APFloat::opStatus ConvertFromStatus =7338 F.convertFromAPInt(HugeInt, /*IsSigned=*/false, RM);7339 EXPECT_EQ(ConvertFromStatus, APFloat::opOK);7340 EXPECT_EQ(F, Exact);7341 }7342 7343 ++HugeInt;7344 // 162259276829213381405976519770113 rounds to either:7345 // 1622592768292133814059765197701127346 // 1622592768292133814059765197701147347 for (const APFloat::roundingMode RM :7348 {APFloat::rmNearestTiesToAway, APFloat::rmTowardNegative,7349 APFloat::rmTowardPositive, APFloat::rmTowardZero,7350 APFloat::rmNearestTiesToEven}) {7351 const APFloat RoundUp =7352 makeDoubleAPFloat(0x1.0000000000001p107, -0x1.fffffffffffffp53);7353 const APFloat RoundDown = makeDoubleAPFloat(0x1p107, 0x1p54);7354 EXPECT_LT(RoundDown, RoundUp);7355 7356 APFloat F{APFloat::PPCDoubleDouble()};7357 const APFloat::opStatus ConvertFromStatus =7358 F.convertFromAPInt(HugeInt, /*IsSigned=*/false, RM);7359 EXPECT_EQ(ConvertFromStatus, APFloat::opInexact);7360 7361 if (RM == APFloat::rmNearestTiesToAway || RM == APFloat::rmTowardPositive)7362 EXPECT_EQ(F, RoundUp);7363 else7364 EXPECT_EQ(F, RoundDown);7365 }7366}7367 7368TEST(APFloatTest, x87Largest) {7369 APFloat MaxX87Val = APFloat::getLargest(APFloat::x87DoubleExtended());7370 EXPECT_TRUE(MaxX87Val.isLargest());7371}7372 7373TEST(APFloatTest, x87Next) {7374 APFloat F(APFloat::x87DoubleExtended(), "-1.0");7375 F.next(false);7376 EXPECT_TRUE(ilogb(F) == -1);7377}7378 7379TEST(APFloatTest, Float8ExhaustivePair) {7380 // Test each pair of 8-bit floats with non-standard semantics7381 for (APFloat::Semantics Sem :7382 {APFloat::S_Float8E4M3FN, APFloat::S_Float8E5M2FNUZ,7383 APFloat::S_Float8E4M3FNUZ, APFloat::S_Float8E4M3B11FNUZ}) {7384 const llvm::fltSemantics &S = APFloat::EnumToSemantics(Sem);7385 for (int i = 0; i < 256; i++) {7386 for (int j = 0; j < 256; j++) {7387 SCOPED_TRACE("sem=" + std::to_string(Sem) + ",i=" + std::to_string(i) +7388 ",j=" + std::to_string(j));7389 APFloat x(S, APInt(8, i));7390 APFloat y(S, APInt(8, j));7391 7392 bool losesInfo;7393 APFloat x16 = x;7394 x16.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven,7395 &losesInfo);7396 EXPECT_FALSE(losesInfo);7397 APFloat y16 = y;7398 y16.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven,7399 &losesInfo);7400 EXPECT_FALSE(losesInfo);7401 7402 // Add7403 APFloat z = x;7404 z.add(y, APFloat::rmNearestTiesToEven);7405 APFloat z16 = x16;7406 z16.add(y16, APFloat::rmNearestTiesToEven);7407 z16.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);7408 EXPECT_TRUE(z.bitwiseIsEqual(z16))7409 << "sem=" << Sem << ", i=" << i << ", j=" << j;7410 7411 // Subtract7412 z = x;7413 z.subtract(y, APFloat::rmNearestTiesToEven);7414 z16 = x16;7415 z16.subtract(y16, APFloat::rmNearestTiesToEven);7416 z16.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);7417 EXPECT_TRUE(z.bitwiseIsEqual(z16))7418 << "sem=" << Sem << ", i=" << i << ", j=" << j;7419 7420 // Multiply7421 z = x;7422 z.multiply(y, APFloat::rmNearestTiesToEven);7423 z16 = x16;7424 z16.multiply(y16, APFloat::rmNearestTiesToEven);7425 z16.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);7426 EXPECT_TRUE(z.bitwiseIsEqual(z16))7427 << "sem=" << Sem << ", i=" << i << ", j=" << j;7428 7429 // Divide7430 z = x;7431 z.divide(y, APFloat::rmNearestTiesToEven);7432 z16 = x16;7433 z16.divide(y16, APFloat::rmNearestTiesToEven);7434 z16.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);7435 EXPECT_TRUE(z.bitwiseIsEqual(z16))7436 << "sem=" << Sem << ", i=" << i << ", j=" << j;7437 7438 // Mod7439 z = x;7440 z.mod(y);7441 z16 = x16;7442 z16.mod(y16);7443 z16.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);7444 EXPECT_TRUE(z.bitwiseIsEqual(z16))7445 << "sem=" << Sem << ", i=" << i << ", j=" << j;7446 7447 // Remainder7448 z = x;7449 z.remainder(y);7450 z16 = x16;7451 z16.remainder(y16);7452 z16.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);7453 EXPECT_TRUE(z.bitwiseIsEqual(z16))7454 << "sem=" << Sem << ", i=" << i << ", j=" << j;7455 }7456 }7457 }7458}7459 7460TEST(APFloatTest, Float8E8M0FNUExhaustivePair) {7461 // Test each pair of 8-bit values for Float8E8M0FNU format7462 APFloat::Semantics Sem = APFloat::S_Float8E8M0FNU;7463 const llvm::fltSemantics &S = APFloat::EnumToSemantics(Sem);7464 for (int i = 0; i < 256; i++) {7465 for (int j = 0; j < 256; j++) {7466 SCOPED_TRACE("sem=" + std::to_string(Sem) + ",i=" + std::to_string(i) +7467 ",j=" + std::to_string(j));7468 APFloat x(S, APInt(8, i));7469 APFloat y(S, APInt(8, j));7470 7471 bool losesInfo;7472 APFloat xd = x;7473 xd.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,7474 &losesInfo);7475 EXPECT_FALSE(losesInfo);7476 APFloat yd = y;7477 yd.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,7478 &losesInfo);7479 EXPECT_FALSE(losesInfo);7480 7481 // Add7482 APFloat z = x;7483 z.add(y, APFloat::rmNearestTiesToEven);7484 APFloat zd = xd;7485 zd.add(yd, APFloat::rmNearestTiesToEven);7486 zd.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);7487 EXPECT_TRUE(z.bitwiseIsEqual(zd))7488 << "sem=" << Sem << ", i=" << i << ", j=" << j;7489 7490 // Subtract7491 if (i >= j) {7492 z = x;7493 z.subtract(y, APFloat::rmNearestTiesToEven);7494 zd = xd;7495 zd.subtract(yd, APFloat::rmNearestTiesToEven);7496 zd.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);7497 EXPECT_TRUE(z.bitwiseIsEqual(zd))7498 << "sem=" << Sem << ", i=" << i << ", j=" << j;7499 }7500 7501 // Multiply7502 z = x;7503 z.multiply(y, APFloat::rmNearestTiesToEven);7504 zd = xd;7505 zd.multiply(yd, APFloat::rmNearestTiesToEven);7506 zd.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);7507 EXPECT_TRUE(z.bitwiseIsEqual(zd))7508 << "sem=" << Sem << ", i=" << i << ", j=" << j;7509 7510 // Divide7511 z = x;7512 z.divide(y, APFloat::rmNearestTiesToEven);7513 zd = xd;7514 zd.divide(yd, APFloat::rmNearestTiesToEven);7515 zd.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);7516 EXPECT_TRUE(z.bitwiseIsEqual(zd))7517 << "sem=" << Sem << ", i=" << i << ", j=" << j;7518 7519 // Mod7520 z = x;7521 z.mod(y);7522 zd = xd;7523 zd.mod(yd);7524 zd.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);7525 EXPECT_TRUE(z.bitwiseIsEqual(zd))7526 << "sem=" << Sem << ", i=" << i << ", j=" << j;7527 APFloat mod_cached = z;7528 // When one of them is a NaN, the result is a NaN.7529 // When i < j, the mod is 'i' since it is the smaller7530 // number. Otherwise the mod is always zero since7531 // both x and y are powers-of-two in this format.7532 // Since this format does not support zero and it is7533 // represented as the smallest normalized value, we7534 // test for isSmallestNormalized().7535 if (i == 255 || j == 255)7536 EXPECT_TRUE(z.isNaN());7537 else if (i >= j)7538 EXPECT_TRUE(z.isSmallestNormalized());7539 else7540 EXPECT_TRUE(z.bitwiseIsEqual(x));7541 7542 // Remainder7543 z = x;7544 z.remainder(y);7545 zd = xd;7546 zd.remainder(yd);7547 zd.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);7548 EXPECT_TRUE(z.bitwiseIsEqual(zd))7549 << "sem=" << Sem << ", i=" << i << ", j=" << j;7550 // Since this format has only exponents (i.e. no precision)7551 // we expect the remainder and mod to provide the same results.7552 EXPECT_TRUE(z.bitwiseIsEqual(mod_cached))7553 << "sem=" << Sem << ", i=" << i << ", j=" << j;7554 }7555 }7556}7557 7558TEST(APFloatTest, Float6ExhaustivePair) {7559 // Test each pair of 6-bit floats with non-standard semantics7560 for (APFloat::Semantics Sem :7561 {APFloat::S_Float6E3M2FN, APFloat::S_Float6E2M3FN}) {7562 const llvm::fltSemantics &S = APFloat::EnumToSemantics(Sem);7563 for (int i = 1; i < 64; i++) {7564 for (int j = 1; j < 64; j++) {7565 SCOPED_TRACE("sem=" + std::to_string(Sem) + ",i=" + std::to_string(i) +7566 ",j=" + std::to_string(j));7567 APFloat x(S, APInt(6, i));7568 APFloat y(S, APInt(6, j));7569 7570 bool losesInfo;7571 APFloat x16 = x;7572 x16.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven,7573 &losesInfo);7574 EXPECT_FALSE(losesInfo);7575 APFloat y16 = y;7576 y16.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven,7577 &losesInfo);7578 EXPECT_FALSE(losesInfo);7579 7580 // Add7581 APFloat z = x;7582 z.add(y, APFloat::rmNearestTiesToEven);7583 APFloat z16 = x16;7584 z16.add(y16, APFloat::rmNearestTiesToEven);7585 z16.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);7586 EXPECT_TRUE(z.bitwiseIsEqual(z16))7587 << "sem=" << Sem << ", i=" << i << ", j=" << j;7588 7589 // Subtract7590 z = x;7591 z.subtract(y, APFloat::rmNearestTiesToEven);7592 z16 = x16;7593 z16.subtract(y16, APFloat::rmNearestTiesToEven);7594 z16.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);7595 EXPECT_TRUE(z.bitwiseIsEqual(z16))7596 << "sem=" << Sem << ", i=" << i << ", j=" << j;7597 7598 // Multiply7599 z = x;7600 z.multiply(y, APFloat::rmNearestTiesToEven);7601 z16 = x16;7602 z16.multiply(y16, APFloat::rmNearestTiesToEven);7603 z16.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);7604 EXPECT_TRUE(z.bitwiseIsEqual(z16))7605 << "sem=" << Sem << ", i=" << i << ", j=" << j;7606 7607 // Skip divide by 07608 if (j == 0 || j == 32)7609 continue;7610 7611 // Divide7612 z = x;7613 z.divide(y, APFloat::rmNearestTiesToEven);7614 z16 = x16;7615 z16.divide(y16, APFloat::rmNearestTiesToEven);7616 z16.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);7617 EXPECT_TRUE(z.bitwiseIsEqual(z16))7618 << "sem=" << Sem << ", i=" << i << ", j=" << j;7619 7620 // Mod7621 z = x;7622 z.mod(y);7623 z16 = x16;7624 z16.mod(y16);7625 z16.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);7626 EXPECT_TRUE(z.bitwiseIsEqual(z16))7627 << "sem=" << Sem << ", i=" << i << ", j=" << j;7628 7629 // Remainder7630 z = x;7631 z.remainder(y);7632 z16 = x16;7633 z16.remainder(y16);7634 z16.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);7635 EXPECT_TRUE(z.bitwiseIsEqual(z16))7636 << "sem=" << Sem << ", i=" << i << ", j=" << j;7637 }7638 }7639 }7640}7641 7642TEST(APFloatTest, Float4ExhaustivePair) {7643 // Test each pair of 4-bit floats with non-standard semantics7644 for (APFloat::Semantics Sem : {APFloat::S_Float4E2M1FN}) {7645 const llvm::fltSemantics &S = APFloat::EnumToSemantics(Sem);7646 for (int i = 0; i < 16; i++) {7647 for (int j = 0; j < 16; j++) {7648 SCOPED_TRACE("sem=" + std::to_string(Sem) + ",i=" + std::to_string(i) +7649 ",j=" + std::to_string(j));7650 APFloat x(S, APInt(4, i));7651 APFloat y(S, APInt(4, j));7652 7653 bool losesInfo;7654 APFloat x16 = x;7655 x16.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven,7656 &losesInfo);7657 EXPECT_FALSE(losesInfo);7658 APFloat y16 = y;7659 y16.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven,7660 &losesInfo);7661 EXPECT_FALSE(losesInfo);7662 7663 // Add7664 APFloat z = x;7665 z.add(y, APFloat::rmNearestTiesToEven);7666 APFloat z16 = x16;7667 z16.add(y16, APFloat::rmNearestTiesToEven);7668 z16.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);7669 EXPECT_TRUE(z.bitwiseIsEqual(z16))7670 << "sem=" << Sem << ", i=" << i << ", j=" << j;7671 7672 // Subtract7673 z = x;7674 z.subtract(y, APFloat::rmNearestTiesToEven);7675 z16 = x16;7676 z16.subtract(y16, APFloat::rmNearestTiesToEven);7677 z16.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);7678 EXPECT_TRUE(z.bitwiseIsEqual(z16))7679 << "sem=" << Sem << ", i=" << i << ", j=" << j;7680 7681 // Multiply7682 z = x;7683 z.multiply(y, APFloat::rmNearestTiesToEven);7684 z16 = x16;7685 z16.multiply(y16, APFloat::rmNearestTiesToEven);7686 z16.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);7687 EXPECT_TRUE(z.bitwiseIsEqual(z16))7688 << "sem=" << Sem << ", i=" << i << ", j=" << j;7689 7690 // Skip divide by 07691 if (j == 0 || j == 8)7692 continue;7693 7694 // Divide7695 z = x;7696 z.divide(y, APFloat::rmNearestTiesToEven);7697 z16 = x16;7698 z16.divide(y16, APFloat::rmNearestTiesToEven);7699 z16.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);7700 EXPECT_TRUE(z.bitwiseIsEqual(z16))7701 << "sem=" << Sem << ", i=" << i << ", j=" << j;7702 7703 // Mod7704 z = x;7705 z.mod(y);7706 z16 = x16;7707 z16.mod(y16);7708 z16.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);7709 EXPECT_TRUE(z.bitwiseIsEqual(z16))7710 << "sem=" << Sem << ", i=" << i << ", j=" << j;7711 7712 // Remainder7713 z = x;7714 z.remainder(y);7715 z16 = x16;7716 z16.remainder(y16);7717 z16.convert(S, APFloat::rmNearestTiesToEven, &losesInfo);7718 EXPECT_TRUE(z.bitwiseIsEqual(z16))7719 << "sem=" << Sem << ", i=" << i << ", j=" << j;7720 }7721 }7722 }7723}7724 7725TEST(APFloatTest, ConvertE4M3FNToE5M2) {7726 bool losesInfo;7727 APFloat test(APFloat::Float8E4M3FN(), "1.0");7728 APFloat::opStatus status = test.convert(7729 APFloat::Float8E5M2(), APFloat::rmNearestTiesToEven, &losesInfo);7730 EXPECT_EQ(1.0f, test.convertToFloat());7731 EXPECT_FALSE(losesInfo);7732 EXPECT_EQ(status, APFloat::opOK);7733 7734 test = APFloat(APFloat::Float8E4M3FN(), "0.0");7735 status = test.convert(APFloat::Float8E5M2(), APFloat::rmNearestTiesToEven,7736 &losesInfo);7737 EXPECT_EQ(0.0f, test.convertToFloat());7738 EXPECT_FALSE(losesInfo);7739 EXPECT_EQ(status, APFloat::opOK);7740 7741 test = APFloat(APFloat::Float8E4M3FN(), "0x1.2p0"); // 1.1257742 status = test.convert(APFloat::Float8E5M2(), APFloat::rmNearestTiesToEven,7743 &losesInfo);7744 EXPECT_EQ(0x1.0p0 /* 1.0 */, test.convertToFloat());7745 EXPECT_TRUE(losesInfo);7746 EXPECT_EQ(status, APFloat::opInexact);7747 7748 test = APFloat(APFloat::Float8E4M3FN(), "0x1.6p0"); // 1.3757749 status = test.convert(APFloat::Float8E5M2(), APFloat::rmNearestTiesToEven,7750 &losesInfo);7751 EXPECT_EQ(0x1.8p0 /* 1.5 */, test.convertToFloat());7752 EXPECT_TRUE(losesInfo);7753 EXPECT_EQ(status, APFloat::opInexact);7754 7755 // Convert E4M3FN denormal to E5M2 normal. Should not be truncated, despite7756 // the destination format having one fewer significand bit7757 test = APFloat(APFloat::Float8E4M3FN(), "0x1.Cp-7");7758 status = test.convert(APFloat::Float8E5M2(), APFloat::rmNearestTiesToEven,7759 &losesInfo);7760 EXPECT_EQ(0x1.Cp-7, test.convertToFloat());7761 EXPECT_FALSE(losesInfo);7762 EXPECT_EQ(status, APFloat::opOK);7763 7764 // Test convert from NaN7765 test = APFloat(APFloat::Float8E4M3FN(), "nan");7766 status = test.convert(APFloat::Float8E5M2(), APFloat::rmNearestTiesToEven,7767 &losesInfo);7768 EXPECT_TRUE(std::isnan(test.convertToFloat()));7769 EXPECT_FALSE(losesInfo);7770 EXPECT_EQ(status, APFloat::opOK);7771}7772 7773TEST(APFloatTest, ConvertE5M2ToE4M3FN) {7774 bool losesInfo;7775 APFloat test(APFloat::Float8E5M2(), "1.0");7776 APFloat::opStatus status = test.convert(7777 APFloat::Float8E4M3FN(), APFloat::rmNearestTiesToEven, &losesInfo);7778 EXPECT_EQ(1.0f, test.convertToFloat());7779 EXPECT_FALSE(losesInfo);7780 EXPECT_EQ(status, APFloat::opOK);7781 7782 test = APFloat(APFloat::Float8E5M2(), "0.0");7783 status = test.convert(APFloat::Float8E4M3FN(), APFloat::rmNearestTiesToEven,7784 &losesInfo);7785 EXPECT_EQ(0.0f, test.convertToFloat());7786 EXPECT_FALSE(losesInfo);7787 EXPECT_EQ(status, APFloat::opOK);7788 7789 test = APFloat(APFloat::Float8E5M2(), "0x1.Cp8"); // 4487790 status = test.convert(APFloat::Float8E4M3FN(), APFloat::rmNearestTiesToEven,7791 &losesInfo);7792 EXPECT_EQ(0x1.Cp8 /* 448 */, test.convertToFloat());7793 EXPECT_FALSE(losesInfo);7794 EXPECT_EQ(status, APFloat::opOK);7795 7796 // Test overflow7797 test = APFloat(APFloat::Float8E5M2(), "0x1.0p9"); // 5127798 status = test.convert(APFloat::Float8E4M3FN(), APFloat::rmNearestTiesToEven,7799 &losesInfo);7800 EXPECT_TRUE(std::isnan(test.convertToFloat()));7801 EXPECT_TRUE(losesInfo);7802 EXPECT_EQ(status, APFloat::opOverflow | APFloat::opInexact);7803 7804 // Test underflow7805 test = APFloat(APFloat::Float8E5M2(), "0x1.0p-10");7806 status = test.convert(APFloat::Float8E4M3FN(), APFloat::rmNearestTiesToEven,7807 &losesInfo);7808 EXPECT_EQ(0., test.convertToFloat());7809 EXPECT_TRUE(losesInfo);7810 EXPECT_EQ(status, APFloat::opUnderflow | APFloat::opInexact);7811 7812 // Test rounding up to smallest denormal number7813 test = APFloat(APFloat::Float8E5M2(), "0x1.8p-10");7814 status = test.convert(APFloat::Float8E4M3FN(), APFloat::rmNearestTiesToEven,7815 &losesInfo);7816 EXPECT_EQ(0x1.0p-9, test.convertToFloat());7817 EXPECT_TRUE(losesInfo);7818 EXPECT_EQ(status, APFloat::opUnderflow | APFloat::opInexact);7819 7820 // Testing inexact rounding to denormal number7821 test = APFloat(APFloat::Float8E5M2(), "0x1.8p-9");7822 status = test.convert(APFloat::Float8E4M3FN(), APFloat::rmNearestTiesToEven,7823 &losesInfo);7824 EXPECT_EQ(0x1.0p-8, test.convertToFloat());7825 EXPECT_TRUE(losesInfo);7826 EXPECT_EQ(status, APFloat::opUnderflow | APFloat::opInexact);7827 7828 APFloat nan = APFloat(APFloat::Float8E4M3FN(), "nan");7829 7830 // Testing convert from Inf7831 test = APFloat(APFloat::Float8E5M2(), "inf");7832 status = test.convert(APFloat::Float8E4M3FN(), APFloat::rmNearestTiesToEven,7833 &losesInfo);7834 EXPECT_TRUE(std::isnan(test.convertToFloat()));7835 EXPECT_TRUE(losesInfo);7836 EXPECT_EQ(status, APFloat::opInexact);7837 EXPECT_TRUE(test.bitwiseIsEqual(nan));7838 7839 // Testing convert from quiet NaN7840 test = APFloat(APFloat::Float8E5M2(), "nan");7841 status = test.convert(APFloat::Float8E4M3FN(), APFloat::rmNearestTiesToEven,7842 &losesInfo);7843 EXPECT_TRUE(std::isnan(test.convertToFloat()));7844 EXPECT_TRUE(losesInfo);7845 EXPECT_EQ(status, APFloat::opOK);7846 EXPECT_TRUE(test.bitwiseIsEqual(nan));7847 7848 // Testing convert from signaling NaN7849 test = APFloat(APFloat::Float8E5M2(), "snan");7850 status = test.convert(APFloat::Float8E4M3FN(), APFloat::rmNearestTiesToEven,7851 &losesInfo);7852 EXPECT_TRUE(std::isnan(test.convertToFloat()));7853 EXPECT_TRUE(losesInfo);7854 EXPECT_EQ(status, APFloat::opInvalidOp);7855 EXPECT_TRUE(test.bitwiseIsEqual(nan));7856}7857 7858TEST(APFloatTest, Float8E4M3FNGetInf) {7859 APFloat t = APFloat::getInf(APFloat::Float8E4M3FN());7860 EXPECT_TRUE(t.isNaN());7861 EXPECT_FALSE(t.isInfinity());7862}7863 7864TEST(APFloatTest, Float8E4M3FNFromString) {7865 // Exactly representable7866 EXPECT_EQ(448, APFloat(APFloat::Float8E4M3FN(), "448").convertToDouble());7867 // Round down to maximum value7868 EXPECT_EQ(448, APFloat(APFloat::Float8E4M3FN(), "464").convertToDouble());7869 // Round up, causing overflow to NaN7870 EXPECT_TRUE(APFloat(APFloat::Float8E4M3FN(), "465").isNaN());7871 // Overflow without rounding7872 EXPECT_TRUE(APFloat(APFloat::Float8E4M3FN(), "480").isNaN());7873 // Inf converted to NaN7874 EXPECT_TRUE(APFloat(APFloat::Float8E4M3FN(), "inf").isNaN());7875 // NaN converted to NaN7876 EXPECT_TRUE(APFloat(APFloat::Float8E4M3FN(), "nan").isNaN());7877}7878 7879TEST(APFloatTest, Float8E4M3FNAdd) {7880 APFloat QNaN = APFloat::getNaN(APFloat::Float8E4M3FN(), false);7881 7882 auto FromStr = [](StringRef S) {7883 return APFloat(APFloat::Float8E4M3FN(), S);7884 };7885 7886 struct {7887 APFloat x;7888 APFloat y;7889 const char *result;7890 int status;7891 int category;7892 APFloat::roundingMode roundingMode = APFloat::rmNearestTiesToEven;7893 } AdditionTests[] = {7894 // Test addition operations involving NaN, overflow, and the max E4M3FN7895 // value (448) because E4M3FN differs from IEEE-754 types in these regards7896 {FromStr("448"), FromStr("16"), "448", APFloat::opInexact,7897 APFloat::fcNormal},7898 {FromStr("448"), FromStr("18"), "NaN",7899 APFloat::opOverflow | APFloat::opInexact, APFloat::fcNaN},7900 {FromStr("448"), FromStr("32"), "NaN",7901 APFloat::opOverflow | APFloat::opInexact, APFloat::fcNaN},7902 {FromStr("-448"), FromStr("-32"), "-NaN",7903 APFloat::opOverflow | APFloat::opInexact, APFloat::fcNaN},7904 {QNaN, FromStr("-448"), "NaN", APFloat::opOK, APFloat::fcNaN},7905 {FromStr("448"), FromStr("-32"), "416", APFloat::opOK, APFloat::fcNormal},7906 {FromStr("448"), FromStr("0"), "448", APFloat::opOK, APFloat::fcNormal},7907 {FromStr("448"), FromStr("32"), "448", APFloat::opInexact,7908 APFloat::fcNormal, APFloat::rmTowardZero},7909 {FromStr("448"), FromStr("448"), "448", APFloat::opInexact,7910 APFloat::fcNormal, APFloat::rmTowardZero},7911 };7912 7913 for (size_t i = 0; i < std::size(AdditionTests); ++i) {7914 APFloat x(AdditionTests[i].x);7915 APFloat y(AdditionTests[i].y);7916 APFloat::opStatus status = x.add(y, AdditionTests[i].roundingMode);7917 7918 APFloat result(APFloat::Float8E4M3FN(), AdditionTests[i].result);7919 7920 EXPECT_TRUE(result.bitwiseIsEqual(x));7921 EXPECT_EQ(AdditionTests[i].status, (int)status);7922 EXPECT_EQ(AdditionTests[i].category, (int)x.getCategory());7923 }7924}7925 7926TEST(APFloatTest, Float8E4M3FNDivideByZero) {7927 APFloat x(APFloat::Float8E4M3FN(), "1");7928 APFloat zero(APFloat::Float8E4M3FN(), "0");7929 EXPECT_EQ(x.divide(zero, APFloat::rmNearestTiesToEven), APFloat::opDivByZero);7930 EXPECT_TRUE(x.isNaN());7931}7932 7933TEST(APFloatTest, Float8E4M3FNNext) {7934 APFloat test(APFloat::Float8E4M3FN(), APFloat::uninitialized);7935 APFloat expected(APFloat::Float8E4M3FN(), APFloat::uninitialized);7936 7937 // nextUp on positive numbers7938 for (int i = 0; i < 127; i++) {7939 test = APFloat(APFloat::Float8E4M3FN(), APInt(8, i));7940 expected = APFloat(APFloat::Float8E4M3FN(), APInt(8, i + 1));7941 EXPECT_EQ(test.next(false), APFloat::opOK);7942 EXPECT_TRUE(test.bitwiseIsEqual(expected));7943 }7944 7945 // nextUp on negative zero7946 test = APFloat::getZero(APFloat::Float8E4M3FN(), true);7947 expected = APFloat::getSmallest(APFloat::Float8E4M3FN(), false);7948 EXPECT_EQ(test.next(false), APFloat::opOK);7949 EXPECT_TRUE(test.bitwiseIsEqual(expected));7950 7951 // nextUp on negative nonzero numbers7952 for (int i = 129; i < 255; i++) {7953 test = APFloat(APFloat::Float8E4M3FN(), APInt(8, i));7954 expected = APFloat(APFloat::Float8E4M3FN(), APInt(8, i - 1));7955 EXPECT_EQ(test.next(false), APFloat::opOK);7956 EXPECT_TRUE(test.bitwiseIsEqual(expected));7957 }7958 7959 // nextUp on NaN7960 test = APFloat::getQNaN(APFloat::Float8E4M3FN(), false);7961 expected = APFloat::getQNaN(APFloat::Float8E4M3FN(), false);7962 EXPECT_EQ(test.next(false), APFloat::opOK);7963 EXPECT_TRUE(test.bitwiseIsEqual(expected));7964 7965 // nextDown on positive nonzero finite numbers7966 for (int i = 1; i < 127; i++) {7967 test = APFloat(APFloat::Float8E4M3FN(), APInt(8, i));7968 expected = APFloat(APFloat::Float8E4M3FN(), APInt(8, i - 1));7969 EXPECT_EQ(test.next(true), APFloat::opOK);7970 EXPECT_TRUE(test.bitwiseIsEqual(expected));7971 }7972 7973 // nextDown on positive zero7974 test = APFloat::getZero(APFloat::Float8E4M3FN(), true);7975 expected = APFloat::getSmallest(APFloat::Float8E4M3FN(), true);7976 EXPECT_EQ(test.next(true), APFloat::opOK);7977 EXPECT_TRUE(test.bitwiseIsEqual(expected));7978 7979 // nextDown on negative finite numbers7980 for (int i = 128; i < 255; i++) {7981 test = APFloat(APFloat::Float8E4M3FN(), APInt(8, i));7982 expected = APFloat(APFloat::Float8E4M3FN(), APInt(8, i + 1));7983 EXPECT_EQ(test.next(true), APFloat::opOK);7984 EXPECT_TRUE(test.bitwiseIsEqual(expected));7985 }7986 7987 // nextDown on NaN7988 test = APFloat::getQNaN(APFloat::Float8E4M3FN(), false);7989 expected = APFloat::getQNaN(APFloat::Float8E4M3FN(), false);7990 EXPECT_EQ(test.next(true), APFloat::opOK);7991 EXPECT_TRUE(test.bitwiseIsEqual(expected));7992}7993 7994TEST(APFloatTest, Float8E4M3FNExhaustive) {7995 // Test each of the 256 Float8E4M3FN values.7996 for (int i = 0; i < 256; i++) {7997 APFloat test(APFloat::Float8E4M3FN(), APInt(8, i));7998 SCOPED_TRACE("i=" + std::to_string(i));7999 8000 // isLargest8001 if (i == 126 || i == 254) {8002 EXPECT_TRUE(test.isLargest());8003 EXPECT_EQ(abs(test).convertToDouble(), 448.);8004 } else {8005 EXPECT_FALSE(test.isLargest());8006 }8007 8008 // isSmallest8009 if (i == 1 || i == 129) {8010 EXPECT_TRUE(test.isSmallest());8011 EXPECT_EQ(abs(test).convertToDouble(), 0x1p-9);8012 } else {8013 EXPECT_FALSE(test.isSmallest());8014 }8015 8016 // convert to BFloat8017 APFloat test2 = test;8018 bool losesInfo;8019 APFloat::opStatus status = test2.convert(8020 APFloat::BFloat(), APFloat::rmNearestTiesToEven, &losesInfo);8021 EXPECT_EQ(status, APFloat::opOK);8022 EXPECT_FALSE(losesInfo);8023 if (i == 127 || i == 255)8024 EXPECT_TRUE(test2.isNaN());8025 else8026 EXPECT_EQ(test.convertToFloat(), test2.convertToFloat());8027 8028 // bitcastToAPInt8029 EXPECT_EQ(i, test.bitcastToAPInt());8030 }8031}8032 8033TEST(APFloatTest, Float8E8M0FNUExhaustive) {8034 // Test each of the 256 Float8E8M0FNU values.8035 for (int i = 0; i < 256; i++) {8036 APFloat test(APFloat::Float8E8M0FNU(), APInt(8, i));8037 SCOPED_TRACE("i=" + std::to_string(i));8038 8039 // bitcastToAPInt8040 EXPECT_EQ(i, test.bitcastToAPInt());8041 8042 // isLargest8043 if (i == 254) {8044 EXPECT_TRUE(test.isLargest());8045 EXPECT_EQ(abs(test).convertToDouble(), 0x1.0p127);8046 } else {8047 EXPECT_FALSE(test.isLargest());8048 }8049 8050 // isSmallest8051 if (i == 0) {8052 EXPECT_TRUE(test.isSmallest());8053 EXPECT_EQ(abs(test).convertToDouble(), 0x1.0p-127);8054 } else {8055 EXPECT_FALSE(test.isSmallest());8056 }8057 8058 // convert to Double8059 bool losesInfo;8060 std::string val = std::to_string(i - 127); // 127 is the bias8061 llvm::SmallString<16> str("0x1.0p");8062 str += val;8063 APFloat test2(APFloat::IEEEdouble(), str);8064 8065 APFloat::opStatus status = test.convert(8066 APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &losesInfo);8067 EXPECT_EQ(status, APFloat::opOK);8068 EXPECT_FALSE(losesInfo);8069 if (i == 255)8070 EXPECT_TRUE(test.isNaN());8071 else8072 EXPECT_EQ(test.convertToDouble(), test2.convertToDouble());8073 }8074}8075 8076TEST(APFloatTest, Float8E5M2FNUZNext) {8077 APFloat test(APFloat::Float8E5M2FNUZ(), APFloat::uninitialized);8078 APFloat expected(APFloat::Float8E5M2FNUZ(), APFloat::uninitialized);8079 8080 // 1. NextUp of largest bit pattern is nan8081 test = APFloat::getLargest(APFloat::Float8E5M2FNUZ());8082 expected = APFloat::getNaN(APFloat::Float8E5M2FNUZ());8083 EXPECT_EQ(test.next(false), APFloat::opOK);8084 EXPECT_FALSE(test.isInfinity());8085 EXPECT_FALSE(test.isZero());8086 EXPECT_TRUE(test.isNaN());8087 EXPECT_TRUE(test.bitwiseIsEqual(expected));8088 8089 // 2. NextUp of smallest negative denormal is +08090 test = APFloat::getSmallest(APFloat::Float8E5M2FNUZ(), true);8091 expected = APFloat::getZero(APFloat::Float8E5M2FNUZ(), false);8092 EXPECT_EQ(test.next(false), APFloat::opOK);8093 EXPECT_FALSE(test.isNegZero());8094 EXPECT_TRUE(test.isPosZero());8095 EXPECT_TRUE(test.bitwiseIsEqual(expected));8096 8097 // 3. nextDown of negative of largest value is NaN8098 test = APFloat::getLargest(APFloat::Float8E5M2FNUZ(), true);8099 expected = APFloat::getNaN(APFloat::Float8E5M2FNUZ());8100 EXPECT_EQ(test.next(true), APFloat::opOK);8101 EXPECT_FALSE(test.isInfinity());8102 EXPECT_FALSE(test.isZero());8103 EXPECT_TRUE(test.isNaN());8104 EXPECT_TRUE(test.bitwiseIsEqual(expected));8105 8106 // 4. nextDown of +0 is smallest negative denormal8107 test = APFloat::getZero(APFloat::Float8E5M2FNUZ(), false);8108 expected = APFloat::getSmallest(APFloat::Float8E5M2FNUZ(), true);8109 EXPECT_EQ(test.next(true), APFloat::opOK);8110 EXPECT_FALSE(test.isZero());8111 EXPECT_TRUE(test.isDenormal());8112 EXPECT_TRUE(test.bitwiseIsEqual(expected));8113 8114 // 5. nextUp of NaN is NaN8115 test = APFloat::getNaN(APFloat::Float8E5M2FNUZ(), false);8116 expected = APFloat::getNaN(APFloat::Float8E5M2FNUZ(), true);8117 EXPECT_EQ(test.next(false), APFloat::opOK);8118 EXPECT_TRUE(test.isNaN());8119 8120 // 6. nextDown of NaN is NaN8121 test = APFloat::getNaN(APFloat::Float8E5M2FNUZ(), false);8122 expected = APFloat::getNaN(APFloat::Float8E5M2FNUZ(), true);8123 EXPECT_EQ(test.next(true), APFloat::opOK);8124 EXPECT_TRUE(test.isNaN());8125}8126 8127TEST(APFloatTest, Float8E5M2FNUZChangeSign) {8128 APFloat test = APFloat(APFloat::Float8E5M2FNUZ(), "1.0");8129 APFloat expected = APFloat(APFloat::Float8E5M2FNUZ(), "-1.0");8130 test.changeSign();8131 EXPECT_TRUE(test.bitwiseIsEqual(expected));8132 8133 test = APFloat::getZero(APFloat::Float8E5M2FNUZ());8134 expected = test;8135 test.changeSign();8136 EXPECT_TRUE(test.bitwiseIsEqual(expected));8137 8138 test = APFloat::getNaN(APFloat::Float8E5M2FNUZ());8139 expected = test;8140 test.changeSign();8141 EXPECT_TRUE(test.bitwiseIsEqual(expected));8142}8143 8144TEST(APFloatTest, Float8E5M2FNUZFromString) {8145 // Exactly representable8146 EXPECT_EQ(57344,8147 APFloat(APFloat::Float8E5M2FNUZ(), "57344").convertToDouble());8148 // Round down to maximum value8149 EXPECT_EQ(57344,8150 APFloat(APFloat::Float8E5M2FNUZ(), "59392").convertToDouble());8151 // Round up, causing overflow to NaN8152 EXPECT_TRUE(APFloat(APFloat::Float8E5M2FNUZ(), "61440").isNaN());8153 // Overflow without rounding8154 EXPECT_TRUE(APFloat(APFloat::Float8E5M2FNUZ(), "131072").isNaN());8155 // Inf converted to NaN8156 EXPECT_TRUE(APFloat(APFloat::Float8E5M2FNUZ(), "inf").isNaN());8157 // NaN converted to NaN8158 EXPECT_TRUE(APFloat(APFloat::Float8E5M2FNUZ(), "nan").isNaN());8159 // Negative zero converted to positive zero8160 EXPECT_TRUE(APFloat(APFloat::Float8E5M2FNUZ(), "-0").isPosZero());8161}8162 8163TEST(APFloatTest, UnsignedZeroArithmeticSpecial) {8164 // Float semantics with only unsigned zero (ex. Float8E4M3FNUZ) violate the8165 // IEEE rules about signs in arithmetic operations when producing zeros,8166 // because they only have one zero. Most of the rest of the complexities of8167 // arithmetic on these values are covered by the other Float8 types' test8168 // cases and so are not repeated here.8169 8170 // The IEEE round towards negative rule doesn't apply8171 for (APFloat::Semantics S :8172 {APFloat::S_Float8E4M3FNUZ, APFloat::S_Float8E4M3B11FNUZ}) {8173 const llvm::fltSemantics &Sem = APFloat::EnumToSemantics(S);8174 APFloat test = APFloat::getSmallest(Sem);8175 APFloat rhs = test;8176 EXPECT_EQ(test.subtract(rhs, APFloat::rmTowardNegative), APFloat::opOK);8177 EXPECT_TRUE(test.isZero());8178 EXPECT_FALSE(test.isNegative());8179 8180 // Multiplication of (small) * (-small) is +08181 test = APFloat::getSmallestNormalized(Sem);8182 rhs = -test;8183 EXPECT_EQ(test.multiply(rhs, APFloat::rmNearestTiesToAway),8184 APFloat::opInexact | APFloat::opUnderflow);8185 EXPECT_TRUE(test.isZero());8186 EXPECT_FALSE(test.isNegative());8187 8188 // Dividing the negatize float_min by anything gives +08189 test = APFloat::getSmallest(Sem, true);8190 rhs = APFloat(Sem, "2.0");8191 EXPECT_EQ(test.divide(rhs, APFloat::rmNearestTiesToEven),8192 APFloat::opInexact | APFloat::opUnderflow);8193 EXPECT_TRUE(test.isZero());8194 EXPECT_FALSE(test.isNegative());8195 8196 // Remainder can't copy sign because there's only one zero8197 test = APFloat(Sem, "-4.0");8198 rhs = APFloat(Sem, "2.0");8199 EXPECT_EQ(test.remainder(rhs), APFloat::opOK);8200 EXPECT_TRUE(test.isZero());8201 EXPECT_FALSE(test.isNegative());8202 8203 // And same for mod8204 test = APFloat(Sem, "-4.0");8205 rhs = APFloat(Sem, "2.0");8206 EXPECT_EQ(test.mod(rhs), APFloat::opOK);8207 EXPECT_TRUE(test.isZero());8208 EXPECT_FALSE(test.isNegative());8209 8210 // FMA correctly handles both the multiply and add parts of all this8211 test = APFloat(Sem, "2.0");8212 rhs = test;8213 APFloat addend = APFloat(Sem, "-4.0");8214 EXPECT_EQ(test.fusedMultiplyAdd(rhs, addend, APFloat::rmTowardNegative),8215 APFloat::opOK);8216 EXPECT_TRUE(test.isZero());8217 EXPECT_FALSE(test.isNegative());8218 }8219}8220 8221TEST(APFloatTest, Float8E5M2FNUZAdd) {8222 APFloat QNaN = APFloat::getNaN(APFloat::Float8E5M2FNUZ(), false);8223 8224 auto FromStr = [](StringRef S) {8225 return APFloat(APFloat::Float8E5M2FNUZ(), S);8226 };8227 8228 struct {8229 APFloat x;8230 APFloat y;8231 const char *result;8232 int status;8233 int category;8234 APFloat::roundingMode roundingMode = APFloat::rmNearestTiesToEven;8235 } AdditionTests[] = {8236 // Test addition operations involving NaN, overflow, and the max E5M2FNUZ8237 // value (57344) because E5M2FNUZ differs from IEEE-754 types in these8238 // regards8239 {FromStr("57344"), FromStr("2048"), "57344", APFloat::opInexact,8240 APFloat::fcNormal},8241 {FromStr("57344"), FromStr("4096"), "NaN",8242 APFloat::opOverflow | APFloat::opInexact, APFloat::fcNaN},8243 {FromStr("-57344"), FromStr("-4096"), "NaN",8244 APFloat::opOverflow | APFloat::opInexact, APFloat::fcNaN},8245 {QNaN, FromStr("-57344"), "NaN", APFloat::opOK, APFloat::fcNaN},8246 {FromStr("57344"), FromStr("-8192"), "49152", APFloat::opOK,8247 APFloat::fcNormal},8248 {FromStr("57344"), FromStr("0"), "57344", APFloat::opOK,8249 APFloat::fcNormal},8250 {FromStr("57344"), FromStr("4096"), "57344", APFloat::opInexact,8251 APFloat::fcNormal, APFloat::rmTowardZero},8252 {FromStr("57344"), FromStr("57344"), "57344", APFloat::opInexact,8253 APFloat::fcNormal, APFloat::rmTowardZero},8254 };8255 8256 for (size_t i = 0; i < std::size(AdditionTests); ++i) {8257 APFloat x(AdditionTests[i].x);8258 APFloat y(AdditionTests[i].y);8259 APFloat::opStatus status = x.add(y, AdditionTests[i].roundingMode);8260 8261 APFloat result(APFloat::Float8E5M2FNUZ(), AdditionTests[i].result);8262 8263 EXPECT_TRUE(result.bitwiseIsEqual(x));8264 EXPECT_EQ(AdditionTests[i].status, (int)status);8265 EXPECT_EQ(AdditionTests[i].category, (int)x.getCategory());8266 }8267}8268 8269TEST(APFloatTest, Float8E5M2FNUZDivideByZero) {8270 APFloat x(APFloat::Float8E5M2FNUZ(), "1");8271 APFloat zero(APFloat::Float8E5M2FNUZ(), "0");8272 EXPECT_EQ(x.divide(zero, APFloat::rmNearestTiesToEven), APFloat::opDivByZero);8273 EXPECT_TRUE(x.isNaN());8274}8275 8276TEST(APFloatTest, Float8UnsignedZeroExhaustive) {8277 struct {8278 const fltSemantics *semantics;8279 const double largest;8280 const double smallest;8281 } const exhaustiveTests[] = {{&APFloat::Float8E5M2FNUZ(), 57344., 0x1.0p-17},8282 {&APFloat::Float8E4M3FNUZ(), 240., 0x1.0p-10},8283 {&APFloat::Float8E4M3B11FNUZ(), 30., 0x1.0p-13}};8284 for (const auto &testInfo : exhaustiveTests) {8285 const fltSemantics &sem = *testInfo.semantics;8286 SCOPED_TRACE("Semantics=" + std::to_string(APFloat::SemanticsToEnum(sem)));8287 // Test each of the 256 values.8288 for (int i = 0; i < 256; i++) {8289 SCOPED_TRACE("i=" + std::to_string(i));8290 APFloat test(sem, APInt(8, i));8291 8292 // isLargest8293 if (i == 127 || i == 255) {8294 EXPECT_TRUE(test.isLargest());8295 EXPECT_EQ(abs(test).convertToDouble(), testInfo.largest);8296 } else {8297 EXPECT_FALSE(test.isLargest());8298 }8299 8300 // isSmallest8301 if (i == 1 || i == 129) {8302 EXPECT_TRUE(test.isSmallest());8303 EXPECT_EQ(abs(test).convertToDouble(), testInfo.smallest);8304 } else {8305 EXPECT_FALSE(test.isSmallest());8306 }8307 8308 // convert to BFloat8309 APFloat test2 = test;8310 bool losesInfo;8311 APFloat::opStatus status = test2.convert(8312 APFloat::BFloat(), APFloat::rmNearestTiesToEven, &losesInfo);8313 EXPECT_EQ(status, APFloat::opOK);8314 EXPECT_FALSE(losesInfo);8315 if (i == 128)8316 EXPECT_TRUE(test2.isNaN());8317 else8318 EXPECT_EQ(test.convertToFloat(), test2.convertToFloat());8319 8320 // bitcastToAPInt8321 EXPECT_EQ(i, test.bitcastToAPInt());8322 }8323 }8324}8325 8326TEST(APFloatTest, Float8E4M3FNUZNext) {8327 for (APFloat::Semantics S :8328 {APFloat::S_Float8E4M3FNUZ, APFloat::S_Float8E4M3B11FNUZ}) {8329 const llvm::fltSemantics &Sem = APFloat::EnumToSemantics(S);8330 APFloat test(Sem, APFloat::uninitialized);8331 APFloat expected(Sem, APFloat::uninitialized);8332 8333 // 1. NextUp of largest bit pattern is nan8334 test = APFloat::getLargest(Sem);8335 expected = APFloat::getNaN(Sem);8336 EXPECT_EQ(test.next(false), APFloat::opOK);8337 EXPECT_FALSE(test.isInfinity());8338 EXPECT_FALSE(test.isZero());8339 EXPECT_TRUE(test.isNaN());8340 EXPECT_TRUE(test.bitwiseIsEqual(expected));8341 8342 // 2. NextUp of smallest negative denormal is +08343 test = APFloat::getSmallest(Sem, true);8344 expected = APFloat::getZero(Sem, false);8345 EXPECT_EQ(test.next(false), APFloat::opOK);8346 EXPECT_FALSE(test.isNegZero());8347 EXPECT_TRUE(test.isPosZero());8348 EXPECT_TRUE(test.bitwiseIsEqual(expected));8349 8350 // 3. nextDown of negative of largest value is NaN8351 test = APFloat::getLargest(Sem, true);8352 expected = APFloat::getNaN(Sem);8353 EXPECT_EQ(test.next(true), APFloat::opOK);8354 EXPECT_FALSE(test.isInfinity());8355 EXPECT_FALSE(test.isZero());8356 EXPECT_TRUE(test.isNaN());8357 EXPECT_TRUE(test.bitwiseIsEqual(expected));8358 8359 // 4. nextDown of +0 is smallest negative denormal8360 test = APFloat::getZero(Sem, false);8361 expected = APFloat::getSmallest(Sem, true);8362 EXPECT_EQ(test.next(true), APFloat::opOK);8363 EXPECT_FALSE(test.isZero());8364 EXPECT_TRUE(test.isDenormal());8365 EXPECT_TRUE(test.bitwiseIsEqual(expected));8366 8367 // 5. nextUp of NaN is NaN8368 test = APFloat::getNaN(Sem, false);8369 expected = APFloat::getNaN(Sem, true);8370 EXPECT_EQ(test.next(false), APFloat::opOK);8371 EXPECT_TRUE(test.isNaN());8372 8373 // 6. nextDown of NaN is NaN8374 test = APFloat::getNaN(Sem, false);8375 expected = APFloat::getNaN(Sem, true);8376 EXPECT_EQ(test.next(true), APFloat::opOK);8377 EXPECT_TRUE(test.isNaN());8378 }8379}8380 8381TEST(APFloatTest, Float8E4M3FNUZChangeSign) {8382 for (APFloat::Semantics S :8383 {APFloat::S_Float8E4M3FNUZ, APFloat::S_Float8E4M3B11FNUZ}) {8384 const llvm::fltSemantics &Sem = APFloat::EnumToSemantics(S);8385 APFloat test = APFloat(Sem, "1.0");8386 APFloat expected = APFloat(Sem, "-1.0");8387 test.changeSign();8388 EXPECT_TRUE(test.bitwiseIsEqual(expected));8389 8390 test = APFloat::getZero(Sem);8391 expected = test;8392 test.changeSign();8393 EXPECT_TRUE(test.bitwiseIsEqual(expected));8394 8395 test = APFloat::getNaN(Sem);8396 expected = test;8397 test.changeSign();8398 EXPECT_TRUE(test.bitwiseIsEqual(expected));8399 }8400}8401 8402TEST(APFloatTest, Float8E4M3FNUZFromString) {8403 // Exactly representable8404 EXPECT_EQ(240, APFloat(APFloat::Float8E4M3FNUZ(), "240").convertToDouble());8405 // Round down to maximum value8406 EXPECT_EQ(240, APFloat(APFloat::Float8E4M3FNUZ(), "247").convertToDouble());8407 // Round up, causing overflow to NaN8408 EXPECT_TRUE(APFloat(APFloat::Float8E4M3FNUZ(), "248").isNaN());8409 // Overflow without rounding8410 EXPECT_TRUE(APFloat(APFloat::Float8E4M3FNUZ(), "480").isNaN());8411 // Inf converted to NaN8412 EXPECT_TRUE(APFloat(APFloat::Float8E4M3FNUZ(), "inf").isNaN());8413 // NaN converted to NaN8414 EXPECT_TRUE(APFloat(APFloat::Float8E4M3FNUZ(), "nan").isNaN());8415 // Negative zero converted to positive zero8416 EXPECT_TRUE(APFloat(APFloat::Float8E4M3FNUZ(), "-0").isPosZero());8417}8418 8419TEST(APFloatTest, Float8E4M3FNUZAdd) {8420 APFloat QNaN = APFloat::getNaN(APFloat::Float8E4M3FNUZ(), false);8421 8422 auto FromStr = [](StringRef S) {8423 return APFloat(APFloat::Float8E4M3FNUZ(), S);8424 };8425 8426 struct {8427 APFloat x;8428 APFloat y;8429 const char *result;8430 int status;8431 int category;8432 APFloat::roundingMode roundingMode = APFloat::rmNearestTiesToEven;8433 } AdditionTests[] = {8434 // Test addition operations involving NaN, overflow, and the max E4M3FNUZ8435 // value (240) because E4M3FNUZ differs from IEEE-754 types in these8436 // regards8437 {FromStr("240"), FromStr("4"), "240", APFloat::opInexact,8438 APFloat::fcNormal},8439 {FromStr("240"), FromStr("8"), "NaN",8440 APFloat::opOverflow | APFloat::opInexact, APFloat::fcNaN},8441 {FromStr("240"), FromStr("16"), "NaN",8442 APFloat::opOverflow | APFloat::opInexact, APFloat::fcNaN},8443 {FromStr("-240"), FromStr("-16"), "NaN",8444 APFloat::opOverflow | APFloat::opInexact, APFloat::fcNaN},8445 {QNaN, FromStr("-240"), "NaN", APFloat::opOK, APFloat::fcNaN},8446 {FromStr("240"), FromStr("-16"), "224", APFloat::opOK, APFloat::fcNormal},8447 {FromStr("240"), FromStr("0"), "240", APFloat::opOK, APFloat::fcNormal},8448 {FromStr("240"), FromStr("32"), "240", APFloat::opInexact,8449 APFloat::fcNormal, APFloat::rmTowardZero},8450 {FromStr("240"), FromStr("240"), "240", APFloat::opInexact,8451 APFloat::fcNormal, APFloat::rmTowardZero},8452 };8453 8454 for (size_t i = 0; i < std::size(AdditionTests); ++i) {8455 APFloat x(AdditionTests[i].x);8456 APFloat y(AdditionTests[i].y);8457 APFloat::opStatus status = x.add(y, AdditionTests[i].roundingMode);8458 8459 APFloat result(APFloat::Float8E4M3FNUZ(), AdditionTests[i].result);8460 8461 EXPECT_TRUE(result.bitwiseIsEqual(x));8462 EXPECT_EQ(AdditionTests[i].status, (int)status);8463 EXPECT_EQ(AdditionTests[i].category, (int)x.getCategory());8464 }8465}8466 8467TEST(APFloatTest, Float8E4M3FNUZDivideByZero) {8468 APFloat x(APFloat::Float8E4M3FNUZ(), "1");8469 APFloat zero(APFloat::Float8E4M3FNUZ(), "0");8470 EXPECT_EQ(x.divide(zero, APFloat::rmNearestTiesToEven), APFloat::opDivByZero);8471 EXPECT_TRUE(x.isNaN());8472}8473 8474TEST(APFloatTest, ConvertE5M2FNUZToE4M3FNUZ) {8475 bool losesInfo;8476 APFloat test(APFloat::Float8E5M2FNUZ(), "1.0");8477 APFloat::opStatus status = test.convert(8478 APFloat::Float8E4M3FNUZ(), APFloat::rmNearestTiesToEven, &losesInfo);8479 EXPECT_EQ(1.0f, test.convertToFloat());8480 EXPECT_FALSE(losesInfo);8481 EXPECT_EQ(status, APFloat::opOK);8482 8483 losesInfo = true;8484 test = APFloat(APFloat::Float8E5M2FNUZ(), "0.0");8485 status = test.convert(APFloat::Float8E4M3FNUZ(), APFloat::rmNearestTiesToEven,8486 &losesInfo);8487 EXPECT_EQ(0.0f, test.convertToFloat());8488 EXPECT_FALSE(losesInfo);8489 EXPECT_EQ(status, APFloat::opOK);8490 8491 losesInfo = true;8492 test = APFloat(APFloat::Float8E5M2FNUZ(), "0x1.Cp7"); // 2248493 status = test.convert(APFloat::Float8E4M3FNUZ(), APFloat::rmNearestTiesToEven,8494 &losesInfo);8495 EXPECT_EQ(0x1.Cp7 /* 224 */, test.convertToFloat());8496 EXPECT_FALSE(losesInfo);8497 EXPECT_EQ(status, APFloat::opOK);8498 8499 // Test overflow8500 losesInfo = false;8501 test = APFloat(APFloat::Float8E5M2FNUZ(), "0x1.0p8"); // 2568502 status = test.convert(APFloat::Float8E4M3FNUZ(), APFloat::rmNearestTiesToEven,8503 &losesInfo);8504 EXPECT_TRUE(std::isnan(test.convertToFloat()));8505 EXPECT_TRUE(losesInfo);8506 EXPECT_EQ(status, APFloat::opOverflow | APFloat::opInexact);8507 8508 // Test underflow8509 test = APFloat(APFloat::Float8E5M2FNUZ(), "0x1.0p-11");8510 status = test.convert(APFloat::Float8E4M3FNUZ(), APFloat::rmNearestTiesToEven,8511 &losesInfo);8512 EXPECT_EQ(0., test.convertToFloat());8513 EXPECT_TRUE(losesInfo);8514 EXPECT_EQ(status, APFloat::opUnderflow | APFloat::opInexact);8515 8516 // Test rounding up to smallest denormal number8517 losesInfo = false;8518 test = APFloat(APFloat::Float8E5M2FNUZ(), "0x1.8p-11");8519 status = test.convert(APFloat::Float8E4M3FNUZ(), APFloat::rmNearestTiesToEven,8520 &losesInfo);8521 EXPECT_EQ(0x1.0p-10, test.convertToFloat());8522 EXPECT_TRUE(losesInfo);8523 EXPECT_EQ(status, APFloat::opUnderflow | APFloat::opInexact);8524 8525 // Testing inexact rounding to denormal number8526 losesInfo = false;8527 test = APFloat(APFloat::Float8E5M2FNUZ(), "0x1.8p-10");8528 status = test.convert(APFloat::Float8E4M3FNUZ(), APFloat::rmNearestTiesToEven,8529 &losesInfo);8530 EXPECT_EQ(0x1.0p-9, test.convertToFloat());8531 EXPECT_TRUE(losesInfo);8532 EXPECT_EQ(status, APFloat::opUnderflow | APFloat::opInexact);8533}8534 8535TEST(APFloatTest, ConvertE4M3FNUZToE5M2FNUZ) {8536 bool losesInfo;8537 APFloat test(APFloat::Float8E4M3FNUZ(), "1.0");8538 APFloat::opStatus status = test.convert(8539 APFloat::Float8E5M2FNUZ(), APFloat::rmNearestTiesToEven, &losesInfo);8540 EXPECT_EQ(1.0f, test.convertToFloat());8541 EXPECT_FALSE(losesInfo);8542 EXPECT_EQ(status, APFloat::opOK);8543 8544 losesInfo = true;8545 test = APFloat(APFloat::Float8E4M3FNUZ(), "0.0");8546 status = test.convert(APFloat::Float8E5M2FNUZ(), APFloat::rmNearestTiesToEven,8547 &losesInfo);8548 EXPECT_EQ(0.0f, test.convertToFloat());8549 EXPECT_FALSE(losesInfo);8550 EXPECT_EQ(status, APFloat::opOK);8551 8552 losesInfo = false;8553 test = APFloat(APFloat::Float8E4M3FNUZ(), "0x1.2p0"); // 1.1258554 status = test.convert(APFloat::Float8E5M2FNUZ(), APFloat::rmNearestTiesToEven,8555 &losesInfo);8556 EXPECT_EQ(0x1.0p0 /* 1.0 */, test.convertToFloat());8557 EXPECT_TRUE(losesInfo);8558 EXPECT_EQ(status, APFloat::opInexact);8559 8560 losesInfo = false;8561 test = APFloat(APFloat::Float8E4M3FNUZ(), "0x1.6p0"); // 1.3758562 status = test.convert(APFloat::Float8E5M2FNUZ(), APFloat::rmNearestTiesToEven,8563 &losesInfo);8564 EXPECT_EQ(0x1.8p0 /* 1.5 */, test.convertToFloat());8565 EXPECT_TRUE(losesInfo);8566 EXPECT_EQ(status, APFloat::opInexact);8567 8568 // Convert E4M3FNUZ denormal to E5M2 normal. Should not be truncated, despite8569 // the destination format having one fewer significand bit8570 losesInfo = true;8571 test = APFloat(APFloat::Float8E4M3FNUZ(), "0x1.Cp-8");8572 status = test.convert(APFloat::Float8E5M2FNUZ(), APFloat::rmNearestTiesToEven,8573 &losesInfo);8574 EXPECT_EQ(0x1.Cp-8, test.convertToFloat());8575 EXPECT_FALSE(losesInfo);8576 EXPECT_EQ(status, APFloat::opOK);8577}8578 8579TEST(APFloatTest, F8ToString) {8580 for (APFloat::Semantics S :8581 {APFloat::S_Float8E5M2, APFloat::S_Float8E4M3FN,8582 APFloat::S_Float8E5M2FNUZ, APFloat::S_Float8E4M3FNUZ,8583 APFloat::S_Float8E4M3B11FNUZ}) {8584 SCOPED_TRACE("Semantics=" + std::to_string(S));8585 for (int i = 0; i < 256; i++) {8586 SCOPED_TRACE("i=" + std::to_string(i));8587 APFloat test(APFloat::EnumToSemantics(S), APInt(8, i));8588 llvm::SmallString<128> str;8589 test.toString(str);8590 8591 if (test.isNaN()) {8592 EXPECT_EQ(str, "NaN");8593 } else {8594 APFloat test2(APFloat::EnumToSemantics(S), str);8595 EXPECT_TRUE(test.bitwiseIsEqual(test2));8596 }8597 }8598 }8599}8600 8601TEST(APFloatTest, BitsToF8ToBits) {8602 for (APFloat::Semantics S :8603 {APFloat::S_Float8E5M2, APFloat::S_Float8E4M3FN,8604 APFloat::S_Float8E5M2FNUZ, APFloat::S_Float8E4M3FNUZ,8605 APFloat::S_Float8E4M3B11FNUZ}) {8606 SCOPED_TRACE("Semantics=" + std::to_string(S));8607 for (int i = 0; i < 256; i++) {8608 SCOPED_TRACE("i=" + std::to_string(i));8609 APInt bits_in = APInt(8, i);8610 APFloat test(APFloat::EnumToSemantics(S), bits_in);8611 APInt bits_out = test.bitcastToAPInt();8612 EXPECT_EQ(bits_in, bits_out);8613 }8614 }8615}8616 8617TEST(APFloatTest, F8ToBitsToF8) {8618 for (APFloat::Semantics S :8619 {APFloat::S_Float8E5M2, APFloat::S_Float8E4M3FN,8620 APFloat::S_Float8E5M2FNUZ, APFloat::S_Float8E4M3FNUZ,8621 APFloat::S_Float8E4M3B11FNUZ}) {8622 SCOPED_TRACE("Semantics=" + std::to_string(S));8623 auto &Sem = APFloat::EnumToSemantics(S);8624 for (bool negative : {false, true}) {8625 SCOPED_TRACE("negative=" + std::to_string(negative));8626 APFloat test = APFloat::getZero(Sem, /*Negative=*/negative);8627 for (int i = 0; i < 128; i++, test.next(/*nextDown=*/negative)) {8628 SCOPED_TRACE("i=" + std::to_string(i));8629 APInt bits = test.bitcastToAPInt();8630 APFloat test2 = APFloat(Sem, bits);8631 if (test.isNaN()) {8632 EXPECT_TRUE(test2.isNaN());8633 } else {8634 EXPECT_TRUE(test.bitwiseIsEqual(test2));8635 }8636 }8637 }8638 }8639}8640 8641TEST(APFloatTest, IEEEdoubleToDouble) {8642 APFloat DPosZero(0.0);8643 APFloat DPosZeroToDouble(DPosZero.convertToDouble());8644 EXPECT_TRUE(DPosZeroToDouble.isPosZero());8645 APFloat DNegZero(-0.0);8646 APFloat DNegZeroToDouble(DNegZero.convertToDouble());8647 EXPECT_TRUE(DNegZeroToDouble.isNegZero());8648 8649 APFloat DOne(1.0);8650 EXPECT_EQ(1.0, DOne.convertToDouble());8651 APFloat DPosLargest = APFloat::getLargest(APFloat::IEEEdouble(), false);8652 EXPECT_EQ(std::numeric_limits<double>::max(), DPosLargest.convertToDouble());8653 APFloat DNegLargest = APFloat::getLargest(APFloat::IEEEdouble(), true);8654 EXPECT_EQ(-std::numeric_limits<double>::max(), DNegLargest.convertToDouble());8655 APFloat DPosSmallest =8656 APFloat::getSmallestNormalized(APFloat::IEEEdouble(), false);8657 EXPECT_EQ(std::numeric_limits<double>::min(), DPosSmallest.convertToDouble());8658 APFloat DNegSmallest =8659 APFloat::getSmallestNormalized(APFloat::IEEEdouble(), true);8660 EXPECT_EQ(-std::numeric_limits<double>::min(),8661 DNegSmallest.convertToDouble());8662 8663 APFloat DSmallestDenorm = APFloat::getSmallest(APFloat::IEEEdouble(), false);8664 EXPECT_EQ(std::numeric_limits<double>::denorm_min(),8665 DSmallestDenorm.convertToDouble());8666 APFloat DLargestDenorm(APFloat::IEEEdouble(), "0x0.FFFFFFFFFFFFFp-1022");8667 EXPECT_EQ(/*0x0.FFFFFFFFFFFFFp-1022*/ 2.225073858507201e-308,8668 DLargestDenorm.convertToDouble());8669 8670 APFloat DPosInf = APFloat::getInf(APFloat::IEEEdouble());8671 EXPECT_EQ(std::numeric_limits<double>::infinity(), DPosInf.convertToDouble());8672 APFloat DNegInf = APFloat::getInf(APFloat::IEEEdouble(), true);8673 EXPECT_EQ(-std::numeric_limits<double>::infinity(),8674 DNegInf.convertToDouble());8675 APFloat DQNaN = APFloat::getQNaN(APFloat::IEEEdouble());8676 EXPECT_TRUE(std::isnan(DQNaN.convertToDouble()));8677}8678 8679TEST(APFloatTest, IEEEsingleToDouble) {8680 APFloat FPosZero(0.0F);8681 APFloat FPosZeroToDouble(FPosZero.convertToDouble());8682 EXPECT_TRUE(FPosZeroToDouble.isPosZero());8683 APFloat FNegZero(-0.0F);8684 APFloat FNegZeroToDouble(FNegZero.convertToDouble());8685 EXPECT_TRUE(FNegZeroToDouble.isNegZero());8686 8687 APFloat FOne(1.0F);8688 EXPECT_EQ(1.0, FOne.convertToDouble());8689 APFloat FPosLargest = APFloat::getLargest(APFloat::IEEEsingle(), false);8690 EXPECT_EQ(std::numeric_limits<float>::max(), FPosLargest.convertToDouble());8691 APFloat FNegLargest = APFloat::getLargest(APFloat::IEEEsingle(), true);8692 EXPECT_EQ(-std::numeric_limits<float>::max(), FNegLargest.convertToDouble());8693 APFloat FPosSmallest =8694 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);8695 EXPECT_EQ(std::numeric_limits<float>::min(), FPosSmallest.convertToDouble());8696 APFloat FNegSmallest =8697 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);8698 EXPECT_EQ(-std::numeric_limits<float>::min(), FNegSmallest.convertToDouble());8699 8700 APFloat FSmallestDenorm = APFloat::getSmallest(APFloat::IEEEsingle(), false);8701 EXPECT_EQ(std::numeric_limits<float>::denorm_min(),8702 FSmallestDenorm.convertToDouble());8703 APFloat FLargestDenorm(APFloat::IEEEdouble(), "0x0.FFFFFEp-126");8704 EXPECT_EQ(/*0x0.FFFFFEp-126*/ 1.1754942106924411e-38,8705 FLargestDenorm.convertToDouble());8706 8707 APFloat FPosInf = APFloat::getInf(APFloat::IEEEsingle());8708 EXPECT_EQ(std::numeric_limits<double>::infinity(), FPosInf.convertToDouble());8709 APFloat FNegInf = APFloat::getInf(APFloat::IEEEsingle(), true);8710 EXPECT_EQ(-std::numeric_limits<double>::infinity(),8711 FNegInf.convertToDouble());8712 APFloat FQNaN = APFloat::getQNaN(APFloat::IEEEsingle());8713 EXPECT_TRUE(std::isnan(FQNaN.convertToDouble()));8714}8715 8716TEST(APFloatTest, IEEEhalfToDouble) {8717 APFloat HPosZero = APFloat::getZero(APFloat::IEEEhalf());8718 APFloat HPosZeroToDouble(HPosZero.convertToDouble());8719 EXPECT_TRUE(HPosZeroToDouble.isPosZero());8720 APFloat HNegZero = APFloat::getZero(APFloat::IEEEhalf(), true);8721 APFloat HNegZeroToDouble(HNegZero.convertToDouble());8722 EXPECT_TRUE(HNegZeroToDouble.isNegZero());8723 8724 APFloat HOne(APFloat::IEEEhalf(), "1.0");8725 EXPECT_EQ(1.0, HOne.convertToDouble());8726 APFloat HPosLargest = APFloat::getLargest(APFloat::IEEEhalf(), false);8727 EXPECT_EQ(65504.0, HPosLargest.convertToDouble());8728 APFloat HNegLargest = APFloat::getLargest(APFloat::IEEEhalf(), true);8729 EXPECT_EQ(-65504.0, HNegLargest.convertToDouble());8730 APFloat HPosSmallest =8731 APFloat::getSmallestNormalized(APFloat::IEEEhalf(), false);8732 EXPECT_EQ(/*0x1.p-14*/ 6.103515625e-05, HPosSmallest.convertToDouble());8733 APFloat HNegSmallest =8734 APFloat::getSmallestNormalized(APFloat::IEEEhalf(), true);8735 EXPECT_EQ(/*-0x1.p-14*/ -6.103515625e-05, HNegSmallest.convertToDouble());8736 8737 APFloat HSmallestDenorm = APFloat::getSmallest(APFloat::IEEEhalf(), false);8738 EXPECT_EQ(/*0x1.p-24*/ 5.960464477539063e-08,8739 HSmallestDenorm.convertToDouble());8740 APFloat HLargestDenorm(APFloat::IEEEhalf(), "0x1.FFCp-14");8741 EXPECT_EQ(/*0x1.FFCp-14*/ 0.00012201070785522461,8742 HLargestDenorm.convertToDouble());8743 8744 APFloat HPosInf = APFloat::getInf(APFloat::IEEEhalf());8745 EXPECT_EQ(std::numeric_limits<double>::infinity(), HPosInf.convertToDouble());8746 APFloat HNegInf = APFloat::getInf(APFloat::IEEEhalf(), true);8747 EXPECT_EQ(-std::numeric_limits<double>::infinity(),8748 HNegInf.convertToDouble());8749 APFloat HQNaN = APFloat::getQNaN(APFloat::IEEEhalf());8750 EXPECT_TRUE(std::isnan(HQNaN.convertToDouble()));8751 8752 APFloat BPosZero = APFloat::getZero(APFloat::IEEEhalf());8753 APFloat BPosZeroToDouble(BPosZero.convertToDouble());8754 EXPECT_TRUE(BPosZeroToDouble.isPosZero());8755 APFloat BNegZero = APFloat::getZero(APFloat::IEEEhalf(), true);8756 APFloat BNegZeroToDouble(BNegZero.convertToDouble());8757 EXPECT_TRUE(BNegZeroToDouble.isNegZero());8758}8759 8760TEST(APFloatTest, BFloatToDouble) {8761 APFloat BOne(APFloat::BFloat(), "1.0");8762 EXPECT_EQ(1.0, BOne.convertToDouble());8763 APFloat BPosLargest = APFloat::getLargest(APFloat::BFloat(), false);8764 EXPECT_EQ(/*0x1.FEp127*/ 3.3895313892515355e+38,8765 BPosLargest.convertToDouble());8766 APFloat BNegLargest = APFloat::getLargest(APFloat::BFloat(), true);8767 EXPECT_EQ(/*-0x1.FEp127*/ -3.3895313892515355e+38,8768 BNegLargest.convertToDouble());8769 APFloat BPosSmallest =8770 APFloat::getSmallestNormalized(APFloat::BFloat(), false);8771 EXPECT_EQ(/*0x1.p-126*/ 1.1754943508222875e-38,8772 BPosSmallest.convertToDouble());8773 APFloat BNegSmallest =8774 APFloat::getSmallestNormalized(APFloat::BFloat(), true);8775 EXPECT_EQ(/*-0x1.p-126*/ -1.1754943508222875e-38,8776 BNegSmallest.convertToDouble());8777 8778 APFloat BSmallestDenorm = APFloat::getSmallest(APFloat::BFloat(), false);8779 EXPECT_EQ(/*0x1.p-133*/ 9.183549615799121e-41,8780 BSmallestDenorm.convertToDouble());8781 APFloat BLargestDenorm(APFloat::BFloat(), "0x1.FCp-127");8782 EXPECT_EQ(/*0x1.FCp-127*/ 1.1663108012064884e-38,8783 BLargestDenorm.convertToDouble());8784 8785 APFloat BPosInf = APFloat::getInf(APFloat::BFloat());8786 EXPECT_EQ(std::numeric_limits<double>::infinity(), BPosInf.convertToDouble());8787 APFloat BNegInf = APFloat::getInf(APFloat::BFloat(), true);8788 EXPECT_EQ(-std::numeric_limits<double>::infinity(),8789 BNegInf.convertToDouble());8790 APFloat BQNaN = APFloat::getQNaN(APFloat::BFloat());8791 EXPECT_TRUE(std::isnan(BQNaN.convertToDouble()));8792}8793 8794TEST(APFloatTest, Float8E5M2ToDouble) {8795 APFloat One(APFloat::Float8E5M2(), "1.0");8796 EXPECT_EQ(1.0, One.convertToDouble());8797 APFloat Two(APFloat::Float8E5M2(), "2.0");8798 EXPECT_EQ(2.0, Two.convertToDouble());8799 APFloat PosLargest = APFloat::getLargest(APFloat::Float8E5M2(), false);8800 EXPECT_EQ(5.734400e+04, PosLargest.convertToDouble());8801 APFloat NegLargest = APFloat::getLargest(APFloat::Float8E5M2(), true);8802 EXPECT_EQ(-5.734400e+04, NegLargest.convertToDouble());8803 APFloat PosSmallest =8804 APFloat::getSmallestNormalized(APFloat::Float8E5M2(), false);8805 EXPECT_EQ(0x1.p-14, PosSmallest.convertToDouble());8806 APFloat NegSmallest =8807 APFloat::getSmallestNormalized(APFloat::Float8E5M2(), true);8808 EXPECT_EQ(-0x1.p-14, NegSmallest.convertToDouble());8809 8810 APFloat SmallestDenorm = APFloat::getSmallest(APFloat::Float8E5M2(), false);8811 EXPECT_TRUE(SmallestDenorm.isDenormal());8812 EXPECT_EQ(0x1p-16, SmallestDenorm.convertToDouble());8813 8814 APFloat PosInf = APFloat::getInf(APFloat::Float8E5M2());8815 EXPECT_EQ(std::numeric_limits<double>::infinity(), PosInf.convertToDouble());8816 APFloat NegInf = APFloat::getInf(APFloat::Float8E5M2(), true);8817 EXPECT_EQ(-std::numeric_limits<double>::infinity(), NegInf.convertToDouble());8818 APFloat QNaN = APFloat::getQNaN(APFloat::Float8E5M2());8819 EXPECT_TRUE(std::isnan(QNaN.convertToDouble()));8820}8821 8822TEST(APFloatTest, Float8E4M3ToDouble) {8823 APFloat One(APFloat::Float8E4M3(), "1.0");8824 EXPECT_EQ(1.0, One.convertToDouble());8825 APFloat Two(APFloat::Float8E4M3(), "2.0");8826 EXPECT_EQ(2.0, Two.convertToDouble());8827 APFloat PosLargest = APFloat::getLargest(APFloat::Float8E4M3(), false);8828 EXPECT_EQ(240.0F, PosLargest.convertToDouble());8829 APFloat NegLargest = APFloat::getLargest(APFloat::Float8E4M3(), true);8830 EXPECT_EQ(-240.0F, NegLargest.convertToDouble());8831 APFloat PosSmallest =8832 APFloat::getSmallestNormalized(APFloat::Float8E4M3(), false);8833 EXPECT_EQ(0x1.p-6, PosSmallest.convertToDouble());8834 APFloat NegSmallest =8835 APFloat::getSmallestNormalized(APFloat::Float8E4M3(), true);8836 EXPECT_EQ(-0x1.p-6, NegSmallest.convertToDouble());8837 8838 APFloat SmallestDenorm = APFloat::getSmallest(APFloat::Float8E4M3(), false);8839 EXPECT_TRUE(SmallestDenorm.isDenormal());8840 EXPECT_EQ(0x1.p-9, SmallestDenorm.convertToDouble());8841 8842 APFloat PosInf = APFloat::getInf(APFloat::Float8E4M3());8843 EXPECT_EQ(std::numeric_limits<double>::infinity(), PosInf.convertToDouble());8844 APFloat NegInf = APFloat::getInf(APFloat::Float8E4M3(), true);8845 EXPECT_EQ(-std::numeric_limits<double>::infinity(), NegInf.convertToDouble());8846 APFloat QNaN = APFloat::getQNaN(APFloat::Float8E4M3());8847 EXPECT_TRUE(std::isnan(QNaN.convertToDouble()));8848}8849 8850TEST(APFloatTest, Float8E4M3FNToDouble) {8851 APFloat One(APFloat::Float8E4M3FN(), "1.0");8852 EXPECT_EQ(1.0, One.convertToDouble());8853 APFloat Two(APFloat::Float8E4M3FN(), "2.0");8854 EXPECT_EQ(2.0, Two.convertToDouble());8855 APFloat PosLargest = APFloat::getLargest(APFloat::Float8E4M3FN(), false);8856 EXPECT_EQ(448., PosLargest.convertToDouble());8857 APFloat NegLargest = APFloat::getLargest(APFloat::Float8E4M3FN(), true);8858 EXPECT_EQ(-448., NegLargest.convertToDouble());8859 APFloat PosSmallest =8860 APFloat::getSmallestNormalized(APFloat::Float8E4M3FN(), false);8861 EXPECT_EQ(0x1.p-6, PosSmallest.convertToDouble());8862 APFloat NegSmallest =8863 APFloat::getSmallestNormalized(APFloat::Float8E4M3FN(), true);8864 EXPECT_EQ(-0x1.p-6, NegSmallest.convertToDouble());8865 8866 APFloat SmallestDenorm = APFloat::getSmallest(APFloat::Float8E4M3FN(), false);8867 EXPECT_TRUE(SmallestDenorm.isDenormal());8868 EXPECT_EQ(0x1p-9, SmallestDenorm.convertToDouble());8869 8870 APFloat QNaN = APFloat::getQNaN(APFloat::Float8E4M3FN());8871 EXPECT_TRUE(std::isnan(QNaN.convertToDouble()));8872}8873 8874TEST(APFloatTest, Float8E5M2FNUZToDouble) {8875 APFloat One(APFloat::Float8E5M2FNUZ(), "1.0");8876 EXPECT_EQ(1.0, One.convertToDouble());8877 APFloat Two(APFloat::Float8E5M2FNUZ(), "2.0");8878 EXPECT_EQ(2.0, Two.convertToDouble());8879 APFloat PosLargest = APFloat::getLargest(APFloat::Float8E5M2FNUZ(), false);8880 EXPECT_EQ(57344., PosLargest.convertToDouble());8881 APFloat NegLargest = APFloat::getLargest(APFloat::Float8E5M2FNUZ(), true);8882 EXPECT_EQ(-57344., NegLargest.convertToDouble());8883 APFloat PosSmallest =8884 APFloat::getSmallestNormalized(APFloat::Float8E5M2FNUZ(), false);8885 EXPECT_EQ(0x1.p-15, PosSmallest.convertToDouble());8886 APFloat NegSmallest =8887 APFloat::getSmallestNormalized(APFloat::Float8E5M2FNUZ(), true);8888 EXPECT_EQ(-0x1.p-15, NegSmallest.convertToDouble());8889 8890 APFloat SmallestDenorm =8891 APFloat::getSmallest(APFloat::Float8E5M2FNUZ(), false);8892 EXPECT_TRUE(SmallestDenorm.isDenormal());8893 EXPECT_EQ(0x1p-17, SmallestDenorm.convertToDouble());8894 8895 APFloat QNaN = APFloat::getQNaN(APFloat::Float8E5M2FNUZ());8896 EXPECT_TRUE(std::isnan(QNaN.convertToDouble()));8897}8898 8899TEST(APFloatTest, Float8E4M3FNUZToDouble) {8900 APFloat One(APFloat::Float8E4M3FNUZ(), "1.0");8901 EXPECT_EQ(1.0, One.convertToDouble());8902 APFloat Two(APFloat::Float8E4M3FNUZ(), "2.0");8903 EXPECT_EQ(2.0, Two.convertToDouble());8904 APFloat PosLargest = APFloat::getLargest(APFloat::Float8E4M3FNUZ(), false);8905 EXPECT_EQ(240., PosLargest.convertToDouble());8906 APFloat NegLargest = APFloat::getLargest(APFloat::Float8E4M3FNUZ(), true);8907 EXPECT_EQ(-240., NegLargest.convertToDouble());8908 APFloat PosSmallest =8909 APFloat::getSmallestNormalized(APFloat::Float8E4M3FNUZ(), false);8910 EXPECT_EQ(0x1.p-7, PosSmallest.convertToDouble());8911 APFloat NegSmallest =8912 APFloat::getSmallestNormalized(APFloat::Float8E4M3FNUZ(), true);8913 EXPECT_EQ(-0x1.p-7, NegSmallest.convertToDouble());8914 8915 APFloat SmallestDenorm =8916 APFloat::getSmallest(APFloat::Float8E4M3FNUZ(), false);8917 EXPECT_TRUE(SmallestDenorm.isDenormal());8918 EXPECT_EQ(0x1p-10, SmallestDenorm.convertToDouble());8919 8920 APFloat QNaN = APFloat::getQNaN(APFloat::Float8E4M3FNUZ());8921 EXPECT_TRUE(std::isnan(QNaN.convertToDouble()));8922}8923 8924TEST(APFloatTest, Float8E3M4ToDouble) {8925 APFloat PosZero = APFloat::getZero(APFloat::Float8E3M4(), false);8926 APFloat PosZeroToDouble(PosZero.convertToDouble());8927 EXPECT_TRUE(PosZeroToDouble.isPosZero());8928 APFloat NegZero = APFloat::getZero(APFloat::Float8E3M4(), true);8929 APFloat NegZeroToDouble(NegZero.convertToDouble());8930 EXPECT_TRUE(NegZeroToDouble.isNegZero());8931 8932 APFloat One(APFloat::Float8E3M4(), "1.0");8933 EXPECT_EQ(1.0, One.convertToDouble());8934 APFloat Two(APFloat::Float8E3M4(), "2.0");8935 EXPECT_EQ(2.0, Two.convertToDouble());8936 APFloat PosLargest = APFloat::getLargest(APFloat::Float8E3M4(), false);8937 EXPECT_EQ(15.5F, PosLargest.convertToDouble());8938 APFloat NegLargest = APFloat::getLargest(APFloat::Float8E3M4(), true);8939 EXPECT_EQ(-15.5F, NegLargest.convertToDouble());8940 APFloat PosSmallest =8941 APFloat::getSmallestNormalized(APFloat::Float8E3M4(), false);8942 EXPECT_EQ(0x1.p-2, PosSmallest.convertToDouble());8943 APFloat NegSmallest =8944 APFloat::getSmallestNormalized(APFloat::Float8E3M4(), true);8945 EXPECT_EQ(-0x1.p-2, NegSmallest.convertToDouble());8946 8947 APFloat PosSmallestDenorm =8948 APFloat::getSmallest(APFloat::Float8E3M4(), false);8949 EXPECT_TRUE(PosSmallestDenorm.isDenormal());8950 EXPECT_EQ(0x1.p-6, PosSmallestDenorm.convertToDouble());8951 APFloat NegSmallestDenorm = APFloat::getSmallest(APFloat::Float8E3M4(), true);8952 EXPECT_TRUE(NegSmallestDenorm.isDenormal());8953 EXPECT_EQ(-0x1.p-6, NegSmallestDenorm.convertToDouble());8954 8955 APFloat PosInf = APFloat::getInf(APFloat::Float8E3M4());8956 EXPECT_EQ(std::numeric_limits<double>::infinity(), PosInf.convertToDouble());8957 APFloat NegInf = APFloat::getInf(APFloat::Float8E3M4(), true);8958 EXPECT_EQ(-std::numeric_limits<double>::infinity(), NegInf.convertToDouble());8959 APFloat QNaN = APFloat::getQNaN(APFloat::Float8E3M4());8960 EXPECT_TRUE(std::isnan(QNaN.convertToDouble()));8961}8962 8963TEST(APFloatTest, FloatTF32ToDouble) {8964 APFloat One(APFloat::FloatTF32(), "1.0");8965 EXPECT_EQ(1.0, One.convertToDouble());8966 APFloat PosLargest = APFloat::getLargest(APFloat::FloatTF32(), false);8967 EXPECT_EQ(3.401162134214653489792616e+38, PosLargest.convertToDouble());8968 APFloat NegLargest = APFloat::getLargest(APFloat::FloatTF32(), true);8969 EXPECT_EQ(-3.401162134214653489792616e+38, NegLargest.convertToDouble());8970 APFloat PosSmallest =8971 APFloat::getSmallestNormalized(APFloat::FloatTF32(), false);8972 EXPECT_EQ(1.1754943508222875079687e-38, PosSmallest.convertToDouble());8973 APFloat NegSmallest =8974 APFloat::getSmallestNormalized(APFloat::FloatTF32(), true);8975 EXPECT_EQ(-1.1754943508222875079687e-38, NegSmallest.convertToDouble());8976 8977 APFloat SmallestDenorm = APFloat::getSmallest(APFloat::FloatTF32(), false);8978 EXPECT_EQ(1.1479437019748901445007e-41, SmallestDenorm.convertToDouble());8979 APFloat LargestDenorm(APFloat::FloatTF32(), "0x1.FF8p-127");8980 EXPECT_EQ(/*0x1.FF8p-127*/ 1.1743464071203126178242e-38,8981 LargestDenorm.convertToDouble());8982 8983 APFloat PosInf = APFloat::getInf(APFloat::FloatTF32());8984 EXPECT_EQ(std::numeric_limits<double>::infinity(), PosInf.convertToDouble());8985 APFloat NegInf = APFloat::getInf(APFloat::FloatTF32(), true);8986 EXPECT_EQ(-std::numeric_limits<double>::infinity(), NegInf.convertToDouble());8987 APFloat QNaN = APFloat::getQNaN(APFloat::FloatTF32());8988 EXPECT_TRUE(std::isnan(QNaN.convertToDouble()));8989}8990 8991TEST(APFloatTest, Float8E5M2FNUZToFloat) {8992 APFloat PosZero = APFloat::getZero(APFloat::Float8E5M2FNUZ());8993 APFloat PosZeroToFloat(PosZero.convertToFloat());8994 EXPECT_TRUE(PosZeroToFloat.isPosZero());8995 // Negative zero is not supported8996 APFloat NegZero = APFloat::getZero(APFloat::Float8E5M2FNUZ(), true);8997 APFloat NegZeroToFloat(NegZero.convertToFloat());8998 EXPECT_TRUE(NegZeroToFloat.isPosZero());8999 APFloat One(APFloat::Float8E5M2FNUZ(), "1.0");9000 EXPECT_EQ(1.0F, One.convertToFloat());9001 APFloat Two(APFloat::Float8E5M2FNUZ(), "2.0");9002 EXPECT_EQ(2.0F, Two.convertToFloat());9003 APFloat PosLargest = APFloat::getLargest(APFloat::Float8E5M2FNUZ(), false);9004 EXPECT_EQ(57344.F, PosLargest.convertToFloat());9005 APFloat NegLargest = APFloat::getLargest(APFloat::Float8E5M2FNUZ(), true);9006 EXPECT_EQ(-57344.F, NegLargest.convertToFloat());9007 APFloat PosSmallest =9008 APFloat::getSmallestNormalized(APFloat::Float8E5M2FNUZ(), false);9009 EXPECT_EQ(0x1.p-15F, PosSmallest.convertToFloat());9010 APFloat NegSmallest =9011 APFloat::getSmallestNormalized(APFloat::Float8E5M2FNUZ(), true);9012 EXPECT_EQ(-0x1.p-15F, NegSmallest.convertToFloat());9013 9014 APFloat SmallestDenorm =9015 APFloat::getSmallest(APFloat::Float8E5M2FNUZ(), false);9016 EXPECT_TRUE(SmallestDenorm.isDenormal());9017 EXPECT_EQ(0x1p-17F, SmallestDenorm.convertToFloat());9018 9019 APFloat QNaN = APFloat::getQNaN(APFloat::Float8E5M2FNUZ());9020 EXPECT_TRUE(std::isnan(QNaN.convertToFloat()));9021}9022 9023TEST(APFloatTest, Float8E4M3FNUZToFloat) {9024 APFloat PosZero = APFloat::getZero(APFloat::Float8E4M3FNUZ());9025 APFloat PosZeroToFloat(PosZero.convertToFloat());9026 EXPECT_TRUE(PosZeroToFloat.isPosZero());9027 // Negative zero is not supported9028 APFloat NegZero = APFloat::getZero(APFloat::Float8E4M3FNUZ(), true);9029 APFloat NegZeroToFloat(NegZero.convertToFloat());9030 EXPECT_TRUE(NegZeroToFloat.isPosZero());9031 APFloat One(APFloat::Float8E4M3FNUZ(), "1.0");9032 EXPECT_EQ(1.0F, One.convertToFloat());9033 APFloat Two(APFloat::Float8E4M3FNUZ(), "2.0");9034 EXPECT_EQ(2.0F, Two.convertToFloat());9035 APFloat PosLargest = APFloat::getLargest(APFloat::Float8E4M3FNUZ(), false);9036 EXPECT_EQ(240.F, PosLargest.convertToFloat());9037 APFloat NegLargest = APFloat::getLargest(APFloat::Float8E4M3FNUZ(), true);9038 EXPECT_EQ(-240.F, NegLargest.convertToFloat());9039 APFloat PosSmallest =9040 APFloat::getSmallestNormalized(APFloat::Float8E4M3FNUZ(), false);9041 EXPECT_EQ(0x1.p-7F, PosSmallest.convertToFloat());9042 APFloat NegSmallest =9043 APFloat::getSmallestNormalized(APFloat::Float8E4M3FNUZ(), true);9044 EXPECT_EQ(-0x1.p-7F, NegSmallest.convertToFloat());9045 9046 APFloat SmallestDenorm =9047 APFloat::getSmallest(APFloat::Float8E4M3FNUZ(), false);9048 EXPECT_TRUE(SmallestDenorm.isDenormal());9049 EXPECT_EQ(0x1p-10F, SmallestDenorm.convertToFloat());9050 9051 APFloat QNaN = APFloat::getQNaN(APFloat::Float8E4M3FNUZ());9052 EXPECT_TRUE(std::isnan(QNaN.convertToFloat()));9053}9054 9055TEST(APFloatTest, IEEEsingleToFloat) {9056 APFloat FPosZero(0.0F);9057 APFloat FPosZeroToFloat(FPosZero.convertToFloat());9058 EXPECT_TRUE(FPosZeroToFloat.isPosZero());9059 APFloat FNegZero(-0.0F);9060 APFloat FNegZeroToFloat(FNegZero.convertToFloat());9061 EXPECT_TRUE(FNegZeroToFloat.isNegZero());9062 9063 APFloat FOne(1.0F);9064 EXPECT_EQ(1.0F, FOne.convertToFloat());9065 APFloat FPosLargest = APFloat::getLargest(APFloat::IEEEsingle(), false);9066 EXPECT_EQ(std::numeric_limits<float>::max(), FPosLargest.convertToFloat());9067 APFloat FNegLargest = APFloat::getLargest(APFloat::IEEEsingle(), true);9068 EXPECT_EQ(-std::numeric_limits<float>::max(), FNegLargest.convertToFloat());9069 APFloat FPosSmallest =9070 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), false);9071 EXPECT_EQ(std::numeric_limits<float>::min(), FPosSmallest.convertToFloat());9072 APFloat FNegSmallest =9073 APFloat::getSmallestNormalized(APFloat::IEEEsingle(), true);9074 EXPECT_EQ(-std::numeric_limits<float>::min(), FNegSmallest.convertToFloat());9075 9076 APFloat FSmallestDenorm = APFloat::getSmallest(APFloat::IEEEsingle(), false);9077 EXPECT_EQ(std::numeric_limits<float>::denorm_min(),9078 FSmallestDenorm.convertToFloat());9079 APFloat FLargestDenorm(APFloat::IEEEsingle(), "0x1.FFFFFEp-126");9080 EXPECT_EQ(/*0x1.FFFFFEp-126*/ 2.3509885615147286e-38F,9081 FLargestDenorm.convertToFloat());9082 9083 APFloat FPosInf = APFloat::getInf(APFloat::IEEEsingle());9084 EXPECT_EQ(std::numeric_limits<float>::infinity(), FPosInf.convertToFloat());9085 APFloat FNegInf = APFloat::getInf(APFloat::IEEEsingle(), true);9086 EXPECT_EQ(-std::numeric_limits<float>::infinity(), FNegInf.convertToFloat());9087 APFloat FQNaN = APFloat::getQNaN(APFloat::IEEEsingle());9088 EXPECT_TRUE(std::isnan(FQNaN.convertToFloat()));9089}9090 9091TEST(APFloatTest, IEEEhalfToFloat) {9092 APFloat HPosZero = APFloat::getZero(APFloat::IEEEhalf());9093 APFloat HPosZeroToFloat(HPosZero.convertToFloat());9094 EXPECT_TRUE(HPosZeroToFloat.isPosZero());9095 APFloat HNegZero = APFloat::getZero(APFloat::IEEEhalf(), true);9096 APFloat HNegZeroToFloat(HNegZero.convertToFloat());9097 EXPECT_TRUE(HNegZeroToFloat.isNegZero());9098 9099 APFloat HOne(APFloat::IEEEhalf(), "1.0");9100 EXPECT_EQ(1.0F, HOne.convertToFloat());9101 APFloat HPosLargest = APFloat::getLargest(APFloat::IEEEhalf(), false);9102 EXPECT_EQ(/*0x1.FFCp15*/ 65504.0F, HPosLargest.convertToFloat());9103 APFloat HNegLargest = APFloat::getLargest(APFloat::IEEEhalf(), true);9104 EXPECT_EQ(/*-0x1.FFCp15*/ -65504.0F, HNegLargest.convertToFloat());9105 APFloat HPosSmallest =9106 APFloat::getSmallestNormalized(APFloat::IEEEhalf(), false);9107 EXPECT_EQ(/*0x1.p-14*/ 6.103515625e-05F, HPosSmallest.convertToFloat());9108 APFloat HNegSmallest =9109 APFloat::getSmallestNormalized(APFloat::IEEEhalf(), true);9110 EXPECT_EQ(/*-0x1.p-14*/ -6.103515625e-05F, HNegSmallest.convertToFloat());9111 9112 APFloat HSmallestDenorm = APFloat::getSmallest(APFloat::IEEEhalf(), false);9113 EXPECT_EQ(/*0x1.p-24*/ 5.960464477539063e-08F,9114 HSmallestDenorm.convertToFloat());9115 APFloat HLargestDenorm(APFloat::IEEEhalf(), "0x1.FFCp-14");9116 EXPECT_EQ(/*0x1.FFCp-14*/ 0.00012201070785522461F,9117 HLargestDenorm.convertToFloat());9118 9119 APFloat HPosInf = APFloat::getInf(APFloat::IEEEhalf());9120 EXPECT_EQ(std::numeric_limits<float>::infinity(), HPosInf.convertToFloat());9121 APFloat HNegInf = APFloat::getInf(APFloat::IEEEhalf(), true);9122 EXPECT_EQ(-std::numeric_limits<float>::infinity(), HNegInf.convertToFloat());9123 APFloat HQNaN = APFloat::getQNaN(APFloat::IEEEhalf());9124 EXPECT_TRUE(std::isnan(HQNaN.convertToFloat()));9125}9126 9127TEST(APFloatTest, BFloatToFloat) {9128 APFloat BPosZero = APFloat::getZero(APFloat::BFloat());9129 APFloat BPosZeroToDouble(BPosZero.convertToFloat());9130 EXPECT_TRUE(BPosZeroToDouble.isPosZero());9131 APFloat BNegZero = APFloat::getZero(APFloat::BFloat(), true);9132 APFloat BNegZeroToDouble(BNegZero.convertToFloat());9133 EXPECT_TRUE(BNegZeroToDouble.isNegZero());9134 9135 APFloat BOne(APFloat::BFloat(), "1.0");9136 EXPECT_EQ(1.0F, BOne.convertToFloat());9137 APFloat BPosLargest = APFloat::getLargest(APFloat::BFloat(), false);9138 EXPECT_EQ(/*0x1.FEp127*/ 3.3895313892515355e+38F,9139 BPosLargest.convertToFloat());9140 APFloat BNegLargest = APFloat::getLargest(APFloat::BFloat(), true);9141 EXPECT_EQ(/*-0x1.FEp127*/ -3.3895313892515355e+38F,9142 BNegLargest.convertToFloat());9143 APFloat BPosSmallest =9144 APFloat::getSmallestNormalized(APFloat::BFloat(), false);9145 EXPECT_EQ(/*0x1.p-126*/ 1.1754943508222875e-38F,9146 BPosSmallest.convertToFloat());9147 APFloat BNegSmallest =9148 APFloat::getSmallestNormalized(APFloat::BFloat(), true);9149 EXPECT_EQ(/*-0x1.p-126*/ -1.1754943508222875e-38F,9150 BNegSmallest.convertToFloat());9151 9152 APFloat BSmallestDenorm = APFloat::getSmallest(APFloat::BFloat(), false);9153 EXPECT_EQ(/*0x1.p-133*/ 9.183549615799121e-41F,9154 BSmallestDenorm.convertToFloat());9155 APFloat BLargestDenorm(APFloat::BFloat(), "0x1.FCp-127");9156 EXPECT_EQ(/*0x1.FCp-127*/ 1.1663108012064884e-38F,9157 BLargestDenorm.convertToFloat());9158 9159 APFloat BPosInf = APFloat::getInf(APFloat::BFloat());9160 EXPECT_EQ(std::numeric_limits<float>::infinity(), BPosInf.convertToFloat());9161 APFloat BNegInf = APFloat::getInf(APFloat::BFloat(), true);9162 EXPECT_EQ(-std::numeric_limits<float>::infinity(), BNegInf.convertToFloat());9163 APFloat BQNaN = APFloat::getQNaN(APFloat::BFloat());9164 EXPECT_TRUE(std::isnan(BQNaN.convertToFloat()));9165}9166 9167TEST(APFloatTest, Float8E5M2ToFloat) {9168 APFloat PosZero = APFloat::getZero(APFloat::Float8E5M2());9169 APFloat PosZeroToFloat(PosZero.convertToFloat());9170 EXPECT_TRUE(PosZeroToFloat.isPosZero());9171 APFloat NegZero = APFloat::getZero(APFloat::Float8E5M2(), true);9172 APFloat NegZeroToFloat(NegZero.convertToFloat());9173 EXPECT_TRUE(NegZeroToFloat.isNegZero());9174 9175 APFloat One(APFloat::Float8E5M2(), "1.0");9176 EXPECT_EQ(1.0F, One.convertToFloat());9177 APFloat Two(APFloat::Float8E5M2(), "2.0");9178 EXPECT_EQ(2.0F, Two.convertToFloat());9179 9180 APFloat PosLargest = APFloat::getLargest(APFloat::Float8E5M2(), false);9181 EXPECT_EQ(5.734400e+04, PosLargest.convertToFloat());9182 APFloat NegLargest = APFloat::getLargest(APFloat::Float8E5M2(), true);9183 EXPECT_EQ(-5.734400e+04, NegLargest.convertToFloat());9184 APFloat PosSmallest =9185 APFloat::getSmallestNormalized(APFloat::Float8E5M2(), false);9186 EXPECT_EQ(0x1.p-14, PosSmallest.convertToFloat());9187 APFloat NegSmallest =9188 APFloat::getSmallestNormalized(APFloat::Float8E5M2(), true);9189 EXPECT_EQ(-0x1.p-14, NegSmallest.convertToFloat());9190 9191 APFloat SmallestDenorm = APFloat::getSmallest(APFloat::Float8E5M2(), false);9192 EXPECT_TRUE(SmallestDenorm.isDenormal());9193 EXPECT_EQ(0x1.p-16, SmallestDenorm.convertToFloat());9194 9195 APFloat PosInf = APFloat::getInf(APFloat::Float8E5M2());9196 EXPECT_EQ(std::numeric_limits<float>::infinity(), PosInf.convertToFloat());9197 APFloat NegInf = APFloat::getInf(APFloat::Float8E5M2(), true);9198 EXPECT_EQ(-std::numeric_limits<float>::infinity(), NegInf.convertToFloat());9199 APFloat QNaN = APFloat::getQNaN(APFloat::Float8E5M2());9200 EXPECT_TRUE(std::isnan(QNaN.convertToFloat()));9201}9202 9203TEST(APFloatTest, Float8E4M3ToFloat) {9204 APFloat PosZero = APFloat::getZero(APFloat::Float8E4M3());9205 APFloat PosZeroToFloat(PosZero.convertToFloat());9206 EXPECT_TRUE(PosZeroToFloat.isPosZero());9207 APFloat NegZero = APFloat::getZero(APFloat::Float8E4M3(), true);9208 APFloat NegZeroToFloat(NegZero.convertToFloat());9209 EXPECT_TRUE(NegZeroToFloat.isNegZero());9210 9211 APFloat One(APFloat::Float8E4M3(), "1.0");9212 EXPECT_EQ(1.0F, One.convertToFloat());9213 APFloat Two(APFloat::Float8E4M3(), "2.0");9214 EXPECT_EQ(2.0F, Two.convertToFloat());9215 9216 APFloat PosLargest = APFloat::getLargest(APFloat::Float8E4M3(), false);9217 EXPECT_EQ(240.0F, PosLargest.convertToFloat());9218 APFloat NegLargest = APFloat::getLargest(APFloat::Float8E4M3(), true);9219 EXPECT_EQ(-240.0F, NegLargest.convertToFloat());9220 APFloat PosSmallest =9221 APFloat::getSmallestNormalized(APFloat::Float8E4M3(), false);9222 EXPECT_EQ(0x1.p-6, PosSmallest.convertToFloat());9223 APFloat NegSmallest =9224 APFloat::getSmallestNormalized(APFloat::Float8E4M3(), true);9225 EXPECT_EQ(-0x1.p-6, NegSmallest.convertToFloat());9226 9227 APFloat SmallestDenorm = APFloat::getSmallest(APFloat::Float8E4M3(), false);9228 EXPECT_TRUE(SmallestDenorm.isDenormal());9229 EXPECT_EQ(0x1.p-9, SmallestDenorm.convertToFloat());9230 9231 APFloat PosInf = APFloat::getInf(APFloat::Float8E4M3());9232 EXPECT_EQ(std::numeric_limits<float>::infinity(), PosInf.convertToFloat());9233 APFloat NegInf = APFloat::getInf(APFloat::Float8E4M3(), true);9234 EXPECT_EQ(-std::numeric_limits<float>::infinity(), NegInf.convertToFloat());9235 APFloat QNaN = APFloat::getQNaN(APFloat::Float8E4M3());9236 EXPECT_TRUE(std::isnan(QNaN.convertToFloat()));9237}9238 9239TEST(APFloatTest, Float8E4M3FNToFloat) {9240 APFloat PosZero = APFloat::getZero(APFloat::Float8E4M3FN());9241 APFloat PosZeroToFloat(PosZero.convertToFloat());9242 EXPECT_TRUE(PosZeroToFloat.isPosZero());9243 APFloat NegZero = APFloat::getZero(APFloat::Float8E4M3FN(), true);9244 APFloat NegZeroToFloat(NegZero.convertToFloat());9245 EXPECT_TRUE(NegZeroToFloat.isNegZero());9246 9247 APFloat One(APFloat::Float8E4M3FN(), "1.0");9248 EXPECT_EQ(1.0F, One.convertToFloat());9249 APFloat Two(APFloat::Float8E4M3FN(), "2.0");9250 EXPECT_EQ(2.0F, Two.convertToFloat());9251 9252 APFloat PosLargest = APFloat::getLargest(APFloat::Float8E4M3FN(), false);9253 EXPECT_EQ(448., PosLargest.convertToFloat());9254 APFloat NegLargest = APFloat::getLargest(APFloat::Float8E4M3FN(), true);9255 EXPECT_EQ(-448, NegLargest.convertToFloat());9256 APFloat PosSmallest =9257 APFloat::getSmallestNormalized(APFloat::Float8E4M3FN(), false);9258 EXPECT_EQ(0x1.p-6, PosSmallest.convertToFloat());9259 APFloat NegSmallest =9260 APFloat::getSmallestNormalized(APFloat::Float8E4M3FN(), true);9261 EXPECT_EQ(-0x1.p-6, NegSmallest.convertToFloat());9262 9263 APFloat SmallestDenorm = APFloat::getSmallest(APFloat::Float8E4M3FN(), false);9264 EXPECT_TRUE(SmallestDenorm.isDenormal());9265 EXPECT_EQ(0x1.p-9, SmallestDenorm.convertToFloat());9266 9267 APFloat QNaN = APFloat::getQNaN(APFloat::Float8E4M3FN());9268 EXPECT_TRUE(std::isnan(QNaN.convertToFloat()));9269}9270 9271TEST(APFloatTest, Float8E3M4ToFloat) {9272 APFloat PosZero = APFloat::getZero(APFloat::Float8E3M4(), false);9273 APFloat PosZeroToFloat(PosZero.convertToFloat());9274 EXPECT_TRUE(PosZeroToFloat.isPosZero());9275 APFloat NegZero = APFloat::getZero(APFloat::Float8E3M4(), true);9276 APFloat NegZeroToFloat(NegZero.convertToFloat());9277 EXPECT_TRUE(NegZeroToFloat.isNegZero());9278 9279 APFloat One(APFloat::Float8E3M4(), "1.0");9280 EXPECT_EQ(1.0F, One.convertToFloat());9281 APFloat Two(APFloat::Float8E3M4(), "2.0");9282 EXPECT_EQ(2.0F, Two.convertToFloat());9283 9284 APFloat PosLargest = APFloat::getLargest(APFloat::Float8E3M4(), false);9285 EXPECT_EQ(15.5F, PosLargest.convertToFloat());9286 APFloat NegLargest = APFloat::getLargest(APFloat::Float8E3M4(), true);9287 EXPECT_EQ(-15.5F, NegLargest.convertToFloat());9288 APFloat PosSmallest =9289 APFloat::getSmallestNormalized(APFloat::Float8E3M4(), false);9290 EXPECT_EQ(0x1.p-2, PosSmallest.convertToFloat());9291 APFloat NegSmallest =9292 APFloat::getSmallestNormalized(APFloat::Float8E3M4(), true);9293 EXPECT_EQ(-0x1.p-2, NegSmallest.convertToFloat());9294 9295 APFloat PosSmallestDenorm =9296 APFloat::getSmallest(APFloat::Float8E3M4(), false);9297 EXPECT_TRUE(PosSmallestDenorm.isDenormal());9298 EXPECT_EQ(0x1.p-6, PosSmallestDenorm.convertToFloat());9299 APFloat NegSmallestDenorm = APFloat::getSmallest(APFloat::Float8E3M4(), true);9300 EXPECT_TRUE(NegSmallestDenorm.isDenormal());9301 EXPECT_EQ(-0x1.p-6, NegSmallestDenorm.convertToFloat());9302 9303 APFloat PosInf = APFloat::getInf(APFloat::Float8E3M4());9304 EXPECT_EQ(std::numeric_limits<float>::infinity(), PosInf.convertToFloat());9305 APFloat NegInf = APFloat::getInf(APFloat::Float8E3M4(), true);9306 EXPECT_EQ(-std::numeric_limits<float>::infinity(), NegInf.convertToFloat());9307 APFloat QNaN = APFloat::getQNaN(APFloat::Float8E3M4());9308 EXPECT_TRUE(std::isnan(QNaN.convertToFloat()));9309}9310 9311TEST(APFloatTest, FloatTF32ToFloat) {9312 APFloat PosZero = APFloat::getZero(APFloat::FloatTF32());9313 APFloat PosZeroToFloat(PosZero.convertToFloat());9314 EXPECT_TRUE(PosZeroToFloat.isPosZero());9315 APFloat NegZero = APFloat::getZero(APFloat::FloatTF32(), true);9316 APFloat NegZeroToFloat(NegZero.convertToFloat());9317 EXPECT_TRUE(NegZeroToFloat.isNegZero());9318 9319 APFloat One(APFloat::FloatTF32(), "1.0");9320 EXPECT_EQ(1.0F, One.convertToFloat());9321 APFloat Two(APFloat::FloatTF32(), "2.0");9322 EXPECT_EQ(2.0F, Two.convertToFloat());9323 9324 APFloat PosLargest = APFloat::getLargest(APFloat::FloatTF32(), false);9325 EXPECT_EQ(3.40116213421e+38F, PosLargest.convertToFloat());9326 9327 APFloat NegLargest = APFloat::getLargest(APFloat::FloatTF32(), true);9328 EXPECT_EQ(-3.40116213421e+38F, NegLargest.convertToFloat());9329 9330 APFloat PosSmallest =9331 APFloat::getSmallestNormalized(APFloat::FloatTF32(), false);9332 EXPECT_EQ(/*0x1.p-126*/ 1.1754943508222875e-38F,9333 PosSmallest.convertToFloat());9334 APFloat NegSmallest =9335 APFloat::getSmallestNormalized(APFloat::FloatTF32(), true);9336 EXPECT_EQ(/*-0x1.p-126*/ -1.1754943508222875e-38F,9337 NegSmallest.convertToFloat());9338 9339 APFloat SmallestDenorm = APFloat::getSmallest(APFloat::FloatTF32(), false);9340 EXPECT_TRUE(SmallestDenorm.isDenormal());9341 EXPECT_EQ(0x0.004p-126, SmallestDenorm.convertToFloat());9342 9343 APFloat QNaN = APFloat::getQNaN(APFloat::FloatTF32());9344 EXPECT_TRUE(std::isnan(QNaN.convertToFloat()));9345}9346 9347TEST(APFloatTest, getExactLog2) {9348 for (unsigned I = 0; I != APFloat::S_MaxSemantics + 1; ++I) {9349 auto SemEnum = static_cast<APFloat::Semantics>(I);9350 const fltSemantics &Semantics = APFloat::EnumToSemantics(SemEnum);9351 9352 // For the Float8E8M0FNU format, the below cases along9353 // with some more corner cases are tested through9354 // Float8E8M0FNUGetExactLog2.9355 if (I == APFloat::S_Float8E8M0FNU)9356 continue;9357 9358 APFloat One(Semantics, "1.0");9359 APFloat Smallest = APFloat::getSmallest(Semantics);9360 APFloat Largest = APFloat::getLargest(Semantics);9361 9362 int MinExp = APFloat::semanticsMinExponent(Semantics);9363 int MaxExp = APFloat::semanticsMaxExponent(Semantics);9364 int Precision = APFloat::semanticsPrecision(Semantics);9365 9366 EXPECT_EQ(0, One.getExactLog2());9367 EXPECT_EQ(INT_MIN, APFloat(Semantics, "3.0").getExactLog2());9368 EXPECT_EQ(INT_MIN, APFloat(Semantics, "-3.0").getExactLog2());9369 EXPECT_EQ(INT_MIN, APFloat(Semantics, "3.0").getExactLog2Abs());9370 EXPECT_EQ(INT_MIN, APFloat(Semantics, "-3.0").getExactLog2Abs());9371 9372 if (I == APFloat::S_Float6E2M3FN || I == APFloat::S_Float4E2M1FN) {9373 EXPECT_EQ(2, APFloat(Semantics, "4.0").getExactLog2());9374 EXPECT_EQ(INT_MIN, APFloat(Semantics, "-4.0").getExactLog2());9375 EXPECT_EQ(2, APFloat(Semantics, "4.0").getExactLog2Abs());9376 EXPECT_EQ(2, APFloat(Semantics, "-4.0").getExactLog2Abs());9377 } else {9378 EXPECT_EQ(3, APFloat(Semantics, "8.0").getExactLog2());9379 EXPECT_EQ(INT_MIN, APFloat(Semantics, "-8.0").getExactLog2());9380 EXPECT_EQ(-2, APFloat(Semantics, "0.25").getExactLog2());9381 EXPECT_EQ(-2, APFloat(Semantics, "0.25").getExactLog2Abs());9382 EXPECT_EQ(INT_MIN, APFloat(Semantics, "-0.25").getExactLog2());9383 EXPECT_EQ(-2, APFloat(Semantics, "-0.25").getExactLog2Abs());9384 EXPECT_EQ(3, APFloat(Semantics, "8.0").getExactLog2Abs());9385 EXPECT_EQ(3, APFloat(Semantics, "-8.0").getExactLog2Abs());9386 }9387 9388 EXPECT_EQ(INT_MIN, APFloat::getZero(Semantics, false).getExactLog2());9389 EXPECT_EQ(INT_MIN, APFloat::getZero(Semantics, true).getExactLog2());9390 EXPECT_EQ(INT_MIN, APFloat::getZero(Semantics, false).getExactLog2Abs());9391 EXPECT_EQ(INT_MIN, APFloat::getZero(Semantics, true).getExactLog2Abs());9392 9393 if (APFloat::semanticsHasNaN(Semantics)) {9394 // Types that do not support Inf will return NaN when asked for Inf.9395 // (But only if they support NaN.)9396 EXPECT_EQ(INT_MIN, APFloat::getInf(Semantics).getExactLog2());9397 EXPECT_EQ(INT_MIN, APFloat::getInf(Semantics, true).getExactLog2());9398 EXPECT_EQ(INT_MIN, APFloat::getNaN(Semantics, false).getExactLog2());9399 EXPECT_EQ(INT_MIN, APFloat::getNaN(Semantics, true).getExactLog2());9400 9401 EXPECT_EQ(INT_MIN, APFloat::getInf(Semantics).getExactLog2Abs());9402 EXPECT_EQ(INT_MIN, APFloat::getInf(Semantics, true).getExactLog2Abs());9403 EXPECT_EQ(INT_MIN, APFloat::getNaN(Semantics, false).getExactLog2Abs());9404 EXPECT_EQ(INT_MIN, APFloat::getNaN(Semantics, true).getExactLog2Abs());9405 }9406 9407 EXPECT_EQ(9408 INT_MIN,9409 scalbn(Smallest, -2, APFloat::rmNearestTiesToEven).getExactLog2());9410 EXPECT_EQ(9411 INT_MIN,9412 scalbn(Smallest, -1, APFloat::rmNearestTiesToEven).getExactLog2());9413 9414 EXPECT_EQ(INT_MIN,9415 scalbn(Largest, 1, APFloat::rmNearestTiesToEven).getExactLog2());9416 9417 for (int i = MinExp - Precision + 1; i <= MaxExp; ++i) {9418 EXPECT_EQ(i, scalbn(One, i, APFloat::rmNearestTiesToEven).getExactLog2());9419 }9420 }9421}9422 9423TEST(APFloatTest, Float8E8M0FNUGetZero) {9424#ifdef GTEST_HAS_DEATH_TEST9425#ifndef NDEBUG9426 EXPECT_DEATH(APFloat::getZero(APFloat::Float8E8M0FNU(), false),9427 "This floating point format does not support Zero");9428 EXPECT_DEATH(APFloat::getZero(APFloat::Float8E8M0FNU(), true),9429 "This floating point format does not support Zero");9430#endif9431#endif9432}9433 9434TEST(APFloatTest, Float8E8M0FNUGetSignedValues) {9435#ifdef GTEST_HAS_DEATH_TEST9436#ifndef NDEBUG9437 EXPECT_DEATH(APFloat(APFloat::Float8E8M0FNU(), "-64"),9438 "This floating point format does not support signed values");9439 EXPECT_DEATH(APFloat(APFloat::Float8E8M0FNU(), "-0x1.0p128"),9440 "This floating point format does not support signed values");9441 EXPECT_DEATH(APFloat(APFloat::Float8E8M0FNU(), "-inf"),9442 "This floating point format does not support signed values");9443 EXPECT_DEATH(APFloat::getNaN(APFloat::Float8E8M0FNU(), true),9444 "This floating point format does not support signed values");9445 EXPECT_DEATH(APFloat::getInf(APFloat::Float8E8M0FNU(), true),9446 "This floating point format does not support signed values");9447 EXPECT_DEATH(APFloat::getSmallest(APFloat::Float8E8M0FNU(), true),9448 "This floating point format does not support signed values");9449 EXPECT_DEATH(APFloat::getSmallestNormalized(APFloat::Float8E8M0FNU(), true),9450 "This floating point format does not support signed values");9451 EXPECT_DEATH(APFloat::getLargest(APFloat::Float8E8M0FNU(), true),9452 "This floating point format does not support signed values");9453 APFloat x = APFloat(APFloat::Float8E8M0FNU(), "4");9454 APFloat y = APFloat(APFloat::Float8E8M0FNU(), "8");9455 EXPECT_DEATH(x.subtract(y, APFloat::rmNearestTiesToEven),9456 "This floating point format does not support signed values");9457#endif9458#endif9459}9460 9461TEST(APFloatTest, Float8E8M0FNUGetInf) {9462 // The E8M0 format does not support infinity and the9463 // all ones representation is treated as NaN.9464 APFloat t = APFloat::getInf(APFloat::Float8E8M0FNU());9465 EXPECT_TRUE(t.isNaN());9466 EXPECT_FALSE(t.isInfinity());9467}9468 9469TEST(APFloatTest, Float8E8M0FNUFromString) {9470 // Exactly representable9471 EXPECT_EQ(64, APFloat(APFloat::Float8E8M0FNU(), "64").convertToDouble());9472 // Overflow to NaN9473 EXPECT_TRUE(APFloat(APFloat::Float8E8M0FNU(), "0x1.0p128").isNaN());9474 // Inf converted to NaN9475 EXPECT_TRUE(APFloat(APFloat::Float8E8M0FNU(), "inf").isNaN());9476 // NaN converted to NaN9477 EXPECT_TRUE(APFloat(APFloat::Float8E8M0FNU(), "nan").isNaN());9478}9479 9480TEST(APFloatTest, Float8E8M0FNUDivideByZero) {9481 APFloat x(APFloat::Float8E8M0FNU(), "1");9482 APFloat zero(APFloat::Float8E8M0FNU(), "0");9483 x.divide(zero, APFloat::rmNearestTiesToEven);9484 9485 // Zero is represented as the smallest normalized value9486 // in this format i.e 2^-127.9487 // This tests the fix in convertFromDecimalString() function.9488 EXPECT_EQ(0x1.0p-127, zero.convertToDouble());9489 9490 // [1 / (2^-127)] = 2^1279491 EXPECT_EQ(0x1.0p127, x.convertToDouble());9492}9493 9494TEST(APFloatTest, Float8E8M0FNUGetExactLog2) {9495 const fltSemantics &Semantics = APFloat::Float8E8M0FNU();9496 APFloat One(Semantics, "1.0");9497 EXPECT_EQ(0, One.getExactLog2());9498 9499 // In the Float8E8M0FNU format, 3 is rounded-up to 4.9500 // So, we expect 2 as the result.9501 EXPECT_EQ(2, APFloat(Semantics, "3.0").getExactLog2());9502 EXPECT_EQ(2, APFloat(Semantics, "3.0").getExactLog2Abs());9503 9504 // In the Float8E8M0FNU format, 5 is rounded-down to 4.9505 // So, we expect 2 as the result.9506 EXPECT_EQ(2, APFloat(Semantics, "5.0").getExactLog2());9507 EXPECT_EQ(2, APFloat(Semantics, "5.0").getExactLog2Abs());9508 9509 // Exact power-of-two value.9510 EXPECT_EQ(3, APFloat(Semantics, "8.0").getExactLog2());9511 EXPECT_EQ(3, APFloat(Semantics, "8.0").getExactLog2Abs());9512 9513 // Negative exponent value.9514 EXPECT_EQ(-2, APFloat(Semantics, "0.25").getExactLog2());9515 EXPECT_EQ(-2, APFloat(Semantics, "0.25").getExactLog2Abs());9516 9517 int MinExp = APFloat::semanticsMinExponent(Semantics);9518 int MaxExp = APFloat::semanticsMaxExponent(Semantics);9519 int Precision = APFloat::semanticsPrecision(Semantics);9520 9521 // Values below the minExp getting capped to minExp.9522 EXPECT_EQ(-127,9523 scalbn(One, MinExp - Precision - 1, APFloat::rmNearestTiesToEven)9524 .getExactLog2());9525 EXPECT_EQ(-127, scalbn(One, MinExp - Precision, APFloat::rmNearestTiesToEven)9526 .getExactLog2());9527 9528 // Values above the maxExp overflow to NaN, and getExactLog2() returns9529 // INT_MIN for these cases.9530 EXPECT_EQ(9531 INT_MIN,9532 scalbn(One, MaxExp + 1, APFloat::rmNearestTiesToEven).getExactLog2());9533 9534 // This format can represent [minExp, maxExp].9535 // So, the result is the same as the 'Exp' of the scalbn.9536 for (int i = MinExp - Precision + 1; i <= MaxExp; ++i) {9537 EXPECT_EQ(i, scalbn(One, i, APFloat::rmNearestTiesToEven).getExactLog2());9538 }9539}9540 9541TEST(APFloatTest, Float8E8M0FNUSmallest) {9542 APFloat test(APFloat::getSmallest(APFloat::Float8E8M0FNU()));9543 EXPECT_EQ(0x1.0p-127, test.convertToDouble());9544 9545 // For E8M0 format, there are no denorms.9546 // So, getSmallest is equal to isSmallestNormalized().9547 EXPECT_TRUE(test.isSmallestNormalized());9548 EXPECT_EQ(fcPosNormal, test.classify());9549 9550 test = APFloat::getAllOnesValue(APFloat::Float8E8M0FNU());9551 EXPECT_FALSE(test.isSmallestNormalized());9552 EXPECT_TRUE(test.isNaN());9553}9554 9555TEST(APFloatTest, Float8E8M0FNUNext) {9556 APFloat test(APFloat::getSmallest(APFloat::Float8E8M0FNU()));9557 // Increment of 1 should reach 2^-1269558 EXPECT_EQ(APFloat::opOK, test.next(false));9559 EXPECT_FALSE(test.isSmallestNormalized());9560 EXPECT_EQ(0x1.0p-126, test.convertToDouble());9561 9562 // Decrement of 1, again, should reach 2^-1279563 // i.e. smallest normalized9564 EXPECT_EQ(APFloat::opOK, test.next(true));9565 EXPECT_TRUE(test.isSmallestNormalized());9566 9567 // Decrement again, but gets capped at the smallest normalized9568 EXPECT_EQ(APFloat::opOK, test.next(true));9569 EXPECT_TRUE(test.isSmallestNormalized());9570}9571 9572TEST(APFloatTest, Float8E8M0FNUFMA) {9573 APFloat f1(APFloat::Float8E8M0FNU(), "4.0");9574 APFloat f2(APFloat::Float8E8M0FNU(), "2.0");9575 APFloat f3(APFloat::Float8E8M0FNU(), "8.0");9576 9577 // Exact value: 4*2 + 8 = 16.9578 f1.fusedMultiplyAdd(f2, f3, APFloat::rmNearestTiesToEven);9579 EXPECT_EQ(16.0, f1.convertToDouble());9580 9581 // 4*2 + 4 = 12 but it gets rounded-up to 16.9582 f1 = APFloat(APFloat::Float8E8M0FNU(), "4.0");9583 f1.fusedMultiplyAdd(f2, f1, APFloat::rmNearestTiesToEven);9584 EXPECT_EQ(16.0, f1.convertToDouble());9585 9586 // 4*2 + 2 = 10 but it gets rounded-down to 8.9587 f1 = APFloat(APFloat::Float8E8M0FNU(), "4.0");9588 f1.fusedMultiplyAdd(f2, f2, APFloat::rmNearestTiesToEven);9589 EXPECT_EQ(8.0, f1.convertToDouble());9590 9591 // All of them using the same value.9592 f1 = APFloat(APFloat::Float8E8M0FNU(), "1.0");9593 f1.fusedMultiplyAdd(f1, f1, APFloat::rmNearestTiesToEven);9594 EXPECT_EQ(2.0, f1.convertToDouble());9595}9596 9597TEST(APFloatTest, ConvertDoubleToE8M0FNU) {9598 bool losesInfo;9599 APFloat test(APFloat::IEEEdouble(), "1.0");9600 APFloat::opStatus status = test.convert(9601 APFloat::Float8E8M0FNU(), APFloat::rmNearestTiesToEven, &losesInfo);9602 EXPECT_EQ(1.0, test.convertToDouble());9603 EXPECT_FALSE(losesInfo);9604 EXPECT_EQ(status, APFloat::opOK);9605 9606 // For E8M0, zero encoding is represented as the smallest normalized value.9607 test = APFloat(APFloat::IEEEdouble(), "0.0");9608 status = test.convert(APFloat::Float8E8M0FNU(), APFloat::rmNearestTiesToEven,9609 &losesInfo);9610 EXPECT_TRUE(test.isSmallestNormalized());9611 EXPECT_EQ(0x1.0p-127, test.convertToDouble());9612 EXPECT_FALSE(losesInfo);9613 EXPECT_EQ(status, APFloat::opOK);9614 9615 // Test that the conversion of a power-of-two value is precise.9616 test = APFloat(APFloat::IEEEdouble(), "8.0");9617 status = test.convert(APFloat::Float8E8M0FNU(), APFloat::rmNearestTiesToEven,9618 &losesInfo);9619 EXPECT_EQ(8.0f, test.convertToDouble());9620 EXPECT_FALSE(losesInfo);9621 EXPECT_EQ(status, APFloat::opOK);9622 9623 // Test to check round-down conversion to power-of-two.9624 // The fractional part of 9 is "001" (i.e. 1.125x2^3=9).9625 test = APFloat(APFloat::IEEEdouble(), "9.0");9626 status = test.convert(APFloat::Float8E8M0FNU(), APFloat::rmNearestTiesToEven,9627 &losesInfo);9628 EXPECT_EQ(8.0f, test.convertToDouble());9629 EXPECT_TRUE(losesInfo);9630 EXPECT_EQ(status, APFloat::opInexact);9631 9632 // Test to check round-up conversion to power-of-two.9633 // The fractional part of 13 is "101" (i.e. 1.625x2^3=13).9634 test = APFloat(APFloat::IEEEdouble(), "13.0");9635 status = test.convert(APFloat::Float8E8M0FNU(), APFloat::rmNearestTiesToEven,9636 &losesInfo);9637 EXPECT_EQ(16.0f, test.convertToDouble());9638 EXPECT_TRUE(losesInfo);9639 EXPECT_EQ(status, APFloat::opInexact);9640 9641 // Test to check round-up conversion to power-of-two.9642 // The fractional part of 12 is "100" (i.e. 1.5x2^3=12).9643 test = APFloat(APFloat::IEEEdouble(), "12.0");9644 status = test.convert(APFloat::Float8E8M0FNU(), APFloat::rmNearestTiesToEven,9645 &losesInfo);9646 EXPECT_EQ(16.0f, test.convertToDouble());9647 EXPECT_TRUE(losesInfo);9648 EXPECT_EQ(status, APFloat::opInexact);9649 9650 // Overflow to NaN.9651 test = APFloat(APFloat::IEEEdouble(), "0x1.0p128");9652 status = test.convert(APFloat::Float8E8M0FNU(), APFloat::rmNearestTiesToEven,9653 &losesInfo);9654 EXPECT_TRUE(test.isNaN());9655 EXPECT_TRUE(losesInfo);9656 EXPECT_EQ(status, APFloat::opOverflow | APFloat::opInexact);9657 9658 // Underflow to smallest normalized value.9659 test = APFloat(APFloat::IEEEdouble(), "0x1.0p-128");9660 status = test.convert(APFloat::Float8E8M0FNU(), APFloat::rmNearestTiesToEven,9661 &losesInfo);9662 EXPECT_TRUE(test.isSmallestNormalized());9663 EXPECT_TRUE(losesInfo);9664 EXPECT_EQ(status, APFloat::opUnderflow | APFloat::opInexact);9665}9666 9667TEST(APFloatTest, Float6E3M2FNFromString) {9668 // Exactly representable9669 EXPECT_EQ(28, APFloat(APFloat::Float6E3M2FN(), "28").convertToDouble());9670 // Round down to maximum value9671 EXPECT_EQ(28, APFloat(APFloat::Float6E3M2FN(), "32").convertToDouble());9672 9673#ifdef GTEST_HAS_DEATH_TEST9674#ifndef NDEBUG9675 EXPECT_DEATH(APFloat(APFloat::Float6E3M2FN(), "inf"),9676 "This floating point format does not support Inf");9677 EXPECT_DEATH(APFloat(APFloat::Float6E3M2FN(), "nan"),9678 "This floating point format does not support NaN");9679#endif9680#endif9681 9682 EXPECT_TRUE(APFloat(APFloat::Float6E3M2FN(), "0").isPosZero());9683 EXPECT_TRUE(APFloat(APFloat::Float6E3M2FN(), "-0").isNegZero());9684}9685 9686TEST(APFloatTest, Float6E2M3FNFromString) {9687 // Exactly representable9688 EXPECT_EQ(7.5, APFloat(APFloat::Float6E2M3FN(), "7.5").convertToDouble());9689 // Round down to maximum value9690 EXPECT_EQ(7.5, APFloat(APFloat::Float6E2M3FN(), "32").convertToDouble());9691 9692#ifdef GTEST_HAS_DEATH_TEST9693#ifndef NDEBUG9694 EXPECT_DEATH(APFloat(APFloat::Float6E2M3FN(), "inf"),9695 "This floating point format does not support Inf");9696 EXPECT_DEATH(APFloat(APFloat::Float6E2M3FN(), "nan"),9697 "This floating point format does not support NaN");9698#endif9699#endif9700 9701 EXPECT_TRUE(APFloat(APFloat::Float6E2M3FN(), "0").isPosZero());9702 EXPECT_TRUE(APFloat(APFloat::Float6E2M3FN(), "-0").isNegZero());9703}9704 9705TEST(APFloatTest, Float4E2M1FNFromString) {9706 // Exactly representable9707 EXPECT_EQ(6, APFloat(APFloat::Float4E2M1FN(), "6").convertToDouble());9708 // Round down to maximum value9709 EXPECT_EQ(6, APFloat(APFloat::Float4E2M1FN(), "32").convertToDouble());9710 9711#ifdef GTEST_HAS_DEATH_TEST9712#ifndef NDEBUG9713 EXPECT_DEATH(APFloat(APFloat::Float4E2M1FN(), "inf"),9714 "This floating point format does not support Inf");9715 EXPECT_DEATH(APFloat(APFloat::Float4E2M1FN(), "nan"),9716 "This floating point format does not support NaN");9717#endif9718#endif9719 9720 EXPECT_TRUE(APFloat(APFloat::Float4E2M1FN(), "0").isPosZero());9721 EXPECT_TRUE(APFloat(APFloat::Float4E2M1FN(), "-0").isNegZero());9722}9723 9724TEST(APFloatTest, ConvertE3M2FToE2M3F) {9725 bool losesInfo;9726 APFloat test(APFloat::Float6E3M2FN(), "1.0");9727 APFloat::opStatus status = test.convert(9728 APFloat::Float6E2M3FN(), APFloat::rmNearestTiesToEven, &losesInfo);9729 EXPECT_EQ(1.0f, test.convertToFloat());9730 EXPECT_FALSE(losesInfo);9731 EXPECT_EQ(status, APFloat::opOK);9732 9733 test = APFloat(APFloat::Float6E3M2FN(), "0.0");9734 status = test.convert(APFloat::Float6E2M3FN(), APFloat::rmNearestTiesToEven,9735 &losesInfo);9736 EXPECT_EQ(0.0f, test.convertToFloat());9737 EXPECT_FALSE(losesInfo);9738 EXPECT_EQ(status, APFloat::opOK);9739 9740 // Test overflow9741 test = APFloat(APFloat::Float6E3M2FN(), "28");9742 status = test.convert(APFloat::Float6E2M3FN(), APFloat::rmNearestTiesToEven,9743 &losesInfo);9744 EXPECT_EQ(7.5f, test.convertToFloat());9745 EXPECT_TRUE(losesInfo);9746 EXPECT_EQ(status, APFloat::opInexact);9747 9748 // Test underflow9749 test = APFloat(APFloat::Float6E3M2FN(), ".0625");9750 status = test.convert(APFloat::Float6E2M3FN(), APFloat::rmNearestTiesToEven,9751 &losesInfo);9752 EXPECT_EQ(0., test.convertToFloat());9753 EXPECT_TRUE(losesInfo);9754 EXPECT_EQ(status, APFloat::opUnderflow | APFloat::opInexact);9755 9756 // Testing inexact rounding to denormal number9757 test = APFloat(APFloat::Float6E3M2FN(), "0.1875");9758 status = test.convert(APFloat::Float6E2M3FN(), APFloat::rmNearestTiesToEven,9759 &losesInfo);9760 EXPECT_EQ(0.25, test.convertToFloat());9761 EXPECT_TRUE(losesInfo);9762 EXPECT_EQ(status, APFloat::opUnderflow | APFloat::opInexact);9763}9764 9765TEST(APFloatTest, ConvertE2M3FToE3M2F) {9766 bool losesInfo;9767 APFloat test(APFloat::Float6E2M3FN(), "1.0");9768 APFloat::opStatus status = test.convert(9769 APFloat::Float6E3M2FN(), APFloat::rmNearestTiesToEven, &losesInfo);9770 EXPECT_EQ(1.0f, test.convertToFloat());9771 EXPECT_FALSE(losesInfo);9772 EXPECT_EQ(status, APFloat::opOK);9773 9774 test = APFloat(APFloat::Float6E2M3FN(), "0.0");9775 status = test.convert(APFloat::Float6E3M2FN(), APFloat::rmNearestTiesToEven,9776 &losesInfo);9777 EXPECT_EQ(0.0f, test.convertToFloat());9778 EXPECT_FALSE(losesInfo);9779 EXPECT_EQ(status, APFloat::opOK);9780 9781 test = APFloat(APFloat::Float6E2M3FN(), ".125");9782 status = test.convert(APFloat::Float6E3M2FN(), APFloat::rmNearestTiesToEven,9783 &losesInfo);9784 EXPECT_EQ(.125, test.convertToFloat());9785 EXPECT_FALSE(losesInfo);9786 EXPECT_EQ(status, APFloat::opOK);9787 9788 // Test inexact rounding9789 test = APFloat(APFloat::Float6E2M3FN(), "7.5");9790 status = test.convert(APFloat::Float6E3M2FN(), APFloat::rmNearestTiesToEven,9791 &losesInfo);9792 EXPECT_EQ(8, test.convertToFloat());9793 EXPECT_TRUE(losesInfo);9794 EXPECT_EQ(status, APFloat::opInexact);9795}9796 9797TEST(APFloatTest, ConvertDoubleToE2M1F) {9798 bool losesInfo;9799 APFloat test(APFloat::IEEEdouble(), "1.0");9800 APFloat::opStatus status = test.convert(9801 APFloat::Float4E2M1FN(), APFloat::rmNearestTiesToEven, &losesInfo);9802 EXPECT_EQ(1.0, test.convertToDouble());9803 EXPECT_FALSE(losesInfo);9804 EXPECT_EQ(status, APFloat::opOK);9805 9806 test = APFloat(APFloat::IEEEdouble(), "0.0");9807 status = test.convert(APFloat::Float4E2M1FN(), APFloat::rmNearestTiesToEven,9808 &losesInfo);9809 EXPECT_EQ(0.0f, test.convertToDouble());9810 EXPECT_FALSE(losesInfo);9811 EXPECT_EQ(status, APFloat::opOK);9812 9813 // Test overflow9814 test = APFloat(APFloat::IEEEdouble(), "8");9815 status = test.convert(APFloat::Float4E2M1FN(), APFloat::rmNearestTiesToEven,9816 &losesInfo);9817 EXPECT_EQ(6, test.convertToDouble());9818 EXPECT_TRUE(losesInfo);9819 EXPECT_EQ(status, APFloat::opInexact);9820 9821 // Test underflow9822 test = APFloat(APFloat::IEEEdouble(), "0.25");9823 status = test.convert(APFloat::Float4E2M1FN(), APFloat::rmNearestTiesToEven,9824 &losesInfo);9825 EXPECT_EQ(0., test.convertToDouble());9826 EXPECT_TRUE(losesInfo);9827 EXPECT_FALSE(test.isDenormal());9828 EXPECT_EQ(status, APFloat::opUnderflow | APFloat::opInexact);9829}9830 9831TEST(APFloatTest, Float6E3M2FNNext) {9832 APFloat test(APFloat::Float6E3M2FN(), APFloat::uninitialized);9833 APFloat expected(APFloat::Float6E3M2FN(), APFloat::uninitialized);9834 9835 // 1. NextUp of largest bit pattern is the same9836 test = APFloat::getLargest(APFloat::Float6E3M2FN());9837 expected = APFloat::getLargest(APFloat::Float6E3M2FN());9838 EXPECT_EQ(test.next(false), APFloat::opOK);9839 EXPECT_FALSE(test.isInfinity());9840 EXPECT_FALSE(test.isZero());9841 EXPECT_TRUE(test.bitwiseIsEqual(expected));9842 9843 // 2. NextUp of smallest negative denormal is -09844 test = APFloat::getSmallest(APFloat::Float6E3M2FN(), true);9845 expected = APFloat::getZero(APFloat::Float6E3M2FN(), true);9846 EXPECT_EQ(test.next(false), APFloat::opOK);9847 EXPECT_TRUE(test.isNegZero());9848 EXPECT_FALSE(test.isPosZero());9849 EXPECT_TRUE(test.bitwiseIsEqual(expected));9850 9851 // 3. nextDown of negative of largest value is the same9852 test = APFloat::getLargest(APFloat::Float6E3M2FN(), true);9853 expected = test;9854 EXPECT_EQ(test.next(true), APFloat::opOK);9855 EXPECT_FALSE(test.isInfinity());9856 EXPECT_FALSE(test.isZero());9857 EXPECT_FALSE(test.isNaN());9858 EXPECT_TRUE(test.bitwiseIsEqual(expected));9859 9860 // 4. nextDown of +0 is smallest negative denormal9861 test = APFloat::getZero(APFloat::Float6E3M2FN(), false);9862 expected = APFloat::getSmallest(APFloat::Float6E3M2FN(), true);9863 EXPECT_EQ(test.next(true), APFloat::opOK);9864 EXPECT_FALSE(test.isZero());9865 EXPECT_TRUE(test.isDenormal());9866 EXPECT_TRUE(test.bitwiseIsEqual(expected));9867}9868 9869TEST(APFloatTest, Float6E2M3FNNext) {9870 APFloat test(APFloat::Float6E2M3FN(), APFloat::uninitialized);9871 APFloat expected(APFloat::Float6E2M3FN(), APFloat::uninitialized);9872 9873 // 1. NextUp of largest bit pattern is the same9874 test = APFloat::getLargest(APFloat::Float6E2M3FN());9875 expected = APFloat::getLargest(APFloat::Float6E2M3FN());9876 EXPECT_EQ(test.next(false), APFloat::opOK);9877 EXPECT_FALSE(test.isInfinity());9878 EXPECT_FALSE(test.isZero());9879 EXPECT_TRUE(test.bitwiseIsEqual(expected));9880 9881 // 2. NextUp of smallest negative denormal is -09882 test = APFloat::getSmallest(APFloat::Float6E2M3FN(), true);9883 expected = APFloat::getZero(APFloat::Float6E2M3FN(), true);9884 EXPECT_EQ(test.next(false), APFloat::opOK);9885 EXPECT_TRUE(test.isNegZero());9886 EXPECT_FALSE(test.isPosZero());9887 EXPECT_TRUE(test.bitwiseIsEqual(expected));9888 9889 // 3. nextDown of negative of largest value is the same9890 test = APFloat::getLargest(APFloat::Float6E2M3FN(), true);9891 expected = test;9892 EXPECT_EQ(test.next(true), APFloat::opOK);9893 EXPECT_FALSE(test.isInfinity());9894 EXPECT_FALSE(test.isZero());9895 EXPECT_FALSE(test.isNaN());9896 EXPECT_TRUE(test.bitwiseIsEqual(expected));9897 9898 // 4. nextDown of +0 is smallest negative denormal9899 test = APFloat::getZero(APFloat::Float6E2M3FN(), false);9900 expected = APFloat::getSmallest(APFloat::Float6E2M3FN(), true);9901 EXPECT_EQ(test.next(true), APFloat::opOK);9902 EXPECT_FALSE(test.isZero());9903 EXPECT_TRUE(test.isDenormal());9904 EXPECT_TRUE(test.bitwiseIsEqual(expected));9905}9906 9907TEST(APFloatTest, Float4E2M1FNNext) {9908 APFloat test(APFloat::Float4E2M1FN(), APFloat::uninitialized);9909 APFloat expected(APFloat::Float4E2M1FN(), APFloat::uninitialized);9910 9911 // 1. NextUp of largest bit pattern is the same9912 test = APFloat::getLargest(APFloat::Float4E2M1FN());9913 expected = APFloat::getLargest(APFloat::Float4E2M1FN());9914 EXPECT_EQ(test.next(false), APFloat::opOK);9915 EXPECT_FALSE(test.isInfinity());9916 EXPECT_FALSE(test.isZero());9917 EXPECT_TRUE(test.bitwiseIsEqual(expected));9918 9919 // 2. NextUp of smallest negative denormal is -09920 test = APFloat::getSmallest(APFloat::Float4E2M1FN(), true);9921 expected = APFloat::getZero(APFloat::Float4E2M1FN(), true);9922 EXPECT_EQ(test.next(false), APFloat::opOK);9923 EXPECT_TRUE(test.isNegZero());9924 EXPECT_FALSE(test.isPosZero());9925 EXPECT_TRUE(test.bitwiseIsEqual(expected));9926 9927 // 3. nextDown of negative of largest value is the same9928 test = APFloat::getLargest(APFloat::Float4E2M1FN(), true);9929 expected = test;9930 EXPECT_EQ(test.next(true), APFloat::opOK);9931 EXPECT_FALSE(test.isInfinity());9932 EXPECT_FALSE(test.isZero());9933 EXPECT_FALSE(test.isNaN());9934 EXPECT_TRUE(test.bitwiseIsEqual(expected));9935 9936 // 4. nextDown of +0 is smallest negative denormal9937 test = APFloat::getZero(APFloat::Float4E2M1FN(), false);9938 expected = APFloat::getSmallest(APFloat::Float4E2M1FN(), true);9939 EXPECT_EQ(test.next(true), APFloat::opOK);9940 EXPECT_FALSE(test.isZero());9941 EXPECT_TRUE(test.isDenormal());9942 EXPECT_TRUE(test.bitwiseIsEqual(expected));9943}9944 9945#ifdef GTEST_HAS_DEATH_TEST9946#ifndef NDEBUG9947TEST(APFloatTest, Float6E3M2FNGetInfNaN) {9948 EXPECT_DEATH(APFloat::getInf(APFloat::Float6E3M2FN()),9949 "This floating point format does not support Inf");9950 EXPECT_DEATH(APFloat::getNaN(APFloat::Float6E3M2FN()),9951 "This floating point format does not support NaN");9952}9953 9954TEST(APFloatTest, Float6E2M3FNGetInfNaN) {9955 EXPECT_DEATH(APFloat::getInf(APFloat::Float6E2M3FN()),9956 "This floating point format does not support Inf");9957 EXPECT_DEATH(APFloat::getNaN(APFloat::Float6E2M3FN()),9958 "This floating point format does not support NaN");9959}9960 9961TEST(APFloatTest, Float4E2M1FNGetInfNaN) {9962 EXPECT_DEATH(APFloat::getInf(APFloat::Float4E2M1FN()),9963 "This floating point format does not support Inf");9964 EXPECT_DEATH(APFloat::getNaN(APFloat::Float4E2M1FN()),9965 "This floating point format does not support NaN");9966}9967#endif9968#endif9969 9970TEST(APFloatTest, Float6E3M2FNToDouble) {9971 APFloat One(APFloat::Float6E3M2FN(), "1.0");9972 EXPECT_EQ(1.0, One.convertToDouble());9973 APFloat Two(APFloat::Float6E3M2FN(), "2.0");9974 EXPECT_EQ(2.0, Two.convertToDouble());9975 APFloat PosLargest = APFloat::getLargest(APFloat::Float6E3M2FN(), false);9976 EXPECT_EQ(28., PosLargest.convertToDouble());9977 APFloat NegLargest = APFloat::getLargest(APFloat::Float6E3M2FN(), true);9978 EXPECT_EQ(-28., NegLargest.convertToDouble());9979 APFloat PosSmallest =9980 APFloat::getSmallestNormalized(APFloat::Float6E3M2FN(), false);9981 EXPECT_EQ(0x1p-2, PosSmallest.convertToDouble());9982 APFloat NegSmallest =9983 APFloat::getSmallestNormalized(APFloat::Float6E3M2FN(), true);9984 EXPECT_EQ(-0x1p-2, NegSmallest.convertToDouble());9985 9986 APFloat SmallestDenorm = APFloat::getSmallest(APFloat::Float6E3M2FN(), false);9987 EXPECT_TRUE(SmallestDenorm.isDenormal());9988 EXPECT_EQ(0x0.1p0, SmallestDenorm.convertToDouble());9989}9990 9991TEST(APFloatTest, Float6E2M3FNToDouble) {9992 APFloat One(APFloat::Float6E2M3FN(), "1.0");9993 EXPECT_EQ(1.0, One.convertToDouble());9994 APFloat Two(APFloat::Float6E2M3FN(), "2.0");9995 EXPECT_EQ(2.0, Two.convertToDouble());9996 APFloat PosLargest = APFloat::getLargest(APFloat::Float6E2M3FN(), false);9997 EXPECT_EQ(7.5, PosLargest.convertToDouble());9998 APFloat NegLargest = APFloat::getLargest(APFloat::Float6E2M3FN(), true);9999 EXPECT_EQ(-7.5, NegLargest.convertToDouble());10000 APFloat PosSmallest =10001 APFloat::getSmallestNormalized(APFloat::Float6E2M3FN(), false);10002 EXPECT_EQ(0x1p0, PosSmallest.convertToDouble());10003 APFloat NegSmallest =10004 APFloat::getSmallestNormalized(APFloat::Float6E2M3FN(), true);10005 EXPECT_EQ(-0x1p0, NegSmallest.convertToDouble());10006 10007 APFloat SmallestDenorm = APFloat::getSmallest(APFloat::Float6E2M3FN(), false);10008 EXPECT_TRUE(SmallestDenorm.isDenormal());10009 EXPECT_EQ(0x0.2p0, SmallestDenorm.convertToDouble());10010}10011 10012TEST(APFloatTest, Float4E2M1FNToDouble) {10013 APFloat One(APFloat::Float4E2M1FN(), "1.0");10014 EXPECT_EQ(1.0, One.convertToDouble());10015 APFloat Two(APFloat::Float4E2M1FN(), "2.0");10016 EXPECT_EQ(2.0, Two.convertToDouble());10017 APFloat PosLargest = APFloat::getLargest(APFloat::Float4E2M1FN(), false);10018 EXPECT_EQ(6, PosLargest.convertToDouble());10019 APFloat NegLargest = APFloat::getLargest(APFloat::Float4E2M1FN(), true);10020 EXPECT_EQ(-6, NegLargest.convertToDouble());10021 APFloat PosSmallest =10022 APFloat::getSmallestNormalized(APFloat::Float4E2M1FN(), false);10023 EXPECT_EQ(0x1p0, PosSmallest.convertToDouble());10024 APFloat NegSmallest =10025 APFloat::getSmallestNormalized(APFloat::Float4E2M1FN(), true);10026 EXPECT_EQ(-0x1p0, NegSmallest.convertToDouble());10027 10028 APFloat SmallestDenorm = APFloat::getSmallest(APFloat::Float4E2M1FN(), false);10029 EXPECT_TRUE(SmallestDenorm.isDenormal());10030 EXPECT_EQ(0x0.8p0, SmallestDenorm.convertToDouble());10031}10032 10033TEST(APFloatTest, Float6E3M2FNToFloat) {10034 APFloat PosZero = APFloat::getZero(APFloat::Float6E3M2FN());10035 APFloat PosZeroToFloat(PosZero.convertToFloat());10036 EXPECT_TRUE(PosZeroToFloat.isPosZero());10037 APFloat NegZero = APFloat::getZero(APFloat::Float6E3M2FN(), true);10038 APFloat NegZeroToFloat(NegZero.convertToFloat());10039 EXPECT_TRUE(NegZeroToFloat.isNegZero());10040 10041 APFloat One(APFloat::Float6E3M2FN(), "1.0");10042 EXPECT_EQ(1.0F, One.convertToFloat());10043 APFloat Two(APFloat::Float6E3M2FN(), "2.0");10044 EXPECT_EQ(2.0F, Two.convertToFloat());10045 10046 APFloat PosLargest = APFloat::getLargest(APFloat::Float6E3M2FN(), false);10047 EXPECT_EQ(28., PosLargest.convertToFloat());10048 APFloat NegLargest = APFloat::getLargest(APFloat::Float6E3M2FN(), true);10049 EXPECT_EQ(-28, NegLargest.convertToFloat());10050 APFloat PosSmallest =10051 APFloat::getSmallestNormalized(APFloat::Float6E3M2FN(), false);10052 EXPECT_EQ(0x1p-2, PosSmallest.convertToFloat());10053 APFloat NegSmallest =10054 APFloat::getSmallestNormalized(APFloat::Float6E3M2FN(), true);10055 EXPECT_EQ(-0x1p-2, NegSmallest.convertToFloat());10056 10057 APFloat SmallestDenorm = APFloat::getSmallest(APFloat::Float6E3M2FN(), false);10058 EXPECT_TRUE(SmallestDenorm.isDenormal());10059 EXPECT_EQ(0x0.1p0, SmallestDenorm.convertToFloat());10060}10061 10062TEST(APFloatTest, Float6E2M3FNToFloat) {10063 APFloat PosZero = APFloat::getZero(APFloat::Float6E2M3FN());10064 APFloat PosZeroToFloat(PosZero.convertToFloat());10065 EXPECT_TRUE(PosZeroToFloat.isPosZero());10066 APFloat NegZero = APFloat::getZero(APFloat::Float6E2M3FN(), true);10067 APFloat NegZeroToFloat(NegZero.convertToFloat());10068 EXPECT_TRUE(NegZeroToFloat.isNegZero());10069 10070 APFloat One(APFloat::Float6E2M3FN(), "1.0");10071 EXPECT_EQ(1.0F, One.convertToFloat());10072 APFloat Two(APFloat::Float6E2M3FN(), "2.0");10073 EXPECT_EQ(2.0F, Two.convertToFloat());10074 10075 APFloat PosLargest = APFloat::getLargest(APFloat::Float6E2M3FN(), false);10076 EXPECT_EQ(7.5, PosLargest.convertToFloat());10077 APFloat NegLargest = APFloat::getLargest(APFloat::Float6E2M3FN(), true);10078 EXPECT_EQ(-7.5, NegLargest.convertToFloat());10079 APFloat PosSmallest =10080 APFloat::getSmallestNormalized(APFloat::Float6E2M3FN(), false);10081 EXPECT_EQ(0x1p0, PosSmallest.convertToFloat());10082 APFloat NegSmallest =10083 APFloat::getSmallestNormalized(APFloat::Float6E2M3FN(), true);10084 EXPECT_EQ(-0x1p0, NegSmallest.convertToFloat());10085 10086 APFloat SmallestDenorm = APFloat::getSmallest(APFloat::Float6E2M3FN(), false);10087 EXPECT_TRUE(SmallestDenorm.isDenormal());10088 EXPECT_EQ(0x0.2p0, SmallestDenorm.convertToFloat());10089}10090 10091TEST(APFloatTest, Float4E2M1FNToFloat) {10092 APFloat PosZero = APFloat::getZero(APFloat::Float4E2M1FN());10093 APFloat PosZeroToFloat(PosZero.convertToFloat());10094 EXPECT_TRUE(PosZeroToFloat.isPosZero());10095 APFloat NegZero = APFloat::getZero(APFloat::Float4E2M1FN(), true);10096 APFloat NegZeroToFloat(NegZero.convertToFloat());10097 EXPECT_TRUE(NegZeroToFloat.isNegZero());10098 10099 APFloat One(APFloat::Float4E2M1FN(), "1.0");10100 EXPECT_EQ(1.0F, One.convertToFloat());10101 APFloat Two(APFloat::Float4E2M1FN(), "2.0");10102 EXPECT_EQ(2.0F, Two.convertToFloat());10103 10104 APFloat PosLargest = APFloat::getLargest(APFloat::Float4E2M1FN(), false);10105 EXPECT_EQ(6, PosLargest.convertToFloat());10106 APFloat NegLargest = APFloat::getLargest(APFloat::Float4E2M1FN(), true);10107 EXPECT_EQ(-6, NegLargest.convertToFloat());10108 APFloat PosSmallest =10109 APFloat::getSmallestNormalized(APFloat::Float4E2M1FN(), false);10110 EXPECT_EQ(0x1p0, PosSmallest.convertToFloat());10111 APFloat NegSmallest =10112 APFloat::getSmallestNormalized(APFloat::Float4E2M1FN(), true);10113 EXPECT_EQ(-0x1p0, NegSmallest.convertToFloat());10114 10115 APFloat SmallestDenorm = APFloat::getSmallest(APFloat::Float4E2M1FN(), false);10116 EXPECT_TRUE(SmallestDenorm.isDenormal());10117 EXPECT_EQ(0x0.8p0, SmallestDenorm.convertToFloat());10118}10119 10120TEST(APFloatTest, AddOrSubtractSignificand) {10121 using Helper = detail::IEEEFloatUnitTestHelper;10122 // Test cases are all combinations of:10123 // {equal exponents, LHS larger exponent, RHS larger exponent}10124 // {equal significands, LHS larger significand, RHS larger significand}10125 // {no loss, loss}10126 10127 // Equal exponents (loss cannot occur as their is no shifting)10128 Helper::runTest(true, false, 1, 0x10, false, 1, 0x5, false, 1, 0xb,10129 lfExactlyZero);10130 Helper::runTest(false, false, -2, 0x20, true, -2, 0x20, false, -2, 0,10131 lfExactlyZero);10132 Helper::runTest(false, true, 3, 0x20, false, 3, 0x30, false, 3, 0x10,10133 lfExactlyZero);10134 10135 // LHS larger exponent10136 // LHS significand greater after shitfing10137 Helper::runTest(true, false, 7, 0x100, false, 3, 0x100, false, 6, 0x1e0,10138 lfExactlyZero);10139 Helper::runTest(true, false, 7, 0x100, false, 3, 0x101, false, 6, 0x1df,10140 lfMoreThanHalf);10141 // Significands equal after shitfing10142 Helper::runTest(true, false, 7, 0x100, false, 3, 0x1000, false, 6, 0,10143 lfExactlyZero);10144 Helper::runTest(true, false, 7, 0x100, false, 3, 0x1001, true, 6, 0,10145 lfLessThanHalf);10146 // RHS significand greater after shitfing10147 Helper::runTest(true, false, 7, 0x100, false, 3, 0x10000, true, 6, 0x1e00,10148 lfExactlyZero);10149 Helper::runTest(true, false, 7, 0x100, false, 3, 0x10001, true, 6, 0x1e00,10150 lfLessThanHalf);10151 10152 // RHS larger exponent10153 // RHS significand greater after shitfing10154 Helper::runTest(true, false, 3, 0x100, false, 7, 0x100, true, 6, 0x1e0,10155 lfExactlyZero);10156 Helper::runTest(true, false, 3, 0x101, false, 7, 0x100, true, 6, 0x1df,10157 lfMoreThanHalf);10158 // Significands equal after shitfing10159 Helper::runTest(true, false, 3, 0x1000, false, 7, 0x100, false, 6, 0,10160 lfExactlyZero);10161 Helper::runTest(true, false, 3, 0x1001, false, 7, 0x100, false, 6, 0,10162 lfLessThanHalf);10163 // LHS significand greater after shitfing10164 Helper::runTest(true, false, 3, 0x10000, false, 7, 0x100, false, 6, 0x1e00,10165 lfExactlyZero);10166 Helper::runTest(true, false, 3, 0x10001, false, 7, 0x100, false, 6, 0x1e00,10167 lfLessThanHalf);10168}10169 10170TEST(APFloatTest, hasSignBitInMSB) {10171 EXPECT_TRUE(APFloat::hasSignBitInMSB(APFloat::IEEEsingle()));10172 EXPECT_TRUE(APFloat::hasSignBitInMSB(APFloat::x87DoubleExtended()));10173 EXPECT_TRUE(APFloat::hasSignBitInMSB(APFloat::PPCDoubleDouble()));10174 EXPECT_TRUE(APFloat::hasSignBitInMSB(APFloat::IEEEquad()));10175 EXPECT_FALSE(APFloat::hasSignBitInMSB(APFloat::Float8E8M0FNU()));10176}10177 10178TEST(APFloatTest, FrexpQuietSNaN) {10179 APFloat SNaN = APFloat::getSNaN(APFloat::PPCDoubleDouble());10180 int Exp;10181 APFloat Result = frexp(SNaN, Exp, APFloat::rmNearestTiesToEven);10182 EXPECT_FALSE(Result.isSignaling());10183}10184 10185} // namespace10186