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/utils/random-number-generator.h" 33#include "src/bignum.h" 34#include "src/diy-fp.h" 35#include "src/double.h" 36#include "src/strtod.h" 37#include "test/cctest/cctest.h" 38 39using namespace v8::internal; 40 41static Vector<const char> StringToVector(const char* str) { 42 return Vector<const char>(str, StrLength(str)); 43} 44 45 46static double StrtodChar(const char* str, int exponent) { 47 return Strtod(StringToVector(str), exponent); 48} 49 50 51TEST(Strtod) { 52 Vector<const char> vector; 53 54 vector = StringToVector("0"); 55 CHECK_EQ(0.0, Strtod(vector, 1)); 56 CHECK_EQ(0.0, Strtod(vector, 2)); 57 CHECK_EQ(0.0, Strtod(vector, -2)); 58 CHECK_EQ(0.0, Strtod(vector, -999)); 59 CHECK_EQ(0.0, Strtod(vector, +999)); 60 61 vector = StringToVector("1"); 62 CHECK_EQ(1.0, Strtod(vector, 0)); 63 CHECK_EQ(10.0, Strtod(vector, 1)); 64 CHECK_EQ(100.0, Strtod(vector, 2)); 65 CHECK_EQ(1e20, Strtod(vector, 20)); 66 CHECK_EQ(1e22, Strtod(vector, 22)); 67 CHECK_EQ(1e23, Strtod(vector, 23)); 68 CHECK_EQ(1e35, Strtod(vector, 35)); 69 CHECK_EQ(1e36, Strtod(vector, 36)); 70 CHECK_EQ(1e37, Strtod(vector, 37)); 71 CHECK_EQ(1e-1, Strtod(vector, -1)); 72 CHECK_EQ(1e-2, Strtod(vector, -2)); 73 CHECK_EQ(1e-5, Strtod(vector, -5)); 74 CHECK_EQ(1e-20, Strtod(vector, -20)); 75 CHECK_EQ(1e-22, Strtod(vector, -22)); 76 CHECK_EQ(1e-23, Strtod(vector, -23)); 77 CHECK_EQ(1e-25, Strtod(vector, -25)); 78 CHECK_EQ(1e-39, Strtod(vector, -39)); 79 80 vector = StringToVector("2"); 81 CHECK_EQ(2.0, Strtod(vector, 0)); 82 CHECK_EQ(20.0, Strtod(vector, 1)); 83 CHECK_EQ(200.0, Strtod(vector, 2)); 84 CHECK_EQ(2e20, Strtod(vector, 20)); 85 CHECK_EQ(2e22, Strtod(vector, 22)); 86 CHECK_EQ(2e23, Strtod(vector, 23)); 87 CHECK_EQ(2e35, Strtod(vector, 35)); 88 CHECK_EQ(2e36, Strtod(vector, 36)); 89 CHECK_EQ(2e37, Strtod(vector, 37)); 90 CHECK_EQ(2e-1, Strtod(vector, -1)); 91 CHECK_EQ(2e-2, Strtod(vector, -2)); 92 CHECK_EQ(2e-5, Strtod(vector, -5)); 93 CHECK_EQ(2e-20, Strtod(vector, -20)); 94 CHECK_EQ(2e-22, Strtod(vector, -22)); 95 CHECK_EQ(2e-23, Strtod(vector, -23)); 96 CHECK_EQ(2e-25, Strtod(vector, -25)); 97 CHECK_EQ(2e-39, Strtod(vector, -39)); 98 99 vector = StringToVector("9"); 100 CHECK_EQ(9.0, Strtod(vector, 0)); 101 CHECK_EQ(90.0, Strtod(vector, 1)); 102 CHECK_EQ(900.0, Strtod(vector, 2)); 103 CHECK_EQ(9e20, Strtod(vector, 20)); 104 CHECK_EQ(9e22, Strtod(vector, 22)); 105 CHECK_EQ(9e23, Strtod(vector, 23)); 106 CHECK_EQ(9e35, Strtod(vector, 35)); 107 CHECK_EQ(9e36, Strtod(vector, 36)); 108 CHECK_EQ(9e37, Strtod(vector, 37)); 109 CHECK_EQ(9e-1, Strtod(vector, -1)); 110 CHECK_EQ(9e-2, Strtod(vector, -2)); 111 CHECK_EQ(9e-5, Strtod(vector, -5)); 112 CHECK_EQ(9e-20, Strtod(vector, -20)); 113 CHECK_EQ(9e-22, Strtod(vector, -22)); 114 CHECK_EQ(9e-23, Strtod(vector, -23)); 115 CHECK_EQ(9e-25, Strtod(vector, -25)); 116 CHECK_EQ(9e-39, Strtod(vector, -39)); 117 118 vector = StringToVector("12345"); 119 CHECK_EQ(12345.0, Strtod(vector, 0)); 120 CHECK_EQ(123450.0, Strtod(vector, 1)); 121 CHECK_EQ(1234500.0, Strtod(vector, 2)); 122 CHECK_EQ(12345e20, Strtod(vector, 20)); 123 CHECK_EQ(12345e22, Strtod(vector, 22)); 124 CHECK_EQ(12345e23, Strtod(vector, 23)); 125 CHECK_EQ(12345e30, Strtod(vector, 30)); 126 CHECK_EQ(12345e31, Strtod(vector, 31)); 127 CHECK_EQ(12345e32, Strtod(vector, 32)); 128 CHECK_EQ(12345e35, Strtod(vector, 35)); 129 CHECK_EQ(12345e36, Strtod(vector, 36)); 130 CHECK_EQ(12345e37, Strtod(vector, 37)); 131 CHECK_EQ(12345e-1, Strtod(vector, -1)); 132 CHECK_EQ(12345e-2, Strtod(vector, -2)); 133 CHECK_EQ(12345e-5, Strtod(vector, -5)); 134 CHECK_EQ(12345e-20, Strtod(vector, -20)); 135 CHECK_EQ(12345e-22, Strtod(vector, -22)); 136 CHECK_EQ(12345e-23, Strtod(vector, -23)); 137 CHECK_EQ(12345e-25, Strtod(vector, -25)); 138 CHECK_EQ(12345e-39, Strtod(vector, -39)); 139 140 vector = StringToVector("12345678901234"); 141 CHECK_EQ(12345678901234.0, Strtod(vector, 0)); 142 CHECK_EQ(123456789012340.0, Strtod(vector, 1)); 143 CHECK_EQ(1234567890123400.0, Strtod(vector, 2)); 144 CHECK_EQ(12345678901234e20, Strtod(vector, 20)); 145 CHECK_EQ(12345678901234e22, Strtod(vector, 22)); 146 CHECK_EQ(12345678901234e23, Strtod(vector, 23)); 147 CHECK_EQ(12345678901234e30, Strtod(vector, 30)); 148 CHECK_EQ(12345678901234e31, Strtod(vector, 31)); 149 CHECK_EQ(12345678901234e32, Strtod(vector, 32)); 150 CHECK_EQ(12345678901234e35, Strtod(vector, 35)); 151 CHECK_EQ(12345678901234e36, Strtod(vector, 36)); 152 CHECK_EQ(12345678901234e37, Strtod(vector, 37)); 153 CHECK_EQ(12345678901234e-1, Strtod(vector, -1)); 154 CHECK_EQ(12345678901234e-2, Strtod(vector, -2)); 155 CHECK_EQ(12345678901234e-5, Strtod(vector, -5)); 156 CHECK_EQ(12345678901234e-20, Strtod(vector, -20)); 157 CHECK_EQ(12345678901234e-22, Strtod(vector, -22)); 158 CHECK_EQ(12345678901234e-23, Strtod(vector, -23)); 159 CHECK_EQ(12345678901234e-25, Strtod(vector, -25)); 160 CHECK_EQ(12345678901234e-39, Strtod(vector, -39)); 161 162 vector = StringToVector("123456789012345"); 163 CHECK_EQ(123456789012345.0, Strtod(vector, 0)); 164 CHECK_EQ(1234567890123450.0, Strtod(vector, 1)); 165 CHECK_EQ(12345678901234500.0, Strtod(vector, 2)); 166 CHECK_EQ(123456789012345e20, Strtod(vector, 20)); 167 CHECK_EQ(123456789012345e22, Strtod(vector, 22)); 168 CHECK_EQ(123456789012345e23, Strtod(vector, 23)); 169 CHECK_EQ(123456789012345e35, Strtod(vector, 35)); 170 CHECK_EQ(123456789012345e36, Strtod(vector, 36)); 171 CHECK_EQ(123456789012345e37, Strtod(vector, 37)); 172 CHECK_EQ(123456789012345e39, Strtod(vector, 39)); 173 CHECK_EQ(123456789012345e-1, Strtod(vector, -1)); 174 CHECK_EQ(123456789012345e-2, Strtod(vector, -2)); 175 CHECK_EQ(123456789012345e-5, Strtod(vector, -5)); 176 CHECK_EQ(123456789012345e-20, Strtod(vector, -20)); 177 CHECK_EQ(123456789012345e-22, Strtod(vector, -22)); 178 CHECK_EQ(123456789012345e-23, Strtod(vector, -23)); 179 CHECK_EQ(123456789012345e-25, Strtod(vector, -25)); 180 CHECK_EQ(123456789012345e-39, Strtod(vector, -39)); 181 182 CHECK_EQ(0.0, StrtodChar("0", 12345)); 183 CHECK_EQ(0.0, StrtodChar("", 1324)); 184 CHECK_EQ(0.0, StrtodChar("000000000", 123)); 185 CHECK_EQ(0.0, StrtodChar("2", -324)); 186 CHECK_EQ(4e-324, StrtodChar("3", -324)); 187 // It would be more readable to put non-zero literals on the left side (i.e. 188 // CHECK_EQ(1e-325, StrtodChar("1", -325))), but then Gcc complains that 189 // they are truncated to zero. 190 CHECK_EQ(0.0, StrtodChar("1", -325)); 191 CHECK_EQ(0.0, StrtodChar("1", -325)); 192 CHECK_EQ(0.0, StrtodChar("20000", -328)); 193 CHECK_EQ(40000e-328, StrtodChar("30000", -328)); 194 CHECK_EQ(0.0, StrtodChar("10000", -329)); 195 CHECK_EQ(0.0, StrtodChar("90000", -329)); 196 CHECK_EQ(0.0, StrtodChar("000000001", -325)); 197 CHECK_EQ(0.0, StrtodChar("000000001", -325)); 198 CHECK_EQ(0.0, StrtodChar("0000000020000", -328)); 199 CHECK_EQ(40000e-328, StrtodChar("00000030000", -328)); 200 CHECK_EQ(0.0, StrtodChar("0000000010000", -329)); 201 CHECK_EQ(0.0, StrtodChar("0000000090000", -329)); 202 203 // It would be more readable to put the literals (and not V8_INFINITY) on the 204 // left side (i.e. CHECK_EQ(1e309, StrtodChar("1", 309))), but then Gcc 205 // complains that the floating constant exceeds range of 'double'. 206 CHECK_EQ(V8_INFINITY, StrtodChar("1", 309)); 207 CHECK_EQ(1e308, StrtodChar("1", 308)); 208 CHECK_EQ(1234e305, StrtodChar("1234", 305)); 209 CHECK_EQ(1234e304, StrtodChar("1234", 304)); 210 CHECK_EQ(V8_INFINITY, StrtodChar("18", 307)); 211 CHECK_EQ(17e307, StrtodChar("17", 307)); 212 CHECK_EQ(V8_INFINITY, StrtodChar("0000001", 309)); 213 CHECK_EQ(1e308, StrtodChar("00000001", 308)); 214 CHECK_EQ(1234e305, StrtodChar("00000001234", 305)); 215 CHECK_EQ(1234e304, StrtodChar("000000001234", 304)); 216 CHECK_EQ(V8_INFINITY, StrtodChar("0000000018", 307)); 217 CHECK_EQ(17e307, StrtodChar("0000000017", 307)); 218 CHECK_EQ(V8_INFINITY, StrtodChar("1000000", 303)); 219 CHECK_EQ(1e308, StrtodChar("100000", 303)); 220 CHECK_EQ(1234e305, StrtodChar("123400000", 300)); 221 CHECK_EQ(1234e304, StrtodChar("123400000", 299)); 222 CHECK_EQ(V8_INFINITY, StrtodChar("180000000", 300)); 223 CHECK_EQ(17e307, StrtodChar("170000000", 300)); 224 CHECK_EQ(V8_INFINITY, StrtodChar("00000001000000", 303)); 225 CHECK_EQ(1e308, StrtodChar("000000000000100000", 303)); 226 CHECK_EQ(1234e305, StrtodChar("00000000123400000", 300)); 227 CHECK_EQ(1234e304, StrtodChar("0000000123400000", 299)); 228 CHECK_EQ(V8_INFINITY, StrtodChar("00000000180000000", 300)); 229 CHECK_EQ(17e307, StrtodChar("00000000170000000", 300)); 230 CHECK_EQ(1.7976931348623157E+308, StrtodChar("17976931348623157", 292)); 231 CHECK_EQ(1.7976931348623158E+308, StrtodChar("17976931348623158", 292)); 232 CHECK_EQ(V8_INFINITY, StrtodChar("17976931348623159", 292)); 233 234 // The following number is the result of 89255.0/1e22. Both floating-point 235 // numbers can be accurately represented with doubles. However on Linux,x86 236 // the floating-point stack is set to 80bits and the double-rounding 237 // introduces an error. 238 CHECK_EQ(89255e-22, StrtodChar("89255", -22)); 239 240 // Some random values. 241 CHECK_EQ(358416272e-33, StrtodChar("358416272", -33)); 242 CHECK_EQ(104110013277974872254e-225, 243 StrtodChar("104110013277974872254", -225)); 244 245 CHECK_EQ(123456789e108, StrtodChar("123456789", 108)); 246 CHECK_EQ(123456789e109, StrtodChar("123456789", 109)); 247 CHECK_EQ(123456789e110, StrtodChar("123456789", 110)); 248 CHECK_EQ(123456789e111, StrtodChar("123456789", 111)); 249 CHECK_EQ(123456789e112, StrtodChar("123456789", 112)); 250 CHECK_EQ(123456789e113, StrtodChar("123456789", 113)); 251 CHECK_EQ(123456789e114, StrtodChar("123456789", 114)); 252 CHECK_EQ(123456789e115, StrtodChar("123456789", 115)); 253 254 CHECK_EQ(1234567890123456789012345e108, 255 StrtodChar("1234567890123456789012345", 108)); 256 CHECK_EQ(1234567890123456789012345e109, 257 StrtodChar("1234567890123456789012345", 109)); 258 CHECK_EQ(1234567890123456789012345e110, 259 StrtodChar("1234567890123456789012345", 110)); 260 CHECK_EQ(1234567890123456789012345e111, 261 StrtodChar("1234567890123456789012345", 111)); 262 CHECK_EQ(1234567890123456789012345e112, 263 StrtodChar("1234567890123456789012345", 112)); 264 CHECK_EQ(1234567890123456789012345e113, 265 StrtodChar("1234567890123456789012345", 113)); 266 CHECK_EQ(1234567890123456789012345e114, 267 StrtodChar("1234567890123456789012345", 114)); 268 CHECK_EQ(1234567890123456789012345e115, 269 StrtodChar("1234567890123456789012345", 115)); 270 271 CHECK_EQ(1234567890123456789052345e108, 272 StrtodChar("1234567890123456789052345", 108)); 273 CHECK_EQ(1234567890123456789052345e109, 274 StrtodChar("1234567890123456789052345", 109)); 275 CHECK_EQ(1234567890123456789052345e110, 276 StrtodChar("1234567890123456789052345", 110)); 277 CHECK_EQ(1234567890123456789052345e111, 278 StrtodChar("1234567890123456789052345", 111)); 279 CHECK_EQ(1234567890123456789052345e112, 280 StrtodChar("1234567890123456789052345", 112)); 281 CHECK_EQ(1234567890123456789052345e113, 282 StrtodChar("1234567890123456789052345", 113)); 283 CHECK_EQ(1234567890123456789052345e114, 284 StrtodChar("1234567890123456789052345", 114)); 285 CHECK_EQ(1234567890123456789052345e115, 286 StrtodChar("1234567890123456789052345", 115)); 287 288 CHECK_EQ(5.445618932859895e-255, 289 StrtodChar("5445618932859895362967233318697132813618813095743952975" 290 "4392982234069699615600475529427176366709107287468930197" 291 "8628345413991790019316974825934906752493984055268219809" 292 "5012176093045431437495773903922425632551857520884625114" 293 "6241265881735209066709685420744388526014389929047617597" 294 "0302268848374508109029268898695825171158085457567481507" 295 "4162979705098246243690189880319928315307816832576838178" 296 "2563074014542859888710209237525873301724479666744537857" 297 "9026553346649664045621387124193095870305991178772256504" 298 "4368663670643970181259143319016472430928902201239474588" 299 "1392338901353291306607057623202353588698746085415097902" 300 "6640064319118728664842287477491068264828851624402189317" 301 "2769161449825765517353755844373640588822904791244190695" 302 "2998382932630754670573838138825217065450843010498555058" 303 "88186560731", -1035)); 304 305 // Boundary cases. Boundaries themselves should round to even. 306 // 307 // 0x1FFFFFFFFFFFF * 2^3 = 72057594037927928 308 // next: 72057594037927936 309 // boundary: 72057594037927932 should round up. 310 CHECK_EQ(72057594037927928.0, StrtodChar("72057594037927928", 0)); 311 CHECK_EQ(72057594037927936.0, StrtodChar("72057594037927936", 0)); 312 CHECK_EQ(72057594037927936.0, StrtodChar("72057594037927932", 0)); 313 CHECK_EQ(72057594037927928.0, StrtodChar("7205759403792793199999", -5)); 314 CHECK_EQ(72057594037927936.0, StrtodChar("7205759403792793200001", -5)); 315 316 // 0x1FFFFFFFFFFFF * 2^10 = 9223372036854774784 317 // next: 9223372036854775808 318 // boundary: 9223372036854775296 should round up. 319 CHECK_EQ(9223372036854774784.0, StrtodChar("9223372036854774784", 0)); 320 CHECK_EQ(9223372036854775808.0, StrtodChar("9223372036854775808", 0)); 321 CHECK_EQ(9223372036854775808.0, StrtodChar("9223372036854775296", 0)); 322 CHECK_EQ(9223372036854774784.0, StrtodChar("922337203685477529599999", -5)); 323 CHECK_EQ(9223372036854775808.0, StrtodChar("922337203685477529600001", -5)); 324 325 // 0x1FFFFFFFFFFFF * 2^50 = 10141204801825834086073718800384 326 // next: 10141204801825835211973625643008 327 // boundary: 10141204801825834649023672221696 should round up. 328 CHECK_EQ(10141204801825834086073718800384.0, 329 StrtodChar("10141204801825834086073718800384", 0)); 330 CHECK_EQ(10141204801825835211973625643008.0, 331 StrtodChar("10141204801825835211973625643008", 0)); 332 CHECK_EQ(10141204801825835211973625643008.0, 333 StrtodChar("10141204801825834649023672221696", 0)); 334 CHECK_EQ(10141204801825834086073718800384.0, 335 StrtodChar("1014120480182583464902367222169599999", -5)); 336 CHECK_EQ(10141204801825835211973625643008.0, 337 StrtodChar("1014120480182583464902367222169600001", -5)); 338 339 // 0x1FFFFFFFFFFFF * 2^99 = 5708990770823838890407843763683279797179383808 340 // next: 5708990770823839524233143877797980545530986496 341 // boundary: 5708990770823839207320493820740630171355185152 342 // The boundary should round up. 343 CHECK_EQ(5708990770823838890407843763683279797179383808.0, 344 StrtodChar("5708990770823838890407843763683279797179383808", 0)); 345 CHECK_EQ(5708990770823839524233143877797980545530986496.0, 346 StrtodChar("5708990770823839524233143877797980545530986496", 0)); 347 CHECK_EQ(5708990770823839524233143877797980545530986496.0, 348 StrtodChar("5708990770823839207320493820740630171355185152", 0)); 349 CHECK_EQ(5708990770823838890407843763683279797179383808.0, 350 StrtodChar("5708990770823839207320493820740630171355185151999", -3)); 351 CHECK_EQ(5708990770823839524233143877797980545530986496.0, 352 StrtodChar("5708990770823839207320493820740630171355185152001", -3)); 353 354 // The following test-cases got some public attention in early 2011 when they 355 // sent Java and PHP into an infinite loop. 356 CHECK_EQ(2.225073858507201e-308, StrtodChar("22250738585072011", -324)); 357 CHECK_EQ(2.22507385850720138309e-308, 358 StrtodChar("22250738585072011360574097967091319759348195463516456480" 359 "23426109724822222021076945516529523908135087914149158913" 360 "03962110687008643869459464552765720740782062174337998814" 361 "10632673292535522868813721490129811224514518898490572223" 362 "07285255133155755015914397476397983411801999323962548289" 363 "01710708185069063066665599493827577257201576306269066333" 364 "26475653000092458883164330377797918696120494973903778297" 365 "04905051080609940730262937128958950003583799967207254304" 366 "36028407889577179615094551674824347103070260914462157228" 367 "98802581825451803257070188608721131280795122334262883686" 368 "22321503775666622503982534335974568884423900265498198385" 369 "48794829220689472168983109969836584681402285424333066033" 370 "98508864458040010349339704275671864433837704860378616227" 371 "71738545623065874679014086723327636718751", -1076)); 372} 373 374 375static int CompareBignumToDiyFp(const Bignum& bignum_digits, 376 int bignum_exponent, 377 DiyFp diy_fp) { 378 Bignum bignum; 379 bignum.AssignBignum(bignum_digits); 380 Bignum other; 381 other.AssignUInt64(diy_fp.f()); 382 if (bignum_exponent >= 0) { 383 bignum.MultiplyByPowerOfTen(bignum_exponent); 384 } else { 385 other.MultiplyByPowerOfTen(-bignum_exponent); 386 } 387 if (diy_fp.e() >= 0) { 388 other.ShiftLeft(diy_fp.e()); 389 } else { 390 bignum.ShiftLeft(-diy_fp.e()); 391 } 392 return Bignum::Compare(bignum, other); 393} 394 395 396static bool CheckDouble(Vector<const char> buffer, 397 int exponent, 398 double to_check) { 399 DiyFp lower_boundary; 400 DiyFp upper_boundary; 401 Bignum input_digits; 402 input_digits.AssignDecimalString(buffer); 403 if (to_check == 0.0) { 404 const double kMinDouble = 4e-324; 405 // Check that the buffer*10^exponent < (0 + kMinDouble)/2. 406 Double d(kMinDouble); 407 d.NormalizedBoundaries(&lower_boundary, &upper_boundary); 408 return CompareBignumToDiyFp(input_digits, exponent, lower_boundary) <= 0; 409 } 410 if (to_check == V8_INFINITY) { 411 const double kMaxDouble = 1.7976931348623157e308; 412 // Check that the buffer*10^exponent >= boundary between kMaxDouble and inf. 413 Double d(kMaxDouble); 414 d.NormalizedBoundaries(&lower_boundary, &upper_boundary); 415 return CompareBignumToDiyFp(input_digits, exponent, upper_boundary) >= 0; 416 } 417 Double d(to_check); 418 d.NormalizedBoundaries(&lower_boundary, &upper_boundary); 419 if ((d.Significand() & 1) == 0) { 420 return CompareBignumToDiyFp(input_digits, exponent, lower_boundary) >= 0 && 421 CompareBignumToDiyFp(input_digits, exponent, upper_boundary) <= 0; 422 } else { 423 return CompareBignumToDiyFp(input_digits, exponent, lower_boundary) > 0 && 424 CompareBignumToDiyFp(input_digits, exponent, upper_boundary) < 0; 425 } 426} 427 428 429// Copied from v8.cc and adapted to make the function deterministic. 430static uint32_t DeterministicRandom() { 431 // Random number generator using George Marsaglia's MWC algorithm. 432 static uint32_t hi = 0; 433 static uint32_t lo = 0; 434 435 // Initialization values don't have any special meaning. (They are the result 436 // of two calls to rand().) 437 if (hi == 0) hi = 0xbfe166e7; 438 if (lo == 0) lo = 0x64d1c3c9; 439 440 // Mix the bits. 441 hi = 36969 * (hi & 0xFFFF) + (hi >> 16); 442 lo = 18273 * (lo & 0xFFFF) + (lo >> 16); 443 return (hi << 16) + (lo & 0xFFFF); 444} 445 446 447static const int kBufferSize = 1024; 448static const int kShortStrtodRandomCount = 2; 449static const int kLargeStrtodRandomCount = 2; 450 451TEST(RandomStrtod) { 452 v8::base::RandomNumberGenerator rng; 453 char buffer[kBufferSize]; 454 for (int length = 1; length < 15; length++) { 455 for (int i = 0; i < kShortStrtodRandomCount; ++i) { 456 int pos = 0; 457 for (int j = 0; j < length; ++j) { 458 buffer[pos++] = rng.NextInt(10) + '0'; 459 } 460 int exponent = DeterministicRandom() % (25*2 + 1) - 25 - length; 461 buffer[pos] = '\0'; 462 Vector<const char> vector(buffer, pos); 463 double strtod_result = Strtod(vector, exponent); 464 CHECK(CheckDouble(vector, exponent, strtod_result)); 465 } 466 } 467 for (int length = 15; length < 800; length += 2) { 468 for (int i = 0; i < kLargeStrtodRandomCount; ++i) { 469 int pos = 0; 470 for (int j = 0; j < length; ++j) { 471 buffer[pos++] = rng.NextInt(10) + '0'; 472 } 473 int exponent = DeterministicRandom() % (308*2 + 1) - 308 - length; 474 buffer[pos] = '\0'; 475 Vector<const char> vector(buffer, pos); 476 double strtod_result = Strtod(vector, exponent); 477 CHECK(CheckDouble(vector, exponent, strtod_result)); 478 } 479 } 480} 481