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