diff --git a/doc/modules/ROOT/pages/charconv.adoc b/doc/modules/ROOT/pages/charconv.adoc index 718d3f641..da402f2f7 100644 --- a/doc/modules/ROOT/pages/charconv.adoc +++ b/doc/modules/ROOT/pages/charconv.adoc @@ -12,11 +12,6 @@ https://www.boost.org/LICENSE_1_0.txt The following functions analogous to those from https://en.cppreference.com/w/cpp/header/charconv[] are provided: -IMPORTANT: `std::from_chars` has an open issue with LWG here: https://cplusplus.github.io/LWG/lwg-active.html#3081. -The standard for does not distinguish between underflow and overflow like strtod does. -`boost::decimal::from_chars` modifies `value` in order to communicate this to the user in a divergence from the standard. -This behavior is the same as that of https://www.boost.org/doc/libs/master/libs/charconv/doc/html/charconv.html#from_chars_usage_notes_for_from_chars_for_floating_point_types[`boost::charconv::from_chars_erange`]. - [#chars_format] == chars_format [source, c++] diff --git a/doc/modules/ROOT/pages/cmath.adoc b/doc/modules/ROOT/pages/cmath.adoc index ad73c4edf..77ddd0e2b 100644 --- a/doc/modules/ROOT/pages/cmath.adoc +++ b/doc/modules/ROOT/pages/cmath.adoc @@ -13,11 +13,6 @@ They are also all constexpr with C\\++14 unlike the built-in floating point type Additionally, all functions are marked `noexcept`. All of these functions are impacted by the global rounding mode as described in xref:cfenv.adoc[rounding modes] as well as the `DEC_FLT_EVAL_METHOD` from xref:cfloat.adoc[evaluation methods]. -IEEE 754 specifies for correct rounding: "This standard’s method of converting an infinitely precise result to a floating-point number, as determined by the applicable rounding direction. A floating-point number so obtained is said to be correctly rounded." -None of these functions meet the definition of correctly rounded (which would imply precision of https://en.wikipedia.org/wiki/Unit_in_the_last_place[0.5 ULP]). -From the https://www.netlib.org/misc/intel/README.txt[Intel libdfp README]: "binary floating-point mathematical functions -implemented for example in C or other compiler math libraries are in general -not correctly rounded either". == Basic Operations diff --git a/doc/modules/ROOT/pages/design.adoc b/doc/modules/ROOT/pages/design.adoc index e9a23ebb3..ed2b6fc83 100644 --- a/doc/modules/ROOT/pages/design.adoc +++ b/doc/modules/ROOT/pages/design.adoc @@ -5,7 +5,7 @@ https://www.boost.org/LICENSE_1_0.txt //// [#design] -= Design Decisions += Design Decisions and Standards Deviations :idprefix: design_ == C++14 Requirement @@ -20,7 +20,67 @@ This allows Boost.Decimal to better emulate the functionality a built-in type wo Boost.Math requires C++14 as the minimum language standard for the library. By meeting this requirement, and Boost.Math's conceptual requirements for a user-defined type we are able to provide the statistics, interpolation, quadrature, etc. out of the box. -=== No Binary Floating Point Operations +== No Binary Floating Point Operations The library deliberately does not contain any operations between a binary floating point type and the decimal floating point types. The rationale is similar to that of the library in the first place in that you may end up with surprising results. Conversion operators and constructors are available for all decimal types should the user want to explicit cast one side of the operation to conduct the operation. + +== IEEE Deviations + +=== `` Functions Do Not Meet the Definition of Correctly Rounded + +IEEE 754 specifies for correct rounding: "This standard’s method of converting an infinitely precise result to a floating-point number, as determined by the applicable rounding direction. A floating-point number so obtained is said to be correctly rounded." +None of these functions meet the definition of correctly rounded (which would imply precision of https://en.wikipedia.org/wiki/Unit_in_the_last_place[0.5 ULP]). +From the https://www.netlib.org/misc/intel/README.txt[Intel libdfp README]: "binary floating-point mathematical functions +implemented for example in C or other compiler math libraries are in general +not correctly rounded either". +Technically IEEE 754 differentiates the specification for mandatory operations (e.g. `fma`, `sqrt`, etc.) in Clause 5, and recommended operations (e.g. `exp`, `log`, etc.) in Clause 9, but our statement about half ULP precision applies to all non-boolean result `` functions. +This does not apply to Clause 5 functions like `isnan` which has a boolean result because ULP precision does not apply. + +=== Floating Point Exception Flags are not Supported + +The normal method in pass:[C++] to set and get the current floating point exception flags is via http://en.cppreference.com/w/cpp/numeric/fenv/feexceptflag.html[`std::fegetexceptflag` and `std::fesetexceptflag`]. +The decision then becomes do we support `constexpr` or floating point exceptions? +We find that the former is far more useful than the latter. +The alternative to would be to use C style functions such as: + +[source, C++] +---- +decimal64_t dec64_add(decimal64_t a, decimal64_t b, rounding_mode round, int* floating_point_flags); +---- + +This style of function is used in Intel libdfp because it is a C library. +We find this to be unidiomatic and unergonomic for a modern pass:[C++] library. + +== C++ Standards Deviations + +=== `from_chars` Distinguishes Overflow from Underflow + +`std::from_chars` has an open issue with LWG here: https://cplusplus.github.io/LWG/lwg-active.html#3081. +The standard for does not distinguish between underflow and overflow like strtod does. +`boost::decimal::from_chars` modifies `value` in order to communicate this to the user in a divergence from the standard. +This behavior is the same as that of https://www.boost.org/doc/libs/master/libs/charconv/doc/html/charconv.html#from_chars_usage_notes_for_from_chars_for_floating_point_types[`boost::charconv::from_chars_erange`]. + +[#non-finite-deviation] +=== `istream` of Non-finite Values is Allowed + +Unlike built-in binary floating point types the library allows input of non-finite values such as the below: + +[source, c++] +---- +std::istringstream is("INF"); +decimal32_t x; +is >> x; +const auto endpos {is.tellg()}; + +assert(isinf(x)); +assert(endpos == 3); +---- + +The result of `tellg()` will only parse until a complete non-finite value is found and then terminate. +For example `nanfinity` will construct a `NAN` and set `endpos = 3`, or `nan(snan)JUNK` will construct `SNAN` and set `endpos = 9` since `nan(snan)` contains a valid payload. +This is designed to match the value of `r.ptr` in xref:charconv.adoc[``]. + +=== Locale Facets are Unsupported + +Facets as discussed in https://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2849.pdf[N2849] section 3.10 are unimplemented. diff --git a/doc/modules/ROOT/pages/generic_decimal.adoc b/doc/modules/ROOT/pages/generic_decimal.adoc index 04dd51237..b1f950121 100644 --- a/doc/modules/ROOT/pages/generic_decimal.adoc +++ b/doc/modules/ROOT/pages/generic_decimal.adoc @@ -162,19 +162,5 @@ In the event of binary arithmetic between a non-decimal type and a decimal type In the event of binary arithmetic between two decimal types the result will be the higher precision type of the two (e.g. decimal64_t + decimal32_t -> decimal64_t) == 3.2.10 Note -Unlike built-in binary floating point types the library allows input of non-finite values such as the below: -[source, c++] ----- -std::istringstream is("INF"); -decimal32_t x; -is >> x; -const auto endpos {is.tellg()}; - -assert(isinf(x)); -assert(endpos == 3); ----- - -The result of `tellg()` will only parse until a complete non-finite value is found and then terminate. -For example `nanfinity` will construct a `NAN` and set `endpos = 3`, or `nan(snan)JUNK` will construct `SNAN` and set `endpos = 9` since `nan(snan)` contains a valid payload. -This is designed to match the value of `r.ptr` in xref:charconv.adoc[``]. +xref:design.adoc#non-finite-deviation[Non-finite values are supported]