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