mirror of
https://github.com/XRPLF/rippled.git
synced 2026-06-03 08:46:46 +00:00
Fix usage of the Number class
This commit is contained in:
@@ -2176,7 +2176,7 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
Bytes const floatIntMin = {0x99, 0x20, 0xc4, 0x9b, 0xa5, 0xe3, 0x53, 0xf8}; // -2^63
|
||||
Bytes const floatIntZero = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // 0
|
||||
Bytes const floatIntMax = {0xd9, 0x20, 0xc4, 0x9b, 0xa5, 0xe3, 0x53, 0xf8}; // 2^63-1
|
||||
Bytes const floatUIntMax = {0xd9, 0x46, 0x8d, 0xb8, 0xba, 0xc7, 0x10, 0xcb}; // 2^64
|
||||
Bytes const floatUIntMax = {0xd9, 0x46, 0x8d, 0xb8, 0xba, 0xc7, 0x10, 0xcb}; // 2^64-1
|
||||
Bytes const floatMaxExp = {0xEC, 0x43, 0x8D, 0x7E, 0xA4, 0xC6, 0x80, 0x00}; // 1e(80+15)
|
||||
Bytes const floatPreMaxExp = {0xEC, 0x03, 0x8D, 0x7E, 0xA4, 0xC6, 0x80, 0x00}; // 1e(79+15)
|
||||
Bytes const floatMinusMaxExp = {0xAC, 0x43, 0x8D, 0x7E, 0xA4, 0xC6, 0x80, 0x00}; // -1e(80+15)
|
||||
@@ -2365,7 +2365,7 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
auto const result =
|
||||
hfs.floatSet(1, Number::maxExponent + normalExp + 1, 0);
|
||||
hfs.floatSet(1, wasm_float::maxExponent + normalExp + 1, 0);
|
||||
BEAST_EXPECT(!result) &&
|
||||
BEAST_EXPECT(
|
||||
result.error() ==
|
||||
@@ -2406,8 +2406,8 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
}
|
||||
|
||||
{
|
||||
auto const result = hfs.floatSet(
|
||||
wasm_float::maxMantissa, wasm_float::maxExponent, 0);
|
||||
auto const result =
|
||||
hfs.floatSet(STAmount::cMaxValue, wasm_float::maxExponent, 0);
|
||||
BEAST_EXPECT(result) && BEAST_EXPECT(*result == floatMaxIOU);
|
||||
}
|
||||
|
||||
@@ -2713,7 +2713,7 @@ struct HostFuncImpl_test : public beast::unit_test::suite
|
||||
|
||||
{
|
||||
auto const y = hfs.floatSet(
|
||||
wasm_float::maxMantissa, -normalExp - 1, 0); // 0.9999999...
|
||||
STAmount::cMaxValue, -normalExp - 1, 0); // 0.9999999...
|
||||
if (BEAST_EXPECT(y))
|
||||
{
|
||||
auto const result =
|
||||
|
||||
@@ -274,10 +274,10 @@ public:
|
||||
namespace wasm_float {
|
||||
|
||||
// The range for the mantissa and exponent when normalized
|
||||
static std::int64_t constexpr minMantissa = STAmount::cMinValue;
|
||||
static std::int64_t constexpr maxMantissa = STAmount::cMaxValue;
|
||||
static int constexpr minExponent = STAmount::cMinOffset;
|
||||
static int constexpr maxExponent = STAmount::cMaxOffset;
|
||||
static std::int64_t constexpr minMantissa = 1'000'000'000'000'000ll;
|
||||
static std::int64_t constexpr maxMantissa = (1ull << 54) - 1;
|
||||
static int constexpr minExponent = -96;
|
||||
static int constexpr maxExponent = 80;
|
||||
|
||||
} // namespace wasm_float
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ public:
|
||||
if (!m)
|
||||
return;
|
||||
|
||||
Number x(m, e + minExponent - 1);
|
||||
Number x(makeNumber(m, e + wasm_float::minExponent - 1));
|
||||
*static_cast<Number*>(this) = x;
|
||||
good_ = true;
|
||||
}
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
Number2(int64_t x) : Number(x), good_(true)
|
||||
Number2(int64_t x) : Number(makeNumber(x, 0)), good_(true)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -62,22 +62,36 @@ public:
|
||||
{
|
||||
using mtype = std::invoke_result_t<decltype(&Number::mantissa), Number>;
|
||||
if (x <= std::numeric_limits<mtype>::max())
|
||||
*this = Number(x);
|
||||
*this = makeNumber(x, 0);
|
||||
else
|
||||
*this = Number(x / 10, 1) + Number(x % 10);
|
||||
|
||||
*this = makeNumber(x / 10, 1);
|
||||
good_ = true;
|
||||
}
|
||||
|
||||
Number2(int64_t mantissa, int32_t exponent)
|
||||
: Number(mantissa, exponent), good_(true)
|
||||
: Number(makeNumber(mantissa, exponent)), good_(true)
|
||||
{
|
||||
}
|
||||
|
||||
Number2(Number const& n) : Number(n), good_(true)
|
||||
Number2(Number const& n)
|
||||
: Number(makeNumber(n.mantissa(), n.exponent())), good_(true)
|
||||
{
|
||||
}
|
||||
|
||||
static Number
|
||||
makeNumber(int64_t mantissa, int32_t exponent)
|
||||
{
|
||||
if (mantissa < 0)
|
||||
return Number(true, -mantissa, exponent, Number::normalized());
|
||||
return Number(false, mantissa, exponent, Number::normalized());
|
||||
}
|
||||
|
||||
static Number
|
||||
makeNumber(uint64_t mantissa, int32_t exponent)
|
||||
{
|
||||
return Number(false, mantissa, exponent, Number::normalized());
|
||||
}
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return good_;
|
||||
@@ -102,17 +116,17 @@ public:
|
||||
}
|
||||
return FLOAT_NULL;
|
||||
}
|
||||
else if (absM > ((1ull << 54) - 1))
|
||||
else if (absM > wasm_float::maxMantissa)
|
||||
{
|
||||
return Unexpected(
|
||||
HostFunctionError::FLOAT_COMPUTATION_ERROR); // LCOV_EXCL_LINE
|
||||
}
|
||||
else if (exponent() > maxExponent)
|
||||
else if (exponent() > wasm_float::maxExponent)
|
||||
return Unexpected(HostFunctionError::FLOAT_COMPUTATION_ERROR);
|
||||
else if (exponent() < minExponent)
|
||||
else if (exponent() < wasm_float::minExponent)
|
||||
return FLOAT_NULL;
|
||||
|
||||
int const e = exponent() - minExponent + 1; //+97
|
||||
int const e = exponent() - wasm_float::minExponent + 1; //+97
|
||||
v |= absM;
|
||||
v |= ((uint64_t)e) << 54;
|
||||
|
||||
@@ -136,24 +150,30 @@ public:
|
||||
Bytes const Number2::FLOAT_NULL =
|
||||
{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
struct SetRound
|
||||
struct FloatState
|
||||
{
|
||||
Number::rounding_mode oldMode_;
|
||||
MantissaRange::mantissa_scale oldScale_;
|
||||
bool good_;
|
||||
|
||||
SetRound(int32_t mode) : oldMode_(Number::getround()), good_(false)
|
||||
FloatState(int32_t mode)
|
||||
: oldMode_(Number::getround())
|
||||
, oldScale_(Number::getMantissaScale())
|
||||
, good_(false)
|
||||
{
|
||||
if (mode < Number::rounding_mode::to_nearest ||
|
||||
mode > Number::rounding_mode::upward)
|
||||
return;
|
||||
|
||||
Number::setround(static_cast<Number::rounding_mode>(mode));
|
||||
Number::setMantissaScale(MantissaRange::mantissa_scale::small);
|
||||
good_ = true;
|
||||
}
|
||||
|
||||
~SetRound()
|
||||
~FloatState()
|
||||
{
|
||||
Number::setround(oldMode_);
|
||||
Number::setMantissaScale(oldScale_);
|
||||
}
|
||||
|
||||
operator bool() const
|
||||
@@ -186,7 +206,7 @@ floatFromIntImpl(int64_t x, int32_t mode)
|
||||
{
|
||||
try
|
||||
{
|
||||
detail::SetRound rm(mode);
|
||||
detail::FloatState rm(mode);
|
||||
if (!rm)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
|
||||
@@ -206,12 +226,13 @@ floatFromUintImpl(uint64_t x, int32_t mode)
|
||||
{
|
||||
try
|
||||
{
|
||||
detail::SetRound rm(mode);
|
||||
detail::FloatState rm(mode);
|
||||
if (!rm)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
|
||||
detail::Number2 num(x);
|
||||
return num.toBytes();
|
||||
auto r = num.toBytes();
|
||||
return r;
|
||||
}
|
||||
// LCOV_EXCL_START
|
||||
catch (...)
|
||||
@@ -226,7 +247,7 @@ floatSetImpl(int64_t mantissa, int32_t exponent, int32_t mode)
|
||||
{
|
||||
try
|
||||
{
|
||||
detail::SetRound rm(mode);
|
||||
detail::FloatState rm(mode);
|
||||
if (!rm)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
detail::Number2 num(mantissa, exponent);
|
||||
@@ -264,7 +285,7 @@ floatAddImpl(Slice const& x, Slice const& y, int32_t mode)
|
||||
{
|
||||
try
|
||||
{
|
||||
detail::SetRound rm(mode);
|
||||
detail::FloatState rm(mode);
|
||||
if (!rm)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
|
||||
@@ -291,7 +312,7 @@ floatSubtractImpl(Slice const& x, Slice const& y, int32_t mode)
|
||||
{
|
||||
try
|
||||
{
|
||||
detail::SetRound rm(mode);
|
||||
detail::FloatState rm(mode);
|
||||
if (!rm)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
detail::Number2 xx(x);
|
||||
@@ -317,7 +338,7 @@ floatMultiplyImpl(Slice const& x, Slice const& y, int32_t mode)
|
||||
{
|
||||
try
|
||||
{
|
||||
detail::SetRound rm(mode);
|
||||
detail::FloatState rm(mode);
|
||||
if (!rm)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
detail::Number2 xx(x);
|
||||
@@ -343,7 +364,7 @@ floatDivideImpl(Slice const& x, Slice const& y, int32_t mode)
|
||||
{
|
||||
try
|
||||
{
|
||||
detail::SetRound rm(mode);
|
||||
detail::FloatState rm(mode);
|
||||
if (!rm)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
detail::Number2 xx(x);
|
||||
@@ -370,7 +391,7 @@ floatRootImpl(Slice const& x, int32_t n, int32_t mode)
|
||||
if (n < 1)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
|
||||
detail::SetRound rm(mode);
|
||||
detail::FloatState rm(mode);
|
||||
if (!rm)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
|
||||
@@ -395,10 +416,10 @@ floatPowerImpl(Slice const& x, int32_t n, int32_t mode)
|
||||
{
|
||||
try
|
||||
{
|
||||
if ((n < 0) || (n > maxExponent))
|
||||
if ((n < 0) || (n > wasm_float::maxExponent))
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
|
||||
detail::SetRound rm(mode);
|
||||
detail::FloatState rm(mode);
|
||||
if (!rm)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
|
||||
@@ -425,7 +446,7 @@ floatLogImpl(Slice const& x, int32_t mode)
|
||||
{
|
||||
try
|
||||
{
|
||||
detail::SetRound rm(mode);
|
||||
detail::FloatState rm(mode);
|
||||
if (!rm)
|
||||
return Unexpected(HostFunctionError::FLOAT_INPUT_MALFORMED);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user