Revert return type change in floor, ceil, trunc, quo (#5064)

This commit is contained in:
PgBiel 2024-09-30 04:55:34 -03:00 committed by GitHub
parent 1494373faf
commit 0b151b866a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 58 additions and 60 deletions

View File

@ -615,28 +615,26 @@ pub fn lcm(
/// ///
/// If the number is already an integer, it is returned unchanged. /// If the number is already an integer, it is returned unchanged.
/// ///
/// Note that this function will return the same type as the operand. That is, /// Note that this function will always return an [integer]($int), and will
/// applying `floor` to a [`float`] will return a `float`, and to a [`decimal`], /// error if the resulting [`float`] or [`decimal`] is larger than the maximum
/// another `decimal`. You may explicitly convert the output of this function to /// 64-bit signed integer or smaller than the minimum for that type.
/// an integer with [`int`], but note that such a conversion will error if the
/// `float` or `decimal` is larger than the maximum 64-bit signed integer or
/// smaller than the minimum integer.
/// ///
/// ```example /// ```example
/// #assert(calc.floor(3) == 3) /// #assert(calc.floor(3) == 3)
/// #assert(calc.floor(3.14) == 3.0) /// #assert(calc.floor(3.14) == 3)
/// #assert(calc.floor(decimal("-3.14")) == decimal("-4")) /// #assert(calc.floor(decimal("-3.14")) == -4)
/// #calc.floor(500.1) /// #calc.floor(500.1)
/// ``` /// ```
#[func] #[func]
pub fn floor( pub fn floor(
/// The number to round down. /// The number to round down.
value: DecNum, value: DecNum,
) -> DecNum { ) -> StrResult<i64> {
match value { match value {
DecNum::Int(n) => DecNum::Int(n), DecNum::Int(n) => Ok(n),
DecNum::Float(n) => DecNum::Float(n.floor()), DecNum::Float(n) => Ok(crate::foundations::convert_float_to_int(n.floor())
DecNum::Decimal(n) => DecNum::Decimal(n.floor()), .map_err(|_| too_large())?),
DecNum::Decimal(n) => Ok(i64::try_from(n.floor()).map_err(|_| too_large())?),
} }
} }
@ -644,28 +642,26 @@ pub fn floor(
/// ///
/// If the number is already an integer, it is returned unchanged. /// If the number is already an integer, it is returned unchanged.
/// ///
/// Note that this function will return the same type as the operand. That is, /// Note that this function will always return an [integer]($int), and will
/// applying `ceil` to a [`float`] will return a `float`, and to a [`decimal`], /// error if the resulting [`float`] or [`decimal`] is larger than the maximum
/// another `decimal`. You may explicitly convert the output of this function to /// 64-bit signed integer or smaller than the minimum for that type.
/// an integer with [`int`], but note that such a conversion will error if the
/// `float` or `decimal` is larger than the maximum 64-bit signed integer or
/// smaller than the minimum integer.
/// ///
/// ```example /// ```example
/// #assert(calc.ceil(3) == 3) /// #assert(calc.ceil(3) == 3)
/// #assert(calc.ceil(3.14) == 4) /// #assert(calc.ceil(3.14) == 4)
/// #assert(calc.ceil(decimal("-3.14")) == decimal("-3")) /// #assert(calc.ceil(decimal("-3.14")) == -3)
/// #calc.ceil(500.1) /// #calc.ceil(500.1)
/// ``` /// ```
#[func] #[func]
pub fn ceil( pub fn ceil(
/// The number to round up. /// The number to round up.
value: DecNum, value: DecNum,
) -> DecNum { ) -> StrResult<i64> {
match value { match value {
DecNum::Int(n) => DecNum::Int(n), DecNum::Int(n) => Ok(n),
DecNum::Float(n) => DecNum::Float(n.ceil()), DecNum::Float(n) => Ok(crate::foundations::convert_float_to_int(n.ceil())
DecNum::Decimal(n) => DecNum::Decimal(n.ceil()), .map_err(|_| too_large())?),
DecNum::Decimal(n) => Ok(i64::try_from(n.ceil()).map_err(|_| too_large())?),
} }
} }
@ -673,28 +669,26 @@ pub fn ceil(
/// ///
/// If the number is already an integer, it is returned unchanged. /// If the number is already an integer, it is returned unchanged.
/// ///
/// Note that this function will return the same type as the operand. That is, /// Note that this function will always return an [integer]($int), and will
/// applying `trunc` to a [`float`] will return a `float`, and to a [`decimal`], /// error if the resulting [`float`] or [`decimal`] is larger than the maximum
/// another `decimal`. You may explicitly convert the output of this function to /// 64-bit signed integer or smaller than the minimum for that type.
/// an integer with [`int`], but note that such a conversion will error if the
/// `float` or `decimal` is larger than the maximum 64-bit signed integer or
/// smaller than the minimum integer.
/// ///
/// ```example /// ```example
/// #assert(calc.trunc(3) == 3) /// #assert(calc.trunc(3) == 3)
/// #assert(calc.trunc(-3.7) == -3.0) /// #assert(calc.trunc(-3.7) == -3)
/// #assert(calc.trunc(decimal("8493.12949582390")) == decimal("8493")) /// #assert(calc.trunc(decimal("8493.12949582390")) == 8493)
/// #calc.trunc(15.9) /// #calc.trunc(15.9)
/// ``` /// ```
#[func(title = "Truncate")] #[func(title = "Truncate")]
pub fn trunc( pub fn trunc(
/// The number to truncate. /// The number to truncate.
value: DecNum, value: DecNum,
) -> DecNum { ) -> StrResult<i64> {
match value { match value {
DecNum::Int(n) => DecNum::Int(n), DecNum::Int(n) => Ok(n),
DecNum::Float(n) => DecNum::Float(n.trunc()), DecNum::Float(n) => Ok(crate::foundations::convert_float_to_int(n.trunc())
DecNum::Decimal(n) => DecNum::Decimal(n.trunc()), .map_err(|_| too_large())?),
DecNum::Decimal(n) => Ok(i64::try_from(n.trunc()).map_err(|_| too_large())?),
} }
} }
@ -1006,6 +1000,10 @@ pub fn rem_euclid(
/// Calculates the quotient (floored division) of two numbers. /// Calculates the quotient (floored division) of two numbers.
/// ///
/// Note that this function will always return an [integer]($int), and will
/// error if the resulting [`float`] or [`decimal`] is larger than the maximum
/// 64-bit signed integer or smaller than the minimum for that type.
///
/// ```example /// ```example
/// $ "quo"(a, b) &= floor(a/b) \ /// $ "quo"(a, b) &= floor(a/b) \
/// "quo"(14, 5) &= #calc.quo(14, 5) \ /// "quo"(14, 5) &= #calc.quo(14, 5) \
@ -1019,7 +1017,7 @@ pub fn quo(
dividend: DecNum, dividend: DecNum,
/// The divisor of the quotient. /// The divisor of the quotient.
divisor: Spanned<DecNum>, divisor: Spanned<DecNum>,
) -> SourceResult<DecNum> { ) -> SourceResult<i64> {
if divisor.v.is_zero() { if divisor.v.is_zero() {
bail!(divisor.span, "divisor must not be zero"); bail!(divisor.span, "divisor must not be zero");
} }
@ -1036,7 +1034,7 @@ pub fn quo(
.ok_or_else(too_large) .ok_or_else(too_large)
.at(span)?; .at(span)?;
Ok(floor(divided)) floor(divided).at(span)
} }
/// A value which can be passed to functions that work with integers and floats. /// A value which can be passed to functions that work with integers and floats.

View File

@ -368,7 +368,7 @@ cast! {
v: Str => Self(parse_int(&v).map_err(|_| eco_format!("invalid integer: {}", v))?), v: Str => Self(parse_int(&v).map_err(|_| eco_format!("invalid integer: {}", v))?),
} }
fn convert_float_to_int(f: f64) -> StrResult<i64> { pub fn convert_float_to_int(f: f64) -> StrResult<i64> {
if f <= i64::MIN as f64 - 1.0 || f >= i64::MAX as f64 + 1.0 { if f <= i64::MIN as f64 - 1.0 || f >= i64::MAX as f64 + 1.0 {
Err(eco_format!("number too large")) Err(eco_format!("number too large"))
} else { } else {

View File

@ -122,10 +122,10 @@
#test(calc.quo(1, 1), 1) #test(calc.quo(1, 1), 1)
#test(calc.quo(5, 3), 1) #test(calc.quo(5, 3), 1)
#test(calc.quo(5, -3), -1) #test(calc.quo(5, -3), -1)
#test(calc.quo(22.5, 10), 2.0) #test(calc.quo(22.5, 10), 2)
#test(calc.quo(9, 4.5), 2.0) #test(calc.quo(9, 4.5), 2)
#test(calc.quo(decimal("22.5"), 10), decimal("2")) #test(calc.quo(decimal("22.5"), 10), 2)
#test(calc.quo(decimal("9"), decimal("4.5")), decimal("2")) #test(calc.quo(decimal("9"), decimal("4.5")), 2)
--- calc-quo-divisor-zero-1 --- --- calc-quo-divisor-zero-1 ---
// Error: 14-15 divisor must not be zero // Error: 14-15 divisor must not be zero
@ -307,29 +307,29 @@
// Error: 2-41 the result is too large // Error: 2-41 the result is too large
#calc.lcm(15486487489457, 4874879896543) #calc.lcm(15486487489457, 4874879896543)
--- calc-rounding-larger-than-max-int --- --- calc-round-larger-than-max-int ---
#test(calc.round(decimal("9223372036854775809.5")), decimal("9223372036854775810")) #test(calc.round(decimal("9223372036854775809.5")), decimal("9223372036854775810"))
#test(calc.round(9223372036854775809.5), 9223372036854775810.0) #test(calc.round(9223372036854775809.5), 9223372036854775810.0)
#test(calc.floor(decimal("9223372036854775809.5")), decimal("9223372036854775809"))
#test(calc.floor(9223372036854775809.5), 9223372036854775809.0)
#test(calc.ceil(decimal("9223372036854775809.5")), decimal("9223372036854775810"))
#test(calc.ceil(9223372036854775809.5), 9223372036854775810.0)
#test(calc.trunc(decimal("9223372036854775809.5")), decimal("9223372036854775809"))
#test(calc.trunc(9223372036854775809.5), 9223372036854775809.0)
#test(calc.quo(decimal("9223372036854775809.5"), 1), decimal("9223372036854775809"))
#test(calc.quo(9223372036854775809.5, 1), 9223372036854775809.0)
--- calc-rounding-smaller-than-min-int --- --- calc-floor-float-larger-than-max-int ---
// Error: 2-35 the result is too large
#calc.floor(9223372036854775809.5)
--- calc-floor-decimal-larger-than-max-int ---
// Error: 2-46 the result is too large
#calc.floor(decimal("9223372036854775809.5"))
--- calc-round-smaller-than-min-int ---
#test(calc.round(decimal("-9223372036854775809.5")), decimal("-9223372036854775810")) #test(calc.round(decimal("-9223372036854775809.5")), decimal("-9223372036854775810"))
#test(calc.round(-9223372036854775809.5), -9223372036854775810.0) #test(calc.round(-9223372036854775809.5), -9223372036854775810.0)
#test(calc.floor(decimal("-9223372036854775809.5")), decimal("-9223372036854775810"))
#test(calc.floor(-9223372036854775809.5), -9223372036854775810.0) --- calc-floor-float-smaller-than-min-int ---
#test(calc.ceil(decimal("-9223372036854775809.5")), decimal("-9223372036854775809")) // Error: 2-36 the result is too large
#test(calc.ceil(-9223372036854775809.5), -9223372036854775809.0) #calc.floor(-9223372036854775809.5)
#test(calc.trunc(decimal("-9223372036854775809.5")), decimal("-9223372036854775809"))
#test(calc.trunc(-9223372036854775809.5), -9223372036854775809.0) --- calc-floor-decimal-smaller-than-min-int ---
#test(calc.quo(decimal("-9223372036854775809.5"), 1), decimal("-9223372036854775810")) // Error: 2-47 the result is too large
#test(calc.quo(-9223372036854775809.5, 1), -9223372036854775810.0) #calc.floor(decimal("-9223372036854775809.5"))
--- calc-min-nothing --- --- calc-min-nothing ---
// Error: 2-12 expected at least one value // Error: 2-12 expected at least one value