v8  3.14.5(node0.10.28)
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 
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 
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);
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 
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 }
const int kFastDtoaMaximalLength
Definition: fast-dtoa.h:46
#define CHECK_EQ(expected, value)
Definition: checks.h:219
Vector< const PrecomputedShortest > PrecomputedShortestRepresentations()
Vector< const PrecomputedPrecision > PrecomputedPrecisionRepresentations()
#define CHECK_GT(a, b)
Definition: checks.h:227
#define CHECK(condition)
Definition: checks.h:56
#define CHECK_GE(a, b)
Definition: checks.h:228
T * start() const
Definition: utils.h:390
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:384
#define V8_2PART_UINT64_C(a, b)
Definition: globals.h:187
int StrLength(const char *string)
Definition: utils.h:234
double value() const
Definition: double.h:178