00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "absl/strings/charconv.h"
00016
00017 #include <cstdlib>
00018 #include <string>
00019
00020 #include "gmock/gmock.h"
00021 #include "gtest/gtest.h"
00022 #include "absl/strings/internal/pow10_helper.h"
00023 #include "absl/strings/str_cat.h"
00024 #include "absl/strings/str_format.h"
00025
00026 #ifdef _MSC_FULL_VER
00027 #define ABSL_COMPILER_DOES_EXACT_ROUNDING 0
00028 #define ABSL_STRTOD_HANDLES_NAN_CORRECTLY 0
00029 #else
00030 #define ABSL_COMPILER_DOES_EXACT_ROUNDING 1
00031 #define ABSL_STRTOD_HANDLES_NAN_CORRECTLY 1
00032 #endif
00033
00034 namespace {
00035
00036 using absl::strings_internal::Pow10;
00037
00038 #if ABSL_COMPILER_DOES_EXACT_ROUNDING
00039
00040
00041
00042 void TestDoubleParse(absl::string_view str, double expected_number) {
00043 SCOPED_TRACE(str);
00044 double actual_number = 0.0;
00045 absl::from_chars_result result =
00046 absl::from_chars(str.data(), str.data() + str.length(), actual_number);
00047 EXPECT_EQ(result.ec, std::errc());
00048 EXPECT_EQ(result.ptr, str.data() + str.length());
00049 EXPECT_EQ(actual_number, expected_number);
00050 }
00051
00052 void TestFloatParse(absl::string_view str, float expected_number) {
00053 SCOPED_TRACE(str);
00054 float actual_number = 0.0;
00055 absl::from_chars_result result =
00056 absl::from_chars(str.data(), str.data() + str.length(), actual_number);
00057 EXPECT_EQ(result.ec, std::errc());
00058 EXPECT_EQ(result.ptr, str.data() + str.length());
00059 EXPECT_EQ(actual_number, expected_number);
00060 }
00061
00062
00063
00064
00065
00066
00067 #define FROM_CHARS_TEST_DOUBLE(number) \
00068 { \
00069 TestDoubleParse(#number, number); \
00070 TestDoubleParse("-" #number, -number); \
00071 }
00072
00073 #define FROM_CHARS_TEST_FLOAT(number) \
00074 { \
00075 TestFloatParse(#number, number##f); \
00076 TestFloatParse("-" #number, -number##f); \
00077 }
00078
00079 TEST(FromChars, NearRoundingCases) {
00080
00081
00082
00083
00084
00085 FROM_CHARS_TEST_DOUBLE(5.e125);
00086 FROM_CHARS_TEST_DOUBLE(69.e267);
00087 FROM_CHARS_TEST_DOUBLE(999.e-026);
00088 FROM_CHARS_TEST_DOUBLE(7861.e-034);
00089 FROM_CHARS_TEST_DOUBLE(75569.e-254);
00090 FROM_CHARS_TEST_DOUBLE(928609.e-261);
00091 FROM_CHARS_TEST_DOUBLE(9210917.e080);
00092 FROM_CHARS_TEST_DOUBLE(84863171.e114);
00093 FROM_CHARS_TEST_DOUBLE(653777767.e273);
00094 FROM_CHARS_TEST_DOUBLE(5232604057.e-298);
00095 FROM_CHARS_TEST_DOUBLE(27235667517.e-109);
00096 FROM_CHARS_TEST_DOUBLE(653532977297.e-123);
00097 FROM_CHARS_TEST_DOUBLE(3142213164987.e-294);
00098 FROM_CHARS_TEST_DOUBLE(46202199371337.e-072);
00099 FROM_CHARS_TEST_DOUBLE(231010996856685.e-073);
00100 FROM_CHARS_TEST_DOUBLE(9324754620109615.e212);
00101 FROM_CHARS_TEST_DOUBLE(78459735791271921.e049);
00102 FROM_CHARS_TEST_DOUBLE(272104041512242479.e200);
00103 FROM_CHARS_TEST_DOUBLE(6802601037806061975.e198);
00104 FROM_CHARS_TEST_DOUBLE(20505426358836677347.e-221);
00105 FROM_CHARS_TEST_DOUBLE(836168422905420598437.e-234);
00106 FROM_CHARS_TEST_DOUBLE(4891559871276714924261.e222);
00107 FROM_CHARS_TEST_FLOAT(5.e-20);
00108 FROM_CHARS_TEST_FLOAT(67.e14);
00109 FROM_CHARS_TEST_FLOAT(985.e15);
00110 FROM_CHARS_TEST_FLOAT(7693.e-42);
00111 FROM_CHARS_TEST_FLOAT(55895.e-16);
00112 FROM_CHARS_TEST_FLOAT(996622.e-44);
00113 FROM_CHARS_TEST_FLOAT(7038531.e-32);
00114 FROM_CHARS_TEST_FLOAT(60419369.e-46);
00115 FROM_CHARS_TEST_FLOAT(702990899.e-20);
00116 FROM_CHARS_TEST_FLOAT(6930161142.e-48);
00117 FROM_CHARS_TEST_FLOAT(25933168707.e-13);
00118 FROM_CHARS_TEST_FLOAT(596428896559.e20);
00119
00120
00121 FROM_CHARS_TEST_DOUBLE(9.e-265);
00122 FROM_CHARS_TEST_DOUBLE(85.e-037);
00123 FROM_CHARS_TEST_DOUBLE(623.e100);
00124 FROM_CHARS_TEST_DOUBLE(3571.e263);
00125 FROM_CHARS_TEST_DOUBLE(81661.e153);
00126 FROM_CHARS_TEST_DOUBLE(920657.e-023);
00127 FROM_CHARS_TEST_DOUBLE(4603285.e-024);
00128 FROM_CHARS_TEST_DOUBLE(87575437.e-309);
00129 FROM_CHARS_TEST_DOUBLE(245540327.e122);
00130 FROM_CHARS_TEST_DOUBLE(6138508175.e120);
00131 FROM_CHARS_TEST_DOUBLE(83356057653.e193);
00132 FROM_CHARS_TEST_DOUBLE(619534293513.e124);
00133 FROM_CHARS_TEST_DOUBLE(2335141086879.e218);
00134 FROM_CHARS_TEST_DOUBLE(36167929443327.e-159);
00135 FROM_CHARS_TEST_DOUBLE(609610927149051.e-255);
00136 FROM_CHARS_TEST_DOUBLE(3743626360493413.e-165);
00137 FROM_CHARS_TEST_DOUBLE(94080055902682397.e-242);
00138 FROM_CHARS_TEST_DOUBLE(899810892172646163.e283);
00139 FROM_CHARS_TEST_DOUBLE(7120190517612959703.e120);
00140 FROM_CHARS_TEST_DOUBLE(25188282901709339043.e-252);
00141 FROM_CHARS_TEST_DOUBLE(308984926168550152811.e-052);
00142 FROM_CHARS_TEST_DOUBLE(6372891218502368041059.e064);
00143 FROM_CHARS_TEST_FLOAT(3.e-23);
00144 FROM_CHARS_TEST_FLOAT(57.e18);
00145 FROM_CHARS_TEST_FLOAT(789.e-35);
00146 FROM_CHARS_TEST_FLOAT(2539.e-18);
00147 FROM_CHARS_TEST_FLOAT(76173.e28);
00148 FROM_CHARS_TEST_FLOAT(887745.e-11);
00149 FROM_CHARS_TEST_FLOAT(5382571.e-37);
00150 FROM_CHARS_TEST_FLOAT(82381273.e-35);
00151 FROM_CHARS_TEST_FLOAT(750486563.e-38);
00152 FROM_CHARS_TEST_FLOAT(3752432815.e-39);
00153 FROM_CHARS_TEST_FLOAT(75224575729.e-45);
00154 FROM_CHARS_TEST_FLOAT(459926601011.e15);
00155 }
00156
00157 #undef FROM_CHARS_TEST_DOUBLE
00158 #undef FROM_CHARS_TEST_FLOAT
00159 #endif
00160
00161 float ToFloat(absl::string_view s) {
00162 float f;
00163 absl::from_chars(s.data(), s.data() + s.size(), f);
00164 return f;
00165 }
00166
00167 double ToDouble(absl::string_view s) {
00168 double d;
00169 absl::from_chars(s.data(), s.data() + s.size(), d);
00170 return d;
00171 }
00172
00173
00174
00175
00176
00177 TEST(FromChars, NearRoundingCasesExplicit) {
00178 EXPECT_EQ(ToDouble("5.e125"), ldexp(6653062250012735, 365));
00179 EXPECT_EQ(ToDouble("69.e267"), ldexp(4705683757438170, 841));
00180 EXPECT_EQ(ToDouble("999.e-026"), ldexp(6798841691080350, -129));
00181 EXPECT_EQ(ToDouble("7861.e-034"), ldexp(8975675289889240, -153));
00182 EXPECT_EQ(ToDouble("75569.e-254"), ldexp(6091718967192243, -880));
00183 EXPECT_EQ(ToDouble("928609.e-261"), ldexp(7849264900213743, -900));
00184 EXPECT_EQ(ToDouble("9210917.e080"), ldexp(8341110837370930, 236));
00185 EXPECT_EQ(ToDouble("84863171.e114"), ldexp(4625202867375927, 353));
00186 EXPECT_EQ(ToDouble("653777767.e273"), ldexp(5068902999763073, 884));
00187 EXPECT_EQ(ToDouble("5232604057.e-298"), ldexp(5741343011915040, -1010));
00188 EXPECT_EQ(ToDouble("27235667517.e-109"), ldexp(6707124626673586, -380));
00189 EXPECT_EQ(ToDouble("653532977297.e-123"), ldexp(7078246407265384, -422));
00190 EXPECT_EQ(ToDouble("3142213164987.e-294"), ldexp(8219991337640559, -988));
00191 EXPECT_EQ(ToDouble("46202199371337.e-072"), ldexp(5224462102115359, -246));
00192 EXPECT_EQ(ToDouble("231010996856685.e-073"), ldexp(5224462102115359, -247));
00193 EXPECT_EQ(ToDouble("9324754620109615.e212"), ldexp(5539753864394442, 705));
00194 EXPECT_EQ(ToDouble("78459735791271921.e049"), ldexp(8388176519442766, 166));
00195 EXPECT_EQ(ToDouble("272104041512242479.e200"), ldexp(5554409530847367, 670));
00196 EXPECT_EQ(ToDouble("6802601037806061975.e198"), ldexp(5554409530847367, 668));
00197 EXPECT_EQ(ToDouble("20505426358836677347.e-221"),
00198 ldexp(4524032052079546, -722));
00199 EXPECT_EQ(ToDouble("836168422905420598437.e-234"),
00200 ldexp(5070963299887562, -760));
00201 EXPECT_EQ(ToDouble("4891559871276714924261.e222"),
00202 ldexp(6452687840519111, 757));
00203 EXPECT_EQ(ToFloat("5.e-20"), ldexpf(15474250, -88));
00204 EXPECT_EQ(ToFloat("67.e14"), ldexpf(12479722, 29));
00205 EXPECT_EQ(ToFloat("985.e15"), ldexpf(14333636, 36));
00206 EXPECT_EQ(ToFloat("7693.e-42"), ldexpf(10979816, -150));
00207 EXPECT_EQ(ToFloat("55895.e-16"), ldexpf(12888509, -61));
00208 EXPECT_EQ(ToFloat("996622.e-44"), ldexpf(14224264, -150));
00209 EXPECT_EQ(ToFloat("7038531.e-32"), ldexpf(11420669, -107));
00210 EXPECT_EQ(ToFloat("60419369.e-46"), ldexpf(8623340, -150));
00211 EXPECT_EQ(ToFloat("702990899.e-20"), ldexpf(16209866, -61));
00212 EXPECT_EQ(ToFloat("6930161142.e-48"), ldexpf(9891056, -150));
00213 EXPECT_EQ(ToFloat("25933168707.e-13"), ldexpf(11138211, -32));
00214 EXPECT_EQ(ToFloat("596428896559.e20"), ldexpf(12333860, 82));
00215
00216
00217 EXPECT_EQ(ToDouble("9.e-265"), ldexp(8168427841980010, -930));
00218 EXPECT_EQ(ToDouble("85.e-037"), ldexp(6360455125664090, -169));
00219 EXPECT_EQ(ToDouble("623.e100"), ldexp(6263531988747231, 289));
00220 EXPECT_EQ(ToDouble("3571.e263"), ldexp(6234526311072170, 833));
00221 EXPECT_EQ(ToDouble("81661.e153"), ldexp(6696636728760206, 472));
00222 EXPECT_EQ(ToDouble("920657.e-023"), ldexp(5975405561110124, -109));
00223 EXPECT_EQ(ToDouble("4603285.e-024"), ldexp(5975405561110124, -110));
00224 EXPECT_EQ(ToDouble("87575437.e-309"), ldexp(8452160731874668, -1053));
00225 EXPECT_EQ(ToDouble("245540327.e122"), ldexp(4985336549131723, 381));
00226 EXPECT_EQ(ToDouble("6138508175.e120"), ldexp(4985336549131723, 379));
00227 EXPECT_EQ(ToDouble("83356057653.e193"), ldexp(5986732817132056, 625));
00228 EXPECT_EQ(ToDouble("619534293513.e124"), ldexp(4798406992060657, 399));
00229 EXPECT_EQ(ToDouble("2335141086879.e218"), ldexp(5419088166961646, 713));
00230 EXPECT_EQ(ToDouble("36167929443327.e-159"), ldexp(8135819834632444, -536));
00231 EXPECT_EQ(ToDouble("609610927149051.e-255"), ldexp(4576664294594737, -850));
00232 EXPECT_EQ(ToDouble("3743626360493413.e-165"), ldexp(6898586531774201, -549));
00233 EXPECT_EQ(ToDouble("94080055902682397.e-242"), ldexp(6273271706052298, -800));
00234 EXPECT_EQ(ToDouble("899810892172646163.e283"), ldexp(7563892574477827, 947));
00235 EXPECT_EQ(ToDouble("7120190517612959703.e120"), ldexp(5385467232557565, 409));
00236 EXPECT_EQ(ToDouble("25188282901709339043.e-252"),
00237 ldexp(5635662608542340, -825));
00238 EXPECT_EQ(ToDouble("308984926168550152811.e-052"),
00239 ldexp(5644774693823803, -157));
00240 EXPECT_EQ(ToDouble("6372891218502368041059.e064"),
00241 ldexp(4616868614322430, 233));
00242
00243 EXPECT_EQ(ToFloat("3.e-23"), ldexpf(9507380, -98));
00244 EXPECT_EQ(ToFloat("57.e18"), ldexpf(12960300, 42));
00245 EXPECT_EQ(ToFloat("789.e-35"), ldexpf(10739312, -130));
00246 EXPECT_EQ(ToFloat("2539.e-18"), ldexpf(11990089, -72));
00247 EXPECT_EQ(ToFloat("76173.e28"), ldexpf(9845130, 86));
00248 EXPECT_EQ(ToFloat("887745.e-11"), ldexpf(9760860, -40));
00249 EXPECT_EQ(ToFloat("5382571.e-37"), ldexpf(11447463, -124));
00250 EXPECT_EQ(ToFloat("82381273.e-35"), ldexpf(8554961, -113));
00251 EXPECT_EQ(ToFloat("750486563.e-38"), ldexpf(9975678, -120));
00252 EXPECT_EQ(ToFloat("3752432815.e-39"), ldexpf(9975678, -121));
00253 EXPECT_EQ(ToFloat("75224575729.e-45"), ldexpf(13105970, -137));
00254 EXPECT_EQ(ToFloat("459926601011.e15"), ldexpf(12466336, 65));
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270 template <typename FloatType>
00271 void TestHalfwayValue(const std::string& mantissa, int exponent,
00272 FloatType expected_low, FloatType expected_high,
00273 FloatType expected_half) {
00274 std::string low_rep = mantissa;
00275 low_rep[low_rep.size() - 1] -= 1;
00276 absl::StrAppend(&low_rep, std::string(1000, '9'), "e", exponent);
00277
00278 FloatType actual_low = 0;
00279 absl::from_chars(low_rep.data(), low_rep.data() + low_rep.size(), actual_low);
00280 EXPECT_EQ(expected_low, actual_low);
00281
00282 std::string high_rep =
00283 absl::StrCat(mantissa, std::string(1000, '0'), "1e", exponent);
00284 FloatType actual_high = 0;
00285 absl::from_chars(high_rep.data(), high_rep.data() + high_rep.size(),
00286 actual_high);
00287 EXPECT_EQ(expected_high, actual_high);
00288
00289 std::string halfway_rep = absl::StrCat(mantissa, "e", exponent);
00290 FloatType actual_half = 0;
00291 absl::from_chars(halfway_rep.data(), halfway_rep.data() + halfway_rep.size(),
00292 actual_half);
00293 EXPECT_EQ(expected_half, actual_half);
00294 }
00295
00296 TEST(FromChars, DoubleRounding) {
00297 const double zero = 0.0;
00298 const double first_subnormal = nextafter(zero, 1.0);
00299 const double second_subnormal = nextafter(first_subnormal, 1.0);
00300
00301 const double first_normal = DBL_MIN;
00302 const double last_subnormal = nextafter(first_normal, 0.0);
00303 const double second_normal = nextafter(first_normal, 1.0);
00304
00305 const double last_normal = DBL_MAX;
00306 const double penultimate_normal = nextafter(last_normal, 0.0);
00307
00308
00309
00310
00311
00312
00313 TestHalfwayValue(
00314 "2."
00315 "470328229206232720882843964341106861825299013071623822127928412503377536"
00316 "351043759326499181808179961898982823477228588654633283551779698981993873"
00317 "980053909390631503565951557022639229085839244910518443593180284993653615"
00318 "250031937045767824921936562366986365848075700158576926990370631192827955"
00319 "855133292783433840935197801553124659726357957462276646527282722005637400"
00320 "648549997709659947045402082816622623785739345073633900796776193057750674"
00321 "017632467360096895134053553745851666113422376667860416215968046191446729"
00322 "184030053005753084904876539171138659164623952491262365388187963623937328"
00323 "042389101867234849766823508986338858792562830275599565752445550725518931"
00324 "369083625477918694866799496832404970582102851318545139621383772282614543"
00325 "7693412532098591327667236328125",
00326 -324, zero, first_subnormal, zero);
00327
00328
00329 TestHalfwayValue(
00330 "7."
00331 "410984687618698162648531893023320585475897039214871466383785237510132609"
00332 "053131277979497545424539885696948470431685765963899850655339096945981621"
00333 "940161728171894510697854671067917687257517734731555330779540854980960845"
00334 "750095811137303474765809687100959097544227100475730780971111893578483867"
00335 "565399878350301522805593404659373979179073872386829939581848166016912201"
00336 "945649993128979841136206248449867871357218035220901702390328579173252022"
00337 "052897402080290685402160661237554998340267130003581248647904138574340187"
00338 "552090159017259254714629617513415977493871857473787096164563890871811984"
00339 "127167305601704549300470526959016576377688490826798697257336652176556794"
00340 "107250876433756084600398490497214911746308553955635418864151316847843631"
00341 "3080237596295773983001708984375",
00342 -324, first_subnormal, second_subnormal, second_subnormal);
00343
00344
00345 TestHalfwayValue(
00346 "2."
00347 "225073858507201136057409796709131975934819546351645648023426109724822222"
00348 "021076945516529523908135087914149158913039621106870086438694594645527657"
00349 "207407820621743379988141063267329253552286881372149012981122451451889849"
00350 "057222307285255133155755015914397476397983411801999323962548289017107081"
00351 "850690630666655994938275772572015763062690663332647565300009245888316433"
00352 "037779791869612049497390377829704905051080609940730262937128958950003583"
00353 "799967207254304360284078895771796150945516748243471030702609144621572289"
00354 "880258182545180325707018860872113128079512233426288368622321503775666622"
00355 "503982534335974568884423900265498198385487948292206894721689831099698365"
00356 "846814022854243330660339850886445804001034933970427567186443383770486037"
00357 "86162277173854562306587467901408672332763671875",
00358 -308, last_subnormal, first_normal, first_normal);
00359
00360
00361 TestHalfwayValue(
00362 "2."
00363 "225073858507201630123055637955676152503612414573018013083228724049586647"
00364 "606759446192036794116886953213985520549032000903434781884412325572184367"
00365 "563347617020518175998922941393629966742598285899994830148971433555578567"
00366 "693279306015978183162142425067962460785295885199272493577688320732492479"
00367 "924816869232247165964934329258783950102250973957579510571600738343645738"
00368 "494324192997092179207389919761694314131497173265255020084997973676783743"
00369 "155205818804439163810572367791175177756227497413804253387084478193655533"
00370 "073867420834526162513029462022730109054820067654020201547112002028139700"
00371 "141575259123440177362244273712468151750189745559978653234255886219611516"
00372 "335924167958029604477064946470184777360934300451421683607013647479513962"
00373 "13837722826145437693412532098591327667236328125",
00374 -308, first_normal, second_normal, first_normal);
00375
00376
00377 TestHalfwayValue(
00378 "1."
00379 "797693134862315608353258760581052985162070023416521662616611746258695532"
00380 "672923265745300992879465492467506314903358770175220871059269879629062776"
00381 "047355692132901909191523941804762171253349609463563872612866401980290377"
00382 "995141836029815117562837277714038305214839639239356331336428021390916694"
00383 "57927874464075218944",
00384 308, penultimate_normal, last_normal, penultimate_normal);
00385 }
00386
00387
00388
00389 TEST(FromChars, FloatRounding) {
00390 const float zero = 0.0;
00391 const float first_subnormal = nextafterf(zero, 1.0);
00392 const float second_subnormal = nextafterf(first_subnormal, 1.0);
00393
00394 const float first_normal = FLT_MIN;
00395 const float last_subnormal = nextafterf(first_normal, 0.0);
00396 const float second_normal = nextafterf(first_normal, 1.0);
00397
00398 const float last_normal = FLT_MAX;
00399 const float penultimate_normal = nextafterf(last_normal, 0.0);
00400
00401
00402 TestHalfwayValue(
00403 "7."
00404 "006492321624085354618647916449580656401309709382578858785341419448955413"
00405 "42930300743319094181060791015625",
00406 -46, zero, first_subnormal, zero);
00407
00408
00409 TestHalfwayValue(
00410 "2."
00411 "101947696487225606385594374934874196920392912814773657635602425834686624"
00412 "028790902229957282543182373046875",
00413 -45, first_subnormal, second_subnormal, second_subnormal);
00414
00415
00416 TestHalfwayValue(
00417 "1."
00418 "175494280757364291727882991035766513322858992758990427682963118425003064"
00419 "9651730385585324256680905818939208984375",
00420 -38, last_subnormal, first_normal, first_normal);
00421
00422
00423 TestHalfwayValue(
00424 "1."
00425 "175494420887210724209590083408724842314472120785184615334540294131831453"
00426 "9442813071445925743319094181060791015625",
00427 -38, first_normal, second_normal, first_normal);
00428
00429
00430 TestHalfwayValue("3.40282336497324057985868971510891282432", 38,
00431 penultimate_normal, last_normal, penultimate_normal);
00432 }
00433
00434 TEST(FromChars, Underflow) {
00435
00436
00437 double d;
00438 float f;
00439 absl::from_chars_result result;
00440
00441 std::string negative_underflow = "-1e-1000";
00442 const char* begin = negative_underflow.data();
00443 const char* end = begin + negative_underflow.size();
00444 d = 100.0;
00445 result = absl::from_chars(begin, end, d);
00446 EXPECT_EQ(result.ptr, end);
00447 EXPECT_EQ(result.ec, std::errc::result_out_of_range);
00448 EXPECT_TRUE(std::signbit(d));
00449 EXPECT_GE(d, -std::numeric_limits<double>::min());
00450 f = 100.0;
00451 result = absl::from_chars(begin, end, f);
00452 EXPECT_EQ(result.ptr, end);
00453 EXPECT_EQ(result.ec, std::errc::result_out_of_range);
00454 EXPECT_TRUE(std::signbit(f));
00455 EXPECT_GE(f, -std::numeric_limits<float>::min());
00456
00457 std::string positive_underflow = "1e-1000";
00458 begin = positive_underflow.data();
00459 end = begin + positive_underflow.size();
00460 d = -100.0;
00461 result = absl::from_chars(begin, end, d);
00462 EXPECT_EQ(result.ptr, end);
00463 EXPECT_EQ(result.ec, std::errc::result_out_of_range);
00464 EXPECT_FALSE(std::signbit(d));
00465 EXPECT_LE(d, std::numeric_limits<double>::min());
00466 f = -100.0;
00467 result = absl::from_chars(begin, end, f);
00468 EXPECT_EQ(result.ptr, end);
00469 EXPECT_EQ(result.ec, std::errc::result_out_of_range);
00470 EXPECT_FALSE(std::signbit(f));
00471 EXPECT_LE(f, std::numeric_limits<float>::min());
00472 }
00473
00474 TEST(FromChars, Overflow) {
00475
00476
00477 double d;
00478 float f;
00479 absl::from_chars_result result;
00480
00481 std::string negative_overflow = "-1e1000";
00482 const char* begin = negative_overflow.data();
00483 const char* end = begin + negative_overflow.size();
00484 d = 100.0;
00485 result = absl::from_chars(begin, end, d);
00486 EXPECT_EQ(result.ptr, end);
00487 EXPECT_EQ(result.ec, std::errc::result_out_of_range);
00488 EXPECT_TRUE(std::signbit(d));
00489 EXPECT_EQ(d, -std::numeric_limits<double>::max());
00490 f = 100.0;
00491 result = absl::from_chars(begin, end, f);
00492 EXPECT_EQ(result.ptr, end);
00493 EXPECT_EQ(result.ec, std::errc::result_out_of_range);
00494 EXPECT_TRUE(std::signbit(f));
00495 EXPECT_EQ(f, -std::numeric_limits<float>::max());
00496
00497 std::string positive_overflow = "1e1000";
00498 begin = positive_overflow.data();
00499 end = begin + positive_overflow.size();
00500 d = -100.0;
00501 result = absl::from_chars(begin, end, d);
00502 EXPECT_EQ(result.ptr, end);
00503 EXPECT_EQ(result.ec, std::errc::result_out_of_range);
00504 EXPECT_FALSE(std::signbit(d));
00505 EXPECT_EQ(d, std::numeric_limits<double>::max());
00506 f = -100.0;
00507 result = absl::from_chars(begin, end, f);
00508 EXPECT_EQ(result.ptr, end);
00509 EXPECT_EQ(result.ec, std::errc::result_out_of_range);
00510 EXPECT_FALSE(std::signbit(f));
00511 EXPECT_EQ(f, std::numeric_limits<float>::max());
00512 }
00513
00514 TEST(FromChars, ReturnValuePtr) {
00515
00516
00517 double d;
00518 absl::from_chars_result result;
00519
00520 std::string normal = "3.14@#$%@#$%";
00521 result = absl::from_chars(normal.data(), normal.data() + normal.size(), d);
00522 EXPECT_EQ(result.ec, std::errc());
00523 EXPECT_EQ(result.ptr - normal.data(), 4);
00524
00525 std::string overflow = "1e1000@#$%@#$%";
00526 result = absl::from_chars(overflow.data(),
00527 overflow.data() + overflow.size(), d);
00528 EXPECT_EQ(result.ec, std::errc::result_out_of_range);
00529 EXPECT_EQ(result.ptr - overflow.data(), 6);
00530
00531 std::string garbage = "#$%@#$%";
00532 result = absl::from_chars(garbage.data(),
00533 garbage.data() + garbage.size(), d);
00534 EXPECT_EQ(result.ec, std::errc::invalid_argument);
00535 EXPECT_EQ(result.ptr - garbage.data(), 0);
00536 }
00537
00538
00539
00540
00541
00542
00543 TEST(FromChars, TestVersusStrtod) {
00544 for (int mantissa = 1000000; mantissa <= 9999999; mantissa += 501) {
00545 for (int exponent = -300; exponent < 300; ++exponent) {
00546 std::string candidate = absl::StrCat(mantissa, "e", exponent);
00547 double strtod_value = strtod(candidate.c_str(), nullptr);
00548 double absl_value = 0;
00549 absl::from_chars(candidate.data(), candidate.data() + candidate.size(),
00550 absl_value);
00551 ASSERT_EQ(strtod_value, absl_value) << candidate;
00552 }
00553 }
00554 }
00555
00556
00557
00558
00559
00560
00561 TEST(FromChars, TestVersusStrtof) {
00562 for (int mantissa = 1000000; mantissa <= 9999999; mantissa += 501) {
00563 for (int exponent = -43; exponent < 32; ++exponent) {
00564 std::string candidate = absl::StrCat(mantissa, "e", exponent);
00565 float strtod_value = strtof(candidate.c_str(), nullptr);
00566 float absl_value = 0;
00567 absl::from_chars(candidate.data(), candidate.data() + candidate.size(),
00568 absl_value);
00569 ASSERT_EQ(strtod_value, absl_value) << candidate;
00570 }
00571 }
00572 }
00573
00574
00575
00576 template <typename Float>
00577 bool Identical(Float a, Float b) {
00578 return 0 == memcmp(&a, &b, sizeof(Float));
00579 }
00580
00581
00582
00583
00584
00585
00586
00587
00588 TEST(FromChars, NaNDoubles) {
00589 for (std::string n_char_sequence :
00590 {"", "1", "2", "3", "fff", "FFF", "200000", "400000", "4000000000000",
00591 "8000000000000", "abc123", "legal_but_unexpected",
00592 "99999999999999999999999", "_"}) {
00593 std::string input = absl::StrCat("nan(", n_char_sequence, ")");
00594 SCOPED_TRACE(input);
00595 double from_chars_double;
00596 absl::from_chars(input.data(), input.data() + input.size(),
00597 from_chars_double);
00598 double std_nan_double = std::nan(n_char_sequence.c_str());
00599 EXPECT_TRUE(Identical(from_chars_double, std_nan_double));
00600
00601
00602
00603 #if ABSL_STRTOD_HANDLES_NAN_CORRECTLY
00604 double strtod_double = strtod(input.c_str(), nullptr);
00605 EXPECT_TRUE(Identical(from_chars_double, strtod_double));
00606 #endif // ABSL_STRTOD_HANDLES_NAN_CORRECTLY
00607
00608
00609 std::string negative_input = "-" + input;
00610 double negative_from_chars_double;
00611 absl::from_chars(negative_input.data(),
00612 negative_input.data() + negative_input.size(),
00613 negative_from_chars_double);
00614 EXPECT_TRUE(std::signbit(negative_from_chars_double));
00615 EXPECT_FALSE(Identical(negative_from_chars_double, from_chars_double));
00616 from_chars_double = std::copysign(from_chars_double, -1.0);
00617 EXPECT_TRUE(Identical(negative_from_chars_double, from_chars_double));
00618 }
00619 }
00620
00621 TEST(FromChars, NaNFloats) {
00622 for (std::string n_char_sequence :
00623 {"", "1", "2", "3", "fff", "FFF", "200000", "400000", "4000000000000",
00624 "8000000000000", "abc123", "legal_but_unexpected",
00625 "99999999999999999999999", "_"}) {
00626 std::string input = absl::StrCat("nan(", n_char_sequence, ")");
00627 SCOPED_TRACE(input);
00628 float from_chars_float;
00629 absl::from_chars(input.data(), input.data() + input.size(),
00630 from_chars_float);
00631 float std_nan_float = std::nanf(n_char_sequence.c_str());
00632 EXPECT_TRUE(Identical(from_chars_float, std_nan_float));
00633
00634
00635
00636 #if ABSL_STRTOD_HANDLES_NAN_CORRECTLY
00637 float strtof_float = strtof(input.c_str(), nullptr);
00638 EXPECT_TRUE(Identical(from_chars_float, strtof_float));
00639 #endif // ABSL_STRTOD_HANDLES_NAN_CORRECTLY
00640
00641
00642 std::string negative_input = "-" + input;
00643 float negative_from_chars_float;
00644 absl::from_chars(negative_input.data(),
00645 negative_input.data() + negative_input.size(),
00646 negative_from_chars_float);
00647 EXPECT_TRUE(std::signbit(negative_from_chars_float));
00648 EXPECT_FALSE(Identical(negative_from_chars_float, from_chars_float));
00649 from_chars_float = std::copysign(from_chars_float, -1.0);
00650 EXPECT_TRUE(Identical(negative_from_chars_float, from_chars_float));
00651 }
00652 }
00653
00654
00655 int NextStep(int step) {
00656 return step + (step >> 2) + 1;
00657 }
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670 template <typename Float>
00671 void TestOverflowAndUnderflow(
00672 const std::function<std::string(int)>& input_generator,
00673 const std::function<Float(int)>& expected_generator, int lower_bound,
00674 int upper_bound) {
00675
00676 int index, step;
00677 for (index = lower_bound, step = 1; index < upper_bound;
00678 index += step, step = NextStep(step)) {
00679 std::string input = input_generator(index);
00680 SCOPED_TRACE(input);
00681 Float expected = expected_generator(index);
00682 Float actual;
00683 auto result =
00684 absl::from_chars(input.data(), input.data() + input.size(), actual);
00685 EXPECT_EQ(result.ec, std::errc());
00686 EXPECT_EQ(expected, actual)
00687 << absl::StrFormat("%a vs %a", expected, actual);
00688 }
00689
00690 for (index = upper_bound, step = 1; index > lower_bound;
00691 index -= step, step = NextStep(step)) {
00692 std::string input = input_generator(index);
00693 SCOPED_TRACE(input);
00694 Float expected = expected_generator(index);
00695 Float actual;
00696 auto result =
00697 absl::from_chars(input.data(), input.data() + input.size(), actual);
00698 EXPECT_EQ(result.ec, std::errc());
00699 EXPECT_EQ(expected, actual)
00700 << absl::StrFormat("%a vs %a", expected, actual);
00701 }
00702
00703 for (index = lower_bound - 1, step = 1; index > -1000000;
00704 index -= step, step = NextStep(step)) {
00705 std::string input = input_generator(index);
00706 SCOPED_TRACE(input);
00707 Float actual;
00708 auto result =
00709 absl::from_chars(input.data(), input.data() + input.size(), actual);
00710 EXPECT_EQ(result.ec, std::errc::result_out_of_range);
00711 EXPECT_LT(actual, 1.0);
00712 }
00713
00714 for (index = upper_bound + 1, step = 1; index < 1000000;
00715 index += step, step = NextStep(step)) {
00716 std::string input = input_generator(index);
00717 SCOPED_TRACE(input);
00718 Float actual;
00719 auto result =
00720 absl::from_chars(input.data(), input.data() + input.size(), actual);
00721 EXPECT_EQ(result.ec, std::errc::result_out_of_range);
00722 EXPECT_GT(actual, 1.0);
00723 }
00724 }
00725
00726
00727
00728
00729
00730
00731
00732 TEST(FromChars, HexdecimalDoubleLimits) {
00733 auto input_gen = [](int index) { return absl::StrCat("0x1.0p", index); };
00734 auto expected_gen = [](int index) { return std::ldexp(1.0, index); };
00735 TestOverflowAndUnderflow<double>(input_gen, expected_gen, -1074, 1023);
00736 }
00737
00738
00739
00740
00741
00742
00743 TEST(FromChars, HexdecimalFloatLimits) {
00744 auto input_gen = [](int index) { return absl::StrCat("0x1.0p", index); };
00745 auto expected_gen = [](int index) { return std::ldexp(1.0f, index); };
00746 TestOverflowAndUnderflow<float>(input_gen, expected_gen, -149, 127);
00747 }
00748
00749
00750
00751
00752
00753
00754
00755 TEST(FromChars, DecimalDoubleLimits) {
00756 auto input_gen = [](int index) { return absl::StrCat("1.0e", index); };
00757 auto expected_gen = [](int index) { return Pow10(index); };
00758 TestOverflowAndUnderflow<double>(input_gen, expected_gen, -323, 308);
00759 }
00760
00761
00762
00763
00764
00765
00766
00767 TEST(FromChars, DecimalFloatLimits) {
00768 auto input_gen = [](int index) { return absl::StrCat("1.0e", index); };
00769 auto expected_gen = [](int index) { return Pow10(index); };
00770 TestOverflowAndUnderflow<float>(input_gen, expected_gen, -45, 38);
00771 }
00772
00773 }