mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Introduce rounding modes for Number:
You can set a thread-local flag to direct Number how to round
non-exact results with the syntax:
Number::rounding_mode prev_mode = Number::setround(Number::towards_zero);
This flag will stay in effect for this thread only until another call
to setround. The previously set rounding mode is returned.
You can also retrieve the current rounding mode with:
Number::rounding_mode current_mode = Number::getround();
The available rounding modes are:
* to_nearest : Rounds to nearest representable value. On tie, rounds
to even.
* towards_zero : Rounds towards zero.
* downward : Rounds towards negative infinity.
* upward : Rounds towards positive infinity.
The default rounding mode is to_nearest.
This commit is contained in:
committed by
Elliot Lee
parent
a82ad5ba76
commit
3f33471220
@@ -23,6 +23,7 @@
|
||||
#include <numeric>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#ifdef _MSVC_LANG
|
||||
#include <boost/multiprecision/cpp_int.hpp>
|
||||
@@ -33,6 +34,20 @@ using uint128_t = __uint128_t;
|
||||
|
||||
namespace ripple {
|
||||
|
||||
thread_local Number::rounding_mode Number::mode_ = Number::to_nearest;
|
||||
|
||||
Number::rounding_mode
|
||||
Number::getround()
|
||||
{
|
||||
return mode_;
|
||||
}
|
||||
|
||||
Number::rounding_mode
|
||||
Number::setround(rounding_mode mode)
|
||||
{
|
||||
return std::exchange(mode_, mode);
|
||||
}
|
||||
|
||||
// Guard
|
||||
|
||||
// The Guard class is used to tempoarily add extra digits of
|
||||
@@ -107,16 +122,40 @@ Number::Guard::pop() noexcept
|
||||
return d;
|
||||
}
|
||||
|
||||
// Returns:
|
||||
// -1 if Guard is less than half
|
||||
// 0 if Guard is exactly half
|
||||
// 1 if Guard is greater than half
|
||||
int
|
||||
Number::Guard::round() noexcept
|
||||
{
|
||||
if (digits_ > 0x5000'0000'0000'0000)
|
||||
return 1;
|
||||
if (digits_ < 0x5000'0000'0000'0000)
|
||||
return -1;
|
||||
if (xbit_)
|
||||
return 1;
|
||||
return 0;
|
||||
auto mode = Number::getround();
|
||||
switch (mode)
|
||||
{
|
||||
case to_nearest:
|
||||
if (digits_ > 0x5000'0000'0000'0000)
|
||||
return 1;
|
||||
if (digits_ < 0x5000'0000'0000'0000)
|
||||
return -1;
|
||||
if (xbit_)
|
||||
return 1;
|
||||
return 0;
|
||||
case towards_zero:
|
||||
return -1;
|
||||
case downward:
|
||||
if (sbit_)
|
||||
{
|
||||
if (digits_ > 0 || xbit_)
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
case upward:
|
||||
if (sbit_)
|
||||
return -1;
|
||||
if (digits_ > 0 || xbit_)
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Number
|
||||
|
||||
Reference in New Issue
Block a user