Home | History | Annotate | Download | only in cctest
      1 // Copyright 2010 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 "dtoa.h"
     33 
     34 #include "cctest.h"
     35 #include "double.h"
     36 #include "gay-fixed.h"
     37 #include "gay-precision.h"
     38 #include "gay-shortest.h"
     39 #include "platform.h"
     40 
     41 
     42 using namespace v8::internal;
     43 
     44 
     45 // Removes trailing '0' digits.
     46 static void TrimRepresentation(Vector<char> representation) {
     47   int len = StrLength(representation.start());
     48   int i;
     49   for (i = len - 1; i >= 0; --i) {
     50     if (representation[i] != '0') break;
     51   }
     52   representation[i + 1] = '\0';
     53 }
     54 
     55 
     56 static const int kBufferSize = 100;
     57 
     58 
     59 TEST(DtoaVariousDoubles) {
     60   char buffer_container[kBufferSize];
     61   Vector<char> buffer(buffer_container, kBufferSize);
     62   int length;
     63   int point;
     64   int sign;
     65 
     66   DoubleToAscii(0.0, DTOA_SHORTEST, 0, buffer, &sign, &length, &point);
     67   CHECK_EQ("0", buffer.start());
     68   CHECK_EQ(1, point);
     69 
     70   DoubleToAscii(0.0, DTOA_FIXED, 2, buffer, &sign, &length, &point);
     71   CHECK_EQ(1, length);
     72   CHECK_EQ("0", buffer.start());
     73   CHECK_EQ(1, point);
     74 
     75   DoubleToAscii(0.0, DTOA_PRECISION, 3, buffer, &sign, &length, &point);
     76   CHECK_EQ(1, length);
     77   CHECK_EQ("0", buffer.start());
     78   CHECK_EQ(1, point);
     79 
     80   DoubleToAscii(1.0, DTOA_SHORTEST, 0, buffer, &sign, &length, &point);
     81   CHECK_EQ("1", buffer.start());
     82   CHECK_EQ(1, point);
     83 
     84   DoubleToAscii(1.0, DTOA_FIXED, 3, buffer, &sign, &length, &point);
     85   CHECK_GE(3, length - point);
     86   TrimRepresentation(buffer);
     87   CHECK_EQ("1", buffer.start());
     88   CHECK_EQ(1, point);
     89 
     90   DoubleToAscii(1.0, DTOA_PRECISION, 3, buffer, &sign, &length, &point);
     91   CHECK_GE(3, length);
     92   TrimRepresentation(buffer);
     93   CHECK_EQ("1", buffer.start());
     94   CHECK_EQ(1, point);
     95 
     96   DoubleToAscii(1.5, DTOA_SHORTEST, 0, buffer, &sign, &length, &point);
     97   CHECK_EQ("15", buffer.start());
     98   CHECK_EQ(1, point);
     99 
    100   DoubleToAscii(1.5, DTOA_FIXED, 10, buffer, &sign, &length, &point);
    101   CHECK_GE(10, length - point);
    102   TrimRepresentation(buffer);
    103   CHECK_EQ("15", buffer.start());
    104   CHECK_EQ(1, point);
    105 
    106   DoubleToAscii(1.5, DTOA_PRECISION, 10, buffer, &sign, &length, &point);
    107   CHECK_GE(10, length);
    108   TrimRepresentation(buffer);
    109   CHECK_EQ("15", buffer.start());
    110   CHECK_EQ(1, point);
    111 
    112   double min_double = 5e-324;
    113   DoubleToAscii(min_double, DTOA_SHORTEST, 0, buffer, &sign, &length, &point);
    114   CHECK_EQ("5", buffer.start());
    115   CHECK_EQ(-323, point);
    116 
    117   DoubleToAscii(min_double, DTOA_FIXED, 5, buffer, &sign, &length, &point);
    118   CHECK_GE(5, length - point);
    119   TrimRepresentation(buffer);
    120   CHECK_EQ("", buffer.start());
    121   CHECK_GE(-5, point);
    122 
    123   DoubleToAscii(min_double, DTOA_PRECISION, 5, buffer, &sign, &length, &point);
    124   CHECK_GE(5, length);
    125   TrimRepresentation(buffer);
    126   CHECK_EQ("49407", buffer.start());
    127   CHECK_EQ(-323, point);
    128 
    129   double max_double = 1.7976931348623157e308;
    130   DoubleToAscii(max_double, DTOA_SHORTEST, 0, buffer, &sign, &length, &point);
    131   CHECK_EQ("17976931348623157", buffer.start());
    132   CHECK_EQ(309, point);
    133 
    134   DoubleToAscii(max_double, DTOA_PRECISION, 7, buffer, &sign, &length, &point);
    135   CHECK_GE(7, length);
    136   TrimRepresentation(buffer);
    137   CHECK_EQ("1797693", buffer.start());
    138   CHECK_EQ(309, point);
    139 
    140   DoubleToAscii(4294967272.0, DTOA_SHORTEST, 0, buffer, &sign, &length, &point);
    141   CHECK_EQ("4294967272", buffer.start());
    142   CHECK_EQ(10, point);
    143 
    144   DoubleToAscii(4294967272.0, DTOA_FIXED, 5, buffer, &sign, &length, &point);
    145   CHECK_GE(5, length - point);
    146   TrimRepresentation(buffer);
    147   CHECK_EQ("4294967272", buffer.start());
    148   CHECK_EQ(10, point);
    149 
    150 
    151   DoubleToAscii(4294967272.0, DTOA_PRECISION, 14,
    152                 buffer, &sign, &length, &point);
    153   CHECK_GE(14, length);
    154   TrimRepresentation(buffer);
    155   CHECK_EQ("4294967272", buffer.start());
    156   CHECK_EQ(10, point);
    157 
    158   DoubleToAscii(4.1855804968213567e298, DTOA_SHORTEST, 0,
    159                 buffer, &sign, &length, &point);
    160   CHECK_EQ("4185580496821357", buffer.start());
    161   CHECK_EQ(299, point);
    162 
    163   DoubleToAscii(4.1855804968213567e298, DTOA_PRECISION, 20,
    164                 buffer, &sign, &length, &point);
    165   CHECK_GE(20, length);
    166   TrimRepresentation(buffer);
    167   CHECK_EQ("41855804968213567225", buffer.start());
    168   CHECK_EQ(299, point);
    169 
    170   DoubleToAscii(5.5626846462680035e-309, DTOA_SHORTEST, 0,
    171                 buffer, &sign, &length, &point);
    172   CHECK_EQ("5562684646268003", buffer.start());
    173   CHECK_EQ(-308, point);
    174 
    175   DoubleToAscii(5.5626846462680035e-309, DTOA_PRECISION, 1,
    176                 buffer, &sign, &length, &point);
    177   CHECK_GE(1, length);
    178   TrimRepresentation(buffer);
    179   CHECK_EQ("6", buffer.start());
    180   CHECK_EQ(-308, point);
    181 
    182   DoubleToAscii(-2147483648.0, DTOA_SHORTEST, 0,
    183                 buffer, &sign, &length, &point);
    184   CHECK_EQ(1, sign);
    185   CHECK_EQ("2147483648", buffer.start());
    186   CHECK_EQ(10, point);
    187 
    188 
    189   DoubleToAscii(-2147483648.0, DTOA_FIXED, 2, buffer, &sign, &length, &point);
    190   CHECK_GE(2, length - point);
    191   TrimRepresentation(buffer);
    192   CHECK_EQ(1, sign);
    193   CHECK_EQ("2147483648", buffer.start());
    194   CHECK_EQ(10, point);
    195 
    196   DoubleToAscii(-2147483648.0, DTOA_PRECISION, 5,
    197                 buffer, &sign, &length, &point);
    198   CHECK_GE(5, length);
    199   TrimRepresentation(buffer);
    200   CHECK_EQ(1, sign);
    201   CHECK_EQ("21475", buffer.start());
    202   CHECK_EQ(10, point);
    203 
    204   DoubleToAscii(-3.5844466002796428e+298, DTOA_SHORTEST, 0,
    205                 buffer, &sign, &length, &point);
    206   CHECK_EQ(1, sign);
    207   CHECK_EQ("35844466002796428", buffer.start());
    208   CHECK_EQ(299, point);
    209 
    210   DoubleToAscii(-3.5844466002796428e+298, DTOA_PRECISION, 10,
    211                 buffer, &sign, &length, &point);
    212   CHECK_EQ(1, sign);
    213   CHECK_GE(10, length);
    214   TrimRepresentation(buffer);
    215   CHECK_EQ("35844466", buffer.start());
    216   CHECK_EQ(299, point);
    217 
    218   uint64_t smallest_normal64 = V8_2PART_UINT64_C(0x00100000, 00000000);
    219   double v = Double(smallest_normal64).value();
    220   DoubleToAscii(v, DTOA_SHORTEST, 0, buffer, &sign, &length, &point);
    221   CHECK_EQ("22250738585072014", buffer.start());
    222   CHECK_EQ(-307, point);
    223 
    224   DoubleToAscii(v, DTOA_PRECISION, 20, buffer, &sign, &length, &point);
    225   CHECK_GE(20, length);
    226   TrimRepresentation(buffer);
    227   CHECK_EQ("22250738585072013831", buffer.start());
    228   CHECK_EQ(-307, point);
    229 
    230   uint64_t largest_denormal64 = V8_2PART_UINT64_C(0x000FFFFF, FFFFFFFF);
    231   v = Double(largest_denormal64).value();
    232   DoubleToAscii(v, DTOA_SHORTEST, 0, buffer, &sign, &length, &point);
    233   CHECK_EQ("2225073858507201", buffer.start());
    234   CHECK_EQ(-307, point);
    235 
    236   DoubleToAscii(v, DTOA_PRECISION, 20, buffer, &sign, &length, &point);
    237   CHECK_GE(20, length);
    238   TrimRepresentation(buffer);
    239   CHECK_EQ("2225073858507200889", buffer.start());
    240   CHECK_EQ(-307, point);
    241 
    242   DoubleToAscii(4128420500802942e-24, DTOA_SHORTEST, 0,
    243                 buffer, &sign, &length, &point);
    244   CHECK_EQ(0, sign);
    245   CHECK_EQ("4128420500802942", buffer.start());
    246   CHECK_EQ(-8, point);
    247 
    248   v = -3.9292015898194142585311918e-10;
    249   DoubleToAscii(v, DTOA_SHORTEST, 0, buffer, &sign, &length, &point);
    250   CHECK_EQ("39292015898194143", buffer.start());
    251 
    252   v = 4194304.0;
    253   DoubleToAscii(v, DTOA_FIXED, 5, buffer, &sign, &length, &point);
    254   CHECK_GE(5, length - point);
    255   TrimRepresentation(buffer);
    256   CHECK_EQ("4194304", buffer.start());
    257 
    258   v = 3.3161339052167390562200598e-237;
    259   DoubleToAscii(v, DTOA_PRECISION, 19, buffer, &sign, &length, &point);
    260   CHECK_GE(19, length);
    261   TrimRepresentation(buffer);
    262   CHECK_EQ("3316133905216739056", buffer.start());
    263   CHECK_EQ(-236, point);
    264 }
    265 
    266 
    267 TEST(DtoaGayShortest) {
    268   char buffer_container[kBufferSize];
    269   Vector<char> buffer(buffer_container, kBufferSize);
    270   int sign;
    271   int length;
    272   int point;
    273 
    274   Vector<const PrecomputedShortest> precomputed =
    275       PrecomputedShortestRepresentations();
    276   for (int i = 0; i < precomputed.length(); ++i) {
    277     const PrecomputedShortest current_test = precomputed[i];
    278     double v = current_test.v;
    279     DoubleToAscii(v, DTOA_SHORTEST, 0, buffer, &sign, &length, &point);
    280     CHECK_EQ(0, sign);  // All precomputed numbers are positive.
    281     CHECK_EQ(current_test.decimal_point, point);
    282     CHECK_EQ(current_test.representation, buffer.start());
    283   }
    284 }
    285 
    286 
    287 TEST(DtoaGayFixed) {
    288   char buffer_container[kBufferSize];
    289   Vector<char> buffer(buffer_container, kBufferSize);
    290   int sign;
    291   int length;
    292   int point;
    293 
    294   Vector<const PrecomputedFixed> precomputed =
    295       PrecomputedFixedRepresentations();
    296   for (int i = 0; i < precomputed.length(); ++i) {
    297     const PrecomputedFixed current_test = precomputed[i];
    298     double v = current_test.v;
    299     int number_digits = current_test.number_digits;
    300     DoubleToAscii(v, DTOA_FIXED, number_digits, buffer, &sign, &length, &point);
    301     CHECK_EQ(0, sign);  // All precomputed numbers are positive.
    302     CHECK_EQ(current_test.decimal_point, point);
    303     CHECK_GE(number_digits, length - point);
    304     TrimRepresentation(buffer);
    305     CHECK_EQ(current_test.representation, buffer.start());
    306   }
    307 }
    308 
    309 
    310 TEST(DtoaGayPrecision) {
    311   char buffer_container[kBufferSize];
    312   Vector<char> buffer(buffer_container, kBufferSize);
    313   int sign;
    314   int length;
    315   int point;
    316 
    317   Vector<const PrecomputedPrecision> precomputed =
    318       PrecomputedPrecisionRepresentations();
    319   for (int i = 0; i < precomputed.length(); ++i) {
    320     const PrecomputedPrecision current_test = precomputed[i];
    321     double v = current_test.v;
    322     int number_digits = current_test.number_digits;
    323     DoubleToAscii(v, DTOA_PRECISION, number_digits,
    324                   buffer, &sign, &length, &point);
    325     CHECK_EQ(0, sign);  // All precomputed numbers are positive.
    326     CHECK_EQ(current_test.decimal_point, point);
    327     CHECK_GE(number_digits, length);
    328     TrimRepresentation(buffer);
    329     CHECK_EQ(current_test.representation, buffer.start());
    330   }
    331 }
    332