-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ed3cbf3
commit 999ccb9
Showing
705 changed files
with
165,260 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
#pragma once | ||
#include <stdio.h> | ||
#include <wchar.h> | ||
|
||
struct constexpr_char_traits { | ||
typedef char char_type; | ||
typedef long int_type; | ||
typedef long pos_type; | ||
typedef long off_type; | ||
typedef mbstate_t state_type; | ||
|
||
static constexpr int compare(const char* first1, const char* first2, size_t count) { | ||
for (; 0 < count; --count, ++first1, ++first2) { | ||
if (!eq(*first1, *first2)) { | ||
return lt(*first1, *first2) ? -1 : +1; | ||
} | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
static constexpr size_t length(const char* first) { | ||
size_t count = 0; | ||
for (; !eq(*first, char()); ++first) { | ||
++count; | ||
} | ||
|
||
return count; | ||
} | ||
|
||
static constexpr char* copy(char* first1, const char* first2, size_t count) { | ||
char* next = first1; | ||
for (; 0 < count; --count, ++next, ++first2) { | ||
assign(*next, *first2); | ||
} | ||
return first1; | ||
} | ||
|
||
static constexpr char* _Copy_s(char* first1, size_t, const char* first2, size_t count) { | ||
// let's just pretend :) | ||
return copy(first1, first2, count); | ||
} | ||
|
||
static constexpr const char* find(const char* first, size_t count, const char ch) { | ||
for (; 0 < count; --count, ++first) { | ||
if (eq(*first, ch)) { | ||
return first; | ||
} | ||
} | ||
|
||
return nullptr; | ||
} | ||
|
||
static constexpr char* move(char* first1, const char* first2, size_t count) { | ||
char* next = first1; | ||
if (first2 < next && next < first2 + count) { | ||
for (next += count, first2 += count; 0 < count; --count) { | ||
assign(*--next, *--first2); | ||
} | ||
} else { | ||
for (; 0 < count; --count, ++next, ++first2) { | ||
assign(*next, *first2); | ||
} | ||
} | ||
return first1; | ||
} | ||
|
||
static constexpr char* assign(char* first, size_t count, const char ch) { | ||
char* next = first; | ||
for (; 0 < count; --count, ++next) { | ||
assign(*next, ch); | ||
} | ||
|
||
return first; | ||
} | ||
|
||
static constexpr void assign(char& left, const char right) noexcept { | ||
left = right; | ||
} | ||
|
||
static constexpr bool eq(const char left, const char right) noexcept { | ||
return left == right; | ||
} | ||
|
||
static constexpr bool lt(const char left, const char right) noexcept { | ||
return left < right; | ||
} | ||
|
||
static constexpr char to_char_type(const int_type meta) noexcept { | ||
return static_cast<char>(meta); | ||
} | ||
|
||
static constexpr int_type to_int_type(const char ch) noexcept { | ||
return ch; | ||
} | ||
|
||
static constexpr bool eq_int_type(const int_type left, const int_type right) noexcept { | ||
return left == right; | ||
} | ||
|
||
static constexpr int_type not_eof(const int_type meta) noexcept { | ||
return meta != eof() ? meta : !eof(); | ||
} | ||
|
||
static constexpr int_type eof() noexcept { | ||
return EOF; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,275 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
|
||
#pragma once | ||
|
||
#include <stdint.h> | ||
#include <utility> | ||
|
||
constexpr std::pair<const char*, uint64_t> floating_point_test_cases_double[] = { | ||
// Verify small exactly-representable integers: | ||
{"1", 0x3FF0000000000000ULL}, | ||
{"2", 0x4000000000000000ULL}, | ||
{"3", 0x4008000000000000ULL}, | ||
{"4", 0x4010000000000000ULL}, | ||
{"5", 0x4014000000000000ULL}, | ||
{"6", 0x4018000000000000ULL}, | ||
{"7", 0x401C000000000000ULL}, | ||
{"8", 0x4020000000000000ULL}, | ||
|
||
// Verify large exactly-representable integers: | ||
{"9007199254740984", 0x433FFFFFFFFFFFF8ULL}, | ||
{"9007199254740985", 0x433FFFFFFFFFFFF9ULL}, | ||
{"9007199254740986", 0x433FFFFFFFFFFFFAULL}, | ||
{"9007199254740987", 0x433FFFFFFFFFFFFBULL}, | ||
{"9007199254740988", 0x433FFFFFFFFFFFFCULL}, | ||
{"9007199254740989", 0x433FFFFFFFFFFFFDULL}, | ||
{"9007199254740990", 0x433FFFFFFFFFFFFEULL}, | ||
{"9007199254740991", 0x433FFFFFFFFFFFFFULL}, // 2^53 - 1 | ||
|
||
// Verify the smallest denormal values: | ||
{"5.0e-324", 0x0000000000000001ULL}, | ||
{"1.0e-323", 0x0000000000000002ULL}, | ||
{"1.5e-323", 0x0000000000000003ULL}, | ||
{"2.0e-323", 0x0000000000000004ULL}, | ||
{"2.5e-323", 0x0000000000000005ULL}, | ||
{"3.0e-323", 0x0000000000000006ULL}, | ||
{"3.5e-323", 0x0000000000000007ULL}, | ||
{"4.0e-323", 0x0000000000000008ULL}, | ||
{"4.5e-323", 0x0000000000000009ULL}, | ||
{"5.0e-323", 0x000000000000000AULL}, | ||
{"5.5e-323", 0x000000000000000BULL}, | ||
{"6.0e-323", 0x000000000000000CULL}, | ||
{"6.5e-323", 0x000000000000000DULL}, | ||
{"7.0e-323", 0x000000000000000EULL}, | ||
{"7.5e-323", 0x000000000000000FULL}, | ||
|
||
// Verify the largest denormal values: | ||
{"2.2250738585071935e-308", 0x000FFFFFFFFFFFF0ULL}, | ||
{"2.2250738585071940e-308", 0x000FFFFFFFFFFFF1ULL}, | ||
{"2.2250738585071945e-308", 0x000FFFFFFFFFFFF2ULL}, | ||
{"2.2250738585071950e-308", 0x000FFFFFFFFFFFF3ULL}, | ||
{"2.2250738585071955e-308", 0x000FFFFFFFFFFFF4ULL}, | ||
{"2.2250738585071960e-308", 0x000FFFFFFFFFFFF5ULL}, | ||
{"2.2250738585071964e-308", 0x000FFFFFFFFFFFF6ULL}, | ||
{"2.2250738585071970e-308", 0x000FFFFFFFFFFFF7ULL}, | ||
{"2.2250738585071974e-308", 0x000FFFFFFFFFFFF8ULL}, | ||
{"2.2250738585071980e-308", 0x000FFFFFFFFFFFF9ULL}, | ||
{"2.2250738585071984e-308", 0x000FFFFFFFFFFFFAULL}, | ||
{"2.2250738585071990e-308", 0x000FFFFFFFFFFFFBULL}, | ||
{"2.2250738585071994e-308", 0x000FFFFFFFFFFFFCULL}, | ||
{"2.2250738585072000e-308", 0x000FFFFFFFFFFFFDULL}, | ||
{"2.2250738585072004e-308", 0x000FFFFFFFFFFFFEULL}, | ||
{"2.2250738585072010e-308", 0x000FFFFFFFFFFFFFULL}, | ||
|
||
// DevDiv#576315 "I/O library incorrect rounds floating point numbers on input" | ||
// DevDiv#616647 "Visual C++ 11: iostream bug: incorrect input streaming of the smallest normal double and some | ||
// denormals" | ||
// DevDiv#730414 "iostreams is still misparsing floating-point" | ||
// DevDiv#938627 "parsing float values using std::istream gives results inconsistent with sscanf() and with C++ | ||
// compiler" | ||
// DevDiv#961116 "floating point string conversion accuracy" | ||
{"2.2250738585072014e-308", 0x0010000000000000ULL}, // DBL_MIN | ||
{"1.7976931348623158e+308", 0x7FEFFFFFFFFFFFFFULL}, // DBL_MAX | ||
{"4.26144921954407e-309", 0x00031076B2F00000ULL}, | ||
{"179.9999999999999855", 0x40667FFFFFFFFFFFULL}, | ||
{"4.1", 0x4010666666666666ULL}, | ||
{"0.2288884", 0x3FCD4C37103785A8ULL}, | ||
{"0.168", 0x3FC5810624DD2F1BULL}, | ||
{"1.68", 0x3FFAE147AE147AE1ULL}, | ||
{"16.80000001", 0x4030CCCCCCF7BFEBULL}, | ||
|
||
// Test cases from Rick Regan's article, "Incorrectly Rounded Conversions in Visual C++": | ||
// https://www.exploringbinary.com/incorrectly-rounded-conversions-in-visual-c-plus-plus/ | ||
|
||
// Example 1: | ||
{"9214843084008499", 0x43405E6CEC57761AULL}, | ||
|
||
// Example 2 (2^-1 + 2^-53 + 2^-54): | ||
{"0.500000000000000166533453693773481063544750213623046875", 0x3FE0000000000002ULL}, | ||
|
||
// Example 3: | ||
{"30078505129381147446200", 0x44997A3C7271B021ULL}, | ||
|
||
// Example 4: | ||
{"1777820000000000000001", 0x4458180D5BAD2E3EULL}, | ||
|
||
// Example 5 (2^-1 + 2^-53 + 2^-54 + 2^-66): | ||
{"0.500000000000000166547006220929549868969843373633921146392822265625", 0x3FE0000000000002ULL}, | ||
|
||
// Example 6 (2^-1 + 2^-53 + 2^-54 + 2^-65): | ||
{"0.50000000000000016656055874808561867439493653364479541778564453125", 0x3FE0000000000002ULL}, | ||
|
||
// Example 7: | ||
{"0.3932922657273", 0x3FD92BB352C4623AULL}, | ||
|
||
// The following test cases are taken from other articles on Rick Regan's | ||
// Exploring Binary blog. These are conversions that other implementations | ||
// were found to perform incorrectly. | ||
|
||
// https://www.exploringbinary.com/incorrectly-rounded-subnormal-conversions-in-java/ | ||
// Example 1 (2^-1047 + 2^-1075, half-ulp above a power of two): | ||
{"6.6312368714697582767853966302759672433990999473553031442499717587" | ||
"362866301392654396180682007880487441059604205526018528897150063763" | ||
"256665955396033303618005191075917832333584923372080578494993608994" | ||
"251286407188566165030934449228547591599881603044399098682919739314" | ||
"266256986631577498362522745234853124423586512070512924530832781161" | ||
"439325697279187097860044978723221938561502254152119972830784963194" | ||
"121246401117772161481107528151017752957198119743384519360959074196" | ||
"224175384736794951486324803914359317679811223967034438033355297560" | ||
"033532098300718322306892013830155987921841729099279241763393155074" | ||
"022348361207309147831684007154624400538175927027662135590421159867" | ||
"638194826541287705957668068727833491469671712939495988506756821156" | ||
"96218943412532098591327667236328125E-316", | ||
0x0000000008000000ULL}, | ||
|
||
// Example 2 (2^-1058 - 2^-1075, half-ulp below a power of two): | ||
{"3.2378839133029012895883524125015321748630376694231080599012970495" | ||
"523019706706765657868357425877995578606157765598382834355143910841" | ||
"531692526891905643964595773946180389283653051434639551003566966656" | ||
"292020173313440317300443693602052583458034314716600326995807313009" | ||
"548483639755486900107515300188817581841745696521731104736960227499" | ||
"346384253806233697747365600089974040609674980283891918789639685754" | ||
"392222064169814626901133425240027243859416510512935526014211553334" | ||
"302252372915238433223313261384314778235911424088000307751706259156" | ||
"707286570031519536642607698224949379518458015308952384398197084033" | ||
"899378732414634842056080000272705311068273879077914449185347715987" | ||
"501628125488627684932015189916680282517302999531439241685457086639" | ||
"13273994694463908672332763671875E-319", | ||
0x0000000000010000ULL}, | ||
|
||
// Example 3 (2^-1027 + 2^-1066 + 2^-1075, half-ulp above a non-power of two): | ||
{"6.9533558078476771059728052155218916902221198171459507544162056079" | ||
"800301315496366888061157263994418800653863998640286912755395394146" | ||
"528315847956685600829998895513577849614468960421131982842131079351" | ||
"102171626549398024160346762138294097205837595404767869364138165416" | ||
"212878432484332023692099166122496760055730227032447997146221165421" | ||
"888377703760223711720795591258533828013962195524188394697705149041" | ||
"926576270603193728475623010741404426602378441141744972109554498963" | ||
"891803958271916028866544881824524095839813894427833770015054620157" | ||
"450178487545746683421617594966617660200287528887833870748507731929" | ||
"971029979366198762266880963149896457660004790090837317365857503352" | ||
"620998601508967187744019647968271662832256419920407478943826987518" | ||
"09812609536720628966577351093292236328125E-310", | ||
0x0000800000000100ULL}, | ||
|
||
// Example 4 (2^-1058 + 2^-1063 - 2^-1075, half-ulp below a non-power of two): | ||
{"3.3390685575711885818357137012809439119234019169985217716556569973" | ||
"284403145596153181688491490746626090999981130094655664268081703784" | ||
"340657229916596426194677060348844249897410807907667784563321682004" | ||
"646515939958173717821250106683466529959122339932545844611258684816" | ||
"333436749050742710644097630907080178565840197768788124253120088123" | ||
"262603630354748115322368533599053346255754042160606228586332807443" | ||
"018924703005556787346899784768703698535494132771566221702458461669" | ||
"916553215355296238706468887866375289955928004361779017462862722733" | ||
"744717014529914330472578638646014242520247915673681950560773208853" | ||
"293843223323915646452641434007986196650406080775491621739636492640" | ||
"497383622906068758834568265867109610417379088720358034812416003767" | ||
"05491726170293986797332763671875E-319", | ||
0x0000000000010800ULL}, | ||
|
||
// A number between 2^-1074 and 2^-1075, just slightly larger than 2^-1075. | ||
// It has bit 1075 set (the denormal rounding bit), followed by 2506 zeroes, | ||
// followed by one bits. It should round up to 2^-1074. | ||
{"2.470328229206232720882843964341106861825299013071623822127928412503" | ||
"37753635104375932649918180817996189898282347722858865463328355177969" | ||
"89819938739800539093906315035659515570226392290858392449105184435931" | ||
"80284993653615250031937045767824921936562366986365848075700158576926" | ||
"99037063119282795585513329278343384093519780155312465972635795746227" | ||
"66465272827220056374006485499977096599470454020828166226237857393450" | ||
"73633900796776193057750674017632467360096895134053553745851666113422" | ||
"37666786041621596804619144672918403005300575308490487653917113865916" | ||
"46239524912623653881879636239373280423891018672348497668235089863388" | ||
"58792562830275599565752445550725518931369083625477918694866799496832" | ||
"40497058210285131854513962138377228261454376934125320985913276672363" | ||
"28125001e-324", | ||
0x0000000000000001ULL}, | ||
|
||
// This value has a non-terminating binary fraction. It has a 0 at bit 54 followed by 120 ones. | ||
{"1.8254370818746402660437411213933955878019332885742187", 0x3FFD34FD8378EA83ULL}, | ||
|
||
// https://www.exploringbinary.com/incorrect-decimal-to-floating-point-conversion-in-sqlite/ | ||
{"1e-23", 0x3B282DB34012B251ULL}, | ||
{"8.533e+68", 0x4E3FA69165A8EEA2ULL}, | ||
{"4.1006e-184", 0x19DBE0D1C7EA60C9ULL}, | ||
{"9.998e+307", 0x7FE1CC0A350CA87BULL}, | ||
{"9.9538452227e-280", 0x0602117AE45CDE43ULL}, | ||
{"6.47660115e-260", 0x0A1FDD9E333BADADULL}, | ||
{"7.4e+47", 0x49E033D7ECA0ADEFULL}, | ||
{"5.92e+48", 0x4A1033D7ECA0ADEFULL}, | ||
{"7.35e+66", 0x4DD172B70EABABA9ULL}, | ||
{"8.32116e+55", 0x4B8B2628393E02CDULL}, | ||
}; | ||
|
||
constexpr std::pair<const char*, uint32_t> floating_point_test_cases_float[] = { | ||
// Verify small exactly-representable integers: | ||
{"1", 0x3F800000U}, | ||
{"2", 0x40000000U}, | ||
{"3", 0x40400000U}, | ||
{"4", 0x40800000U}, | ||
{"5", 0x40A00000U}, | ||
{"6", 0x40C00000U}, | ||
{"7", 0x40E00000U}, | ||
{"8", 0x41000000U}, | ||
|
||
// Verify large exactly-representable integers: | ||
{"16777208", 0x4B7FFFF8U}, | ||
{"16777209", 0x4B7FFFF9U}, | ||
{"16777210", 0x4B7FFFFAU}, | ||
{"16777211", 0x4B7FFFFBU}, | ||
{"16777212", 0x4B7FFFFCU}, | ||
{"16777213", 0x4B7FFFFDU}, | ||
{"16777214", 0x4B7FFFFEU}, | ||
{"16777215", 0x4B7FFFFFU}, // 2^24 - 1 | ||
|
||
// Verify the smallest denormal values: | ||
{"1.4012984643248170e-45", 0x00000001U}, | ||
{"2.8025969286496340e-45", 0x00000002U}, | ||
{"4.2038953929744510e-45", 0x00000003U}, | ||
{"5.6051938572992680e-45", 0x00000004U}, | ||
{"7.0064923216240850e-45", 0x00000005U}, | ||
{"8.4077907859489020e-45", 0x00000006U}, | ||
{"9.8090892502737200e-45", 0x00000007U}, | ||
{"1.1210387714598537e-44", 0x00000008U}, | ||
{"1.2611686178923354e-44", 0x00000009U}, | ||
{"1.4012984643248170e-44", 0x0000000AU}, | ||
{"1.5414283107572988e-44", 0x0000000BU}, | ||
{"1.6815581571897805e-44", 0x0000000CU}, | ||
{"1.8216880036222622e-44", 0x0000000DU}, | ||
{"1.9618178500547440e-44", 0x0000000EU}, | ||
{"2.1019476964872256e-44", 0x0000000FU}, | ||
|
||
// Verify the largest denormal values: | ||
{"1.1754921087447446e-38", 0x007FFFF0U}, | ||
{"1.1754922488745910e-38", 0x007FFFF1U}, | ||
{"1.1754923890044375e-38", 0x007FFFF2U}, | ||
{"1.1754925291342839e-38", 0x007FFFF3U}, | ||
{"1.1754926692641303e-38", 0x007FFFF4U}, | ||
{"1.1754928093939768e-38", 0x007FFFF5U}, | ||
{"1.1754929495238232e-38", 0x007FFFF6U}, | ||
{"1.1754930896536696e-38", 0x007FFFF7U}, | ||
{"1.1754932297835160e-38", 0x007FFFF8U}, | ||
{"1.1754933699133625e-38", 0x007FFFF9U}, | ||
{"1.1754935100432089e-38", 0x007FFFFAU}, | ||
{"1.1754936501730553e-38", 0x007FFFFBU}, | ||
{"1.1754937903029018e-38", 0x007FFFFCU}, | ||
{"1.1754939304327482e-38", 0x007FFFFDU}, | ||
{"1.1754940705625946e-38", 0x007FFFFEU}, | ||
{"1.1754942106924411e-38", 0x007FFFFFU}, | ||
|
||
// DevDiv#576315 "I/O library incorrect rounds floating point numbers on input" | ||
// DevDiv#616647 "Visual C++ 11: iostream bug: incorrect input streaming of the smallest normal double and some | ||
// denormals" | ||
// DevDiv#730414 "iostreams is still misparsing floating-point" | ||
// DevDiv#938627 "parsing float values using std::istream gives results inconsistent with sscanf() and with C++ | ||
// compiler" | ||
// DevDiv#961116 "floating point string conversion accuracy" | ||
{"1.175494351e-38", 0x00800000U}, // FLT_MIN | ||
{"3.402823466e+38", 0x7F7FFFFFU}, // FLT_MAX | ||
{"179.9999999999999855", 0x43340000U}, | ||
{"4.1", 0x40833333U}, | ||
{"0.2288884", 0x3E6A61B9U}, | ||
{"0.168", 0x3E2C0831U}, | ||
{"1.68", 0x3FD70A3DU}, | ||
{"16.80000001", 0x41866666U}, | ||
}; |
Oops, something went wrong.