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