1// Copyright 2006-2008 the V8 project authors. All rights reserved. 2// Redistribution and use in source and binary forms, with or without 3// modification, are permitted provided that the following conditions are 4// met: 5// 6// * Redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer. 8// * Redistributions in binary form must reproduce the above 9// copyright notice, this list of conditions and the following 10// disclaimer in the documentation and/or other materials provided 11// with the distribution. 12// * Neither the name of Google Inc. nor the names of its 13// contributors may be used to endorse or promote products derived 14// from this software without specific prior written permission. 15// 16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28#include <stdlib.h> 29 30#include "src/v8.h" 31 32#include "src/base/platform/platform.h" 33#include "src/diy-fp.h" 34#include "src/double.h" 35#include "test/cctest/cctest.h" 36 37 38using namespace v8::internal; 39 40 41TEST(Uint64Conversions) { 42 // Start by checking the byte-order. 43 uint64_t ordered = V8_2PART_UINT64_C(0x01234567, 89ABCDEF); 44 CHECK_EQ(3512700564088504e-318, Double(ordered).value()); 45 46 uint64_t min_double64 = V8_2PART_UINT64_C(0x00000000, 00000001); 47 CHECK_EQ(5e-324, Double(min_double64).value()); 48 49 uint64_t max_double64 = V8_2PART_UINT64_C(0x7fefffff, ffffffff); 50 CHECK_EQ(1.7976931348623157e308, Double(max_double64).value()); 51} 52 53 54TEST(AsDiyFp) { 55 uint64_t ordered = V8_2PART_UINT64_C(0x01234567, 89ABCDEF); 56 DiyFp diy_fp = Double(ordered).AsDiyFp(); 57 CHECK_EQ(0x12 - 0x3FF - 52, diy_fp.e()); 58 // The 52 mantissa bits, plus the implicit 1 in bit 52 as a UINT64. 59 CHECK(V8_2PART_UINT64_C(0x00134567, 89ABCDEF) == diy_fp.f()); // NOLINT 60 61 uint64_t min_double64 = V8_2PART_UINT64_C(0x00000000, 00000001); 62 diy_fp = Double(min_double64).AsDiyFp(); 63 CHECK_EQ(-0x3FF - 52 + 1, diy_fp.e()); 64 // This is a denormal; so no hidden bit. 65 CHECK(1 == diy_fp.f()); // NOLINT 66 67 uint64_t max_double64 = V8_2PART_UINT64_C(0x7fefffff, ffffffff); 68 diy_fp = Double(max_double64).AsDiyFp(); 69 CHECK_EQ(0x7FE - 0x3FF - 52, diy_fp.e()); 70 CHECK(V8_2PART_UINT64_C(0x001fffff, ffffffff) == diy_fp.f()); // NOLINT 71} 72 73 74TEST(AsNormalizedDiyFp) { 75 uint64_t ordered = V8_2PART_UINT64_C(0x01234567, 89ABCDEF); 76 DiyFp diy_fp = Double(ordered).AsNormalizedDiyFp(); 77 CHECK_EQ(0x12 - 0x3FF - 52 - 11, diy_fp.e()); 78 CHECK((V8_2PART_UINT64_C(0x00134567, 89ABCDEF) << 11) == 79 diy_fp.f()); // NOLINT 80 81 uint64_t min_double64 = V8_2PART_UINT64_C(0x00000000, 00000001); 82 diy_fp = Double(min_double64).AsNormalizedDiyFp(); 83 CHECK_EQ(-0x3FF - 52 + 1 - 63, diy_fp.e()); 84 // This is a denormal; so no hidden bit. 85 CHECK(V8_2PART_UINT64_C(0x80000000, 00000000) == diy_fp.f()); // NOLINT 86 87 uint64_t max_double64 = V8_2PART_UINT64_C(0x7fefffff, ffffffff); 88 diy_fp = Double(max_double64).AsNormalizedDiyFp(); 89 CHECK_EQ(0x7FE - 0x3FF - 52 - 11, diy_fp.e()); 90 CHECK((V8_2PART_UINT64_C(0x001fffff, ffffffff) << 11) == 91 diy_fp.f()); // NOLINT 92} 93 94 95TEST(IsDenormal) { 96 uint64_t min_double64 = V8_2PART_UINT64_C(0x00000000, 00000001); 97 CHECK(Double(min_double64).IsDenormal()); 98 uint64_t bits = V8_2PART_UINT64_C(0x000FFFFF, FFFFFFFF); 99 CHECK(Double(bits).IsDenormal()); 100 bits = V8_2PART_UINT64_C(0x00100000, 00000000); 101 CHECK(!Double(bits).IsDenormal()); 102} 103 104 105TEST(IsSpecial) { 106 CHECK(Double(V8_INFINITY).IsSpecial()); 107 CHECK(Double(-V8_INFINITY).IsSpecial()); 108 CHECK(Double(v8::base::OS::nan_value()).IsSpecial()); 109 uint64_t bits = V8_2PART_UINT64_C(0xFFF12345, 00000000); 110 CHECK(Double(bits).IsSpecial()); 111 // Denormals are not special: 112 CHECK(!Double(5e-324).IsSpecial()); 113 CHECK(!Double(-5e-324).IsSpecial()); 114 // And some random numbers: 115 CHECK(!Double(0.0).IsSpecial()); 116 CHECK(!Double(-0.0).IsSpecial()); 117 CHECK(!Double(1.0).IsSpecial()); 118 CHECK(!Double(-1.0).IsSpecial()); 119 CHECK(!Double(1000000.0).IsSpecial()); 120 CHECK(!Double(-1000000.0).IsSpecial()); 121 CHECK(!Double(1e23).IsSpecial()); 122 CHECK(!Double(-1e23).IsSpecial()); 123 CHECK(!Double(1.7976931348623157e308).IsSpecial()); 124 CHECK(!Double(-1.7976931348623157e308).IsSpecial()); 125} 126 127 128TEST(IsInfinite) { 129 CHECK(Double(V8_INFINITY).IsInfinite()); 130 CHECK(Double(-V8_INFINITY).IsInfinite()); 131 CHECK(!Double(v8::base::OS::nan_value()).IsInfinite()); 132 CHECK(!Double(0.0).IsInfinite()); 133 CHECK(!Double(-0.0).IsInfinite()); 134 CHECK(!Double(1.0).IsInfinite()); 135 CHECK(!Double(-1.0).IsInfinite()); 136 uint64_t min_double64 = V8_2PART_UINT64_C(0x00000000, 00000001); 137 CHECK(!Double(min_double64).IsInfinite()); 138} 139 140 141TEST(Sign) { 142 CHECK_EQ(1, Double(1.0).Sign()); 143 CHECK_EQ(1, Double(V8_INFINITY).Sign()); 144 CHECK_EQ(-1, Double(-V8_INFINITY).Sign()); 145 CHECK_EQ(1, Double(0.0).Sign()); 146 CHECK_EQ(-1, Double(-0.0).Sign()); 147 uint64_t min_double64 = V8_2PART_UINT64_C(0x00000000, 00000001); 148 CHECK_EQ(1, Double(min_double64).Sign()); 149} 150 151 152TEST(NormalizedBoundaries) { 153 DiyFp boundary_plus; 154 DiyFp boundary_minus; 155 DiyFp diy_fp = Double(1.5).AsNormalizedDiyFp(); 156 Double(1.5).NormalizedBoundaries(&boundary_minus, &boundary_plus); 157 CHECK_EQ(diy_fp.e(), boundary_minus.e()); 158 CHECK_EQ(diy_fp.e(), boundary_plus.e()); 159 // 1.5 does not have a significand of the form 2^p (for some p). 160 // Therefore its boundaries are at the same distance. 161 CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f()); 162 CHECK((1 << 10) == diy_fp.f() - boundary_minus.f()); // NOLINT 163 164 diy_fp = Double(1.0).AsNormalizedDiyFp(); 165 Double(1.0).NormalizedBoundaries(&boundary_minus, &boundary_plus); 166 CHECK_EQ(diy_fp.e(), boundary_minus.e()); 167 CHECK_EQ(diy_fp.e(), boundary_plus.e()); 168 // 1.0 does have a significand of the form 2^p (for some p). 169 // Therefore its lower boundary is twice as close as the upper boundary. 170 CHECK_GT(boundary_plus.f() - diy_fp.f(), diy_fp.f() - boundary_minus.f()); 171 CHECK((1 << 9) == diy_fp.f() - boundary_minus.f()); // NOLINT 172 CHECK((1 << 10) == boundary_plus.f() - diy_fp.f()); // NOLINT 173 174 uint64_t min_double64 = V8_2PART_UINT64_C(0x00000000, 00000001); 175 diy_fp = Double(min_double64).AsNormalizedDiyFp(); 176 Double(min_double64).NormalizedBoundaries(&boundary_minus, &boundary_plus); 177 CHECK_EQ(diy_fp.e(), boundary_minus.e()); 178 CHECK_EQ(diy_fp.e(), boundary_plus.e()); 179 // min-value does not have a significand of the form 2^p (for some p). 180 // Therefore its boundaries are at the same distance. 181 CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f()); 182 // Denormals have their boundaries much closer. 183 CHECK((static_cast<uint64_t>(1) << 62) == 184 diy_fp.f() - boundary_minus.f()); // NOLINT 185 186 uint64_t smallest_normal64 = V8_2PART_UINT64_C(0x00100000, 00000000); 187 diy_fp = Double(smallest_normal64).AsNormalizedDiyFp(); 188 Double(smallest_normal64).NormalizedBoundaries(&boundary_minus, 189 &boundary_plus); 190 CHECK_EQ(diy_fp.e(), boundary_minus.e()); 191 CHECK_EQ(diy_fp.e(), boundary_plus.e()); 192 // Even though the significand is of the form 2^p (for some p), its boundaries 193 // are at the same distance. (This is the only exception). 194 CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f()); 195 CHECK((1 << 10) == diy_fp.f() - boundary_minus.f()); // NOLINT 196 197 uint64_t largest_denormal64 = V8_2PART_UINT64_C(0x000FFFFF, FFFFFFFF); 198 diy_fp = Double(largest_denormal64).AsNormalizedDiyFp(); 199 Double(largest_denormal64).NormalizedBoundaries(&boundary_minus, 200 &boundary_plus); 201 CHECK_EQ(diy_fp.e(), boundary_minus.e()); 202 CHECK_EQ(diy_fp.e(), boundary_plus.e()); 203 CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f()); 204 CHECK((1 << 11) == diy_fp.f() - boundary_minus.f()); // NOLINT 205 206 uint64_t max_double64 = V8_2PART_UINT64_C(0x7fefffff, ffffffff); 207 diy_fp = Double(max_double64).AsNormalizedDiyFp(); 208 Double(max_double64).NormalizedBoundaries(&boundary_minus, &boundary_plus); 209 CHECK_EQ(diy_fp.e(), boundary_minus.e()); 210 CHECK_EQ(diy_fp.e(), boundary_plus.e()); 211 // max-value does not have a significand of the form 2^p (for some p). 212 // Therefore its boundaries are at the same distance. 213 CHECK(diy_fp.f() - boundary_minus.f() == boundary_plus.f() - diy_fp.f()); 214 CHECK((1 << 10) == diy_fp.f() - boundary_minus.f()); // NOLINT 215} 216 217 218TEST(NextDouble) { 219 CHECK_EQ(4e-324, Double(0.0).NextDouble()); 220 CHECK_EQ(0.0, Double(-0.0).NextDouble()); 221 CHECK_EQ(-0.0, Double(-4e-324).NextDouble()); 222 Double d0(-4e-324); 223 Double d1(d0.NextDouble()); 224 Double d2(d1.NextDouble()); 225 CHECK_EQ(-0.0, d1.value()); 226 CHECK_EQ(0.0, d2.value()); 227 CHECK_EQ(4e-324, d2.NextDouble()); 228 CHECK_EQ(-1.7976931348623157e308, Double(-V8_INFINITY).NextDouble()); 229 CHECK_EQ(V8_INFINITY, 230 Double(V8_2PART_UINT64_C(0x7fefffff, ffffffff)).NextDouble()); 231} 232