Add rounding functions to Decimal numbers.
This commit is contained in:
parent
224d93f167
commit
fc21756785
@ -9,6 +9,7 @@ Bug fixes
|
||||
|
||||
* Empty statements (i.e. statements with only one `;`) now parse correctly and no longer hang.
|
||||
* `continue`, `break` and `return` statements no longer panic inside a `try .. catch` block.
|
||||
* `round` function for `f64` is now implemented correctly.
|
||||
|
||||
Breaking changes
|
||||
----------------
|
||||
|
@ -19,6 +19,9 @@ use crate::stdlib::format;
|
||||
#[cfg(feature = "decimal")]
|
||||
use rust_decimal::Decimal;
|
||||
|
||||
#[cfg(feature = "decimal")]
|
||||
use super::arithmetic::make_err;
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[cfg(feature = "only_i32")]
|
||||
pub const MAX_INT: INT = i32::MAX;
|
||||
@ -228,7 +231,7 @@ mod float_functions {
|
||||
}
|
||||
#[rhai_fn(name = "round", get = "round")]
|
||||
pub fn round(x: FLOAT) -> FLOAT {
|
||||
x.ceil()
|
||||
x.round()
|
||||
}
|
||||
#[rhai_fn(name = "int", get = "int")]
|
||||
pub fn int(x: FLOAT) -> FLOAT {
|
||||
@ -311,7 +314,114 @@ mod decimal_functions {
|
||||
}
|
||||
#[rhai_fn(name = "round", get = "round")]
|
||||
pub fn round(x: Decimal) -> Decimal {
|
||||
x.ceil()
|
||||
x.round()
|
||||
}
|
||||
#[rhai_fn(return_raw)]
|
||||
pub fn round_dp(x: Decimal, dp: INT) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||
if cfg!(not(feature = "unchecked")) {
|
||||
if cfg!(not(feature = "only_i32")) && dp > (u32::MAX as INT) {
|
||||
return Err(make_err(format!(
|
||||
"Decimal value {} round to too many decimal points: {}",
|
||||
x, dp
|
||||
)));
|
||||
}
|
||||
if dp < 0 {
|
||||
return Err(make_err(format!(
|
||||
"Decimal value {} round to a negative index: {}",
|
||||
x, dp
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Dynamic::from(x.round_dp(dp as u32)))
|
||||
}
|
||||
#[rhai_fn(return_raw)]
|
||||
pub fn round_up(x: Decimal, dp: INT) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||
if cfg!(not(feature = "unchecked")) {
|
||||
if cfg!(not(feature = "only_i32")) && dp > (u32::MAX as INT) {
|
||||
return Err(make_err(format!(
|
||||
"Decimal value {} round to too many decimal points: {}",
|
||||
x, dp
|
||||
)));
|
||||
}
|
||||
if dp < 0 {
|
||||
return Err(make_err(format!(
|
||||
"Decimal value {} round to a negative index: {}",
|
||||
x, dp
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Dynamic::from(x.round_dp_with_strategy(
|
||||
dp as u32,
|
||||
rust_decimal::prelude::RoundingStrategy::RoundUp,
|
||||
)))
|
||||
}
|
||||
#[rhai_fn(return_raw)]
|
||||
pub fn round_down(x: Decimal, dp: INT) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||
if cfg!(not(feature = "unchecked")) {
|
||||
if cfg!(not(feature = "only_i32")) && dp > (u32::MAX as INT) {
|
||||
return Err(make_err(format!(
|
||||
"Decimal value {} round to too many decimal points: {}",
|
||||
x, dp
|
||||
)));
|
||||
}
|
||||
if dp < 0 {
|
||||
return Err(make_err(format!(
|
||||
"Decimal value {} round to a negative index: {}",
|
||||
x, dp
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Dynamic::from(x.round_dp_with_strategy(
|
||||
dp as u32,
|
||||
rust_decimal::prelude::RoundingStrategy::RoundDown,
|
||||
)))
|
||||
}
|
||||
#[rhai_fn(return_raw)]
|
||||
pub fn round_half_up(x: Decimal, dp: INT) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||
if cfg!(not(feature = "unchecked")) {
|
||||
if cfg!(not(feature = "only_i32")) && dp > (u32::MAX as INT) {
|
||||
return Err(make_err(format!(
|
||||
"Decimal value {} round to too many decimal points: {}",
|
||||
x, dp
|
||||
)));
|
||||
}
|
||||
if dp < 0 {
|
||||
return Err(make_err(format!(
|
||||
"Decimal value {} round to a negative index: {}",
|
||||
x, dp
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Dynamic::from(x.round_dp_with_strategy(
|
||||
dp as u32,
|
||||
rust_decimal::prelude::RoundingStrategy::RoundHalfUp,
|
||||
)))
|
||||
}
|
||||
#[rhai_fn(return_raw)]
|
||||
pub fn round_half_down(x: Decimal, dp: INT) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||
if cfg!(not(feature = "unchecked")) {
|
||||
if cfg!(not(feature = "only_i32")) && dp > (u32::MAX as INT) {
|
||||
return Err(make_err(format!(
|
||||
"Decimal value {} round to too many decimal points: {}",
|
||||
x, dp
|
||||
)));
|
||||
}
|
||||
if dp < 0 {
|
||||
return Err(make_err(format!(
|
||||
"Decimal value {} round to a negative index: {}",
|
||||
x, dp
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Dynamic::from(x.round_dp_with_strategy(
|
||||
dp as u32,
|
||||
rust_decimal::prelude::RoundingStrategy::RoundHalfDown,
|
||||
)))
|
||||
}
|
||||
#[rhai_fn(name = "int", get = "int")]
|
||||
pub fn int(x: Decimal) -> Decimal {
|
||||
|
Loading…
Reference in New Issue
Block a user