12e5b6d6dSopenharmony_ci// Copyright 2006-2008 the V8 project authors. All rights reserved.
22e5b6d6dSopenharmony_ci// Redistribution and use in source and binary forms, with or without
32e5b6d6dSopenharmony_ci// modification, are permitted provided that the following conditions are
42e5b6d6dSopenharmony_ci// met:
52e5b6d6dSopenharmony_ci//
62e5b6d6dSopenharmony_ci//     * Redistributions of source code must retain the above copyright
72e5b6d6dSopenharmony_ci//       notice, this list of conditions and the following disclaimer.
82e5b6d6dSopenharmony_ci//     * Redistributions in binary form must reproduce the above
92e5b6d6dSopenharmony_ci//       copyright notice, this list of conditions and the following
102e5b6d6dSopenharmony_ci//       disclaimer in the documentation and/or other materials provided
112e5b6d6dSopenharmony_ci//       with the distribution.
122e5b6d6dSopenharmony_ci//     * Neither the name of Google Inc. nor the names of its
132e5b6d6dSopenharmony_ci//       contributors may be used to endorse or promote products derived
142e5b6d6dSopenharmony_ci//       from this software without specific prior written permission.
152e5b6d6dSopenharmony_ci//
162e5b6d6dSopenharmony_ci// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172e5b6d6dSopenharmony_ci// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182e5b6d6dSopenharmony_ci// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192e5b6d6dSopenharmony_ci// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202e5b6d6dSopenharmony_ci// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212e5b6d6dSopenharmony_ci// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222e5b6d6dSopenharmony_ci// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232e5b6d6dSopenharmony_ci// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242e5b6d6dSopenharmony_ci// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252e5b6d6dSopenharmony_ci// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262e5b6d6dSopenharmony_ci// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272e5b6d6dSopenharmony_ci
282e5b6d6dSopenharmony_ci#include <stdlib.h>
292e5b6d6dSopenharmony_ci#include <limits>
302e5b6d6dSopenharmony_ci
312e5b6d6dSopenharmony_ci#include "cctest.h"
322e5b6d6dSopenharmony_ci#include "double-conversion/diy-fp.h"
332e5b6d6dSopenharmony_ci#include "double-conversion/utils.h"
342e5b6d6dSopenharmony_ci#include "double-conversion/ieee.h"
352e5b6d6dSopenharmony_ci
362e5b6d6dSopenharmony_ci
372e5b6d6dSopenharmony_ciusing namespace double_conversion;
382e5b6d6dSopenharmony_ci
392e5b6d6dSopenharmony_ci
402e5b6d6dSopenharmony_ciTEST(Uint64Conversions) {
412e5b6d6dSopenharmony_ci  // Start by checking the byte-order.
422e5b6d6dSopenharmony_ci  uint64_t ordered = DOUBLE_CONVERSION_UINT64_2PART_C(0x01234567, 89ABCDEF);
432e5b6d6dSopenharmony_ci  CHECK_EQ(3512700564088504e-318, Double(ordered).value());
442e5b6d6dSopenharmony_ci
452e5b6d6dSopenharmony_ci  uint64_t min_double64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x00000000, 00000001);
462e5b6d6dSopenharmony_ci  CHECK_EQ(5e-324, Double(min_double64).value());
472e5b6d6dSopenharmony_ci
482e5b6d6dSopenharmony_ci  uint64_t max_double64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x7fefffff, ffffffff);
492e5b6d6dSopenharmony_ci  CHECK_EQ(1.7976931348623157e308, Double(max_double64).value());
502e5b6d6dSopenharmony_ci}
512e5b6d6dSopenharmony_ci
522e5b6d6dSopenharmony_ci
532e5b6d6dSopenharmony_ciTEST(Uint32Conversions) {
542e5b6d6dSopenharmony_ci  // Start by checking the byte-order.
552e5b6d6dSopenharmony_ci  uint32_t ordered = 0x01234567;
562e5b6d6dSopenharmony_ci  CHECK_EQ(2.9988165487136453e-38f, Single(ordered).value());
572e5b6d6dSopenharmony_ci
582e5b6d6dSopenharmony_ci  uint32_t min_float32 = 0x00000001;
592e5b6d6dSopenharmony_ci  CHECK_EQ(1.4e-45f, Single(min_float32).value());
602e5b6d6dSopenharmony_ci
612e5b6d6dSopenharmony_ci  uint32_t max_float32 = 0x7f7fffff;
622e5b6d6dSopenharmony_ci  CHECK_EQ(3.4028234e38f, Single(max_float32).value());
632e5b6d6dSopenharmony_ci}
642e5b6d6dSopenharmony_ci
652e5b6d6dSopenharmony_ci
662e5b6d6dSopenharmony_ciTEST(Double_AsDiyFp) {
672e5b6d6dSopenharmony_ci  uint64_t ordered = DOUBLE_CONVERSION_UINT64_2PART_C(0x01234567, 89ABCDEF);
682e5b6d6dSopenharmony_ci  DiyFp diy_fp = Double(ordered).AsDiyFp();
692e5b6d6dSopenharmony_ci  CHECK_EQ(0x12 - 0x3FF - 52, diy_fp.e());
702e5b6d6dSopenharmony_ci  // The 52 mantissa bits, plus the implicit 1 in bit 52 as a UINT64.
712e5b6d6dSopenharmony_ci  CHECK(DOUBLE_CONVERSION_UINT64_2PART_C(0x00134567, 89ABCDEF) == diy_fp.f());  // NOLINT
722e5b6d6dSopenharmony_ci
732e5b6d6dSopenharmony_ci  uint64_t min_double64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x00000000, 00000001);
742e5b6d6dSopenharmony_ci  diy_fp = Double(min_double64).AsDiyFp();
752e5b6d6dSopenharmony_ci  CHECK_EQ(-0x3FF - 52 + 1, diy_fp.e());
762e5b6d6dSopenharmony_ci  // This is a denormal; so no hidden bit.
772e5b6d6dSopenharmony_ci  CHECK(1 == diy_fp.f());  // NOLINT
782e5b6d6dSopenharmony_ci
792e5b6d6dSopenharmony_ci  uint64_t max_double64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x7fefffff, ffffffff);
802e5b6d6dSopenharmony_ci  diy_fp = Double(max_double64).AsDiyFp();
812e5b6d6dSopenharmony_ci  CHECK_EQ(0x7FE - 0x3FF - 52, diy_fp.e());
822e5b6d6dSopenharmony_ci  CHECK(DOUBLE_CONVERSION_UINT64_2PART_C(0x001fffff, ffffffff) == diy_fp.f());  // NOLINT
832e5b6d6dSopenharmony_ci}
842e5b6d6dSopenharmony_ci
852e5b6d6dSopenharmony_ci
862e5b6d6dSopenharmony_ciTEST(Single_AsDiyFp) {
872e5b6d6dSopenharmony_ci  uint32_t ordered = 0x01234567;
882e5b6d6dSopenharmony_ci  DiyFp diy_fp = Single(ordered).AsDiyFp();
892e5b6d6dSopenharmony_ci  CHECK_EQ(0x2 - 0x7F - 23, diy_fp.e());
902e5b6d6dSopenharmony_ci  // The 23 mantissa bits, plus the implicit 1 in bit 24 as a uint32_t.
912e5b6d6dSopenharmony_ci  CHECK_EQ(0xA34567u, diy_fp.f());
922e5b6d6dSopenharmony_ci
932e5b6d6dSopenharmony_ci  uint32_t min_float32 = 0x00000001;
942e5b6d6dSopenharmony_ci  diy_fp = Single(min_float32).AsDiyFp();
952e5b6d6dSopenharmony_ci  CHECK_EQ(-0x7F - 23 + 1, diy_fp.e());
962e5b6d6dSopenharmony_ci  // This is a denormal; so no hidden bit.
972e5b6d6dSopenharmony_ci  CHECK_EQ(1u, diy_fp.f());
982e5b6d6dSopenharmony_ci
992e5b6d6dSopenharmony_ci  uint32_t max_float32 = 0x7f7fffff;
1002e5b6d6dSopenharmony_ci  diy_fp = Single(max_float32).AsDiyFp();
1012e5b6d6dSopenharmony_ci  CHECK_EQ(0xFE - 0x7F - 23, diy_fp.e());
1022e5b6d6dSopenharmony_ci  CHECK_EQ(0x00ffffffu, diy_fp.f());
1032e5b6d6dSopenharmony_ci}
1042e5b6d6dSopenharmony_ci
1052e5b6d6dSopenharmony_ci
1062e5b6d6dSopenharmony_ciTEST(AsNormalizedDiyFp) {
1072e5b6d6dSopenharmony_ci  uint64_t ordered = DOUBLE_CONVERSION_UINT64_2PART_C(0x01234567, 89ABCDEF);
1082e5b6d6dSopenharmony_ci  DiyFp diy_fp = Double(ordered).AsNormalizedDiyFp();
1092e5b6d6dSopenharmony_ci  CHECK_EQ(0x12 - 0x3FF - 52 - 11, diy_fp.e());
1102e5b6d6dSopenharmony_ci  CHECK((DOUBLE_CONVERSION_UINT64_2PART_C(0x00134567, 89ABCDEF) << 11) ==
1112e5b6d6dSopenharmony_ci        diy_fp.f());  // NOLINT
1122e5b6d6dSopenharmony_ci
1132e5b6d6dSopenharmony_ci  uint64_t min_double64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x00000000, 00000001);
1142e5b6d6dSopenharmony_ci  diy_fp = Double(min_double64).AsNormalizedDiyFp();
1152e5b6d6dSopenharmony_ci  CHECK_EQ(-0x3FF - 52 + 1 - 63, diy_fp.e());
1162e5b6d6dSopenharmony_ci  // This is a denormal; so no hidden bit.
1172e5b6d6dSopenharmony_ci  CHECK(DOUBLE_CONVERSION_UINT64_2PART_C(0x80000000, 00000000) == diy_fp.f());  // NOLINT
1182e5b6d6dSopenharmony_ci
1192e5b6d6dSopenharmony_ci  uint64_t max_double64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x7fefffff, ffffffff);
1202e5b6d6dSopenharmony_ci  diy_fp = Double(max_double64).AsNormalizedDiyFp();
1212e5b6d6dSopenharmony_ci  CHECK_EQ(0x7FE - 0x3FF - 52 - 11, diy_fp.e());
1222e5b6d6dSopenharmony_ci  CHECK((DOUBLE_CONVERSION_UINT64_2PART_C(0x001fffff, ffffffff) << 11) ==
1232e5b6d6dSopenharmony_ci        diy_fp.f());  // NOLINT
1242e5b6d6dSopenharmony_ci}
1252e5b6d6dSopenharmony_ci
1262e5b6d6dSopenharmony_ci
1272e5b6d6dSopenharmony_ciTEST(Double_IsDenormal) {
1282e5b6d6dSopenharmony_ci  uint64_t min_double64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x00000000, 00000001);
1292e5b6d6dSopenharmony_ci  CHECK(Double(min_double64).IsDenormal());
1302e5b6d6dSopenharmony_ci  uint64_t bits = DOUBLE_CONVERSION_UINT64_2PART_C(0x000FFFFF, FFFFFFFF);
1312e5b6d6dSopenharmony_ci  CHECK(Double(bits).IsDenormal());
1322e5b6d6dSopenharmony_ci  bits = DOUBLE_CONVERSION_UINT64_2PART_C(0x00100000, 00000000);
1332e5b6d6dSopenharmony_ci  CHECK(!Double(bits).IsDenormal());
1342e5b6d6dSopenharmony_ci}
1352e5b6d6dSopenharmony_ci
1362e5b6d6dSopenharmony_ci
1372e5b6d6dSopenharmony_ciTEST(Single_IsDenormal) {
1382e5b6d6dSopenharmony_ci  uint32_t min_float32 = 0x00000001;
1392e5b6d6dSopenharmony_ci  CHECK(Single(min_float32).IsDenormal());
1402e5b6d6dSopenharmony_ci  uint32_t bits = 0x007FFFFF;
1412e5b6d6dSopenharmony_ci  CHECK(Single(bits).IsDenormal());
1422e5b6d6dSopenharmony_ci  bits = 0x00800000;
1432e5b6d6dSopenharmony_ci  CHECK(!Single(bits).IsDenormal());
1442e5b6d6dSopenharmony_ci}
1452e5b6d6dSopenharmony_ci
1462e5b6d6dSopenharmony_ci
1472e5b6d6dSopenharmony_ciTEST(Double_IsSpecial) {
1482e5b6d6dSopenharmony_ci  CHECK(Double(Double::Infinity()).IsSpecial());
1492e5b6d6dSopenharmony_ci  CHECK(Double(-Double::Infinity()).IsSpecial());
1502e5b6d6dSopenharmony_ci  CHECK(Double(Double::NaN()).IsSpecial());
1512e5b6d6dSopenharmony_ci  uint64_t bits = DOUBLE_CONVERSION_UINT64_2PART_C(0xFFF12345, 00000000);
1522e5b6d6dSopenharmony_ci  CHECK(Double(bits).IsSpecial());
1532e5b6d6dSopenharmony_ci  // Denormals are not special:
1542e5b6d6dSopenharmony_ci  CHECK(!Double(5e-324).IsSpecial());
1552e5b6d6dSopenharmony_ci  CHECK(!Double(-5e-324).IsSpecial());
1562e5b6d6dSopenharmony_ci  // And some random numbers:
1572e5b6d6dSopenharmony_ci  CHECK(!Double(0.0).IsSpecial());
1582e5b6d6dSopenharmony_ci  CHECK(!Double(-0.0).IsSpecial());
1592e5b6d6dSopenharmony_ci  CHECK(!Double(1.0).IsSpecial());
1602e5b6d6dSopenharmony_ci  CHECK(!Double(-1.0).IsSpecial());
1612e5b6d6dSopenharmony_ci  CHECK(!Double(1000000.0).IsSpecial());
1622e5b6d6dSopenharmony_ci  CHECK(!Double(-1000000.0).IsSpecial());
1632e5b6d6dSopenharmony_ci  CHECK(!Double(1e23).IsSpecial());
1642e5b6d6dSopenharmony_ci  CHECK(!Double(-1e23).IsSpecial());
1652e5b6d6dSopenharmony_ci  CHECK(!Double(1.7976931348623157e308).IsSpecial());
1662e5b6d6dSopenharmony_ci  CHECK(!Double(-1.7976931348623157e308).IsSpecial());
1672e5b6d6dSopenharmony_ci}
1682e5b6d6dSopenharmony_ci
1692e5b6d6dSopenharmony_ci
1702e5b6d6dSopenharmony_ciTEST(Single_IsSpecial) {
1712e5b6d6dSopenharmony_ci  CHECK(Single(Single::Infinity()).IsSpecial());
1722e5b6d6dSopenharmony_ci  CHECK(Single(-Single::Infinity()).IsSpecial());
1732e5b6d6dSopenharmony_ci  CHECK(Single(Single::NaN()).IsSpecial());
1742e5b6d6dSopenharmony_ci  uint32_t bits = 0xFFF12345;
1752e5b6d6dSopenharmony_ci  CHECK(Single(bits).IsSpecial());
1762e5b6d6dSopenharmony_ci  // Denormals are not special:
1772e5b6d6dSopenharmony_ci  CHECK(!Single(1.4e-45f).IsSpecial());
1782e5b6d6dSopenharmony_ci  CHECK(!Single(-1.4e-45f).IsSpecial());
1792e5b6d6dSopenharmony_ci  // And some random numbers:
1802e5b6d6dSopenharmony_ci  CHECK(!Single(0.0f).IsSpecial());
1812e5b6d6dSopenharmony_ci  CHECK(!Single(-0.0f).IsSpecial());
1822e5b6d6dSopenharmony_ci  CHECK(!Single(1.0f).IsSpecial());
1832e5b6d6dSopenharmony_ci  CHECK(!Single(-1.0f).IsSpecial());
1842e5b6d6dSopenharmony_ci  CHECK(!Single(1000000.0f).IsSpecial());
1852e5b6d6dSopenharmony_ci  CHECK(!Single(-1000000.0f).IsSpecial());
1862e5b6d6dSopenharmony_ci  CHECK(!Single(1e23f).IsSpecial());
1872e5b6d6dSopenharmony_ci  CHECK(!Single(-1e23f).IsSpecial());
1882e5b6d6dSopenharmony_ci  CHECK(!Single(1.18e-38f).IsSpecial());
1892e5b6d6dSopenharmony_ci  CHECK(!Single(-1.18e-38f).IsSpecial());
1902e5b6d6dSopenharmony_ci}
1912e5b6d6dSopenharmony_ci
1922e5b6d6dSopenharmony_ci
1932e5b6d6dSopenharmony_ciTEST(Double_IsInfinite) {
1942e5b6d6dSopenharmony_ci  CHECK(Double(Double::Infinity()).IsInfinite());
1952e5b6d6dSopenharmony_ci  CHECK(Double(-Double::Infinity()).IsInfinite());
1962e5b6d6dSopenharmony_ci  CHECK(!Double(Double::NaN()).IsInfinite());
1972e5b6d6dSopenharmony_ci  CHECK(!Double(0.0).IsInfinite());
1982e5b6d6dSopenharmony_ci  CHECK(!Double(-0.0).IsInfinite());
1992e5b6d6dSopenharmony_ci  CHECK(!Double(1.0).IsInfinite());
2002e5b6d6dSopenharmony_ci  CHECK(!Double(-1.0).IsInfinite());
2012e5b6d6dSopenharmony_ci  uint64_t min_double64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x00000000, 00000001);
2022e5b6d6dSopenharmony_ci  CHECK(!Double(min_double64).IsInfinite());
2032e5b6d6dSopenharmony_ci}
2042e5b6d6dSopenharmony_ci
2052e5b6d6dSopenharmony_ci
2062e5b6d6dSopenharmony_ciTEST(Single_IsInfinite) {
2072e5b6d6dSopenharmony_ci  CHECK(Single(Single::Infinity()).IsInfinite());
2082e5b6d6dSopenharmony_ci  CHECK(Single(-Single::Infinity()).IsInfinite());
2092e5b6d6dSopenharmony_ci  CHECK(!Single(Single::NaN()).IsInfinite());
2102e5b6d6dSopenharmony_ci  CHECK(!Single(0.0f).IsInfinite());
2112e5b6d6dSopenharmony_ci  CHECK(!Single(-0.0f).IsInfinite());
2122e5b6d6dSopenharmony_ci  CHECK(!Single(1.0f).IsInfinite());
2132e5b6d6dSopenharmony_ci  CHECK(!Single(-1.0f).IsInfinite());
2142e5b6d6dSopenharmony_ci  uint32_t min_float32 = 0x00000001;
2152e5b6d6dSopenharmony_ci  CHECK(!Single(min_float32).IsInfinite());
2162e5b6d6dSopenharmony_ci}
2172e5b6d6dSopenharmony_ci
2182e5b6d6dSopenharmony_ci
2192e5b6d6dSopenharmony_ciTEST(Double_IsNan) {
2202e5b6d6dSopenharmony_ci  CHECK(Double(Double::NaN()).IsNan());
2212e5b6d6dSopenharmony_ci  uint64_t other_nan = DOUBLE_CONVERSION_UINT64_2PART_C(0xFFFFFFFF, 00000001);
2222e5b6d6dSopenharmony_ci  CHECK(Double(other_nan).IsNan());
2232e5b6d6dSopenharmony_ci  CHECK(!Double(Double::Infinity()).IsNan());
2242e5b6d6dSopenharmony_ci  CHECK(!Double(-Double::Infinity()).IsNan());
2252e5b6d6dSopenharmony_ci  CHECK(!Double(0.0).IsNan());
2262e5b6d6dSopenharmony_ci  CHECK(!Double(-0.0).IsNan());
2272e5b6d6dSopenharmony_ci  CHECK(!Double(1.0).IsNan());
2282e5b6d6dSopenharmony_ci  CHECK(!Double(-1.0).IsNan());
2292e5b6d6dSopenharmony_ci  uint64_t min_double64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x00000000, 00000001);
2302e5b6d6dSopenharmony_ci  CHECK(!Double(min_double64).IsNan());
2312e5b6d6dSopenharmony_ci}
2322e5b6d6dSopenharmony_ci
2332e5b6d6dSopenharmony_ci
2342e5b6d6dSopenharmony_ciTEST(Single_IsNan) {
2352e5b6d6dSopenharmony_ci  CHECK(Single(Single::NaN()).IsNan());
2362e5b6d6dSopenharmony_ci  uint32_t other_nan = 0xFFFFF001;
2372e5b6d6dSopenharmony_ci  CHECK(Single(other_nan).IsNan());
2382e5b6d6dSopenharmony_ci  CHECK(!Single(Single::Infinity()).IsNan());
2392e5b6d6dSopenharmony_ci  CHECK(!Single(-Single::Infinity()).IsNan());
2402e5b6d6dSopenharmony_ci  CHECK(!Single(0.0f).IsNan());
2412e5b6d6dSopenharmony_ci  CHECK(!Single(-0.0f).IsNan());
2422e5b6d6dSopenharmony_ci  CHECK(!Single(1.0f).IsNan());
2432e5b6d6dSopenharmony_ci  CHECK(!Single(-1.0f).IsNan());
2442e5b6d6dSopenharmony_ci  uint32_t min_float32 = 0x00000001;
2452e5b6d6dSopenharmony_ci  CHECK(!Single(min_float32).IsNan());
2462e5b6d6dSopenharmony_ci}
2472e5b6d6dSopenharmony_ci
2482e5b6d6dSopenharmony_ci
2492e5b6d6dSopenharmony_ciTEST(Double_Sign) {
2502e5b6d6dSopenharmony_ci  CHECK_EQ(1, Double(1.0).Sign());
2512e5b6d6dSopenharmony_ci  CHECK_EQ(1, Double(Double::Infinity()).Sign());
2522e5b6d6dSopenharmony_ci  CHECK_EQ(-1, Double(-Double::Infinity()).Sign());
2532e5b6d6dSopenharmony_ci  CHECK_EQ(1, Double(0.0).Sign());
2542e5b6d6dSopenharmony_ci  CHECK_EQ(-1, Double(-0.0).Sign());
2552e5b6d6dSopenharmony_ci  uint64_t min_double64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x00000000, 00000001);
2562e5b6d6dSopenharmony_ci  CHECK_EQ(1, Double(min_double64).Sign());
2572e5b6d6dSopenharmony_ci}
2582e5b6d6dSopenharmony_ci
2592e5b6d6dSopenharmony_ci
2602e5b6d6dSopenharmony_ciTEST(Single_Sign) {
2612e5b6d6dSopenharmony_ci  CHECK_EQ(1, Single(1.0f).Sign());
2622e5b6d6dSopenharmony_ci  CHECK_EQ(1, Single(Single::Infinity()).Sign());
2632e5b6d6dSopenharmony_ci  CHECK_EQ(-1, Single(-Single::Infinity()).Sign());
2642e5b6d6dSopenharmony_ci  CHECK_EQ(1, Single(0.0f).Sign());
2652e5b6d6dSopenharmony_ci  CHECK_EQ(-1, Single(-0.0f).Sign());
2662e5b6d6dSopenharmony_ci  uint32_t min_float32 = 0x00000001;
2672e5b6d6dSopenharmony_ci  CHECK_EQ(1, Single(min_float32).Sign());
2682e5b6d6dSopenharmony_ci}
2692e5b6d6dSopenharmony_ci
2702e5b6d6dSopenharmony_ci
2712e5b6d6dSopenharmony_ciTEST(Double_NormalizedBoundaries) {
2722e5b6d6dSopenharmony_ci  DiyFp boundary_plus;
2732e5b6d6dSopenharmony_ci  DiyFp boundary_minus;
2742e5b6d6dSopenharmony_ci  DiyFp diy_fp = Double(1.5).AsNormalizedDiyFp();
2752e5b6d6dSopenharmony_ci  Double(1.5).NormalizedBoundaries(&boundary_minus, &boundary_plus);
2762e5b6d6dSopenharmony_ci  CHECK_EQ(diy_fp.e(), boundary_minus.e());
2772e5b6d6dSopenharmony_ci  CHECK_EQ(diy_fp.e(), boundary_plus.e());
2782e5b6d6dSopenharmony_ci  // 1.5 does not have a significand of the form 2^p (for some p).
2792e5b6d6dSopenharmony_ci  // Therefore its boundaries are at the same distance.
2802e5b6d6dSopenharmony_ci  CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
2812e5b6d6dSopenharmony_ci  CHECK((1 << 10) == diy_fp.f() - boundary_minus.f());  // NOLINT
2822e5b6d6dSopenharmony_ci
2832e5b6d6dSopenharmony_ci  diy_fp = Double(1.0).AsNormalizedDiyFp();
2842e5b6d6dSopenharmony_ci  Double(1.0).NormalizedBoundaries(&boundary_minus, &boundary_plus);
2852e5b6d6dSopenharmony_ci  CHECK_EQ(diy_fp.e(), boundary_minus.e());
2862e5b6d6dSopenharmony_ci  CHECK_EQ(diy_fp.e(), boundary_plus.e());
2872e5b6d6dSopenharmony_ci  // 1.0 does have a significand of the form 2^p (for some p).
2882e5b6d6dSopenharmony_ci  // Therefore its lower boundary is twice as close as the upper boundary.
2892e5b6d6dSopenharmony_ci  CHECK(boundary_plus.f() - diy_fp.f() > diy_fp.f() - boundary_minus.f());
2902e5b6d6dSopenharmony_ci  CHECK((1 << 9) == diy_fp.f() - boundary_minus.f());  // NOLINT
2912e5b6d6dSopenharmony_ci  CHECK((1 << 10) == boundary_plus.f() - diy_fp.f());  // NOLINT
2922e5b6d6dSopenharmony_ci
2932e5b6d6dSopenharmony_ci  uint64_t min_double64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x00000000, 00000001);
2942e5b6d6dSopenharmony_ci  diy_fp = Double(min_double64).AsNormalizedDiyFp();
2952e5b6d6dSopenharmony_ci  Double(min_double64).NormalizedBoundaries(&boundary_minus, &boundary_plus);
2962e5b6d6dSopenharmony_ci  CHECK_EQ(diy_fp.e(), boundary_minus.e());
2972e5b6d6dSopenharmony_ci  CHECK_EQ(diy_fp.e(), boundary_plus.e());
2982e5b6d6dSopenharmony_ci  // min-value does not have a significand of the form 2^p (for some p).
2992e5b6d6dSopenharmony_ci  // Therefore its boundaries are at the same distance.
3002e5b6d6dSopenharmony_ci  CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
3012e5b6d6dSopenharmony_ci  // Denormals have their boundaries much closer.
3022e5b6d6dSopenharmony_ci  CHECK((static_cast<uint64_t>(1) << 62) ==
3032e5b6d6dSopenharmony_ci        diy_fp.f() - boundary_minus.f());  // NOLINT
3042e5b6d6dSopenharmony_ci
3052e5b6d6dSopenharmony_ci  uint64_t smallest_normal64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x00100000, 00000000);
3062e5b6d6dSopenharmony_ci  diy_fp = Double(smallest_normal64).AsNormalizedDiyFp();
3072e5b6d6dSopenharmony_ci  Double(smallest_normal64).NormalizedBoundaries(&boundary_minus,
3082e5b6d6dSopenharmony_ci                                                 &boundary_plus);
3092e5b6d6dSopenharmony_ci  CHECK_EQ(diy_fp.e(), boundary_minus.e());
3102e5b6d6dSopenharmony_ci  CHECK_EQ(diy_fp.e(), boundary_plus.e());
3112e5b6d6dSopenharmony_ci  // Even though the significand is of the form 2^p (for some p), its boundaries
3122e5b6d6dSopenharmony_ci  // are at the same distance. (This is the only exception).
3132e5b6d6dSopenharmony_ci  CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
3142e5b6d6dSopenharmony_ci  CHECK((1 << 10) == diy_fp.f() - boundary_minus.f());  // NOLINT
3152e5b6d6dSopenharmony_ci
3162e5b6d6dSopenharmony_ci  uint64_t largest_denormal64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x000FFFFF, FFFFFFFF);
3172e5b6d6dSopenharmony_ci  diy_fp = Double(largest_denormal64).AsNormalizedDiyFp();
3182e5b6d6dSopenharmony_ci  Double(largest_denormal64).NormalizedBoundaries(&boundary_minus,
3192e5b6d6dSopenharmony_ci                                                  &boundary_plus);
3202e5b6d6dSopenharmony_ci  CHECK_EQ(diy_fp.e(), boundary_minus.e());
3212e5b6d6dSopenharmony_ci  CHECK_EQ(diy_fp.e(), boundary_plus.e());
3222e5b6d6dSopenharmony_ci  CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
3232e5b6d6dSopenharmony_ci  CHECK((1 << 11) == diy_fp.f() - boundary_minus.f());  // NOLINT
3242e5b6d6dSopenharmony_ci
3252e5b6d6dSopenharmony_ci  uint64_t max_double64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x7fefffff, ffffffff);
3262e5b6d6dSopenharmony_ci  diy_fp = Double(max_double64).AsNormalizedDiyFp();
3272e5b6d6dSopenharmony_ci  Double(max_double64).NormalizedBoundaries(&boundary_minus, &boundary_plus);
3282e5b6d6dSopenharmony_ci  CHECK_EQ(diy_fp.e(), boundary_minus.e());
3292e5b6d6dSopenharmony_ci  CHECK_EQ(diy_fp.e(), boundary_plus.e());
3302e5b6d6dSopenharmony_ci  // max-value does not have a significand of the form 2^p (for some p).
3312e5b6d6dSopenharmony_ci  // Therefore its boundaries are at the same distance.
3322e5b6d6dSopenharmony_ci  CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
3332e5b6d6dSopenharmony_ci  CHECK((1 << 10) == diy_fp.f() - boundary_minus.f());  // NOLINT
3342e5b6d6dSopenharmony_ci}
3352e5b6d6dSopenharmony_ci
3362e5b6d6dSopenharmony_ci
3372e5b6d6dSopenharmony_ciTEST(Single_NormalizedBoundaries) {
3382e5b6d6dSopenharmony_ci  uint64_t kOne64 = 1;
3392e5b6d6dSopenharmony_ci  DiyFp boundary_plus;
3402e5b6d6dSopenharmony_ci  DiyFp boundary_minus;
3412e5b6d6dSopenharmony_ci  DiyFp diy_fp = Single(1.5f).AsDiyFp();
3422e5b6d6dSopenharmony_ci  diy_fp.Normalize();
3432e5b6d6dSopenharmony_ci  Single(1.5f).NormalizedBoundaries(&boundary_minus, &boundary_plus);
3442e5b6d6dSopenharmony_ci  CHECK_EQ(diy_fp.e(), boundary_minus.e());
3452e5b6d6dSopenharmony_ci  CHECK_EQ(diy_fp.e(), boundary_plus.e());
3462e5b6d6dSopenharmony_ci  // 1.5 does not have a significand of the form 2^p (for some p).
3472e5b6d6dSopenharmony_ci  // Therefore its boundaries are at the same distance.
3482e5b6d6dSopenharmony_ci  CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
3492e5b6d6dSopenharmony_ci  // Normalization shifts the significand by 8 bits. Add 32 bits for the bigger
3502e5b6d6dSopenharmony_ci  // data-type, and remove 1 because boundaries are at half a ULP.
3512e5b6d6dSopenharmony_ci  CHECK((kOne64 << 39) == diy_fp.f() - boundary_minus.f());
3522e5b6d6dSopenharmony_ci
3532e5b6d6dSopenharmony_ci  diy_fp = Single(1.0f).AsDiyFp();
3542e5b6d6dSopenharmony_ci  diy_fp.Normalize();
3552e5b6d6dSopenharmony_ci  Single(1.0f).NormalizedBoundaries(&boundary_minus, &boundary_plus);
3562e5b6d6dSopenharmony_ci  CHECK_EQ(diy_fp.e(), boundary_minus.e());
3572e5b6d6dSopenharmony_ci  CHECK_EQ(diy_fp.e(), boundary_plus.e());
3582e5b6d6dSopenharmony_ci  // 1.0 does have a significand of the form 2^p (for some p).
3592e5b6d6dSopenharmony_ci  // Therefore its lower boundary is twice as close as the upper boundary.
3602e5b6d6dSopenharmony_ci  CHECK(boundary_plus.f() - diy_fp.f() > diy_fp.f() - boundary_minus.f());
3612e5b6d6dSopenharmony_ci  CHECK((kOne64 << 38) == diy_fp.f() - boundary_minus.f());  // NOLINT
3622e5b6d6dSopenharmony_ci  CHECK((kOne64 << 39) == boundary_plus.f() - diy_fp.f());  // NOLINT
3632e5b6d6dSopenharmony_ci
3642e5b6d6dSopenharmony_ci  uint32_t min_float32 = 0x00000001;
3652e5b6d6dSopenharmony_ci  diy_fp = Single(min_float32).AsDiyFp();
3662e5b6d6dSopenharmony_ci  diy_fp.Normalize();
3672e5b6d6dSopenharmony_ci  Single(min_float32).NormalizedBoundaries(&boundary_minus, &boundary_plus);
3682e5b6d6dSopenharmony_ci  CHECK_EQ(diy_fp.e(), boundary_minus.e());
3692e5b6d6dSopenharmony_ci  CHECK_EQ(diy_fp.e(), boundary_plus.e());
3702e5b6d6dSopenharmony_ci  // min-value does not have a significand of the form 2^p (for some p).
3712e5b6d6dSopenharmony_ci  // Therefore its boundaries are at the same distance.
3722e5b6d6dSopenharmony_ci  CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
3732e5b6d6dSopenharmony_ci  // Denormals have their boundaries much closer.
3742e5b6d6dSopenharmony_ci  CHECK((kOne64 << 62) == diy_fp.f() - boundary_minus.f());  // NOLINT
3752e5b6d6dSopenharmony_ci
3762e5b6d6dSopenharmony_ci  uint32_t smallest_normal32 = 0x00800000;
3772e5b6d6dSopenharmony_ci  diy_fp = Single(smallest_normal32).AsDiyFp();
3782e5b6d6dSopenharmony_ci  diy_fp.Normalize();
3792e5b6d6dSopenharmony_ci  Single(smallest_normal32).NormalizedBoundaries(&boundary_minus,
3802e5b6d6dSopenharmony_ci                                                 &boundary_plus);
3812e5b6d6dSopenharmony_ci  CHECK_EQ(diy_fp.e(), boundary_minus.e());
3822e5b6d6dSopenharmony_ci  CHECK_EQ(diy_fp.e(), boundary_plus.e());
3832e5b6d6dSopenharmony_ci  // Even though the significand is of the form 2^p (for some p), its boundaries
3842e5b6d6dSopenharmony_ci  // are at the same distance. (This is the only exception).
3852e5b6d6dSopenharmony_ci  CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
3862e5b6d6dSopenharmony_ci  CHECK((kOne64 << 39) == diy_fp.f() - boundary_minus.f());  // NOLINT
3872e5b6d6dSopenharmony_ci
3882e5b6d6dSopenharmony_ci  uint32_t largest_denormal32 = 0x007FFFFF;
3892e5b6d6dSopenharmony_ci  diy_fp = Single(largest_denormal32).AsDiyFp();
3902e5b6d6dSopenharmony_ci  diy_fp.Normalize();
3912e5b6d6dSopenharmony_ci  Single(largest_denormal32).NormalizedBoundaries(&boundary_minus,
3922e5b6d6dSopenharmony_ci                                                  &boundary_plus);
3932e5b6d6dSopenharmony_ci  CHECK_EQ(diy_fp.e(), boundary_minus.e());
3942e5b6d6dSopenharmony_ci  CHECK_EQ(diy_fp.e(), boundary_plus.e());
3952e5b6d6dSopenharmony_ci  CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
3962e5b6d6dSopenharmony_ci  CHECK((kOne64 << 40) == diy_fp.f() - boundary_minus.f());  // NOLINT
3972e5b6d6dSopenharmony_ci
3982e5b6d6dSopenharmony_ci  uint32_t max_float32 = 0x7f7fffff;
3992e5b6d6dSopenharmony_ci  diy_fp = Single(max_float32).AsDiyFp();
4002e5b6d6dSopenharmony_ci  diy_fp.Normalize();
4012e5b6d6dSopenharmony_ci  Single(max_float32).NormalizedBoundaries(&boundary_minus, &boundary_plus);
4022e5b6d6dSopenharmony_ci  CHECK_EQ(diy_fp.e(), boundary_minus.e());
4032e5b6d6dSopenharmony_ci  CHECK_EQ(diy_fp.e(), boundary_plus.e());
4042e5b6d6dSopenharmony_ci  // max-value does not have a significand of the form 2^p (for some p).
4052e5b6d6dSopenharmony_ci  // Therefore its boundaries are at the same distance.
4062e5b6d6dSopenharmony_ci  CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f());
4072e5b6d6dSopenharmony_ci  CHECK((kOne64 << 39) == diy_fp.f() - boundary_minus.f());  // NOLINT
4082e5b6d6dSopenharmony_ci}
4092e5b6d6dSopenharmony_ci
4102e5b6d6dSopenharmony_ci
4112e5b6d6dSopenharmony_ciTEST(NextDouble) {
4122e5b6d6dSopenharmony_ci  CHECK_EQ(4e-324, Double(0.0).NextDouble());
4132e5b6d6dSopenharmony_ci  CHECK_EQ(0.0, Double(-0.0).NextDouble());
4142e5b6d6dSopenharmony_ci  CHECK_EQ(-0.0, Double(-4e-324).NextDouble());
4152e5b6d6dSopenharmony_ci  CHECK(Double(Double(-0.0).NextDouble()).Sign() > 0);
4162e5b6d6dSopenharmony_ci  CHECK(Double(Double(-4e-324).NextDouble()).Sign() < 0);
4172e5b6d6dSopenharmony_ci  Double d0(-4e-324);
4182e5b6d6dSopenharmony_ci  Double d1(d0.NextDouble());
4192e5b6d6dSopenharmony_ci  Double d2(d1.NextDouble());
4202e5b6d6dSopenharmony_ci  CHECK_EQ(-0.0, d1.value());
4212e5b6d6dSopenharmony_ci  CHECK(d1.Sign() < 0);
4222e5b6d6dSopenharmony_ci  CHECK_EQ(0.0, d2.value());
4232e5b6d6dSopenharmony_ci  CHECK(d2.Sign() > 0);
4242e5b6d6dSopenharmony_ci  CHECK_EQ(4e-324, d2.NextDouble());
4252e5b6d6dSopenharmony_ci  CHECK_EQ(-1.7976931348623157e308, Double(-Double::Infinity()).NextDouble());
4262e5b6d6dSopenharmony_ci  CHECK_EQ(Double::Infinity(),
4272e5b6d6dSopenharmony_ci           Double(DOUBLE_CONVERSION_UINT64_2PART_C(0x7fefffff, ffffffff)).NextDouble());
4282e5b6d6dSopenharmony_ci}
4292e5b6d6dSopenharmony_ci
4302e5b6d6dSopenharmony_ci
4312e5b6d6dSopenharmony_ciTEST(PreviousDouble) {
4322e5b6d6dSopenharmony_ci  CHECK_EQ(0.0, Double(4e-324).PreviousDouble());
4332e5b6d6dSopenharmony_ci  CHECK_EQ(-0.0, Double(0.0).PreviousDouble());
4342e5b6d6dSopenharmony_ci  CHECK(Double(Double(0.0).PreviousDouble()).Sign() < 0);
4352e5b6d6dSopenharmony_ci  CHECK_EQ(-4e-324, Double(-0.0).PreviousDouble());
4362e5b6d6dSopenharmony_ci  Double d0(4e-324);
4372e5b6d6dSopenharmony_ci  Double d1(d0.PreviousDouble());
4382e5b6d6dSopenharmony_ci  Double d2(d1.PreviousDouble());
4392e5b6d6dSopenharmony_ci  CHECK_EQ(0.0, d1.value());
4402e5b6d6dSopenharmony_ci  CHECK(d1.Sign() > 0);
4412e5b6d6dSopenharmony_ci  CHECK_EQ(-0.0, d2.value());
4422e5b6d6dSopenharmony_ci  CHECK(d2.Sign() < 0);
4432e5b6d6dSopenharmony_ci  CHECK_EQ(-4e-324, d2.PreviousDouble());
4442e5b6d6dSopenharmony_ci  CHECK_EQ(1.7976931348623157e308, Double(Double::Infinity()).PreviousDouble());
4452e5b6d6dSopenharmony_ci  CHECK_EQ(-Double::Infinity(),
4462e5b6d6dSopenharmony_ci           Double(DOUBLE_CONVERSION_UINT64_2PART_C(0xffefffff, ffffffff)).PreviousDouble());
4472e5b6d6dSopenharmony_ci}
4482e5b6d6dSopenharmony_ci
4492e5b6d6dSopenharmony_ciTEST(SignalingNan) {
4502e5b6d6dSopenharmony_ci  Double nan(Double::NaN());
4512e5b6d6dSopenharmony_ci  CHECK(nan.IsNan());
4522e5b6d6dSopenharmony_ci  CHECK(nan.IsQuietNan());
4532e5b6d6dSopenharmony_ci  CHECK(Double(std::numeric_limits<double>::quiet_NaN()).IsQuietNan());
4542e5b6d6dSopenharmony_ci  CHECK(Double(std::numeric_limits<double>::signaling_NaN()).IsSignalingNan());
4552e5b6d6dSopenharmony_ci}
4562e5b6d6dSopenharmony_ci
4572e5b6d6dSopenharmony_ciTEST(SignalingNanSingle) {
4582e5b6d6dSopenharmony_ci  Single nan(Single::NaN());
4592e5b6d6dSopenharmony_ci  CHECK(nan.IsNan());
4602e5b6d6dSopenharmony_ci  CHECK(nan.IsQuietNan());
4612e5b6d6dSopenharmony_ci  CHECK(Single(std::numeric_limits<float>::quiet_NaN()).IsQuietNan());
4622e5b6d6dSopenharmony_ci#ifndef _MSC_VER
4632e5b6d6dSopenharmony_ci  // Visual studio has a bug for generating signaling NaNs:
4642e5b6d6dSopenharmony_ci  // https://developercommunity.visualstudio.com/t/stdnumeric-limitssignaling-nan-returns-quiet-nan/155064
4652e5b6d6dSopenharmony_ci  CHECK(Single(std::numeric_limits<float>::signaling_NaN()).IsSignalingNan());
4662e5b6d6dSopenharmony_ci#endif
4672e5b6d6dSopenharmony_ci}
468