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