xref: /aosp_15_r20/external/abseil-cpp/absl/strings/charconv_test.cc (revision 9356374a3709195abf420251b3e825997ff56c0f)
1*9356374aSAndroid Build Coastguard Worker // Copyright 2018 The Abseil Authors.
2*9356374aSAndroid Build Coastguard Worker //
3*9356374aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*9356374aSAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*9356374aSAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*9356374aSAndroid Build Coastguard Worker //
7*9356374aSAndroid Build Coastguard Worker //      https://www.apache.org/licenses/LICENSE-2.0
8*9356374aSAndroid Build Coastguard Worker //
9*9356374aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*9356374aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*9356374aSAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*9356374aSAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*9356374aSAndroid Build Coastguard Worker // limitations under the License.
14*9356374aSAndroid Build Coastguard Worker 
15*9356374aSAndroid Build Coastguard Worker #include "absl/strings/charconv.h"
16*9356374aSAndroid Build Coastguard Worker 
17*9356374aSAndroid Build Coastguard Worker #include <cfloat>
18*9356374aSAndroid Build Coastguard Worker #include <cmath>
19*9356374aSAndroid Build Coastguard Worker #include <cstdlib>
20*9356374aSAndroid Build Coastguard Worker #include <functional>
21*9356374aSAndroid Build Coastguard Worker #include <limits>
22*9356374aSAndroid Build Coastguard Worker #include <string>
23*9356374aSAndroid Build Coastguard Worker #include <system_error>  // NOLINT(build/c++11)
24*9356374aSAndroid Build Coastguard Worker 
25*9356374aSAndroid Build Coastguard Worker #include "gtest/gtest.h"
26*9356374aSAndroid Build Coastguard Worker #include "absl/strings/internal/pow10_helper.h"
27*9356374aSAndroid Build Coastguard Worker #include "absl/strings/str_cat.h"
28*9356374aSAndroid Build Coastguard Worker #include "absl/strings/str_format.h"
29*9356374aSAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
30*9356374aSAndroid Build Coastguard Worker 
31*9356374aSAndroid Build Coastguard Worker #ifdef _MSC_FULL_VER
32*9356374aSAndroid Build Coastguard Worker #define ABSL_COMPILER_DOES_EXACT_ROUNDING 0
33*9356374aSAndroid Build Coastguard Worker #define ABSL_STRTOD_HANDLES_NAN_CORRECTLY 0
34*9356374aSAndroid Build Coastguard Worker #else
35*9356374aSAndroid Build Coastguard Worker #define ABSL_COMPILER_DOES_EXACT_ROUNDING 1
36*9356374aSAndroid Build Coastguard Worker #define ABSL_STRTOD_HANDLES_NAN_CORRECTLY 1
37*9356374aSAndroid Build Coastguard Worker #endif
38*9356374aSAndroid Build Coastguard Worker 
39*9356374aSAndroid Build Coastguard Worker namespace {
40*9356374aSAndroid Build Coastguard Worker 
41*9356374aSAndroid Build Coastguard Worker using absl::strings_internal::Pow10;
42*9356374aSAndroid Build Coastguard Worker 
43*9356374aSAndroid Build Coastguard Worker #if ABSL_COMPILER_DOES_EXACT_ROUNDING
44*9356374aSAndroid Build Coastguard Worker 
45*9356374aSAndroid Build Coastguard Worker // Tests that the given string is accepted by absl::from_chars, and that it
46*9356374aSAndroid Build Coastguard Worker // converts exactly equal to the given number.
TestDoubleParse(absl::string_view str,double expected_number)47*9356374aSAndroid Build Coastguard Worker void TestDoubleParse(absl::string_view str, double expected_number) {
48*9356374aSAndroid Build Coastguard Worker   SCOPED_TRACE(str);
49*9356374aSAndroid Build Coastguard Worker   double actual_number = 0.0;
50*9356374aSAndroid Build Coastguard Worker   absl::from_chars_result result =
51*9356374aSAndroid Build Coastguard Worker       absl::from_chars(str.data(), str.data() + str.length(), actual_number);
52*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.ec, std::errc());
53*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.ptr, str.data() + str.length());
54*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(actual_number, expected_number);
55*9356374aSAndroid Build Coastguard Worker }
56*9356374aSAndroid Build Coastguard Worker 
TestFloatParse(absl::string_view str,float expected_number)57*9356374aSAndroid Build Coastguard Worker void TestFloatParse(absl::string_view str, float expected_number) {
58*9356374aSAndroid Build Coastguard Worker   SCOPED_TRACE(str);
59*9356374aSAndroid Build Coastguard Worker   float actual_number = 0.0;
60*9356374aSAndroid Build Coastguard Worker   absl::from_chars_result result =
61*9356374aSAndroid Build Coastguard Worker       absl::from_chars(str.data(), str.data() + str.length(), actual_number);
62*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.ec, std::errc());
63*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.ptr, str.data() + str.length());
64*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(actual_number, expected_number);
65*9356374aSAndroid Build Coastguard Worker }
66*9356374aSAndroid Build Coastguard Worker 
67*9356374aSAndroid Build Coastguard Worker // Tests that the given double or single precision floating point literal is
68*9356374aSAndroid Build Coastguard Worker // parsed correctly by absl::from_chars.
69*9356374aSAndroid Build Coastguard Worker //
70*9356374aSAndroid Build Coastguard Worker // These convenience macros assume that the C++ compiler being used also does
71*9356374aSAndroid Build Coastguard Worker // fully correct decimal-to-binary conversions.
72*9356374aSAndroid Build Coastguard Worker #define FROM_CHARS_TEST_DOUBLE(number)     \
73*9356374aSAndroid Build Coastguard Worker   {                                        \
74*9356374aSAndroid Build Coastguard Worker     TestDoubleParse(#number, number);      \
75*9356374aSAndroid Build Coastguard Worker     TestDoubleParse("-" #number, -number); \
76*9356374aSAndroid Build Coastguard Worker   }
77*9356374aSAndroid Build Coastguard Worker 
78*9356374aSAndroid Build Coastguard Worker #define FROM_CHARS_TEST_FLOAT(number)        \
79*9356374aSAndroid Build Coastguard Worker   {                                          \
80*9356374aSAndroid Build Coastguard Worker     TestFloatParse(#number, number##f);      \
81*9356374aSAndroid Build Coastguard Worker     TestFloatParse("-" #number, -number##f); \
82*9356374aSAndroid Build Coastguard Worker   }
83*9356374aSAndroid Build Coastguard Worker 
TEST(FromChars,NearRoundingCases)84*9356374aSAndroid Build Coastguard Worker TEST(FromChars, NearRoundingCases) {
85*9356374aSAndroid Build Coastguard Worker   // Cases from "A Program for Testing IEEE Decimal-Binary Conversion"
86*9356374aSAndroid Build Coastguard Worker   // by Vern Paxson.
87*9356374aSAndroid Build Coastguard Worker 
88*9356374aSAndroid Build Coastguard Worker   // Forms that should round towards zero.  (These are the hardest cases for
89*9356374aSAndroid Build Coastguard Worker   // each decimal mantissa size.)
90*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(5.e125);
91*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(69.e267);
92*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(999.e-026);
93*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(7861.e-034);
94*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(75569.e-254);
95*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(928609.e-261);
96*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(9210917.e080);
97*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(84863171.e114);
98*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(653777767.e273);
99*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(5232604057.e-298);
100*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(27235667517.e-109);
101*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(653532977297.e-123);
102*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(3142213164987.e-294);
103*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(46202199371337.e-072);
104*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(231010996856685.e-073);
105*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(9324754620109615.e212);
106*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(78459735791271921.e049);
107*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(272104041512242479.e200);
108*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(6802601037806061975.e198);
109*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(20505426358836677347.e-221);
110*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(836168422905420598437.e-234);
111*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(4891559871276714924261.e222);
112*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_FLOAT(5.e-20);
113*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_FLOAT(67.e14);
114*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_FLOAT(985.e15);
115*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_FLOAT(7693.e-42);
116*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_FLOAT(55895.e-16);
117*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_FLOAT(996622.e-44);
118*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_FLOAT(7038531.e-32);
119*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_FLOAT(60419369.e-46);
120*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_FLOAT(702990899.e-20);
121*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_FLOAT(6930161142.e-48);
122*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_FLOAT(25933168707.e-13);
123*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_FLOAT(596428896559.e20);
124*9356374aSAndroid Build Coastguard Worker 
125*9356374aSAndroid Build Coastguard Worker   // Similarly, forms that should round away from zero.
126*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(9.e-265);
127*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(85.e-037);
128*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(623.e100);
129*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(3571.e263);
130*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(81661.e153);
131*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(920657.e-023);
132*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(4603285.e-024);
133*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(87575437.e-309);
134*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(245540327.e122);
135*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(6138508175.e120);
136*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(83356057653.e193);
137*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(619534293513.e124);
138*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(2335141086879.e218);
139*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(36167929443327.e-159);
140*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(609610927149051.e-255);
141*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(3743626360493413.e-165);
142*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(94080055902682397.e-242);
143*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(899810892172646163.e283);
144*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(7120190517612959703.e120);
145*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(25188282901709339043.e-252);
146*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(308984926168550152811.e-052);
147*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_DOUBLE(6372891218502368041059.e064);
148*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_FLOAT(3.e-23);
149*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_FLOAT(57.e18);
150*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_FLOAT(789.e-35);
151*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_FLOAT(2539.e-18);
152*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_FLOAT(76173.e28);
153*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_FLOAT(887745.e-11);
154*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_FLOAT(5382571.e-37);
155*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_FLOAT(82381273.e-35);
156*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_FLOAT(750486563.e-38);
157*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_FLOAT(3752432815.e-39);
158*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_FLOAT(75224575729.e-45);
159*9356374aSAndroid Build Coastguard Worker   FROM_CHARS_TEST_FLOAT(459926601011.e15);
160*9356374aSAndroid Build Coastguard Worker }
161*9356374aSAndroid Build Coastguard Worker 
162*9356374aSAndroid Build Coastguard Worker #undef FROM_CHARS_TEST_DOUBLE
163*9356374aSAndroid Build Coastguard Worker #undef FROM_CHARS_TEST_FLOAT
164*9356374aSAndroid Build Coastguard Worker #endif
165*9356374aSAndroid Build Coastguard Worker 
ToFloat(absl::string_view s)166*9356374aSAndroid Build Coastguard Worker float ToFloat(absl::string_view s) {
167*9356374aSAndroid Build Coastguard Worker   float f;
168*9356374aSAndroid Build Coastguard Worker   absl::from_chars(s.data(), s.data() + s.size(), f);
169*9356374aSAndroid Build Coastguard Worker   return f;
170*9356374aSAndroid Build Coastguard Worker }
171*9356374aSAndroid Build Coastguard Worker 
ToDouble(absl::string_view s)172*9356374aSAndroid Build Coastguard Worker double ToDouble(absl::string_view s) {
173*9356374aSAndroid Build Coastguard Worker   double d;
174*9356374aSAndroid Build Coastguard Worker   absl::from_chars(s.data(), s.data() + s.size(), d);
175*9356374aSAndroid Build Coastguard Worker   return d;
176*9356374aSAndroid Build Coastguard Worker }
177*9356374aSAndroid Build Coastguard Worker 
178*9356374aSAndroid Build Coastguard Worker // A duplication of the test cases in "NearRoundingCases" above, but with
179*9356374aSAndroid Build Coastguard Worker // expected values expressed with integers, using ldexp/ldexpf.  These test
180*9356374aSAndroid Build Coastguard Worker // cases will work even on compilers that do not accurately round floating point
181*9356374aSAndroid Build Coastguard Worker // literals.
TEST(FromChars,NearRoundingCasesExplicit)182*9356374aSAndroid Build Coastguard Worker TEST(FromChars, NearRoundingCasesExplicit) {
183*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("5.e125"), ldexp(6653062250012735, 365));
184*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("69.e267"), ldexp(4705683757438170, 841));
185*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("999.e-026"), ldexp(6798841691080350, -129));
186*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("7861.e-034"), ldexp(8975675289889240, -153));
187*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("75569.e-254"), ldexp(6091718967192243, -880));
188*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("928609.e-261"), ldexp(7849264900213743, -900));
189*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("9210917.e080"), ldexp(8341110837370930, 236));
190*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("84863171.e114"), ldexp(4625202867375927, 353));
191*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("653777767.e273"), ldexp(5068902999763073, 884));
192*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("5232604057.e-298"), ldexp(5741343011915040, -1010));
193*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("27235667517.e-109"), ldexp(6707124626673586, -380));
194*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("653532977297.e-123"), ldexp(7078246407265384, -422));
195*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("3142213164987.e-294"), ldexp(8219991337640559, -988));
196*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("46202199371337.e-072"), ldexp(5224462102115359, -246));
197*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("231010996856685.e-073"), ldexp(5224462102115359, -247));
198*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("9324754620109615.e212"), ldexp(5539753864394442, 705));
199*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("78459735791271921.e049"), ldexp(8388176519442766, 166));
200*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("272104041512242479.e200"), ldexp(5554409530847367, 670));
201*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("6802601037806061975.e198"), ldexp(5554409530847367, 668));
202*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("20505426358836677347.e-221"),
203*9356374aSAndroid Build Coastguard Worker             ldexp(4524032052079546, -722));
204*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("836168422905420598437.e-234"),
205*9356374aSAndroid Build Coastguard Worker             ldexp(5070963299887562, -760));
206*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("4891559871276714924261.e222"),
207*9356374aSAndroid Build Coastguard Worker             ldexp(6452687840519111, 757));
208*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToFloat("5.e-20"), ldexpf(15474250, -88));
209*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToFloat("67.e14"), ldexpf(12479722, 29));
210*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToFloat("985.e15"), ldexpf(14333636, 36));
211*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToFloat("7693.e-42"), ldexpf(10979816, -150));
212*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToFloat("55895.e-16"), ldexpf(12888509, -61));
213*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToFloat("996622.e-44"), ldexpf(14224264, -150));
214*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToFloat("7038531.e-32"), ldexpf(11420669, -107));
215*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToFloat("60419369.e-46"), ldexpf(8623340, -150));
216*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToFloat("702990899.e-20"), ldexpf(16209866, -61));
217*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToFloat("6930161142.e-48"), ldexpf(9891056, -150));
218*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToFloat("25933168707.e-13"), ldexpf(11138211, -32));
219*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToFloat("596428896559.e20"), ldexpf(12333860, 82));
220*9356374aSAndroid Build Coastguard Worker 
221*9356374aSAndroid Build Coastguard Worker 
222*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("9.e-265"), ldexp(8168427841980010, -930));
223*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("85.e-037"), ldexp(6360455125664090, -169));
224*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("623.e100"), ldexp(6263531988747231, 289));
225*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("3571.e263"), ldexp(6234526311072170, 833));
226*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("81661.e153"), ldexp(6696636728760206, 472));
227*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("920657.e-023"), ldexp(5975405561110124, -109));
228*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("4603285.e-024"), ldexp(5975405561110124, -110));
229*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("87575437.e-309"), ldexp(8452160731874668, -1053));
230*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("245540327.e122"), ldexp(4985336549131723, 381));
231*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("6138508175.e120"), ldexp(4985336549131723, 379));
232*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("83356057653.e193"), ldexp(5986732817132056, 625));
233*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("619534293513.e124"), ldexp(4798406992060657, 399));
234*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("2335141086879.e218"), ldexp(5419088166961646, 713));
235*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("36167929443327.e-159"), ldexp(8135819834632444, -536));
236*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("609610927149051.e-255"), ldexp(4576664294594737, -850));
237*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("3743626360493413.e-165"), ldexp(6898586531774201, -549));
238*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("94080055902682397.e-242"), ldexp(6273271706052298, -800));
239*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("899810892172646163.e283"), ldexp(7563892574477827, 947));
240*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("7120190517612959703.e120"), ldexp(5385467232557565, 409));
241*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("25188282901709339043.e-252"),
242*9356374aSAndroid Build Coastguard Worker             ldexp(5635662608542340, -825));
243*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("308984926168550152811.e-052"),
244*9356374aSAndroid Build Coastguard Worker             ldexp(5644774693823803, -157));
245*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToDouble("6372891218502368041059.e064"),
246*9356374aSAndroid Build Coastguard Worker             ldexp(4616868614322430, 233));
247*9356374aSAndroid Build Coastguard Worker 
248*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToFloat("3.e-23"), ldexpf(9507380, -98));
249*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToFloat("57.e18"), ldexpf(12960300, 42));
250*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToFloat("789.e-35"), ldexpf(10739312, -130));
251*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToFloat("2539.e-18"), ldexpf(11990089, -72));
252*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToFloat("76173.e28"), ldexpf(9845130, 86));
253*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToFloat("887745.e-11"), ldexpf(9760860, -40));
254*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToFloat("5382571.e-37"), ldexpf(11447463, -124));
255*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToFloat("82381273.e-35"), ldexpf(8554961, -113));
256*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToFloat("750486563.e-38"), ldexpf(9975678, -120));
257*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToFloat("3752432815.e-39"), ldexpf(9975678, -121));
258*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToFloat("75224575729.e-45"), ldexpf(13105970, -137));
259*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(ToFloat("459926601011.e15"), ldexpf(12466336, 65));
260*9356374aSAndroid Build Coastguard Worker }
261*9356374aSAndroid Build Coastguard Worker 
262*9356374aSAndroid Build Coastguard Worker // Common test logic for converting a string which lies exactly halfway between
263*9356374aSAndroid Build Coastguard Worker // two target floats.
264*9356374aSAndroid Build Coastguard Worker //
265*9356374aSAndroid Build Coastguard Worker // mantissa and exponent represent the precise value between two floating point
266*9356374aSAndroid Build Coastguard Worker // numbers, `expected_low` and `expected_high`.  The floating point
267*9356374aSAndroid Build Coastguard Worker // representation to parse in `StrCat(mantissa, "e", exponent)`.
268*9356374aSAndroid Build Coastguard Worker //
269*9356374aSAndroid Build Coastguard Worker // This function checks that an input just slightly less than the exact value
270*9356374aSAndroid Build Coastguard Worker // is rounded down to `expected_low`, and an input just slightly greater than
271*9356374aSAndroid Build Coastguard Worker // the exact value is rounded up to `expected_high`.
272*9356374aSAndroid Build Coastguard Worker //
273*9356374aSAndroid Build Coastguard Worker // The exact value should round to `expected_half`, which must be either
274*9356374aSAndroid Build Coastguard Worker // `expected_low` or `expected_high`.
275*9356374aSAndroid Build Coastguard Worker template <typename FloatType>
TestHalfwayValue(const std::string & mantissa,int exponent,FloatType expected_low,FloatType expected_high,FloatType expected_half)276*9356374aSAndroid Build Coastguard Worker void TestHalfwayValue(const std::string& mantissa, int exponent,
277*9356374aSAndroid Build Coastguard Worker                       FloatType expected_low, FloatType expected_high,
278*9356374aSAndroid Build Coastguard Worker                       FloatType expected_half) {
279*9356374aSAndroid Build Coastguard Worker   std::string low_rep = mantissa;
280*9356374aSAndroid Build Coastguard Worker   low_rep[low_rep.size() - 1] -= 1;
281*9356374aSAndroid Build Coastguard Worker   absl::StrAppend(&low_rep, std::string(1000, '9'), "e", exponent);
282*9356374aSAndroid Build Coastguard Worker 
283*9356374aSAndroid Build Coastguard Worker   FloatType actual_low = 0;
284*9356374aSAndroid Build Coastguard Worker   absl::from_chars(low_rep.data(), low_rep.data() + low_rep.size(), actual_low);
285*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(expected_low, actual_low);
286*9356374aSAndroid Build Coastguard Worker 
287*9356374aSAndroid Build Coastguard Worker   std::string high_rep =
288*9356374aSAndroid Build Coastguard Worker       absl::StrCat(mantissa, std::string(1000, '0'), "1e", exponent);
289*9356374aSAndroid Build Coastguard Worker   FloatType actual_high = 0;
290*9356374aSAndroid Build Coastguard Worker   absl::from_chars(high_rep.data(), high_rep.data() + high_rep.size(),
291*9356374aSAndroid Build Coastguard Worker                    actual_high);
292*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(expected_high, actual_high);
293*9356374aSAndroid Build Coastguard Worker 
294*9356374aSAndroid Build Coastguard Worker   std::string halfway_rep = absl::StrCat(mantissa, "e", exponent);
295*9356374aSAndroid Build Coastguard Worker   FloatType actual_half = 0;
296*9356374aSAndroid Build Coastguard Worker   absl::from_chars(halfway_rep.data(), halfway_rep.data() + halfway_rep.size(),
297*9356374aSAndroid Build Coastguard Worker                    actual_half);
298*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(expected_half, actual_half);
299*9356374aSAndroid Build Coastguard Worker }
300*9356374aSAndroid Build Coastguard Worker 
TEST(FromChars,DoubleRounding)301*9356374aSAndroid Build Coastguard Worker TEST(FromChars, DoubleRounding) {
302*9356374aSAndroid Build Coastguard Worker   const double zero = 0.0;
303*9356374aSAndroid Build Coastguard Worker   const double first_subnormal = nextafter(zero, 1.0);
304*9356374aSAndroid Build Coastguard Worker   const double second_subnormal = nextafter(first_subnormal, 1.0);
305*9356374aSAndroid Build Coastguard Worker 
306*9356374aSAndroid Build Coastguard Worker   const double first_normal = DBL_MIN;
307*9356374aSAndroid Build Coastguard Worker   const double last_subnormal = nextafter(first_normal, 0.0);
308*9356374aSAndroid Build Coastguard Worker   const double second_normal = nextafter(first_normal, 1.0);
309*9356374aSAndroid Build Coastguard Worker 
310*9356374aSAndroid Build Coastguard Worker   const double last_normal = DBL_MAX;
311*9356374aSAndroid Build Coastguard Worker   const double penultimate_normal = nextafter(last_normal, 0.0);
312*9356374aSAndroid Build Coastguard Worker 
313*9356374aSAndroid Build Coastguard Worker   // Various test cases for numbers between two representable floats.  Each
314*9356374aSAndroid Build Coastguard Worker   // call to TestHalfwayValue tests a number just below and just above the
315*9356374aSAndroid Build Coastguard Worker   // halfway point, as well as the number exactly between them.
316*9356374aSAndroid Build Coastguard Worker 
317*9356374aSAndroid Build Coastguard Worker   // Test between zero and first_subnormal.  Round-to-even tie rounds down.
318*9356374aSAndroid Build Coastguard Worker   TestHalfwayValue(
319*9356374aSAndroid Build Coastguard Worker       "2."
320*9356374aSAndroid Build Coastguard Worker       "470328229206232720882843964341106861825299013071623822127928412503377536"
321*9356374aSAndroid Build Coastguard Worker       "351043759326499181808179961898982823477228588654633283551779698981993873"
322*9356374aSAndroid Build Coastguard Worker       "980053909390631503565951557022639229085839244910518443593180284993653615"
323*9356374aSAndroid Build Coastguard Worker       "250031937045767824921936562366986365848075700158576926990370631192827955"
324*9356374aSAndroid Build Coastguard Worker       "855133292783433840935197801553124659726357957462276646527282722005637400"
325*9356374aSAndroid Build Coastguard Worker       "648549997709659947045402082816622623785739345073633900796776193057750674"
326*9356374aSAndroid Build Coastguard Worker       "017632467360096895134053553745851666113422376667860416215968046191446729"
327*9356374aSAndroid Build Coastguard Worker       "184030053005753084904876539171138659164623952491262365388187963623937328"
328*9356374aSAndroid Build Coastguard Worker       "042389101867234849766823508986338858792562830275599565752445550725518931"
329*9356374aSAndroid Build Coastguard Worker       "369083625477918694866799496832404970582102851318545139621383772282614543"
330*9356374aSAndroid Build Coastguard Worker       "7693412532098591327667236328125",
331*9356374aSAndroid Build Coastguard Worker       -324, zero, first_subnormal, zero);
332*9356374aSAndroid Build Coastguard Worker 
333*9356374aSAndroid Build Coastguard Worker   // first_subnormal and second_subnormal.  Round-to-even tie rounds up.
334*9356374aSAndroid Build Coastguard Worker   TestHalfwayValue(
335*9356374aSAndroid Build Coastguard Worker       "7."
336*9356374aSAndroid Build Coastguard Worker       "410984687618698162648531893023320585475897039214871466383785237510132609"
337*9356374aSAndroid Build Coastguard Worker       "053131277979497545424539885696948470431685765963899850655339096945981621"
338*9356374aSAndroid Build Coastguard Worker       "940161728171894510697854671067917687257517734731555330779540854980960845"
339*9356374aSAndroid Build Coastguard Worker       "750095811137303474765809687100959097544227100475730780971111893578483867"
340*9356374aSAndroid Build Coastguard Worker       "565399878350301522805593404659373979179073872386829939581848166016912201"
341*9356374aSAndroid Build Coastguard Worker       "945649993128979841136206248449867871357218035220901702390328579173252022"
342*9356374aSAndroid Build Coastguard Worker       "052897402080290685402160661237554998340267130003581248647904138574340187"
343*9356374aSAndroid Build Coastguard Worker       "552090159017259254714629617513415977493871857473787096164563890871811984"
344*9356374aSAndroid Build Coastguard Worker       "127167305601704549300470526959016576377688490826798697257336652176556794"
345*9356374aSAndroid Build Coastguard Worker       "107250876433756084600398490497214911746308553955635418864151316847843631"
346*9356374aSAndroid Build Coastguard Worker       "3080237596295773983001708984375",
347*9356374aSAndroid Build Coastguard Worker       -324, first_subnormal, second_subnormal, second_subnormal);
348*9356374aSAndroid Build Coastguard Worker 
349*9356374aSAndroid Build Coastguard Worker   // last_subnormal and first_normal.  Round-to-even tie rounds up.
350*9356374aSAndroid Build Coastguard Worker   TestHalfwayValue(
351*9356374aSAndroid Build Coastguard Worker       "2."
352*9356374aSAndroid Build Coastguard Worker       "225073858507201136057409796709131975934819546351645648023426109724822222"
353*9356374aSAndroid Build Coastguard Worker       "021076945516529523908135087914149158913039621106870086438694594645527657"
354*9356374aSAndroid Build Coastguard Worker       "207407820621743379988141063267329253552286881372149012981122451451889849"
355*9356374aSAndroid Build Coastguard Worker       "057222307285255133155755015914397476397983411801999323962548289017107081"
356*9356374aSAndroid Build Coastguard Worker       "850690630666655994938275772572015763062690663332647565300009245888316433"
357*9356374aSAndroid Build Coastguard Worker       "037779791869612049497390377829704905051080609940730262937128958950003583"
358*9356374aSAndroid Build Coastguard Worker       "799967207254304360284078895771796150945516748243471030702609144621572289"
359*9356374aSAndroid Build Coastguard Worker       "880258182545180325707018860872113128079512233426288368622321503775666622"
360*9356374aSAndroid Build Coastguard Worker       "503982534335974568884423900265498198385487948292206894721689831099698365"
361*9356374aSAndroid Build Coastguard Worker       "846814022854243330660339850886445804001034933970427567186443383770486037"
362*9356374aSAndroid Build Coastguard Worker       "86162277173854562306587467901408672332763671875",
363*9356374aSAndroid Build Coastguard Worker       -308, last_subnormal, first_normal, first_normal);
364*9356374aSAndroid Build Coastguard Worker 
365*9356374aSAndroid Build Coastguard Worker   // first_normal and second_normal.  Round-to-even tie rounds down.
366*9356374aSAndroid Build Coastguard Worker   TestHalfwayValue(
367*9356374aSAndroid Build Coastguard Worker       "2."
368*9356374aSAndroid Build Coastguard Worker       "225073858507201630123055637955676152503612414573018013083228724049586647"
369*9356374aSAndroid Build Coastguard Worker       "606759446192036794116886953213985520549032000903434781884412325572184367"
370*9356374aSAndroid Build Coastguard Worker       "563347617020518175998922941393629966742598285899994830148971433555578567"
371*9356374aSAndroid Build Coastguard Worker       "693279306015978183162142425067962460785295885199272493577688320732492479"
372*9356374aSAndroid Build Coastguard Worker       "924816869232247165964934329258783950102250973957579510571600738343645738"
373*9356374aSAndroid Build Coastguard Worker       "494324192997092179207389919761694314131497173265255020084997973676783743"
374*9356374aSAndroid Build Coastguard Worker       "155205818804439163810572367791175177756227497413804253387084478193655533"
375*9356374aSAndroid Build Coastguard Worker       "073867420834526162513029462022730109054820067654020201547112002028139700"
376*9356374aSAndroid Build Coastguard Worker       "141575259123440177362244273712468151750189745559978653234255886219611516"
377*9356374aSAndroid Build Coastguard Worker       "335924167958029604477064946470184777360934300451421683607013647479513962"
378*9356374aSAndroid Build Coastguard Worker       "13837722826145437693412532098591327667236328125",
379*9356374aSAndroid Build Coastguard Worker       -308, first_normal, second_normal, first_normal);
380*9356374aSAndroid Build Coastguard Worker 
381*9356374aSAndroid Build Coastguard Worker   // penultimate_normal and last_normal.  Round-to-even rounds down.
382*9356374aSAndroid Build Coastguard Worker   TestHalfwayValue(
383*9356374aSAndroid Build Coastguard Worker       "1."
384*9356374aSAndroid Build Coastguard Worker       "797693134862315608353258760581052985162070023416521662616611746258695532"
385*9356374aSAndroid Build Coastguard Worker       "672923265745300992879465492467506314903358770175220871059269879629062776"
386*9356374aSAndroid Build Coastguard Worker       "047355692132901909191523941804762171253349609463563872612866401980290377"
387*9356374aSAndroid Build Coastguard Worker       "995141836029815117562837277714038305214839639239356331336428021390916694"
388*9356374aSAndroid Build Coastguard Worker       "57927874464075218944",
389*9356374aSAndroid Build Coastguard Worker       308, penultimate_normal, last_normal, penultimate_normal);
390*9356374aSAndroid Build Coastguard Worker }
391*9356374aSAndroid Build Coastguard Worker 
392*9356374aSAndroid Build Coastguard Worker // Same test cases as DoubleRounding, now with new and improved Much Smaller
393*9356374aSAndroid Build Coastguard Worker // Precision!
TEST(FromChars,FloatRounding)394*9356374aSAndroid Build Coastguard Worker TEST(FromChars, FloatRounding) {
395*9356374aSAndroid Build Coastguard Worker   const float zero = 0.0;
396*9356374aSAndroid Build Coastguard Worker   const float first_subnormal = nextafterf(zero, 1.0);
397*9356374aSAndroid Build Coastguard Worker   const float second_subnormal = nextafterf(first_subnormal, 1.0);
398*9356374aSAndroid Build Coastguard Worker 
399*9356374aSAndroid Build Coastguard Worker   const float first_normal = FLT_MIN;
400*9356374aSAndroid Build Coastguard Worker   const float last_subnormal = nextafterf(first_normal, 0.0);
401*9356374aSAndroid Build Coastguard Worker   const float second_normal = nextafterf(first_normal, 1.0);
402*9356374aSAndroid Build Coastguard Worker 
403*9356374aSAndroid Build Coastguard Worker   const float last_normal = FLT_MAX;
404*9356374aSAndroid Build Coastguard Worker   const float penultimate_normal = nextafterf(last_normal, 0.0);
405*9356374aSAndroid Build Coastguard Worker 
406*9356374aSAndroid Build Coastguard Worker   // Test between zero and first_subnormal.  Round-to-even tie rounds down.
407*9356374aSAndroid Build Coastguard Worker   TestHalfwayValue(
408*9356374aSAndroid Build Coastguard Worker       "7."
409*9356374aSAndroid Build Coastguard Worker       "006492321624085354618647916449580656401309709382578858785341419448955413"
410*9356374aSAndroid Build Coastguard Worker       "42930300743319094181060791015625",
411*9356374aSAndroid Build Coastguard Worker       -46, zero, first_subnormal, zero);
412*9356374aSAndroid Build Coastguard Worker 
413*9356374aSAndroid Build Coastguard Worker   // first_subnormal and second_subnormal.  Round-to-even tie rounds up.
414*9356374aSAndroid Build Coastguard Worker   TestHalfwayValue(
415*9356374aSAndroid Build Coastguard Worker       "2."
416*9356374aSAndroid Build Coastguard Worker       "101947696487225606385594374934874196920392912814773657635602425834686624"
417*9356374aSAndroid Build Coastguard Worker       "028790902229957282543182373046875",
418*9356374aSAndroid Build Coastguard Worker       -45, first_subnormal, second_subnormal, second_subnormal);
419*9356374aSAndroid Build Coastguard Worker 
420*9356374aSAndroid Build Coastguard Worker   // last_subnormal and first_normal.  Round-to-even tie rounds up.
421*9356374aSAndroid Build Coastguard Worker   TestHalfwayValue(
422*9356374aSAndroid Build Coastguard Worker       "1."
423*9356374aSAndroid Build Coastguard Worker       "175494280757364291727882991035766513322858992758990427682963118425003064"
424*9356374aSAndroid Build Coastguard Worker       "9651730385585324256680905818939208984375",
425*9356374aSAndroid Build Coastguard Worker       -38, last_subnormal, first_normal, first_normal);
426*9356374aSAndroid Build Coastguard Worker 
427*9356374aSAndroid Build Coastguard Worker   // first_normal and second_normal.  Round-to-even tie rounds down.
428*9356374aSAndroid Build Coastguard Worker   TestHalfwayValue(
429*9356374aSAndroid Build Coastguard Worker       "1."
430*9356374aSAndroid Build Coastguard Worker       "175494420887210724209590083408724842314472120785184615334540294131831453"
431*9356374aSAndroid Build Coastguard Worker       "9442813071445925743319094181060791015625",
432*9356374aSAndroid Build Coastguard Worker       -38, first_normal, second_normal, first_normal);
433*9356374aSAndroid Build Coastguard Worker 
434*9356374aSAndroid Build Coastguard Worker   // penultimate_normal and last_normal.  Round-to-even rounds down.
435*9356374aSAndroid Build Coastguard Worker   TestHalfwayValue("3.40282336497324057985868971510891282432", 38,
436*9356374aSAndroid Build Coastguard Worker                    penultimate_normal, last_normal, penultimate_normal);
437*9356374aSAndroid Build Coastguard Worker }
438*9356374aSAndroid Build Coastguard Worker 
TEST(FromChars,Underflow)439*9356374aSAndroid Build Coastguard Worker TEST(FromChars, Underflow) {
440*9356374aSAndroid Build Coastguard Worker   // Check that underflow is handled correctly, according to the specification
441*9356374aSAndroid Build Coastguard Worker   // in DR 3081.
442*9356374aSAndroid Build Coastguard Worker   double d;
443*9356374aSAndroid Build Coastguard Worker   float f;
444*9356374aSAndroid Build Coastguard Worker   absl::from_chars_result result;
445*9356374aSAndroid Build Coastguard Worker 
446*9356374aSAndroid Build Coastguard Worker   std::string negative_underflow = "-1e-1000";
447*9356374aSAndroid Build Coastguard Worker   const char* begin = negative_underflow.data();
448*9356374aSAndroid Build Coastguard Worker   const char* end = begin + negative_underflow.size();
449*9356374aSAndroid Build Coastguard Worker   d = 100.0;
450*9356374aSAndroid Build Coastguard Worker   result = absl::from_chars(begin, end, d);
451*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.ptr, end);
452*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.ec, std::errc::result_out_of_range);
453*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::signbit(d));  // negative
454*9356374aSAndroid Build Coastguard Worker   EXPECT_GE(d, -std::numeric_limits<double>::min());
455*9356374aSAndroid Build Coastguard Worker   f = 100.0;
456*9356374aSAndroid Build Coastguard Worker   result = absl::from_chars(begin, end, f);
457*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.ptr, end);
458*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.ec, std::errc::result_out_of_range);
459*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::signbit(f));  // negative
460*9356374aSAndroid Build Coastguard Worker   EXPECT_GE(f, -std::numeric_limits<float>::min());
461*9356374aSAndroid Build Coastguard Worker 
462*9356374aSAndroid Build Coastguard Worker   std::string positive_underflow = "1e-1000";
463*9356374aSAndroid Build Coastguard Worker   begin = positive_underflow.data();
464*9356374aSAndroid Build Coastguard Worker   end = begin + positive_underflow.size();
465*9356374aSAndroid Build Coastguard Worker   d = -100.0;
466*9356374aSAndroid Build Coastguard Worker   result = absl::from_chars(begin, end, d);
467*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.ptr, end);
468*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.ec, std::errc::result_out_of_range);
469*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(std::signbit(d));  // positive
470*9356374aSAndroid Build Coastguard Worker   EXPECT_LE(d, std::numeric_limits<double>::min());
471*9356374aSAndroid Build Coastguard Worker   f = -100.0;
472*9356374aSAndroid Build Coastguard Worker   result = absl::from_chars(begin, end, f);
473*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.ptr, end);
474*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.ec, std::errc::result_out_of_range);
475*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(std::signbit(f));  // positive
476*9356374aSAndroid Build Coastguard Worker   EXPECT_LE(f, std::numeric_limits<float>::min());
477*9356374aSAndroid Build Coastguard Worker }
478*9356374aSAndroid Build Coastguard Worker 
TEST(FromChars,Overflow)479*9356374aSAndroid Build Coastguard Worker TEST(FromChars, Overflow) {
480*9356374aSAndroid Build Coastguard Worker   // Check that overflow is handled correctly, according to the specification
481*9356374aSAndroid Build Coastguard Worker   // in DR 3081.
482*9356374aSAndroid Build Coastguard Worker   double d;
483*9356374aSAndroid Build Coastguard Worker   float f;
484*9356374aSAndroid Build Coastguard Worker   absl::from_chars_result result;
485*9356374aSAndroid Build Coastguard Worker 
486*9356374aSAndroid Build Coastguard Worker   std::string negative_overflow = "-1e1000";
487*9356374aSAndroid Build Coastguard Worker   const char* begin = negative_overflow.data();
488*9356374aSAndroid Build Coastguard Worker   const char* end = begin + negative_overflow.size();
489*9356374aSAndroid Build Coastguard Worker   d = 100.0;
490*9356374aSAndroid Build Coastguard Worker   result = absl::from_chars(begin, end, d);
491*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.ptr, end);
492*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.ec, std::errc::result_out_of_range);
493*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::signbit(d));  // negative
494*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(d, -std::numeric_limits<double>::max());
495*9356374aSAndroid Build Coastguard Worker   f = 100.0;
496*9356374aSAndroid Build Coastguard Worker   result = absl::from_chars(begin, end, f);
497*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.ptr, end);
498*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.ec, std::errc::result_out_of_range);
499*9356374aSAndroid Build Coastguard Worker   EXPECT_TRUE(std::signbit(f));  // negative
500*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(f, -std::numeric_limits<float>::max());
501*9356374aSAndroid Build Coastguard Worker 
502*9356374aSAndroid Build Coastguard Worker   std::string positive_overflow = "1e1000";
503*9356374aSAndroid Build Coastguard Worker   begin = positive_overflow.data();
504*9356374aSAndroid Build Coastguard Worker   end = begin + positive_overflow.size();
505*9356374aSAndroid Build Coastguard Worker   d = -100.0;
506*9356374aSAndroid Build Coastguard Worker   result = absl::from_chars(begin, end, d);
507*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.ptr, end);
508*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.ec, std::errc::result_out_of_range);
509*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(std::signbit(d));  // positive
510*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(d, std::numeric_limits<double>::max());
511*9356374aSAndroid Build Coastguard Worker   f = -100.0;
512*9356374aSAndroid Build Coastguard Worker   result = absl::from_chars(begin, end, f);
513*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.ptr, end);
514*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.ec, std::errc::result_out_of_range);
515*9356374aSAndroid Build Coastguard Worker   EXPECT_FALSE(std::signbit(f));  // positive
516*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(f, std::numeric_limits<float>::max());
517*9356374aSAndroid Build Coastguard Worker }
518*9356374aSAndroid Build Coastguard Worker 
TEST(FromChars,RegressionTestsFromFuzzer)519*9356374aSAndroid Build Coastguard Worker TEST(FromChars, RegressionTestsFromFuzzer) {
520*9356374aSAndroid Build Coastguard Worker   absl::string_view src = "0x21900000p00000000099";
521*9356374aSAndroid Build Coastguard Worker   float f;
522*9356374aSAndroid Build Coastguard Worker   auto result = absl::from_chars(src.data(), src.data() + src.size(), f);
523*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.ec, std::errc::result_out_of_range);
524*9356374aSAndroid Build Coastguard Worker }
525*9356374aSAndroid Build Coastguard Worker 
TEST(FromChars,ReturnValuePtr)526*9356374aSAndroid Build Coastguard Worker TEST(FromChars, ReturnValuePtr) {
527*9356374aSAndroid Build Coastguard Worker   // Check that `ptr` points one past the number scanned, even if that number
528*9356374aSAndroid Build Coastguard Worker   // is not representable.
529*9356374aSAndroid Build Coastguard Worker   double d;
530*9356374aSAndroid Build Coastguard Worker   absl::from_chars_result result;
531*9356374aSAndroid Build Coastguard Worker 
532*9356374aSAndroid Build Coastguard Worker   std::string normal = "3.14@#$%@#$%";
533*9356374aSAndroid Build Coastguard Worker   result = absl::from_chars(normal.data(), normal.data() + normal.size(), d);
534*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.ec, std::errc());
535*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.ptr - normal.data(), 4);
536*9356374aSAndroid Build Coastguard Worker 
537*9356374aSAndroid Build Coastguard Worker   std::string overflow = "1e1000@#$%@#$%";
538*9356374aSAndroid Build Coastguard Worker   result = absl::from_chars(overflow.data(),
539*9356374aSAndroid Build Coastguard Worker                             overflow.data() + overflow.size(), d);
540*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.ec, std::errc::result_out_of_range);
541*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.ptr - overflow.data(), 6);
542*9356374aSAndroid Build Coastguard Worker 
543*9356374aSAndroid Build Coastguard Worker   std::string garbage = "#$%@#$%";
544*9356374aSAndroid Build Coastguard Worker   result = absl::from_chars(garbage.data(),
545*9356374aSAndroid Build Coastguard Worker                             garbage.data() + garbage.size(), d);
546*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.ec, std::errc::invalid_argument);
547*9356374aSAndroid Build Coastguard Worker   EXPECT_EQ(result.ptr - garbage.data(), 0);
548*9356374aSAndroid Build Coastguard Worker }
549*9356374aSAndroid Build Coastguard Worker 
550*9356374aSAndroid Build Coastguard Worker // Check for a wide range of inputs that strtod() and absl::from_chars() exactly
551*9356374aSAndroid Build Coastguard Worker // agree on the conversion amount.
552*9356374aSAndroid Build Coastguard Worker //
553*9356374aSAndroid Build Coastguard Worker // This test assumes the platform's strtod() uses perfect round_to_nearest
554*9356374aSAndroid Build Coastguard Worker // rounding.
TEST(FromChars,TestVersusStrtod)555*9356374aSAndroid Build Coastguard Worker TEST(FromChars, TestVersusStrtod) {
556*9356374aSAndroid Build Coastguard Worker   for (int mantissa = 1000000; mantissa <= 9999999; mantissa += 501) {
557*9356374aSAndroid Build Coastguard Worker     for (int exponent = -300; exponent < 300; ++exponent) {
558*9356374aSAndroid Build Coastguard Worker       std::string candidate = absl::StrCat(mantissa, "e", exponent);
559*9356374aSAndroid Build Coastguard Worker       double strtod_value = strtod(candidate.c_str(), nullptr);
560*9356374aSAndroid Build Coastguard Worker       double absl_value = 0;
561*9356374aSAndroid Build Coastguard Worker       absl::from_chars(candidate.data(), candidate.data() + candidate.size(),
562*9356374aSAndroid Build Coastguard Worker                        absl_value);
563*9356374aSAndroid Build Coastguard Worker       ASSERT_EQ(strtod_value, absl_value) << candidate;
564*9356374aSAndroid Build Coastguard Worker     }
565*9356374aSAndroid Build Coastguard Worker   }
566*9356374aSAndroid Build Coastguard Worker }
567*9356374aSAndroid Build Coastguard Worker 
568*9356374aSAndroid Build Coastguard Worker // Check for a wide range of inputs that strtof() and absl::from_chars() exactly
569*9356374aSAndroid Build Coastguard Worker // agree on the conversion amount.
570*9356374aSAndroid Build Coastguard Worker //
571*9356374aSAndroid Build Coastguard Worker // This test assumes the platform's strtof() uses perfect round_to_nearest
572*9356374aSAndroid Build Coastguard Worker // rounding.
TEST(FromChars,TestVersusStrtof)573*9356374aSAndroid Build Coastguard Worker TEST(FromChars, TestVersusStrtof) {
574*9356374aSAndroid Build Coastguard Worker   for (int mantissa = 1000000; mantissa <= 9999999; mantissa += 501) {
575*9356374aSAndroid Build Coastguard Worker     for (int exponent = -43; exponent < 32; ++exponent) {
576*9356374aSAndroid Build Coastguard Worker       std::string candidate = absl::StrCat(mantissa, "e", exponent);
577*9356374aSAndroid Build Coastguard Worker       float strtod_value = strtof(candidate.c_str(), nullptr);
578*9356374aSAndroid Build Coastguard Worker       float absl_value = 0;
579*9356374aSAndroid Build Coastguard Worker       absl::from_chars(candidate.data(), candidate.data() + candidate.size(),
580*9356374aSAndroid Build Coastguard Worker                        absl_value);
581*9356374aSAndroid Build Coastguard Worker       ASSERT_EQ(strtod_value, absl_value) << candidate;
582*9356374aSAndroid Build Coastguard Worker     }
583*9356374aSAndroid Build Coastguard Worker   }
584*9356374aSAndroid Build Coastguard Worker }
585*9356374aSAndroid Build Coastguard Worker 
586*9356374aSAndroid Build Coastguard Worker // Tests if two floating point values have identical bit layouts.  (EXPECT_EQ
587*9356374aSAndroid Build Coastguard Worker // is not suitable for NaN testing, since NaNs are never equal.)
588*9356374aSAndroid Build Coastguard Worker template <typename Float>
Identical(Float a,Float b)589*9356374aSAndroid Build Coastguard Worker bool Identical(Float a, Float b) {
590*9356374aSAndroid Build Coastguard Worker   return 0 == memcmp(&a, &b, sizeof(Float));
591*9356374aSAndroid Build Coastguard Worker }
592*9356374aSAndroid Build Coastguard Worker 
593*9356374aSAndroid Build Coastguard Worker // Check that NaNs are parsed correctly.  The spec requires that
594*9356374aSAndroid Build Coastguard Worker // std::from_chars on "NaN(123abc)" return the same value as std::nan("123abc").
595*9356374aSAndroid Build Coastguard Worker // How such an n-char-sequence affects the generated NaN is unspecified, so we
596*9356374aSAndroid Build Coastguard Worker // just test for symmetry with std::nan and strtod here.
597*9356374aSAndroid Build Coastguard Worker //
598*9356374aSAndroid Build Coastguard Worker // (In Linux, this parses the value as a number and stuffs that number into the
599*9356374aSAndroid Build Coastguard Worker // free bits of a quiet NaN.)
TEST(FromChars,NaNDoubles)600*9356374aSAndroid Build Coastguard Worker TEST(FromChars, NaNDoubles) {
601*9356374aSAndroid Build Coastguard Worker   for (std::string n_char_sequence :
602*9356374aSAndroid Build Coastguard Worker        {"", "1", "2", "3", "fff", "FFF", "200000", "400000", "4000000000000",
603*9356374aSAndroid Build Coastguard Worker         "8000000000000", "abc123", "legal_but_unexpected",
604*9356374aSAndroid Build Coastguard Worker         "99999999999999999999999", "_"}) {
605*9356374aSAndroid Build Coastguard Worker     std::string input = absl::StrCat("nan(", n_char_sequence, ")");
606*9356374aSAndroid Build Coastguard Worker     SCOPED_TRACE(input);
607*9356374aSAndroid Build Coastguard Worker     double from_chars_double;
608*9356374aSAndroid Build Coastguard Worker     absl::from_chars(input.data(), input.data() + input.size(),
609*9356374aSAndroid Build Coastguard Worker                      from_chars_double);
610*9356374aSAndroid Build Coastguard Worker     double std_nan_double = std::nan(n_char_sequence.c_str());
611*9356374aSAndroid Build Coastguard Worker     EXPECT_TRUE(Identical(from_chars_double, std_nan_double));
612*9356374aSAndroid Build Coastguard Worker 
613*9356374aSAndroid Build Coastguard Worker     // Also check that we match strtod()'s behavior.  This test assumes that the
614*9356374aSAndroid Build Coastguard Worker     // platform has a compliant strtod().
615*9356374aSAndroid Build Coastguard Worker #if ABSL_STRTOD_HANDLES_NAN_CORRECTLY
616*9356374aSAndroid Build Coastguard Worker     double strtod_double = strtod(input.c_str(), nullptr);
617*9356374aSAndroid Build Coastguard Worker     EXPECT_TRUE(Identical(from_chars_double, strtod_double));
618*9356374aSAndroid Build Coastguard Worker #endif  // ABSL_STRTOD_HANDLES_NAN_CORRECTLY
619*9356374aSAndroid Build Coastguard Worker 
620*9356374aSAndroid Build Coastguard Worker     // Check that we can parse a negative NaN
621*9356374aSAndroid Build Coastguard Worker     std::string negative_input = "-" + input;
622*9356374aSAndroid Build Coastguard Worker     double negative_from_chars_double;
623*9356374aSAndroid Build Coastguard Worker     absl::from_chars(negative_input.data(),
624*9356374aSAndroid Build Coastguard Worker                      negative_input.data() + negative_input.size(),
625*9356374aSAndroid Build Coastguard Worker                      negative_from_chars_double);
626*9356374aSAndroid Build Coastguard Worker     EXPECT_TRUE(std::signbit(negative_from_chars_double));
627*9356374aSAndroid Build Coastguard Worker     EXPECT_FALSE(Identical(negative_from_chars_double, from_chars_double));
628*9356374aSAndroid Build Coastguard Worker     from_chars_double = std::copysign(from_chars_double, -1.0);
629*9356374aSAndroid Build Coastguard Worker     EXPECT_TRUE(Identical(negative_from_chars_double, from_chars_double));
630*9356374aSAndroid Build Coastguard Worker   }
631*9356374aSAndroid Build Coastguard Worker }
632*9356374aSAndroid Build Coastguard Worker 
TEST(FromChars,NaNFloats)633*9356374aSAndroid Build Coastguard Worker TEST(FromChars, NaNFloats) {
634*9356374aSAndroid Build Coastguard Worker   for (std::string n_char_sequence :
635*9356374aSAndroid Build Coastguard Worker        {"", "1", "2", "3", "fff", "FFF", "200000", "400000", "4000000000000",
636*9356374aSAndroid Build Coastguard Worker         "8000000000000", "abc123", "legal_but_unexpected",
637*9356374aSAndroid Build Coastguard Worker         "99999999999999999999999", "_"}) {
638*9356374aSAndroid Build Coastguard Worker     std::string input = absl::StrCat("nan(", n_char_sequence, ")");
639*9356374aSAndroid Build Coastguard Worker     SCOPED_TRACE(input);
640*9356374aSAndroid Build Coastguard Worker     float from_chars_float;
641*9356374aSAndroid Build Coastguard Worker     absl::from_chars(input.data(), input.data() + input.size(),
642*9356374aSAndroid Build Coastguard Worker                      from_chars_float);
643*9356374aSAndroid Build Coastguard Worker     float std_nan_float = std::nanf(n_char_sequence.c_str());
644*9356374aSAndroid Build Coastguard Worker     EXPECT_TRUE(Identical(from_chars_float, std_nan_float));
645*9356374aSAndroid Build Coastguard Worker 
646*9356374aSAndroid Build Coastguard Worker     // Also check that we match strtof()'s behavior.  This test assumes that the
647*9356374aSAndroid Build Coastguard Worker     // platform has a compliant strtof().
648*9356374aSAndroid Build Coastguard Worker #if ABSL_STRTOD_HANDLES_NAN_CORRECTLY
649*9356374aSAndroid Build Coastguard Worker     float strtof_float = strtof(input.c_str(), nullptr);
650*9356374aSAndroid Build Coastguard Worker     EXPECT_TRUE(Identical(from_chars_float, strtof_float));
651*9356374aSAndroid Build Coastguard Worker #endif  // ABSL_STRTOD_HANDLES_NAN_CORRECTLY
652*9356374aSAndroid Build Coastguard Worker 
653*9356374aSAndroid Build Coastguard Worker     // Check that we can parse a negative NaN
654*9356374aSAndroid Build Coastguard Worker     std::string negative_input = "-" + input;
655*9356374aSAndroid Build Coastguard Worker     float negative_from_chars_float;
656*9356374aSAndroid Build Coastguard Worker     absl::from_chars(negative_input.data(),
657*9356374aSAndroid Build Coastguard Worker                      negative_input.data() + negative_input.size(),
658*9356374aSAndroid Build Coastguard Worker                      negative_from_chars_float);
659*9356374aSAndroid Build Coastguard Worker     EXPECT_TRUE(std::signbit(negative_from_chars_float));
660*9356374aSAndroid Build Coastguard Worker     EXPECT_FALSE(Identical(negative_from_chars_float, from_chars_float));
661*9356374aSAndroid Build Coastguard Worker     // Use the (float, float) overload of std::copysign to prevent narrowing;
662*9356374aSAndroid Build Coastguard Worker     // see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98251.
663*9356374aSAndroid Build Coastguard Worker     from_chars_float = std::copysign(from_chars_float, -1.0f);
664*9356374aSAndroid Build Coastguard Worker     EXPECT_TRUE(Identical(negative_from_chars_float, from_chars_float));
665*9356374aSAndroid Build Coastguard Worker   }
666*9356374aSAndroid Build Coastguard Worker }
667*9356374aSAndroid Build Coastguard Worker 
668*9356374aSAndroid Build Coastguard Worker // Returns an integer larger than step.  The values grow exponentially.
NextStep(int step)669*9356374aSAndroid Build Coastguard Worker int NextStep(int step) {
670*9356374aSAndroid Build Coastguard Worker   return step + (step >> 2) + 1;
671*9356374aSAndroid Build Coastguard Worker }
672*9356374aSAndroid Build Coastguard Worker 
673*9356374aSAndroid Build Coastguard Worker // Test a conversion on a family of input strings, checking that the calculation
674*9356374aSAndroid Build Coastguard Worker // is correct for in-bounds values, and that overflow and underflow are done
675*9356374aSAndroid Build Coastguard Worker // correctly for out-of-bounds values.
676*9356374aSAndroid Build Coastguard Worker //
677*9356374aSAndroid Build Coastguard Worker // input_generator maps from an integer index to a string to test.
678*9356374aSAndroid Build Coastguard Worker // expected_generator maps from an integer index to an expected Float value.
679*9356374aSAndroid Build Coastguard Worker // from_chars conversion of input_generator(i) should result in
680*9356374aSAndroid Build Coastguard Worker // expected_generator(i).
681*9356374aSAndroid Build Coastguard Worker //
682*9356374aSAndroid Build Coastguard Worker // lower_bound and upper_bound denote the smallest and largest values for which
683*9356374aSAndroid Build Coastguard Worker // the conversion is expected to succeed.
684*9356374aSAndroid Build Coastguard Worker template <typename Float>
TestOverflowAndUnderflow(const std::function<std::string (int)> & input_generator,const std::function<Float (int)> & expected_generator,int lower_bound,int upper_bound)685*9356374aSAndroid Build Coastguard Worker void TestOverflowAndUnderflow(
686*9356374aSAndroid Build Coastguard Worker     const std::function<std::string(int)>& input_generator,
687*9356374aSAndroid Build Coastguard Worker     const std::function<Float(int)>& expected_generator, int lower_bound,
688*9356374aSAndroid Build Coastguard Worker     int upper_bound) {
689*9356374aSAndroid Build Coastguard Worker   // test legal values near lower_bound
690*9356374aSAndroid Build Coastguard Worker   int index, step;
691*9356374aSAndroid Build Coastguard Worker   for (index = lower_bound, step = 1; index < upper_bound;
692*9356374aSAndroid Build Coastguard Worker        index += step, step = NextStep(step)) {
693*9356374aSAndroid Build Coastguard Worker     std::string input = input_generator(index);
694*9356374aSAndroid Build Coastguard Worker     SCOPED_TRACE(input);
695*9356374aSAndroid Build Coastguard Worker     Float expected = expected_generator(index);
696*9356374aSAndroid Build Coastguard Worker     Float actual;
697*9356374aSAndroid Build Coastguard Worker     auto result =
698*9356374aSAndroid Build Coastguard Worker         absl::from_chars(input.data(), input.data() + input.size(), actual);
699*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(result.ec, std::errc());
700*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(expected, actual)
701*9356374aSAndroid Build Coastguard Worker         << absl::StrFormat("%a vs %a", expected, actual);
702*9356374aSAndroid Build Coastguard Worker   }
703*9356374aSAndroid Build Coastguard Worker   // test legal values near upper_bound
704*9356374aSAndroid Build Coastguard Worker   for (index = upper_bound, step = 1; index > lower_bound;
705*9356374aSAndroid Build Coastguard Worker        index -= step, step = NextStep(step)) {
706*9356374aSAndroid Build Coastguard Worker     std::string input = input_generator(index);
707*9356374aSAndroid Build Coastguard Worker     SCOPED_TRACE(input);
708*9356374aSAndroid Build Coastguard Worker     Float expected = expected_generator(index);
709*9356374aSAndroid Build Coastguard Worker     Float actual;
710*9356374aSAndroid Build Coastguard Worker     auto result =
711*9356374aSAndroid Build Coastguard Worker         absl::from_chars(input.data(), input.data() + input.size(), actual);
712*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(result.ec, std::errc());
713*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(expected, actual)
714*9356374aSAndroid Build Coastguard Worker         << absl::StrFormat("%a vs %a", expected, actual);
715*9356374aSAndroid Build Coastguard Worker   }
716*9356374aSAndroid Build Coastguard Worker   // Test underflow values below lower_bound
717*9356374aSAndroid Build Coastguard Worker   for (index = lower_bound - 1, step = 1; index > -1000000;
718*9356374aSAndroid Build Coastguard Worker        index -= step, step = NextStep(step)) {
719*9356374aSAndroid Build Coastguard Worker     std::string input = input_generator(index);
720*9356374aSAndroid Build Coastguard Worker     SCOPED_TRACE(input);
721*9356374aSAndroid Build Coastguard Worker     Float actual;
722*9356374aSAndroid Build Coastguard Worker     auto result =
723*9356374aSAndroid Build Coastguard Worker         absl::from_chars(input.data(), input.data() + input.size(), actual);
724*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(result.ec, std::errc::result_out_of_range);
725*9356374aSAndroid Build Coastguard Worker     EXPECT_LT(actual, 1.0);  // check for underflow
726*9356374aSAndroid Build Coastguard Worker   }
727*9356374aSAndroid Build Coastguard Worker   // Test overflow values above upper_bound
728*9356374aSAndroid Build Coastguard Worker   for (index = upper_bound + 1, step = 1; index < 1000000;
729*9356374aSAndroid Build Coastguard Worker        index += step, step = NextStep(step)) {
730*9356374aSAndroid Build Coastguard Worker     std::string input = input_generator(index);
731*9356374aSAndroid Build Coastguard Worker     SCOPED_TRACE(input);
732*9356374aSAndroid Build Coastguard Worker     Float actual;
733*9356374aSAndroid Build Coastguard Worker     auto result =
734*9356374aSAndroid Build Coastguard Worker         absl::from_chars(input.data(), input.data() + input.size(), actual);
735*9356374aSAndroid Build Coastguard Worker     EXPECT_EQ(result.ec, std::errc::result_out_of_range);
736*9356374aSAndroid Build Coastguard Worker     EXPECT_GT(actual, 1.0);  // check for overflow
737*9356374aSAndroid Build Coastguard Worker   }
738*9356374aSAndroid Build Coastguard Worker }
739*9356374aSAndroid Build Coastguard Worker 
740*9356374aSAndroid Build Coastguard Worker // Check that overflow and underflow are caught correctly for hex doubles.
741*9356374aSAndroid Build Coastguard Worker //
742*9356374aSAndroid Build Coastguard Worker // The largest representable double is 0x1.fffffffffffffp+1023, and the
743*9356374aSAndroid Build Coastguard Worker // smallest representable subnormal is 0x0.0000000000001p-1022, which equals
744*9356374aSAndroid Build Coastguard Worker // 0x1p-1074.  Therefore 1023 and -1074 are the limits of acceptable exponents
745*9356374aSAndroid Build Coastguard Worker // in this test.
TEST(FromChars,HexdecimalDoubleLimits)746*9356374aSAndroid Build Coastguard Worker TEST(FromChars, HexdecimalDoubleLimits) {
747*9356374aSAndroid Build Coastguard Worker   auto input_gen = [](int index) { return absl::StrCat("0x1.0p", index); };
748*9356374aSAndroid Build Coastguard Worker   auto expected_gen = [](int index) { return std::ldexp(1.0, index); };
749*9356374aSAndroid Build Coastguard Worker   TestOverflowAndUnderflow<double>(input_gen, expected_gen, -1074, 1023);
750*9356374aSAndroid Build Coastguard Worker }
751*9356374aSAndroid Build Coastguard Worker 
752*9356374aSAndroid Build Coastguard Worker // Check that overflow and underflow are caught correctly for hex floats.
753*9356374aSAndroid Build Coastguard Worker //
754*9356374aSAndroid Build Coastguard Worker // The largest representable float is 0x1.fffffep+127, and the smallest
755*9356374aSAndroid Build Coastguard Worker // representable subnormal is 0x0.000002p-126, which equals 0x1p-149.
756*9356374aSAndroid Build Coastguard Worker // Therefore 127 and -149 are the limits of acceptable exponents in this test.
TEST(FromChars,HexdecimalFloatLimits)757*9356374aSAndroid Build Coastguard Worker TEST(FromChars, HexdecimalFloatLimits) {
758*9356374aSAndroid Build Coastguard Worker   auto input_gen = [](int index) { return absl::StrCat("0x1.0p", index); };
759*9356374aSAndroid Build Coastguard Worker   auto expected_gen = [](int index) { return std::ldexp(1.0f, index); };
760*9356374aSAndroid Build Coastguard Worker   TestOverflowAndUnderflow<float>(input_gen, expected_gen, -149, 127);
761*9356374aSAndroid Build Coastguard Worker }
762*9356374aSAndroid Build Coastguard Worker 
763*9356374aSAndroid Build Coastguard Worker // Check that overflow and underflow are caught correctly for decimal doubles.
764*9356374aSAndroid Build Coastguard Worker //
765*9356374aSAndroid Build Coastguard Worker // The largest representable double is about 1.8e308, and the smallest
766*9356374aSAndroid Build Coastguard Worker // representable subnormal is about 5e-324.  '1e-324' therefore rounds away from
767*9356374aSAndroid Build Coastguard Worker // the smallest representable positive value.  -323 and 308 are the limits of
768*9356374aSAndroid Build Coastguard Worker // acceptable exponents in this test.
TEST(FromChars,DecimalDoubleLimits)769*9356374aSAndroid Build Coastguard Worker TEST(FromChars, DecimalDoubleLimits) {
770*9356374aSAndroid Build Coastguard Worker   auto input_gen = [](int index) { return absl::StrCat("1.0e", index); };
771*9356374aSAndroid Build Coastguard Worker   auto expected_gen = [](int index) { return Pow10(index); };
772*9356374aSAndroid Build Coastguard Worker   TestOverflowAndUnderflow<double>(input_gen, expected_gen, -323, 308);
773*9356374aSAndroid Build Coastguard Worker }
774*9356374aSAndroid Build Coastguard Worker 
775*9356374aSAndroid Build Coastguard Worker // Check that overflow and underflow are caught correctly for decimal floats.
776*9356374aSAndroid Build Coastguard Worker //
777*9356374aSAndroid Build Coastguard Worker // The largest representable float is about 3.4e38, and the smallest
778*9356374aSAndroid Build Coastguard Worker // representable subnormal is about 1.45e-45.  '1e-45' therefore rounds towards
779*9356374aSAndroid Build Coastguard Worker // the smallest representable positive value.  -45 and 38 are the limits of
780*9356374aSAndroid Build Coastguard Worker // acceptable exponents in this test.
TEST(FromChars,DecimalFloatLimits)781*9356374aSAndroid Build Coastguard Worker TEST(FromChars, DecimalFloatLimits) {
782*9356374aSAndroid Build Coastguard Worker   auto input_gen = [](int index) { return absl::StrCat("1.0e", index); };
783*9356374aSAndroid Build Coastguard Worker   auto expected_gen = [](int index) { return Pow10(index); };
784*9356374aSAndroid Build Coastguard Worker   TestOverflowAndUnderflow<float>(input_gen, expected_gen, -45, 38);
785*9356374aSAndroid Build Coastguard Worker }
786*9356374aSAndroid Build Coastguard Worker 
787*9356374aSAndroid Build Coastguard Worker }  // namespace
788