Use checked exp for decimal.

This commit is contained in:
Stephen Chung 2021-05-24 12:12:29 +08:00
parent aa8dee6460
commit 58d6a88bc4
2 changed files with 28 additions and 33 deletions

View File

@ -92,7 +92,7 @@ default_features = false
optional = true optional = true
[dependencies.rust_decimal] [dependencies.rust_decimal]
version = "1.13" version = "1.14"
default_features = false default_features = false
features = ["maths"] features = ["maths"]
optional = true optional = true

View File

@ -317,13 +317,8 @@ mod decimal_functions {
#[rhai_fn(return_raw)] #[rhai_fn(return_raw)]
pub fn exp(x: Decimal) -> Result<Decimal, Box<EvalAltResult>> { pub fn exp(x: Decimal) -> Result<Decimal, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) { if cfg!(not(feature = "unchecked")) {
if x > Decimal::from_parts(117578, 0, 0, false, 4) { x.checked_exp()
Err(make_err(format!("Exponential overflow: e ** {}", x,))) .ok_or_else(|| make_err(format!("Exponential overflow: e ** {}", x,)))
} else if x < Decimal::from_parts(8, 0, 0, true, 0) {
Err(make_err(format!("Exponential underflow: e ** {}", x,)))
} else {
Ok(x.exp())
}
} else { } else {
Ok(x.exp()) Ok(x.exp())
} }
@ -346,15 +341,15 @@ mod decimal_functions {
#[rhai_fn(name = "round", return_raw)] #[rhai_fn(name = "round", return_raw)]
pub fn round_dp(x: Decimal, dp: INT) -> Result<Decimal, Box<EvalAltResult>> { pub fn round_dp(x: Decimal, dp: INT) -> Result<Decimal, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) { if cfg!(not(feature = "unchecked")) {
if cfg!(not(feature = "only_i32")) && dp > (u32::MAX as INT) {
return Ok(x);
}
if dp < 0 { if dp < 0 {
return Err(make_err(format!( return Err(make_err(format!(
"Decimal value {} round to a negative index: {}", "Invalid number of digits for rounding: {}",
x, dp dp
))); )));
} }
if cfg!(not(feature = "only_i32")) && dp > (u32::MAX as INT) {
return Ok(x);
}
} }
Ok(x.round_dp(dp as u32)) Ok(x.round_dp(dp as u32))
@ -362,15 +357,15 @@ mod decimal_functions {
#[rhai_fn(return_raw)] #[rhai_fn(return_raw)]
pub fn round_up(x: Decimal, dp: INT) -> Result<Decimal, Box<EvalAltResult>> { pub fn round_up(x: Decimal, dp: INT) -> Result<Decimal, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) { if cfg!(not(feature = "unchecked")) {
if cfg!(not(feature = "only_i32")) && dp > (u32::MAX as INT) {
return Ok(x);
}
if dp < 0 { if dp < 0 {
return Err(make_err(format!( return Err(make_err(format!(
"Decimal value {} round to a negative index: {}", "Invalid number of digits for rounding: {}",
x, dp dp
))); )));
} }
if cfg!(not(feature = "only_i32")) && dp > (u32::MAX as INT) {
return Ok(x);
}
} }
Ok(x.round_dp_with_strategy(dp as u32, RoundingStrategy::AwayFromZero)) Ok(x.round_dp_with_strategy(dp as u32, RoundingStrategy::AwayFromZero))
@ -378,15 +373,15 @@ mod decimal_functions {
#[rhai_fn(return_raw)] #[rhai_fn(return_raw)]
pub fn round_down(x: Decimal, dp: INT) -> Result<Decimal, Box<EvalAltResult>> { pub fn round_down(x: Decimal, dp: INT) -> Result<Decimal, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) { if cfg!(not(feature = "unchecked")) {
if cfg!(not(feature = "only_i32")) && dp > (u32::MAX as INT) {
return Ok(x);
}
if dp < 0 { if dp < 0 {
return Err(make_err(format!( return Err(make_err(format!(
"Decimal value {} round to a negative index: {}", "Invalid number of digits for rounding: {}",
x, dp dp
))); )));
} }
if cfg!(not(feature = "only_i32")) && dp > (u32::MAX as INT) {
return Ok(x);
}
} }
Ok(x.round_dp_with_strategy(dp as u32, RoundingStrategy::ToZero)) Ok(x.round_dp_with_strategy(dp as u32, RoundingStrategy::ToZero))
@ -394,15 +389,15 @@ mod decimal_functions {
#[rhai_fn(return_raw)] #[rhai_fn(return_raw)]
pub fn round_half_up(x: Decimal, dp: INT) -> Result<Decimal, Box<EvalAltResult>> { pub fn round_half_up(x: Decimal, dp: INT) -> Result<Decimal, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) { if cfg!(not(feature = "unchecked")) {
if cfg!(not(feature = "only_i32")) && dp > (u32::MAX as INT) {
return Ok(x);
}
if dp < 0 { if dp < 0 {
return Err(make_err(format!( return Err(make_err(format!(
"Decimal value {} round to a negative index: {}", "Invalid number of digits for rounding: {}",
x, dp dp
))); )));
} }
if cfg!(not(feature = "only_i32")) && dp > (u32::MAX as INT) {
return Ok(x);
}
} }
Ok(x.round_dp_with_strategy(dp as u32, RoundingStrategy::MidpointAwayFromZero)) Ok(x.round_dp_with_strategy(dp as u32, RoundingStrategy::MidpointAwayFromZero))
@ -410,15 +405,15 @@ mod decimal_functions {
#[rhai_fn(return_raw)] #[rhai_fn(return_raw)]
pub fn round_half_down(x: Decimal, dp: INT) -> Result<Decimal, Box<EvalAltResult>> { pub fn round_half_down(x: Decimal, dp: INT) -> Result<Decimal, Box<EvalAltResult>> {
if cfg!(not(feature = "unchecked")) { if cfg!(not(feature = "unchecked")) {
if cfg!(not(feature = "only_i32")) && dp > (u32::MAX as INT) {
return Ok(x);
}
if dp < 0 { if dp < 0 {
return Err(make_err(format!( return Err(make_err(format!(
"Decimal value {} round to a negative index: {}", "Invalid number of digits for rounding: {}",
x, dp dp
))); )));
} }
if cfg!(not(feature = "only_i32")) && dp > (u32::MAX as INT) {
return Ok(x);
}
} }
Ok(x.round_dp_with_strategy(dp as u32, RoundingStrategy::MidpointTowardZero)) Ok(x.round_dp_with_strategy(dp as u32, RoundingStrategy::MidpointTowardZero))