charconv_test.cc
Go to the documentation of this file.
00001 // Copyright 2018 The Abseil Authors.
00002 //
00003 // Licensed under the Apache License, Version 2.0 (the "License");
00004 // you may not use this file except in compliance with the License.
00005 // You may obtain a copy of the License at
00006 //
00007 //      https://www.apache.org/licenses/LICENSE-2.0
00008 //
00009 // Unless required by applicable law or agreed to in writing, software
00010 // distributed under the License is distributed on an "AS IS" BASIS,
00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012 // See the License for the specific language governing permissions and
00013 // limitations under the License.
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 // Tests that the given string is accepted by absl::from_chars, and that it
00041 // converts exactly equal to the given number.
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 // Tests that the given double or single precision floating point literal is
00063 // parsed correctly by absl::from_chars.
00064 //
00065 // These convenience macros assume that the C++ compiler being used also does
00066 // fully correct decimal-to-binary conversions.
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   // Cases from "A Program for Testing IEEE Decimal-Binary Conversion"
00081   // by Vern Paxson.
00082 
00083   // Forms that should round towards zero.  (These are the hardest cases for
00084   // each decimal mantissa size.)
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   // Similarly, forms that should round away from zero.
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 // A duplication of the test cases in "NearRoundingCases" above, but with
00174 // expected values expressed with integers, using ldexp/ldexpf.  These test
00175 // cases will work even on compilers that do not accurately round floating point
00176 // literals.
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 // Common test logic for converting a string which lies exactly halfway between
00258 // two target floats.
00259 //
00260 // mantissa and exponent represent the precise value between two floating point
00261 // numbers, `expected_low` and `expected_high`.  The floating point
00262 // representation to parse in `StrCat(mantissa, "e", exponent)`.
00263 //
00264 // This function checks that an input just slightly less than the exact value
00265 // is rounded down to `expected_low`, and an input just slightly greater than
00266 // the exact value is rounded up to `expected_high`.
00267 //
00268 // The exact value should round to `expected_half`, which must be either
00269 // `expected_low` or `expected_high`.
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   // Various test cases for numbers between two representable floats.  Each
00309   // call to TestHalfwayValue tests a number just below and just above the
00310   // halfway point, as well as the number exactly between them.
00311 
00312   // Test between zero and first_subnormal.  Round-to-even tie rounds down.
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   // first_subnormal and second_subnormal.  Round-to-even tie rounds up.
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   // last_subnormal and first_normal.  Round-to-even tie rounds up.
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   // first_normal and second_normal.  Round-to-even tie rounds down.
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   // penultimate_normal and last_normal.  Round-to-even rounds down.
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 // Same test cases as DoubleRounding, now with new and improved Much Smaller
00388 // Precision!
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   // Test between zero and first_subnormal.  Round-to-even tie rounds down.
00402   TestHalfwayValue(
00403       "7."
00404       "006492321624085354618647916449580656401309709382578858785341419448955413"
00405       "42930300743319094181060791015625",
00406       -46, zero, first_subnormal, zero);
00407 
00408   // first_subnormal and second_subnormal.  Round-to-even tie rounds up.
00409   TestHalfwayValue(
00410       "2."
00411       "101947696487225606385594374934874196920392912814773657635602425834686624"
00412       "028790902229957282543182373046875",
00413       -45, first_subnormal, second_subnormal, second_subnormal);
00414 
00415   // last_subnormal and first_normal.  Round-to-even tie rounds up.
00416   TestHalfwayValue(
00417       "1."
00418       "175494280757364291727882991035766513322858992758990427682963118425003064"
00419       "9651730385585324256680905818939208984375",
00420       -38, last_subnormal, first_normal, first_normal);
00421 
00422   // first_normal and second_normal.  Round-to-even tie rounds down.
00423   TestHalfwayValue(
00424       "1."
00425       "175494420887210724209590083408724842314472120785184615334540294131831453"
00426       "9442813071445925743319094181060791015625",
00427       -38, first_normal, second_normal, first_normal);
00428 
00429   // penultimate_normal and last_normal.  Round-to-even rounds down.
00430   TestHalfwayValue("3.40282336497324057985868971510891282432", 38,
00431                    penultimate_normal, last_normal, penultimate_normal);
00432 }
00433 
00434 TEST(FromChars, Underflow) {
00435   // Check that underflow is handled correctly, according to the specification
00436   // in DR 3081.
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));  // negative
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));  // negative
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));  // positive
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));  // positive
00471   EXPECT_LE(f, std::numeric_limits<float>::min());
00472 }
00473 
00474 TEST(FromChars, Overflow) {
00475   // Check that overflow is handled correctly, according to the specification
00476   // in DR 3081.
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));  // negative
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));  // negative
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));  // positive
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));  // positive
00511   EXPECT_EQ(f, std::numeric_limits<float>::max());
00512 }
00513 
00514 TEST(FromChars, ReturnValuePtr) {
00515   // Check that `ptr` points one past the number scanned, even if that number
00516   // is not representable.
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 // Check for a wide range of inputs that strtod() and absl::from_chars() exactly
00539 // agree on the conversion amount.
00540 //
00541 // This test assumes the platform's strtod() uses perfect round_to_nearest
00542 // rounding.
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 // Check for a wide range of inputs that strtof() and absl::from_chars() exactly
00557 // agree on the conversion amount.
00558 //
00559 // This test assumes the platform's strtof() uses perfect round_to_nearest
00560 // rounding.
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 // Tests if two floating point values have identical bit layouts.  (EXPECT_EQ
00575 // is not suitable for NaN testing, since NaNs are never equal.)
00576 template <typename Float>
00577 bool Identical(Float a, Float b) {
00578   return 0 == memcmp(&a, &b, sizeof(Float));
00579 }
00580 
00581 // Check that NaNs are parsed correctly.  The spec requires that
00582 // std::from_chars on "NaN(123abc)" return the same value as std::nan("123abc").
00583 // How such an n-char-sequence affects the generated NaN is unspecified, so we
00584 // just test for symmetry with std::nan and strtod here.
00585 //
00586 // (In Linux, this parses the value as a number and stuffs that number into the
00587 // free bits of a quiet NaN.)
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     // Also check that we match strtod()'s behavior.  This test assumes that the
00602     // platform has a compliant strtod().
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     // Check that we can parse a negative NaN
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     // Also check that we match strtof()'s behavior.  This test assumes that the
00635     // platform has a compliant strtof().
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     // Check that we can parse a negative NaN
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 // Returns an integer larger than step.  The values grow exponentially.
00655 int NextStep(int step) {
00656   return step + (step >> 2) + 1;
00657 }
00658 
00659 // Test a conversion on a family of input strings, checking that the calculation
00660 // is correct for in-bounds values, and that overflow and underflow are done
00661 // correctly for out-of-bounds values.
00662 //
00663 // input_generator maps from an integer index to a string to test.
00664 // expected_generator maps from an integer index to an expected Float value.
00665 // from_chars conversion of input_generator(i) should result in
00666 // expected_generator(i).
00667 //
00668 // lower_bound and upper_bound denote the smallest and largest values for which
00669 // the conversion is expected to succeed.
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   // test legal values near lower_bound
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   // test legal values near upper_bound
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   // Test underflow values below lower_bound
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);  // check for underflow
00712   }
00713   // Test overflow values above upper_bound
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);  // check for overflow
00723   }
00724 }
00725 
00726 // Check that overflow and underflow are caught correctly for hex doubles.
00727 //
00728 // The largest representable double is 0x1.fffffffffffffp+1023, and the
00729 // smallest representable subnormal is 0x0.0000000000001p-1022, which equals
00730 // 0x1p-1074.  Therefore 1023 and -1074 are the limits of acceptable exponents
00731 // in this test.
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 // Check that overflow and underflow are caught correctly for hex floats.
00739 //
00740 // The largest representable float is 0x1.fffffep+127, and the smallest
00741 // representable subnormal is 0x0.000002p-126, which equals 0x1p-149.
00742 // Therefore 127 and -149 are the limits of acceptable exponents in this test.
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 // Check that overflow and underflow are caught correctly for decimal doubles.
00750 //
00751 // The largest representable double is about 1.8e308, and the smallest
00752 // representable subnormal is about 5e-324.  '1e-324' therefore rounds away from
00753 // the smallest representable positive value.  -323 and 308 are the limits of
00754 // acceptable exponents in this test.
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 // Check that overflow and underflow are caught correctly for decimal floats.
00762 //
00763 // The largest representable float is about 3.4e38, and the smallest
00764 // representable subnormal is about 1.45e-45.  '1e-45' therefore rounds towards
00765 // the smallest representable positive value.  -45 and 38 are the limits of
00766 // acceptable exponents in this test.
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 }  // namespace


abseil_cpp
Author(s):
autogenerated on Wed Jun 19 2019 19:42:14