1*a6021da3SAndroid Build Coastguard Worker // Copyright 2006-2008 the V8 project authors. All rights reserved.
2*a6021da3SAndroid Build Coastguard Worker // Redistribution and use in source and binary forms, with or without
3*a6021da3SAndroid Build Coastguard Worker // modification, are permitted provided that the following conditions are
4*a6021da3SAndroid Build Coastguard Worker // met:
5*a6021da3SAndroid Build Coastguard Worker //
6*a6021da3SAndroid Build Coastguard Worker // * Redistributions of source code must retain the above copyright
7*a6021da3SAndroid Build Coastguard Worker // notice, this list of conditions and the following disclaimer.
8*a6021da3SAndroid Build Coastguard Worker // * Redistributions in binary form must reproduce the above
9*a6021da3SAndroid Build Coastguard Worker // copyright notice, this list of conditions and the following
10*a6021da3SAndroid Build Coastguard Worker // disclaimer in the documentation and/or other materials provided
11*a6021da3SAndroid Build Coastguard Worker // with the distribution.
12*a6021da3SAndroid Build Coastguard Worker // * Neither the name of Google Inc. nor the names of its
13*a6021da3SAndroid Build Coastguard Worker // contributors may be used to endorse or promote products derived
14*a6021da3SAndroid Build Coastguard Worker // from this software without specific prior written permission.
15*a6021da3SAndroid Build Coastguard Worker //
16*a6021da3SAndroid Build Coastguard Worker // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17*a6021da3SAndroid Build Coastguard Worker // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18*a6021da3SAndroid Build Coastguard Worker // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19*a6021da3SAndroid Build Coastguard Worker // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20*a6021da3SAndroid Build Coastguard Worker // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21*a6021da3SAndroid Build Coastguard Worker // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22*a6021da3SAndroid Build Coastguard Worker // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23*a6021da3SAndroid Build Coastguard Worker // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24*a6021da3SAndroid Build Coastguard Worker // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25*a6021da3SAndroid Build Coastguard Worker // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26*a6021da3SAndroid Build Coastguard Worker // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*a6021da3SAndroid Build Coastguard Worker
28*a6021da3SAndroid Build Coastguard Worker #include <stdlib.h>
29*a6021da3SAndroid Build Coastguard Worker
30*a6021da3SAndroid Build Coastguard Worker #include "cctest.h"
31*a6021da3SAndroid Build Coastguard Worker #include "double-conversion/diy-fp.h"
32*a6021da3SAndroid Build Coastguard Worker #include "double-conversion/fast-dtoa.h"
33*a6021da3SAndroid Build Coastguard Worker #include "gay-precision.h"
34*a6021da3SAndroid Build Coastguard Worker #include "gay-shortest.h"
35*a6021da3SAndroid Build Coastguard Worker #include "gay-shortest-single.h"
36*a6021da3SAndroid Build Coastguard Worker #include "double-conversion/ieee.h"
37*a6021da3SAndroid Build Coastguard Worker #include "double-conversion/utils.h"
38*a6021da3SAndroid Build Coastguard Worker
39*a6021da3SAndroid Build Coastguard Worker using namespace double_conversion;
40*a6021da3SAndroid Build Coastguard Worker
41*a6021da3SAndroid Build Coastguard Worker static const int kBufferSize = 100;
42*a6021da3SAndroid Build Coastguard Worker
43*a6021da3SAndroid Build Coastguard Worker
44*a6021da3SAndroid Build Coastguard Worker // Removes trailing '0' digits.
TrimRepresentation(Vector<char> representation)45*a6021da3SAndroid Build Coastguard Worker static void TrimRepresentation(Vector<char> representation) {
46*a6021da3SAndroid Build Coastguard Worker int len = static_cast<int>(strlen(representation.start()));
47*a6021da3SAndroid Build Coastguard Worker int i;
48*a6021da3SAndroid Build Coastguard Worker for (i = len - 1; i >= 0; --i) {
49*a6021da3SAndroid Build Coastguard Worker if (representation[i] != '0') break;
50*a6021da3SAndroid Build Coastguard Worker }
51*a6021da3SAndroid Build Coastguard Worker representation[i + 1] = '\0';
52*a6021da3SAndroid Build Coastguard Worker }
53*a6021da3SAndroid Build Coastguard Worker
54*a6021da3SAndroid Build Coastguard Worker
TEST(FastDtoaShortestVariousDoubles)55*a6021da3SAndroid Build Coastguard Worker TEST(FastDtoaShortestVariousDoubles) {
56*a6021da3SAndroid Build Coastguard Worker char buffer_container[kBufferSize];
57*a6021da3SAndroid Build Coastguard Worker Vector<char> buffer(buffer_container, kBufferSize);
58*a6021da3SAndroid Build Coastguard Worker int length;
59*a6021da3SAndroid Build Coastguard Worker int point;
60*a6021da3SAndroid Build Coastguard Worker bool status;
61*a6021da3SAndroid Build Coastguard Worker
62*a6021da3SAndroid Build Coastguard Worker double min_double = 5e-324;
63*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(min_double, FAST_DTOA_SHORTEST, 0,
64*a6021da3SAndroid Build Coastguard Worker buffer, &length, &point);
65*a6021da3SAndroid Build Coastguard Worker CHECK(status);
66*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("5", buffer.start());
67*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(-323, point);
68*a6021da3SAndroid Build Coastguard Worker
69*a6021da3SAndroid Build Coastguard Worker double max_double = 1.7976931348623157e308;
70*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(max_double, FAST_DTOA_SHORTEST, 0,
71*a6021da3SAndroid Build Coastguard Worker buffer, &length, &point);
72*a6021da3SAndroid Build Coastguard Worker CHECK(status);
73*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("17976931348623157", buffer.start());
74*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(309, point);
75*a6021da3SAndroid Build Coastguard Worker
76*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(4294967272.0, FAST_DTOA_SHORTEST, 0,
77*a6021da3SAndroid Build Coastguard Worker buffer, &length, &point);
78*a6021da3SAndroid Build Coastguard Worker CHECK(status);
79*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("4294967272", buffer.start());
80*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(10, point);
81*a6021da3SAndroid Build Coastguard Worker
82*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(4.1855804968213567e298, FAST_DTOA_SHORTEST, 0,
83*a6021da3SAndroid Build Coastguard Worker buffer, &length, &point);
84*a6021da3SAndroid Build Coastguard Worker CHECK(status);
85*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("4185580496821357", buffer.start());
86*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(299, point);
87*a6021da3SAndroid Build Coastguard Worker
88*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(5.5626846462680035e-309, FAST_DTOA_SHORTEST, 0,
89*a6021da3SAndroid Build Coastguard Worker buffer, &length, &point);
90*a6021da3SAndroid Build Coastguard Worker CHECK(status);
91*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("5562684646268003", buffer.start());
92*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(-308, point);
93*a6021da3SAndroid Build Coastguard Worker
94*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(2147483648.0, FAST_DTOA_SHORTEST, 0,
95*a6021da3SAndroid Build Coastguard Worker buffer, &length, &point);
96*a6021da3SAndroid Build Coastguard Worker CHECK(status);
97*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("2147483648", buffer.start());
98*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(10, point);
99*a6021da3SAndroid Build Coastguard Worker
100*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(3.5844466002796428e+298, FAST_DTOA_SHORTEST, 0,
101*a6021da3SAndroid Build Coastguard Worker buffer, &length, &point);
102*a6021da3SAndroid Build Coastguard Worker if (status) { // Not all FastDtoa variants manage to compute this number.
103*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("35844466002796428", buffer.start());
104*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(299, point);
105*a6021da3SAndroid Build Coastguard Worker }
106*a6021da3SAndroid Build Coastguard Worker
107*a6021da3SAndroid Build Coastguard Worker uint64_t smallest_normal64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x00100000, 00000000);
108*a6021da3SAndroid Build Coastguard Worker double v = Double(smallest_normal64).value();
109*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(v, FAST_DTOA_SHORTEST, 0, buffer, &length, &point);
110*a6021da3SAndroid Build Coastguard Worker if (status) {
111*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("22250738585072014", buffer.start());
112*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(-307, point);
113*a6021da3SAndroid Build Coastguard Worker }
114*a6021da3SAndroid Build Coastguard Worker
115*a6021da3SAndroid Build Coastguard Worker uint64_t largest_denormal64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x000FFFFF, FFFFFFFF);
116*a6021da3SAndroid Build Coastguard Worker v = Double(largest_denormal64).value();
117*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(v, FAST_DTOA_SHORTEST, 0, buffer, &length, &point);
118*a6021da3SAndroid Build Coastguard Worker if (status) {
119*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("2225073858507201", buffer.start());
120*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(-307, point);
121*a6021da3SAndroid Build Coastguard Worker }
122*a6021da3SAndroid Build Coastguard Worker }
123*a6021da3SAndroid Build Coastguard Worker
124*a6021da3SAndroid Build Coastguard Worker
TEST(FastDtoaShortestVariousFloats)125*a6021da3SAndroid Build Coastguard Worker TEST(FastDtoaShortestVariousFloats) {
126*a6021da3SAndroid Build Coastguard Worker char buffer_container[kBufferSize];
127*a6021da3SAndroid Build Coastguard Worker Vector<char> buffer(buffer_container, kBufferSize);
128*a6021da3SAndroid Build Coastguard Worker int length;
129*a6021da3SAndroid Build Coastguard Worker int point;
130*a6021da3SAndroid Build Coastguard Worker bool status;
131*a6021da3SAndroid Build Coastguard Worker
132*a6021da3SAndroid Build Coastguard Worker float min_float = 1e-45f;
133*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(min_float, FAST_DTOA_SHORTEST_SINGLE, 0,
134*a6021da3SAndroid Build Coastguard Worker buffer, &length, &point);
135*a6021da3SAndroid Build Coastguard Worker CHECK(status);
136*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("1", buffer.start());
137*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(-44, point);
138*a6021da3SAndroid Build Coastguard Worker
139*a6021da3SAndroid Build Coastguard Worker
140*a6021da3SAndroid Build Coastguard Worker float max_float = 3.4028234e38f;
141*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(max_float, FAST_DTOA_SHORTEST_SINGLE, 0,
142*a6021da3SAndroid Build Coastguard Worker buffer, &length, &point);
143*a6021da3SAndroid Build Coastguard Worker CHECK(status);
144*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("34028235", buffer.start());
145*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(39, point);
146*a6021da3SAndroid Build Coastguard Worker
147*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(4294967272.0f, FAST_DTOA_SHORTEST_SINGLE, 0,
148*a6021da3SAndroid Build Coastguard Worker buffer, &length, &point);
149*a6021da3SAndroid Build Coastguard Worker CHECK(status);
150*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("42949673", buffer.start());
151*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(10, point);
152*a6021da3SAndroid Build Coastguard Worker
153*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(3.32306998946228968226e+35f, FAST_DTOA_SHORTEST_SINGLE, 0,
154*a6021da3SAndroid Build Coastguard Worker buffer, &length, &point);
155*a6021da3SAndroid Build Coastguard Worker CHECK(status);
156*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("332307", buffer.start());
157*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(36, point);
158*a6021da3SAndroid Build Coastguard Worker
159*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(1.2341e-41f, FAST_DTOA_SHORTEST_SINGLE, 0,
160*a6021da3SAndroid Build Coastguard Worker buffer, &length, &point);
161*a6021da3SAndroid Build Coastguard Worker CHECK(status);
162*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("12341", buffer.start());
163*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(-40, point);
164*a6021da3SAndroid Build Coastguard Worker
165*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(3.3554432e7, FAST_DTOA_SHORTEST_SINGLE, 0,
166*a6021da3SAndroid Build Coastguard Worker buffer, &length, &point);
167*a6021da3SAndroid Build Coastguard Worker CHECK(status);
168*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("33554432", buffer.start());
169*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(8, point);
170*a6021da3SAndroid Build Coastguard Worker
171*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(3.26494756798464e14f, FAST_DTOA_SHORTEST_SINGLE, 0,
172*a6021da3SAndroid Build Coastguard Worker buffer, &length, &point);
173*a6021da3SAndroid Build Coastguard Worker CHECK(status);
174*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("32649476", buffer.start());
175*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(15, point);
176*a6021da3SAndroid Build Coastguard Worker
177*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(3.91132223637771935344e37f, FAST_DTOA_SHORTEST_SINGLE, 0,
178*a6021da3SAndroid Build Coastguard Worker buffer, &length, &point);
179*a6021da3SAndroid Build Coastguard Worker if (status) { // Not all FastDtoa variants manage to compute this number.
180*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("39113222", buffer.start());
181*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(38, point);
182*a6021da3SAndroid Build Coastguard Worker }
183*a6021da3SAndroid Build Coastguard Worker
184*a6021da3SAndroid Build Coastguard Worker uint32_t smallest_normal32 = 0x00800000;
185*a6021da3SAndroid Build Coastguard Worker float v = Single(smallest_normal32).value();
186*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(v, FAST_DTOA_SHORTEST_SINGLE, 0, buffer, &length, &point);
187*a6021da3SAndroid Build Coastguard Worker if (status) {
188*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("11754944", buffer.start());
189*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(-37, point);
190*a6021da3SAndroid Build Coastguard Worker }
191*a6021da3SAndroid Build Coastguard Worker
192*a6021da3SAndroid Build Coastguard Worker uint32_t largest_denormal32 = 0x007FFFFF;
193*a6021da3SAndroid Build Coastguard Worker v = Single(largest_denormal32).value();
194*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(v, FAST_DTOA_SHORTEST_SINGLE, 0, buffer, &length, &point);
195*a6021da3SAndroid Build Coastguard Worker CHECK(status);
196*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("11754942", buffer.start());
197*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(-37, point);
198*a6021da3SAndroid Build Coastguard Worker }
199*a6021da3SAndroid Build Coastguard Worker
200*a6021da3SAndroid Build Coastguard Worker
TEST(FastDtoaPrecisionVariousDoubles)201*a6021da3SAndroid Build Coastguard Worker TEST(FastDtoaPrecisionVariousDoubles) {
202*a6021da3SAndroid Build Coastguard Worker char buffer_container[kBufferSize];
203*a6021da3SAndroid Build Coastguard Worker Vector<char> buffer(buffer_container, kBufferSize);
204*a6021da3SAndroid Build Coastguard Worker int length;
205*a6021da3SAndroid Build Coastguard Worker int point;
206*a6021da3SAndroid Build Coastguard Worker bool status;
207*a6021da3SAndroid Build Coastguard Worker
208*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(1.0, FAST_DTOA_PRECISION, 3, buffer, &length, &point);
209*a6021da3SAndroid Build Coastguard Worker CHECK(status);
210*a6021da3SAndroid Build Coastguard Worker CHECK(3 >= length);
211*a6021da3SAndroid Build Coastguard Worker TrimRepresentation(buffer);
212*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("1", buffer.start());
213*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(1, point);
214*a6021da3SAndroid Build Coastguard Worker
215*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(1.5, FAST_DTOA_PRECISION, 10, buffer, &length, &point);
216*a6021da3SAndroid Build Coastguard Worker if (status) {
217*a6021da3SAndroid Build Coastguard Worker CHECK(10 >= length);
218*a6021da3SAndroid Build Coastguard Worker TrimRepresentation(buffer);
219*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("15", buffer.start());
220*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(1, point);
221*a6021da3SAndroid Build Coastguard Worker }
222*a6021da3SAndroid Build Coastguard Worker
223*a6021da3SAndroid Build Coastguard Worker double min_double = 5e-324;
224*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(min_double, FAST_DTOA_PRECISION, 5,
225*a6021da3SAndroid Build Coastguard Worker buffer, &length, &point);
226*a6021da3SAndroid Build Coastguard Worker CHECK(status);
227*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("49407", buffer.start());
228*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(-323, point);
229*a6021da3SAndroid Build Coastguard Worker
230*a6021da3SAndroid Build Coastguard Worker double max_double = 1.7976931348623157e308;
231*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(max_double, FAST_DTOA_PRECISION, 7,
232*a6021da3SAndroid Build Coastguard Worker buffer, &length, &point);
233*a6021da3SAndroid Build Coastguard Worker CHECK(status);
234*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("1797693", buffer.start());
235*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(309, point);
236*a6021da3SAndroid Build Coastguard Worker
237*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(4294967272.0, FAST_DTOA_PRECISION, 14,
238*a6021da3SAndroid Build Coastguard Worker buffer, &length, &point);
239*a6021da3SAndroid Build Coastguard Worker if (status) {
240*a6021da3SAndroid Build Coastguard Worker CHECK(14 >= length);
241*a6021da3SAndroid Build Coastguard Worker TrimRepresentation(buffer);
242*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("4294967272", buffer.start());
243*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(10, point);
244*a6021da3SAndroid Build Coastguard Worker }
245*a6021da3SAndroid Build Coastguard Worker
246*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(4.1855804968213567e298, FAST_DTOA_PRECISION, 17,
247*a6021da3SAndroid Build Coastguard Worker buffer, &length, &point);
248*a6021da3SAndroid Build Coastguard Worker CHECK(status);
249*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("41855804968213567", buffer.start());
250*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(299, point);
251*a6021da3SAndroid Build Coastguard Worker
252*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(5.5626846462680035e-309, FAST_DTOA_PRECISION, 1,
253*a6021da3SAndroid Build Coastguard Worker buffer, &length, &point);
254*a6021da3SAndroid Build Coastguard Worker CHECK(status);
255*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("6", buffer.start());
256*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(-308, point);
257*a6021da3SAndroid Build Coastguard Worker
258*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(2147483648.0, FAST_DTOA_PRECISION, 5,
259*a6021da3SAndroid Build Coastguard Worker buffer, &length, &point);
260*a6021da3SAndroid Build Coastguard Worker CHECK(status);
261*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("21475", buffer.start());
262*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(10, point);
263*a6021da3SAndroid Build Coastguard Worker
264*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(3.5844466002796428e+298, FAST_DTOA_PRECISION, 10,
265*a6021da3SAndroid Build Coastguard Worker buffer, &length, &point);
266*a6021da3SAndroid Build Coastguard Worker CHECK(status);
267*a6021da3SAndroid Build Coastguard Worker CHECK(10 >= length);
268*a6021da3SAndroid Build Coastguard Worker TrimRepresentation(buffer);
269*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("35844466", buffer.start());
270*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(299, point);
271*a6021da3SAndroid Build Coastguard Worker
272*a6021da3SAndroid Build Coastguard Worker uint64_t smallest_normal64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x00100000, 00000000);
273*a6021da3SAndroid Build Coastguard Worker double v = Double(smallest_normal64).value();
274*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(v, FAST_DTOA_PRECISION, 17, buffer, &length, &point);
275*a6021da3SAndroid Build Coastguard Worker CHECK(status);
276*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("22250738585072014", buffer.start());
277*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(-307, point);
278*a6021da3SAndroid Build Coastguard Worker
279*a6021da3SAndroid Build Coastguard Worker uint64_t largest_denormal64 = DOUBLE_CONVERSION_UINT64_2PART_C(0x000FFFFF, FFFFFFFF);
280*a6021da3SAndroid Build Coastguard Worker v = Double(largest_denormal64).value();
281*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(v, FAST_DTOA_PRECISION, 17, buffer, &length, &point);
282*a6021da3SAndroid Build Coastguard Worker CHECK(status);
283*a6021da3SAndroid Build Coastguard Worker CHECK(20 >= length);
284*a6021da3SAndroid Build Coastguard Worker TrimRepresentation(buffer);
285*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("22250738585072009", buffer.start());
286*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(-307, point);
287*a6021da3SAndroid Build Coastguard Worker
288*a6021da3SAndroid Build Coastguard Worker v = 3.3161339052167390562200598e-237;
289*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(v, FAST_DTOA_PRECISION, 18, buffer, &length, &point);
290*a6021da3SAndroid Build Coastguard Worker CHECK(status);
291*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("331613390521673906", buffer.start());
292*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(-236, point);
293*a6021da3SAndroid Build Coastguard Worker
294*a6021da3SAndroid Build Coastguard Worker v = 7.9885183916008099497815232e+191;
295*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(v, FAST_DTOA_PRECISION, 4, buffer, &length, &point);
296*a6021da3SAndroid Build Coastguard Worker CHECK(status);
297*a6021da3SAndroid Build Coastguard Worker CHECK_EQ("7989", buffer.start());
298*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(192, point);
299*a6021da3SAndroid Build Coastguard Worker }
300*a6021da3SAndroid Build Coastguard Worker
301*a6021da3SAndroid Build Coastguard Worker
TEST(FastDtoaGayShortest)302*a6021da3SAndroid Build Coastguard Worker TEST(FastDtoaGayShortest) {
303*a6021da3SAndroid Build Coastguard Worker char buffer_container[kBufferSize];
304*a6021da3SAndroid Build Coastguard Worker Vector<char> buffer(buffer_container, kBufferSize);
305*a6021da3SAndroid Build Coastguard Worker bool status;
306*a6021da3SAndroid Build Coastguard Worker int length;
307*a6021da3SAndroid Build Coastguard Worker int point;
308*a6021da3SAndroid Build Coastguard Worker int succeeded = 0;
309*a6021da3SAndroid Build Coastguard Worker int total = 0;
310*a6021da3SAndroid Build Coastguard Worker bool needed_max_length = false;
311*a6021da3SAndroid Build Coastguard Worker
312*a6021da3SAndroid Build Coastguard Worker Vector<const PrecomputedShortest> precomputed =
313*a6021da3SAndroid Build Coastguard Worker PrecomputedShortestRepresentations();
314*a6021da3SAndroid Build Coastguard Worker for (int i = 0; i < precomputed.length(); ++i) {
315*a6021da3SAndroid Build Coastguard Worker const PrecomputedShortest current_test = precomputed[i];
316*a6021da3SAndroid Build Coastguard Worker total++;
317*a6021da3SAndroid Build Coastguard Worker double v = current_test.v;
318*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(v, FAST_DTOA_SHORTEST, 0, buffer, &length, &point);
319*a6021da3SAndroid Build Coastguard Worker CHECK(kFastDtoaMaximalLength >= length);
320*a6021da3SAndroid Build Coastguard Worker if (!status) continue;
321*a6021da3SAndroid Build Coastguard Worker if (length == kFastDtoaMaximalLength) needed_max_length = true;
322*a6021da3SAndroid Build Coastguard Worker succeeded++;
323*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(current_test.decimal_point, point);
324*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(current_test.representation, buffer.start());
325*a6021da3SAndroid Build Coastguard Worker }
326*a6021da3SAndroid Build Coastguard Worker CHECK(succeeded*1.0/total > 0.99);
327*a6021da3SAndroid Build Coastguard Worker CHECK(needed_max_length);
328*a6021da3SAndroid Build Coastguard Worker }
329*a6021da3SAndroid Build Coastguard Worker
330*a6021da3SAndroid Build Coastguard Worker
TEST(FastDtoaGayShortestSingle)331*a6021da3SAndroid Build Coastguard Worker TEST(FastDtoaGayShortestSingle) {
332*a6021da3SAndroid Build Coastguard Worker char buffer_container[kBufferSize];
333*a6021da3SAndroid Build Coastguard Worker Vector<char> buffer(buffer_container, kBufferSize);
334*a6021da3SAndroid Build Coastguard Worker bool status;
335*a6021da3SAndroid Build Coastguard Worker int length;
336*a6021da3SAndroid Build Coastguard Worker int point;
337*a6021da3SAndroid Build Coastguard Worker int succeeded = 0;
338*a6021da3SAndroid Build Coastguard Worker int total = 0;
339*a6021da3SAndroid Build Coastguard Worker bool needed_max_length = false;
340*a6021da3SAndroid Build Coastguard Worker
341*a6021da3SAndroid Build Coastguard Worker Vector<const PrecomputedShortestSingle> precomputed =
342*a6021da3SAndroid Build Coastguard Worker PrecomputedShortestSingleRepresentations();
343*a6021da3SAndroid Build Coastguard Worker for (int i = 0; i < precomputed.length(); ++i) {
344*a6021da3SAndroid Build Coastguard Worker const PrecomputedShortestSingle current_test = precomputed[i];
345*a6021da3SAndroid Build Coastguard Worker total++;
346*a6021da3SAndroid Build Coastguard Worker float v = current_test.v;
347*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(v, FAST_DTOA_SHORTEST_SINGLE, 0, buffer, &length, &point);
348*a6021da3SAndroid Build Coastguard Worker CHECK(kFastDtoaMaximalSingleLength >= length);
349*a6021da3SAndroid Build Coastguard Worker if (!status) continue;
350*a6021da3SAndroid Build Coastguard Worker if (length == kFastDtoaMaximalSingleLength) needed_max_length = true;
351*a6021da3SAndroid Build Coastguard Worker succeeded++;
352*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(current_test.decimal_point, point);
353*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(current_test.representation, buffer.start());
354*a6021da3SAndroid Build Coastguard Worker }
355*a6021da3SAndroid Build Coastguard Worker CHECK(succeeded*1.0/total > 0.98);
356*a6021da3SAndroid Build Coastguard Worker CHECK(needed_max_length);
357*a6021da3SAndroid Build Coastguard Worker }
358*a6021da3SAndroid Build Coastguard Worker
359*a6021da3SAndroid Build Coastguard Worker
TEST(FastDtoaGayPrecision)360*a6021da3SAndroid Build Coastguard Worker TEST(FastDtoaGayPrecision) {
361*a6021da3SAndroid Build Coastguard Worker char buffer_container[kBufferSize];
362*a6021da3SAndroid Build Coastguard Worker Vector<char> buffer(buffer_container, kBufferSize);
363*a6021da3SAndroid Build Coastguard Worker bool status;
364*a6021da3SAndroid Build Coastguard Worker int length;
365*a6021da3SAndroid Build Coastguard Worker int point;
366*a6021da3SAndroid Build Coastguard Worker int succeeded = 0;
367*a6021da3SAndroid Build Coastguard Worker int total = 0;
368*a6021da3SAndroid Build Coastguard Worker // Count separately for entries with less than 15 requested digits.
369*a6021da3SAndroid Build Coastguard Worker int succeeded_15 = 0;
370*a6021da3SAndroid Build Coastguard Worker int total_15 = 0;
371*a6021da3SAndroid Build Coastguard Worker
372*a6021da3SAndroid Build Coastguard Worker Vector<const PrecomputedPrecision> precomputed =
373*a6021da3SAndroid Build Coastguard Worker PrecomputedPrecisionRepresentations();
374*a6021da3SAndroid Build Coastguard Worker for (int i = 0; i < precomputed.length(); ++i) {
375*a6021da3SAndroid Build Coastguard Worker const PrecomputedPrecision current_test = precomputed[i];
376*a6021da3SAndroid Build Coastguard Worker double v = current_test.v;
377*a6021da3SAndroid Build Coastguard Worker int number_digits = current_test.number_digits;
378*a6021da3SAndroid Build Coastguard Worker total++;
379*a6021da3SAndroid Build Coastguard Worker if (number_digits <= 15) total_15++;
380*a6021da3SAndroid Build Coastguard Worker status = FastDtoa(v, FAST_DTOA_PRECISION, number_digits,
381*a6021da3SAndroid Build Coastguard Worker buffer, &length, &point);
382*a6021da3SAndroid Build Coastguard Worker CHECK(number_digits >= length);
383*a6021da3SAndroid Build Coastguard Worker if (!status) continue;
384*a6021da3SAndroid Build Coastguard Worker succeeded++;
385*a6021da3SAndroid Build Coastguard Worker if (number_digits <= 15) succeeded_15++;
386*a6021da3SAndroid Build Coastguard Worker TrimRepresentation(buffer);
387*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(current_test.decimal_point, point);
388*a6021da3SAndroid Build Coastguard Worker CHECK_EQ(current_test.representation, buffer.start());
389*a6021da3SAndroid Build Coastguard Worker }
390*a6021da3SAndroid Build Coastguard Worker // The precomputed numbers contain many entries with many requested
391*a6021da3SAndroid Build Coastguard Worker // digits. These have a high failure rate and we therefore expect a lower
392*a6021da3SAndroid Build Coastguard Worker // success rate than for the shortest representation.
393*a6021da3SAndroid Build Coastguard Worker CHECK(succeeded*1.0/total > 0.85);
394*a6021da3SAndroid Build Coastguard Worker // However with less than 15 digits almost the algorithm should almost always
395*a6021da3SAndroid Build Coastguard Worker // succeed.
396*a6021da3SAndroid Build Coastguard Worker CHECK(succeeded_15*1.0/total_15 > 0.9999);
397*a6021da3SAndroid Build Coastguard Worker }
398