LCOV - code coverage report
Current view: top level - test/cctest - test-strtod.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 276 278 99.3 %
Date: 2019-01-20 Functions: 8 8 100.0 %

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

Generated by: LCOV version 1.10