brintos

brintos / llvm-project-archived public Read only

0
0
Text · 453.3 KiB · 99cc38b Raw
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