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.
///
/// Note that this function will return the same type as the operand. That is,
/// applying `floor` to a [`float`] will return a `float`, and to a [`decimal`],
/// another `decimal`. You may explicitly convert the output of this function to
/// 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.
/// 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
/// #assert(calc.floor(3) == 3)
/// #assert(calc.floor(3.14) == 3.0)
/// #assert(calc.floor(decimal("-3.14")) == decimal("-4"))
/// #assert(calc.floor(3.14) == 3)
/// #assert(calc.floor(decimal("-3.14")) == -4)
/// #calc.floor(500.1)
/// ```
#[func]
pub fn floor(
/// The number to round down.
value: DecNum,
) -> DecNum {
) -> StrResult<i64> {
match value {
DecNum::Int(n) => DecNum::Int(n),
DecNum::Float(n) => DecNum::Float(n.floor()),
DecNum::Decimal(n) => DecNum::Decimal(n.floor()),
DecNum::Int(n) => Ok(n),
DecNum::Float(n) => Ok(crate::foundations::convert_float_to_int(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.
///
/// Note that this function will return the same type as the operand. That is,
/// applying `ceil` to a [`float`] will return a `float`, and to a [`decimal`],
/// another `decimal`. You may explicitly convert the output of this function to
/// 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.
/// 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
/// #assert(calc.ceil(3) == 3)
/// #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)
/// ```
#[func]
pub fn ceil(
/// The number to round up.
value: DecNum,
) -> DecNum {
) -> StrResult<i64> {
match value {
DecNum::Int(n) => DecNum::Int(n),
DecNum::Float(n) => DecNum::Float(n.ceil()),
DecNum::Decimal(n) => DecNum::Decimal(n.ceil()),
DecNum::Int(n) => Ok(n),
DecNum::Float(n) => Ok(crate::foundations::convert_float_to_int(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.
///
/// Note that this function will return the same type as the operand. That is,
/// applying `trunc` to a [`float`] will return a `float`, and to a [`decimal`],
/// another `decimal`. You may explicitly convert the output of this function to
/// 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.
/// 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
/// #assert(calc.trunc(3) == 3)
/// #assert(calc.trunc(-3.7) == -3.0)
/// #assert(calc.trunc(decimal("8493.12949582390")) == decimal("8493"))
/// #assert(calc.trunc(-3.7) == -3)
/// #assert(calc.trunc(decimal("8493.12949582390")) == 8493)
/// #calc.trunc(15.9)
/// ```
#[func(title = "Truncate")]
pub fn trunc(
/// The number to truncate.
value: DecNum,
) -> DecNum {
) -> StrResult<i64> {
match value {
DecNum::Int(n) => DecNum::Int(n),
DecNum::Float(n) => DecNum::Float(n.trunc()),
DecNum::Decimal(n) => DecNum::Decimal(n.trunc()),
DecNum::Int(n) => Ok(n),
DecNum::Float(n) => Ok(crate::foundations::convert_float_to_int(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.
///
/// 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
/// $ "quo"(a, b) &= floor(a/b) \
/// "quo"(14, 5) &= #calc.quo(14, 5) \
@ -1019,7 +1017,7 @@ pub fn quo(
dividend: DecNum,
/// The divisor of the quotient.
divisor: Spanned<DecNum>,
) -> SourceResult<DecNum> {
) -> SourceResult<i64> {
if divisor.v.is_zero() {
bail!(divisor.span, "divisor must not be zero");
}
@ -1036,7 +1034,7 @@ pub fn quo(
.ok_or_else(too_large)
.at(span)?;
Ok(floor(divided))
floor(divided).at(span)
}
/// 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))?),
}
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 {
Err(eco_format!("number too large"))
} else {

View File

@ -122,10 +122,10 @@
#test(calc.quo(1, 1), 1)
#test(calc.quo(5, 3), 1)
#test(calc.quo(5, -3), -1)
#test(calc.quo(22.5, 10), 2.0)
#test(calc.quo(9, 4.5), 2.0)
#test(calc.quo(decimal("22.5"), 10), decimal("2"))
#test(calc.quo(decimal("9"), decimal("4.5")), decimal("2"))
#test(calc.quo(22.5, 10), 2)
#test(calc.quo(9, 4.5), 2)
#test(calc.quo(decimal("22.5"), 10), 2)
#test(calc.quo(decimal("9"), decimal("4.5")), 2)
--- calc-quo-divisor-zero-1 ---
// Error: 14-15 divisor must not be zero
@ -307,29 +307,29 @@
// Error: 2-41 the result is too large
#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(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(-9223372036854775809.5), -9223372036854775810.0)
#test(calc.floor(decimal("-9223372036854775809.5")), decimal("-9223372036854775810"))
#test(calc.floor(-9223372036854775809.5), -9223372036854775810.0)
#test(calc.ceil(decimal("-9223372036854775809.5")), decimal("-9223372036854775809"))
#test(calc.ceil(-9223372036854775809.5), -9223372036854775809.0)
#test(calc.trunc(decimal("-9223372036854775809.5")), decimal("-9223372036854775809"))
#test(calc.trunc(-9223372036854775809.5), -9223372036854775809.0)
#test(calc.quo(decimal("-9223372036854775809.5"), 1), decimal("-9223372036854775810"))
#test(calc.quo(-9223372036854775809.5, 1), -9223372036854775810.0)
--- calc-floor-float-smaller-than-min-int ---
// Error: 2-36 the result is too large
#calc.floor(-9223372036854775809.5)
--- calc-floor-decimal-smaller-than-min-int ---
// Error: 2-47 the result is too large
#calc.floor(decimal("-9223372036854775809.5"))
--- calc-min-nothing ---
// Error: 2-12 expected at least one value