LCOV - code coverage report
Current view: top level - test/cctest - test-fast-dtoa.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 130 140 92.9 %
Date: 2019-04-17 Functions: 7 7 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/platform/platform.h"
      33             : #include "src/diy-fp.h"
      34             : #include "src/double.h"
      35             : #include "src/fast-dtoa.h"
      36             : #include "test/cctest/cctest.h"
      37             : #include "test/cctest/gay-precision.h"
      38             : #include "test/cctest/gay-shortest.h"
      39             : 
      40             : namespace v8 {
      41             : namespace internal {
      42             : namespace test_fast_dtoa {
      43             : 
      44             : static const int kBufferSize = 100;
      45             : 
      46             : 
      47             : // Removes trailing '0' digits.
      48      434345 : static void TrimRepresentation(Vector<char> representation) {
      49             :   int len = StrLength(representation.start());
      50             :   int i;
      51      480395 :   for (i = len - 1; i >= 0; --i) {
      52      960790 :     if (representation[i] != '0') break;
      53             :   }
      54      868690 :   representation[i + 1] = '\0';
      55      434345 : }
      56             : 
      57             : 
      58       26644 : TEST(FastDtoaShortestVariousDoubles) {
      59             :   char buffer_container[kBufferSize];
      60             :   Vector<char> buffer(buffer_container, kBufferSize);
      61             :   int length;
      62             :   int point;
      63             :   int status;
      64             : 
      65             :   double min_double = 5e-324;
      66           5 :   status = FastDtoa(min_double, FAST_DTOA_SHORTEST, 0,
      67             :                     buffer, &length, &point);
      68           5 :   CHECK(status);
      69           5 :   CHECK_EQ(0, strcmp("5", buffer.start()));
      70           5 :   CHECK_EQ(-323, point);
      71             : 
      72             :   double max_double = 1.7976931348623157e308;
      73           5 :   status = FastDtoa(max_double, FAST_DTOA_SHORTEST, 0,
      74             :                     buffer, &length, &point);
      75           5 :   CHECK(status);
      76           5 :   CHECK_EQ(0, strcmp("17976931348623157", buffer.start()));
      77           5 :   CHECK_EQ(309, point);
      78             : 
      79           5 :   status = FastDtoa(4294967272.0, FAST_DTOA_SHORTEST, 0,
      80             :                     buffer, &length, &point);
      81           5 :   CHECK(status);
      82           5 :   CHECK_EQ(0, strcmp("4294967272", buffer.start()));
      83           5 :   CHECK_EQ(10, point);
      84             : 
      85           5 :   status = FastDtoa(4.1855804968213567e298, FAST_DTOA_SHORTEST, 0,
      86             :                     buffer, &length, &point);
      87           5 :   CHECK(status);
      88           5 :   CHECK_EQ(0, strcmp("4185580496821357", buffer.start()));
      89           5 :   CHECK_EQ(299, point);
      90             : 
      91           5 :   status = FastDtoa(5.5626846462680035e-309, FAST_DTOA_SHORTEST, 0,
      92             :                     buffer, &length, &point);
      93           5 :   CHECK(status);
      94           5 :   CHECK_EQ(0, strcmp("5562684646268003", buffer.start()));
      95           5 :   CHECK_EQ(-308, point);
      96             : 
      97           5 :   status = FastDtoa(2147483648.0, FAST_DTOA_SHORTEST, 0,
      98             :                     buffer, &length, &point);
      99           5 :   CHECK(status);
     100           5 :   CHECK_EQ(0, strcmp("2147483648", buffer.start()));
     101           5 :   CHECK_EQ(10, point);
     102             : 
     103           5 :   status = FastDtoa(3.5844466002796428e+298, FAST_DTOA_SHORTEST, 0,
     104             :                     buffer, &length, &point);
     105           5 :   if (status) {  // Not all FastDtoa variants manage to compute this number.
     106           0 :     CHECK_EQ(0, strcmp("35844466002796428", buffer.start()));
     107           0 :     CHECK_EQ(299, point);
     108             :   }
     109             : 
     110             :   uint64_t smallest_normal64 = V8_2PART_UINT64_C(0x00100000, 00000000);
     111             :   double v = Double(smallest_normal64).value();
     112           5 :   status = FastDtoa(v, FAST_DTOA_SHORTEST, 0, buffer, &length, &point);
     113           5 :   if (status) {
     114           5 :     CHECK_EQ(0, strcmp("22250738585072014", buffer.start()));
     115           5 :     CHECK_EQ(-307, point);
     116             :   }
     117             : 
     118             :   uint64_t largest_denormal64 = V8_2PART_UINT64_C(0x000FFFFF, FFFFFFFF);
     119             :   v = Double(largest_denormal64).value();
     120           5 :   status = FastDtoa(v, FAST_DTOA_SHORTEST, 0, buffer, &length, &point);
     121           5 :   if (status) {
     122           5 :     CHECK_EQ(0, strcmp("2225073858507201", buffer.start()));
     123           5 :     CHECK_EQ(-307, point);
     124             :   }
     125           5 : }
     126             : 
     127             : 
     128       26644 : TEST(FastDtoaPrecisionVariousDoubles) {
     129             :   char buffer_container[kBufferSize];
     130             :   Vector<char> buffer(buffer_container, kBufferSize);
     131             :   int length;
     132             :   int point;
     133             :   int status;
     134             : 
     135           5 :   status = FastDtoa(1.0, FAST_DTOA_PRECISION, 3, buffer, &length, &point);
     136           5 :   CHECK(status);
     137           5 :   CHECK_GE(3, length);
     138           5 :   TrimRepresentation(buffer);
     139           5 :   CHECK_EQ(0, strcmp("1", buffer.start()));
     140           5 :   CHECK_EQ(1, point);
     141             : 
     142           5 :   status = FastDtoa(1.5, FAST_DTOA_PRECISION, 10, buffer, &length, &point);
     143           5 :   if (status) {
     144           0 :     CHECK_GE(10, length);
     145           0 :     TrimRepresentation(buffer);
     146           0 :     CHECK_EQ(0, strcmp("15", buffer.start()));
     147           0 :     CHECK_EQ(1, point);
     148             :   }
     149             : 
     150             :   double min_double = 5e-324;
     151           5 :   status = FastDtoa(min_double, FAST_DTOA_PRECISION, 5,
     152             :                     buffer, &length, &point);
     153           5 :   CHECK(status);
     154           5 :   CHECK_EQ(0, strcmp("49407", buffer.start()));
     155           5 :   CHECK_EQ(-323, point);
     156             : 
     157             :   double max_double = 1.7976931348623157e308;
     158           5 :   status = FastDtoa(max_double, FAST_DTOA_PRECISION, 7,
     159             :                     buffer, &length, &point);
     160           5 :   CHECK(status);
     161           5 :   CHECK_EQ(0, strcmp("1797693", buffer.start()));
     162           5 :   CHECK_EQ(309, point);
     163             : 
     164           5 :   status = FastDtoa(4294967272.0, FAST_DTOA_PRECISION, 14,
     165             :                     buffer, &length, &point);
     166           5 :   if (status) {
     167           0 :     CHECK_GE(14, length);
     168           0 :     TrimRepresentation(buffer);
     169           0 :     CHECK_EQ(0, strcmp("4294967272", buffer.start()));
     170           0 :     CHECK_EQ(10, point);
     171             :   }
     172             : 
     173           5 :   status = FastDtoa(4.1855804968213567e298, FAST_DTOA_PRECISION, 17,
     174             :                     buffer, &length, &point);
     175           5 :   CHECK(status);
     176           5 :   CHECK_EQ(0, strcmp("41855804968213567", buffer.start()));
     177           5 :   CHECK_EQ(299, point);
     178             : 
     179           5 :   status = FastDtoa(5.5626846462680035e-309, FAST_DTOA_PRECISION, 1,
     180             :                     buffer, &length, &point);
     181           5 :   CHECK(status);
     182           5 :   CHECK_EQ(0, strcmp("6", buffer.start()));
     183           5 :   CHECK_EQ(-308, point);
     184             : 
     185           5 :   status = FastDtoa(2147483648.0, FAST_DTOA_PRECISION, 5,
     186             :                     buffer, &length, &point);
     187           5 :   CHECK(status);
     188           5 :   CHECK_EQ(0, strcmp("21475", buffer.start()));
     189           5 :   CHECK_EQ(10, point);
     190             : 
     191           5 :   status = FastDtoa(3.5844466002796428e+298, FAST_DTOA_PRECISION, 10,
     192             :                     buffer, &length, &point);
     193           5 :   CHECK(status);
     194           5 :   CHECK_GE(10, length);
     195           5 :   TrimRepresentation(buffer);
     196           5 :   CHECK_EQ(0, strcmp("35844466", buffer.start()));
     197           5 :   CHECK_EQ(299, point);
     198             : 
     199             :   uint64_t smallest_normal64 = V8_2PART_UINT64_C(0x00100000, 00000000);
     200             :   double v = Double(smallest_normal64).value();
     201           5 :   status = FastDtoa(v, FAST_DTOA_PRECISION, 17, buffer, &length, &point);
     202           5 :   CHECK(status);
     203           5 :   CHECK_EQ(0, strcmp("22250738585072014", buffer.start()));
     204           5 :   CHECK_EQ(-307, point);
     205             : 
     206             :   uint64_t largest_denormal64 = V8_2PART_UINT64_C(0x000FFFFF, FFFFFFFF);
     207             :   v = Double(largest_denormal64).value();
     208           5 :   status = FastDtoa(v, FAST_DTOA_PRECISION, 17, buffer, &length, &point);
     209           5 :   CHECK(status);
     210           5 :   CHECK_GE(20, length);
     211           5 :   TrimRepresentation(buffer);
     212           5 :   CHECK_EQ(0, strcmp("22250738585072009", buffer.start()));
     213           5 :   CHECK_EQ(-307, point);
     214             : 
     215             :   v = 3.3161339052167390562200598e-237;
     216           5 :   status = FastDtoa(v, FAST_DTOA_PRECISION, 18, buffer, &length, &point);
     217           5 :   CHECK(status);
     218           5 :   CHECK_EQ(0, strcmp("331613390521673906", buffer.start()));
     219           5 :   CHECK_EQ(-236, point);
     220             : 
     221             :   v = 7.9885183916008099497815232e+191;
     222           5 :   status = FastDtoa(v, FAST_DTOA_PRECISION, 4, buffer, &length, &point);
     223           5 :   CHECK(status);
     224           5 :   CHECK_EQ(0, strcmp("7989", buffer.start()));
     225           5 :   CHECK_EQ(192, point);
     226           5 : }
     227             : 
     228             : 
     229       26644 : TEST(FastDtoaGayShortest) {
     230             :   char buffer_container[kBufferSize];
     231             :   Vector<char> buffer(buffer_container, kBufferSize);
     232             :   bool status;
     233             :   int length;
     234             :   int point;
     235             :   int succeeded = 0;
     236             :   int total = 0;
     237             :   bool needed_max_length = false;
     238             : 
     239             :   Vector<const PrecomputedShortest> precomputed =
     240           5 :       PrecomputedShortestRepresentations();
     241     1000005 :   for (int i = 0; i < precomputed.length(); ++i) {
     242     1000000 :     const PrecomputedShortest current_test = precomputed[i];
     243      500000 :     total++;
     244             :     double v = current_test.v;
     245      500000 :     status = FastDtoa(v, FAST_DTOA_SHORTEST, 0, buffer, &length, &point);
     246      500000 :     CHECK_GE(kFastDtoaMaximalLength, length);
     247      500000 :     if (!status) continue;
     248      497200 :     if (length == kFastDtoaMaximalLength) needed_max_length = true;
     249      497200 :     succeeded++;
     250      497200 :     CHECK_EQ(current_test.decimal_point, point);
     251      497200 :     CHECK_EQ(0, strcmp(current_test.representation, buffer.start()));
     252             :   }
     253          10 :   CHECK_GT(succeeded*1.0/total, 0.99);
     254           5 :   CHECK(needed_max_length);
     255           5 : }
     256             : 
     257             : 
     258       26644 : TEST(FastDtoaGayPrecision) {
     259             :   char buffer_container[kBufferSize];
     260             :   Vector<char> buffer(buffer_container, kBufferSize);
     261             :   bool status;
     262             :   int length;
     263             :   int point;
     264             :   int succeeded = 0;
     265             :   int total = 0;
     266             :   // Count separately for entries with less than 15 requested digits.
     267             :   int succeeded_15 = 0;
     268             :   int total_15 = 0;
     269             : 
     270             :   Vector<const PrecomputedPrecision> precomputed =
     271           5 :       PrecomputedPrecisionRepresentations();
     272     1000005 :   for (int i = 0; i < precomputed.length(); ++i) {
     273     1000000 :     const PrecomputedPrecision current_test = precomputed[i];
     274             :     double v = current_test.v;
     275             :     int number_digits = current_test.number_digits;
     276      500000 :     total++;
     277      500000 :     if (number_digits <= 15) total_15++;
     278             :     status = FastDtoa(v, FAST_DTOA_PRECISION, number_digits,
     279      500000 :                       buffer, &length, &point);
     280      500000 :     CHECK_GE(number_digits, length);
     281      500000 :     if (!status) continue;
     282      434330 :     succeeded++;
     283      434330 :     if (number_digits <= 15) succeeded_15++;
     284      434330 :     TrimRepresentation(buffer);
     285      434330 :     CHECK_EQ(current_test.decimal_point, point);
     286      434330 :     CHECK_EQ(0, strcmp(current_test.representation, buffer.start()));
     287             :   }
     288             :   // The precomputed numbers contain many entries with many requested
     289             :   // digits. These have a high failure rate and we therefore expect a lower
     290             :   // success rate than for the shortest representation.
     291          10 :   CHECK_GT(succeeded*1.0/total, 0.85);
     292             :   // However with less than 15 digits almost the algorithm should almost always
     293             :   // succeed.
     294          10 :   CHECK_GT(succeeded_15*1.0/total_15, 0.9999);
     295           5 : }
     296             : 
     297             : }  // namespace test_fast_dtoa
     298             : }  // namespace internal
     299       79917 : }  // namespace v8

Generated by: LCOV version 1.10