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 "v8.h" 31 32 #include "platform.h" 33 #include "cctest.h" 34 #include "diy-fp.h" 35 #include "double.h" 36 37 38 using namespace v8::internal; 39 40 41 TEST(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 54 TEST(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 74 TEST(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 95 TEST(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 105 TEST(IsSpecial) { 106 CHECK(Double(V8_INFINITY).IsSpecial()); 107 CHECK(Double(-V8_INFINITY).IsSpecial()); 108 CHECK(Double(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 128 TEST(IsInfinite) { 129 CHECK(Double(V8_INFINITY).IsInfinite()); 130 CHECK(Double(-V8_INFINITY).IsInfinite()); 131 CHECK(!Double(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 141 TEST(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 152 TEST(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 218 TEST(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