Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions doc/modules/ROOT/pages/charconv.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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[<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 <charconv> 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++]
Expand Down
5 changes: 0 additions & 5 deletions doc/modules/ROOT/pages/cmath.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
64 changes: 62 additions & 2 deletions doc/modules/ROOT/pages/design.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

=== `<cmath>` 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 `<cmath>` 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 <charconv> 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[`<charconv>`].

=== 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.
16 changes: 1 addition & 15 deletions doc/modules/ROOT/pages/generic_decimal.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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[`<charconv>`].
xref:design.adoc#non-finite-deviation[Non-finite values are supported]