mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-29 20:17:45 +00:00
uucore: format: Workaround BigDecimal printing bug with 0
This is a bigdecimal issue, see https://github.com/akubera/bigdecimal-rs/issues/144 . Also add a few tests, including a disabled one (our workaround is _before_ the call to format_float_decimal).
This commit is contained in:
parent
35a923b076
commit
afbab45350
1 changed files with 49 additions and 2 deletions
|
@ -2,7 +2,7 @@
|
||||||
//
|
//
|
||||||
// For the full copyright and license information, please view the LICENSE
|
// For the full copyright and license information, please view the LICENSE
|
||||||
// file that was distributed with this source code.
|
// file that was distributed with this source code.
|
||||||
// spell-checker:ignore bigdecimal prec
|
// spell-checker:ignore bigdecimal prec cppreference
|
||||||
//! Utilities for formatting numbers in various formats
|
//! Utilities for formatting numbers in various formats
|
||||||
|
|
||||||
use bigdecimal::BigDecimal;
|
use bigdecimal::BigDecimal;
|
||||||
|
@ -244,7 +244,13 @@ impl Formatter<&ExtendedBigDecimal> for Float {
|
||||||
*/
|
*/
|
||||||
let (abs, negative) = match e {
|
let (abs, negative) = match e {
|
||||||
ExtendedBigDecimal::BigDecimal(bd) => {
|
ExtendedBigDecimal::BigDecimal(bd) => {
|
||||||
(ExtendedBigDecimal::BigDecimal(bd.abs()), bd.is_negative())
|
// Workaround printing bug in BigDecimal, force 0 to scale 0.
|
||||||
|
// TODO: Remove after https://github.com/akubera/bigdecimal-rs/issues/144 is fixed.
|
||||||
|
if bd.is_zero() {
|
||||||
|
(ExtendedBigDecimal::zero(), false)
|
||||||
|
} else {
|
||||||
|
(ExtendedBigDecimal::BigDecimal(bd.abs()), bd.is_negative())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ExtendedBigDecimal::MinusZero => (ExtendedBigDecimal::zero(), true),
|
ExtendedBigDecimal::MinusZero => (ExtendedBigDecimal::zero(), true),
|
||||||
ExtendedBigDecimal::Infinity => (ExtendedBigDecimal::Infinity, false),
|
ExtendedBigDecimal::Infinity => (ExtendedBigDecimal::Infinity, false),
|
||||||
|
@ -719,6 +725,21 @@ mod test {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore = "Need https://github.com/akubera/bigdecimal-rs/issues/144 to be fixed"]
|
||||||
|
fn decimal_float_zero() {
|
||||||
|
use super::format_float_decimal;
|
||||||
|
// We've had issues with "0e10"/"0e-10" formatting.
|
||||||
|
// TODO: Enable after https://github.com/akubera/bigdecimal-rs/issues/144 is fixed,
|
||||||
|
// as our workaround is in .fmt.
|
||||||
|
let f = |digits, scale| {
|
||||||
|
format_float_decimal(&BigDecimal::from_bigint(digits, scale), 6, ForceDecimal::No)
|
||||||
|
};
|
||||||
|
assert_eq!(f(0.into(), 0), "0.000000");
|
||||||
|
assert_eq!(f(0.into(), -10), "0.000000");
|
||||||
|
assert_eq!(f(0.into(), 10), "0.000000");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn scientific_float() {
|
fn scientific_float() {
|
||||||
use super::format_float_scientific;
|
use super::format_float_scientific;
|
||||||
|
@ -748,6 +769,19 @@ mod test {
|
||||||
};
|
};
|
||||||
assert_eq!(f(0.0), "0.000000E+00");
|
assert_eq!(f(0.0), "0.000000E+00");
|
||||||
assert_eq!(f(123_456.789), "1.234568E+05");
|
assert_eq!(f(123_456.789), "1.234568E+05");
|
||||||
|
|
||||||
|
// Test "0e10"/"0e-10". From cppreference.com: "If the value is 0, the exponent is also 0."
|
||||||
|
let f = |digits, scale| {
|
||||||
|
format_float_scientific(
|
||||||
|
&BigDecimal::from_bigint(digits, scale),
|
||||||
|
6,
|
||||||
|
Case::Lowercase,
|
||||||
|
ForceDecimal::No,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
assert_eq!(f(0.into(), 0), "0.000000e+00");
|
||||||
|
assert_eq!(f(0.into(), -10), "0.000000e+00");
|
||||||
|
assert_eq!(f(0.into(), 10), "0.000000e+00");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -928,6 +962,19 @@ mod test {
|
||||||
};
|
};
|
||||||
assert_eq!(f("0.00001"), "0xA.7C5AC4P-20");
|
assert_eq!(f("0.00001"), "0xA.7C5AC4P-20");
|
||||||
assert_eq!(f("0.125"), "0x8.000000P-6");
|
assert_eq!(f("0.125"), "0x8.000000P-6");
|
||||||
|
|
||||||
|
// Test "0e10"/"0e-10". From cppreference.com: "If the value is 0, the exponent is also 0."
|
||||||
|
let f = |digits, scale| {
|
||||||
|
format_float_hexadecimal(
|
||||||
|
&BigDecimal::from_bigint(digits, scale),
|
||||||
|
6,
|
||||||
|
Case::Lowercase,
|
||||||
|
ForceDecimal::No,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
assert_eq!(f(0.into(), 0), "0x0.000000p+0");
|
||||||
|
assert_eq!(f(0.into(), -10), "0x0.000000p+0");
|
||||||
|
assert_eq!(f(0.into(), 10), "0x0.000000p+0");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue