| 1 | // Copyright (c) Microsoft Corporation. |
| 2 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 3 | |
| 4 | #ifndef FLOATING_POINT_TEST_CASES_HPP |
| 5 | #define FLOATING_POINT_TEST_CASES_HPP |
| 6 | |
| 7 | #include <stdint.h> |
| 8 | #include <utility> |
| 9 | |
| 10 | constexpr std::pair<const char*, std::uint64_t> floating_point_test_cases_double[] = { |
| 11 | // Verify small exactly-representable integers: |
| 12 | {"1" , 0x3FF0000000000000ULL}, |
| 13 | {"2" , 0x4000000000000000ULL}, |
| 14 | {"3" , 0x4008000000000000ULL}, |
| 15 | {"4" , 0x4010000000000000ULL}, |
| 16 | {"5" , 0x4014000000000000ULL}, |
| 17 | {"6" , 0x4018000000000000ULL}, |
| 18 | {"7" , 0x401C000000000000ULL}, |
| 19 | {"8" , 0x4020000000000000ULL}, |
| 20 | |
| 21 | // Verify large exactly-representable integers: |
| 22 | {"9007199254740984" , 0x433FFFFFFFFFFFF8ULL}, |
| 23 | {"9007199254740985" , 0x433FFFFFFFFFFFF9ULL}, |
| 24 | {"9007199254740986" , 0x433FFFFFFFFFFFFAULL}, |
| 25 | {"9007199254740987" , 0x433FFFFFFFFFFFFBULL}, |
| 26 | {"9007199254740988" , 0x433FFFFFFFFFFFFCULL}, |
| 27 | {"9007199254740989" , 0x433FFFFFFFFFFFFDULL}, |
| 28 | {"9007199254740990" , 0x433FFFFFFFFFFFFEULL}, |
| 29 | {"9007199254740991" , 0x433FFFFFFFFFFFFFULL}, // 2^53 - 1 |
| 30 | |
| 31 | // Verify the smallest denormal values: |
| 32 | {"5.0e-324" , 0x0000000000000001ULL}, |
| 33 | {"1.0e-323" , 0x0000000000000002ULL}, |
| 34 | {"1.5e-323" , 0x0000000000000003ULL}, |
| 35 | {"2.0e-323" , 0x0000000000000004ULL}, |
| 36 | {"2.5e-323" , 0x0000000000000005ULL}, |
| 37 | {"3.0e-323" , 0x0000000000000006ULL}, |
| 38 | {"3.5e-323" , 0x0000000000000007ULL}, |
| 39 | {"4.0e-323" , 0x0000000000000008ULL}, |
| 40 | {"4.5e-323" , 0x0000000000000009ULL}, |
| 41 | {"5.0e-323" , 0x000000000000000AULL}, |
| 42 | {"5.5e-323" , 0x000000000000000BULL}, |
| 43 | {"6.0e-323" , 0x000000000000000CULL}, |
| 44 | {"6.5e-323" , 0x000000000000000DULL}, |
| 45 | {"7.0e-323" , 0x000000000000000EULL}, |
| 46 | {"7.5e-323" , 0x000000000000000FULL}, |
| 47 | |
| 48 | // Verify the largest denormal values: |
| 49 | {"2.2250738585071935e-308" , 0x000FFFFFFFFFFFF0ULL}, |
| 50 | {"2.2250738585071940e-308" , 0x000FFFFFFFFFFFF1ULL}, |
| 51 | {"2.2250738585071945e-308" , 0x000FFFFFFFFFFFF2ULL}, |
| 52 | {"2.2250738585071950e-308" , 0x000FFFFFFFFFFFF3ULL}, |
| 53 | {"2.2250738585071955e-308" , 0x000FFFFFFFFFFFF4ULL}, |
| 54 | {"2.2250738585071960e-308" , 0x000FFFFFFFFFFFF5ULL}, |
| 55 | {"2.2250738585071964e-308" , 0x000FFFFFFFFFFFF6ULL}, |
| 56 | {"2.2250738585071970e-308" , 0x000FFFFFFFFFFFF7ULL}, |
| 57 | {"2.2250738585071974e-308" , 0x000FFFFFFFFFFFF8ULL}, |
| 58 | {"2.2250738585071980e-308" , 0x000FFFFFFFFFFFF9ULL}, |
| 59 | {"2.2250738585071984e-308" , 0x000FFFFFFFFFFFFAULL}, |
| 60 | {"2.2250738585071990e-308" , 0x000FFFFFFFFFFFFBULL}, |
| 61 | {"2.2250738585071994e-308" , 0x000FFFFFFFFFFFFCULL}, |
| 62 | {"2.2250738585072000e-308" , 0x000FFFFFFFFFFFFDULL}, |
| 63 | {"2.2250738585072004e-308" , 0x000FFFFFFFFFFFFEULL}, |
| 64 | {"2.2250738585072010e-308" , 0x000FFFFFFFFFFFFFULL}, |
| 65 | |
| 66 | // DevDiv#576315 "I/O library incorrect rounds floating point numbers on input" |
| 67 | // DevDiv#616647 "Visual C++ 11: iostream bug: incorrect input streaming of the smallest normal double and some |
| 68 | // denormals" |
| 69 | // DevDiv#730414 "iostreams is still misparsing floating-point" |
| 70 | // DevDiv#938627 "parsing float values using std::istream gives results inconsistent with sscanf() and with C++ |
| 71 | // compiler" |
| 72 | // DevDiv#961116 "floating point string conversion accuracy" |
| 73 | {"2.2250738585072014e-308" , 0x0010000000000000ULL}, // DBL_MIN |
| 74 | {"1.7976931348623158e+308" , 0x7FEFFFFFFFFFFFFFULL}, // DBL_MAX |
| 75 | {"4.26144921954407e-309" , 0x00031076B2F00000ULL}, |
| 76 | {"179.9999999999999855" , 0x40667FFFFFFFFFFFULL}, |
| 77 | {"4.1" , 0x4010666666666666ULL}, |
| 78 | {"0.2288884" , 0x3FCD4C37103785A8ULL}, |
| 79 | {"0.168" , 0x3FC5810624DD2F1BULL}, |
| 80 | {"1.68" , 0x3FFAE147AE147AE1ULL}, |
| 81 | {"16.80000001" , 0x4030CCCCCCF7BFEBULL}, |
| 82 | |
| 83 | // Test cases from Rick Regan's article, "Incorrectly Rounded Conversions in Visual C++": |
| 84 | // https://www.exploringbinary.com/incorrectly-rounded-conversions-in-visual-c-plus-plus/ |
| 85 | |
| 86 | // Example 1: |
| 87 | {"9214843084008499" , 0x43405E6CEC57761AULL}, |
| 88 | |
| 89 | // Example 2 (2^-1 + 2^-53 + 2^-54): |
| 90 | {"0.500000000000000166533453693773481063544750213623046875" , 0x3FE0000000000002ULL}, |
| 91 | |
| 92 | // Example 3: |
| 93 | {"30078505129381147446200" , 0x44997A3C7271B021ULL}, |
| 94 | |
| 95 | // Example 4: |
| 96 | {"1777820000000000000001" , 0x4458180D5BAD2E3EULL}, |
| 97 | |
| 98 | // Example 5 (2^-1 + 2^-53 + 2^-54 + 2^-66): |
| 99 | {"0.500000000000000166547006220929549868969843373633921146392822265625" , 0x3FE0000000000002ULL}, |
| 100 | |
| 101 | // Example 6 (2^-1 + 2^-53 + 2^-54 + 2^-65): |
| 102 | {"0.50000000000000016656055874808561867439493653364479541778564453125" , 0x3FE0000000000002ULL}, |
| 103 | |
| 104 | // Example 7: |
| 105 | {"0.3932922657273" , 0x3FD92BB352C4623AULL}, |
| 106 | |
| 107 | // The following test cases are taken from other articles on Rick Regan's |
| 108 | // Exploring Binary blog. These are conversions that other implementations |
| 109 | // were found to perform incorrectly. |
| 110 | |
| 111 | // https://www.exploringbinary.com/incorrectly-rounded-subnormal-conversions-in-java/ |
| 112 | // Example 1 (2^-1047 + 2^-1075, half-ulp above a power of two): |
| 113 | {"6.6312368714697582767853966302759672433990999473553031442499717587" |
| 114 | "362866301392654396180682007880487441059604205526018528897150063763" |
| 115 | "256665955396033303618005191075917832333584923372080578494993608994" |
| 116 | "251286407188566165030934449228547591599881603044399098682919739314" |
| 117 | "266256986631577498362522745234853124423586512070512924530832781161" |
| 118 | "439325697279187097860044978723221938561502254152119972830784963194" |
| 119 | "121246401117772161481107528151017752957198119743384519360959074196" |
| 120 | "224175384736794951486324803914359317679811223967034438033355297560" |
| 121 | "033532098300718322306892013830155987921841729099279241763393155074" |
| 122 | "022348361207309147831684007154624400538175927027662135590421159867" |
| 123 | "638194826541287705957668068727833491469671712939495988506756821156" |
| 124 | "96218943412532098591327667236328125E-316" , |
| 125 | 0x0000000008000000ULL}, |
| 126 | |
| 127 | // Example 2 (2^-1058 - 2^-1075, half-ulp below a power of two): |
| 128 | {"3.2378839133029012895883524125015321748630376694231080599012970495" |
| 129 | "523019706706765657868357425877995578606157765598382834355143910841" |
| 130 | "531692526891905643964595773946180389283653051434639551003566966656" |
| 131 | "292020173313440317300443693602052583458034314716600326995807313009" |
| 132 | "548483639755486900107515300188817581841745696521731104736960227499" |
| 133 | "346384253806233697747365600089974040609674980283891918789639685754" |
| 134 | "392222064169814626901133425240027243859416510512935526014211553334" |
| 135 | "302252372915238433223313261384314778235911424088000307751706259156" |
| 136 | "707286570031519536642607698224949379518458015308952384398197084033" |
| 137 | "899378732414634842056080000272705311068273879077914449185347715987" |
| 138 | "501628125488627684932015189916680282517302999531439241685457086639" |
| 139 | "13273994694463908672332763671875E-319" , |
| 140 | 0x0000000000010000ULL}, |
| 141 | |
| 142 | // Example 3 (2^-1027 + 2^-1066 + 2^-1075, half-ulp above a non-power of two): |
| 143 | {"6.9533558078476771059728052155218916902221198171459507544162056079" |
| 144 | "800301315496366888061157263994418800653863998640286912755395394146" |
| 145 | "528315847956685600829998895513577849614468960421131982842131079351" |
| 146 | "102171626549398024160346762138294097205837595404767869364138165416" |
| 147 | "212878432484332023692099166122496760055730227032447997146221165421" |
| 148 | "888377703760223711720795591258533828013962195524188394697705149041" |
| 149 | "926576270603193728475623010741404426602378441141744972109554498963" |
| 150 | "891803958271916028866544881824524095839813894427833770015054620157" |
| 151 | "450178487545746683421617594966617660200287528887833870748507731929" |
| 152 | "971029979366198762266880963149896457660004790090837317365857503352" |
| 153 | "620998601508967187744019647968271662832256419920407478943826987518" |
| 154 | "09812609536720628966577351093292236328125E-310" , |
| 155 | 0x0000800000000100ULL}, |
| 156 | |
| 157 | // Example 4 (2^-1058 + 2^-1063 - 2^-1075, half-ulp below a non-power of two): |
| 158 | {"3.3390685575711885818357137012809439119234019169985217716556569973" |
| 159 | "284403145596153181688491490746626090999981130094655664268081703784" |
| 160 | "340657229916596426194677060348844249897410807907667784563321682004" |
| 161 | "646515939958173717821250106683466529959122339932545844611258684816" |
| 162 | "333436749050742710644097630907080178565840197768788124253120088123" |
| 163 | "262603630354748115322368533599053346255754042160606228586332807443" |
| 164 | "018924703005556787346899784768703698535494132771566221702458461669" |
| 165 | "916553215355296238706468887866375289955928004361779017462862722733" |
| 166 | "744717014529914330472578638646014242520247915673681950560773208853" |
| 167 | "293843223323915646452641434007986196650406080775491621739636492640" |
| 168 | "497383622906068758834568265867109610417379088720358034812416003767" |
| 169 | "05491726170293986797332763671875E-319" , |
| 170 | 0x0000000000010800ULL}, |
| 171 | |
| 172 | // A number between 2^-1074 and 2^-1075, just slightly larger than 2^-1075. |
| 173 | // It has bit 1075 set (the denormal rounding bit), followed by 2506 zeroes, |
| 174 | // followed by one bits. It should round up to 2^-1074. |
| 175 | {"2.470328229206232720882843964341106861825299013071623822127928412503" |
| 176 | "37753635104375932649918180817996189898282347722858865463328355177969" |
| 177 | "89819938739800539093906315035659515570226392290858392449105184435931" |
| 178 | "80284993653615250031937045767824921936562366986365848075700158576926" |
| 179 | "99037063119282795585513329278343384093519780155312465972635795746227" |
| 180 | "66465272827220056374006485499977096599470454020828166226237857393450" |
| 181 | "73633900796776193057750674017632467360096895134053553745851666113422" |
| 182 | "37666786041621596804619144672918403005300575308490487653917113865916" |
| 183 | "46239524912623653881879636239373280423891018672348497668235089863388" |
| 184 | "58792562830275599565752445550725518931369083625477918694866799496832" |
| 185 | "40497058210285131854513962138377228261454376934125320985913276672363" |
| 186 | "28125001e-324" , |
| 187 | 0x0000000000000001ULL}, |
| 188 | |
| 189 | // This value has a non-terminating binary fraction. It has a 0 at bit 54 followed by 120 ones. |
| 190 | {"1.8254370818746402660437411213933955878019332885742187" , 0x3FFD34FD8378EA83ULL}, |
| 191 | |
| 192 | // https://www.exploringbinary.com/incorrect-decimal-to-floating-point-conversion-in-sqlite/ |
| 193 | {"1e-23" , 0x3B282DB34012B251ULL}, |
| 194 | {"8.533e+68" , 0x4E3FA69165A8EEA2ULL}, |
| 195 | {"4.1006e-184" , 0x19DBE0D1C7EA60C9ULL}, |
| 196 | {"9.998e+307" , 0x7FE1CC0A350CA87BULL}, |
| 197 | {"9.9538452227e-280" , 0x0602117AE45CDE43ULL}, |
| 198 | {"6.47660115e-260" , 0x0A1FDD9E333BADADULL}, |
| 199 | {"7.4e+47" , 0x49E033D7ECA0ADEFULL}, |
| 200 | {"5.92e+48" , 0x4A1033D7ECA0ADEFULL}, |
| 201 | {"7.35e+66" , 0x4DD172B70EABABA9ULL}, |
| 202 | {"8.32116e+55" , 0x4B8B2628393E02CDULL}, |
| 203 | }; |
| 204 | |
| 205 | constexpr std::pair<const char*, std::uint32_t> floating_point_test_cases_float[] = { |
| 206 | // Verify small exactly-representable integers: |
| 207 | {"1" , 0x3F800000U}, |
| 208 | {"2" , 0x40000000U}, |
| 209 | {"3" , 0x40400000U}, |
| 210 | {"4" , 0x40800000U}, |
| 211 | {"5" , 0x40A00000U}, |
| 212 | {"6" , 0x40C00000U}, |
| 213 | {"7" , 0x40E00000U}, |
| 214 | {"8" , 0x41000000U}, |
| 215 | |
| 216 | // Verify large exactly-representable integers: |
| 217 | {"16777208" , 0x4B7FFFF8U}, |
| 218 | {"16777209" , 0x4B7FFFF9U}, |
| 219 | {"16777210" , 0x4B7FFFFAU}, |
| 220 | {"16777211" , 0x4B7FFFFBU}, |
| 221 | {"16777212" , 0x4B7FFFFCU}, |
| 222 | {"16777213" , 0x4B7FFFFDU}, |
| 223 | {"16777214" , 0x4B7FFFFEU}, |
| 224 | {"16777215" , 0x4B7FFFFFU}, // 2^24 - 1 |
| 225 | |
| 226 | // Verify the smallest denormal values: |
| 227 | {"1.4012984643248170e-45" , 0x00000001U}, |
| 228 | {"2.8025969286496340e-45" , 0x00000002U}, |
| 229 | {"4.2038953929744510e-45" , 0x00000003U}, |
| 230 | {"5.6051938572992680e-45" , 0x00000004U}, |
| 231 | {"7.0064923216240850e-45" , 0x00000005U}, |
| 232 | {"8.4077907859489020e-45" , 0x00000006U}, |
| 233 | {"9.8090892502737200e-45" , 0x00000007U}, |
| 234 | {"1.1210387714598537e-44" , 0x00000008U}, |
| 235 | {"1.2611686178923354e-44" , 0x00000009U}, |
| 236 | {"1.4012984643248170e-44" , 0x0000000AU}, |
| 237 | {"1.5414283107572988e-44" , 0x0000000BU}, |
| 238 | {"1.6815581571897805e-44" , 0x0000000CU}, |
| 239 | {"1.8216880036222622e-44" , 0x0000000DU}, |
| 240 | {"1.9618178500547440e-44" , 0x0000000EU}, |
| 241 | {"2.1019476964872256e-44" , 0x0000000FU}, |
| 242 | |
| 243 | // Verify the largest denormal values: |
| 244 | {"1.1754921087447446e-38" , 0x007FFFF0U}, |
| 245 | {"1.1754922488745910e-38" , 0x007FFFF1U}, |
| 246 | {"1.1754923890044375e-38" , 0x007FFFF2U}, |
| 247 | {"1.1754925291342839e-38" , 0x007FFFF3U}, |
| 248 | {"1.1754926692641303e-38" , 0x007FFFF4U}, |
| 249 | {"1.1754928093939768e-38" , 0x007FFFF5U}, |
| 250 | {"1.1754929495238232e-38" , 0x007FFFF6U}, |
| 251 | {"1.1754930896536696e-38" , 0x007FFFF7U}, |
| 252 | {"1.1754932297835160e-38" , 0x007FFFF8U}, |
| 253 | {"1.1754933699133625e-38" , 0x007FFFF9U}, |
| 254 | {"1.1754935100432089e-38" , 0x007FFFFAU}, |
| 255 | {"1.1754936501730553e-38" , 0x007FFFFBU}, |
| 256 | {"1.1754937903029018e-38" , 0x007FFFFCU}, |
| 257 | {"1.1754939304327482e-38" , 0x007FFFFDU}, |
| 258 | {"1.1754940705625946e-38" , 0x007FFFFEU}, |
| 259 | {"1.1754942106924411e-38" , 0x007FFFFFU}, |
| 260 | |
| 261 | // DevDiv#576315 "I/O library incorrect rounds floating point numbers on input" |
| 262 | // DevDiv#616647 "Visual C++ 11: iostream bug: incorrect input streaming of the smallest normal double and some |
| 263 | // denormals" |
| 264 | // DevDiv#730414 "iostreams is still misparsing floating-point" |
| 265 | // DevDiv#938627 "parsing float values using std::istream gives results inconsistent with sscanf() and with C++ |
| 266 | // compiler" |
| 267 | // DevDiv#961116 "floating point string conversion accuracy" |
| 268 | {"1.175494351e-38" , 0x00800000U}, // FLT_MIN |
| 269 | {"3.402823466e+38" , 0x7F7FFFFFU}, // FLT_MAX |
| 270 | {"179.9999999999999855" , 0x43340000U}, |
| 271 | {"4.1" , 0x40833333U}, |
| 272 | {"0.2288884" , 0x3E6A61B9U}, |
| 273 | {"0.168" , 0x3E2C0831U}, |
| 274 | {"1.68" , 0x3FD70A3DU}, |
| 275 | {"16.80000001" , 0x41866666U}, |
| 276 | }; |
| 277 | |
| 278 | #endif // FLOATING_POINT_TEST_CASES_HPP |
| 279 | |