1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-31 04:57:45 +00:00

uucode: format: Change Formatter to take an &ExtendedBigDecimal

Only changes the external interface, right now the number is
casted back to f64 for printing. We'll update that in follow-up.
This commit is contained in:
Nicolas Boichat 2025-03-05 20:00:20 +01:00 committed by Sylvestre Ledru
parent 241e2291bd
commit 8e11dab995
4 changed files with 22 additions and 20 deletions

View file

@ -157,7 +157,7 @@ impl ProgUpdate {
variant: FloatVariant::Shortest,
..Default::default()
}
.fmt(&mut duration_str, duration)?;
.fmt(&mut duration_str, &duration.into())?;
// We assume that printf will output valid UTF-8
let duration_str = std::str::from_utf8(&duration_str).unwrap();

View file

@ -149,7 +149,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
let format = options
.format
.map(Format::<num_format::Float, f64>::parse)
.map(Format::<num_format::Float, &ExtendedBigDecimal>::parse)
.transpose()?;
let result = print_seq(
@ -258,7 +258,7 @@ fn print_seq(
terminator: &str,
pad: bool,
padding: usize,
format: Option<&Format<num_format::Float, f64>>,
format: Option<&Format<num_format::Float, &ExtendedBigDecimal>>,
) -> std::io::Result<()> {
let stdout = stdout().lock();
let mut stdout = BufWriter::new(stdout);
@ -293,17 +293,7 @@ fn print_seq(
// shouldn't have to do so much converting back and forth via
// strings.
match &format {
Some(f) => {
let float = match &value {
ExtendedBigDecimal::BigDecimal(bd) => bd.to_f64().unwrap(),
ExtendedBigDecimal::Infinity => f64::INFINITY,
ExtendedBigDecimal::MinusInfinity => f64::NEG_INFINITY,
ExtendedBigDecimal::MinusZero => -0.0,
ExtendedBigDecimal::Nan => f64::NAN,
ExtendedBigDecimal::MinusNan => -f64::NAN,
};
f.fmt(&mut stdout, float)?;
}
Some(f) => f.fmt(&mut stdout, &value)?,
None => write_value_float(&mut stdout, &value, padding, precision)?,
}
// TODO Implement augmenting addition.

View file

@ -5,12 +5,13 @@
//! Utilities for formatting numbers in various formats
use num_traits::ToPrimitive;
use std::cmp::min;
use std::io::Write;
use super::{
spec::{CanAsterisk, Spec},
FormatError,
ExtendedBigDecimal, FormatError,
};
pub trait Formatter<T> {
@ -231,9 +232,19 @@ impl Default for Float {
}
}
impl Formatter<f64> for Float {
fn fmt(&self, writer: impl Write, f: f64) -> std::io::Result<()> {
impl Formatter<&ExtendedBigDecimal> for Float {
fn fmt(&self, writer: impl Write, e: &ExtendedBigDecimal) -> std::io::Result<()> {
// TODO: For now we just convert ExtendedBigDecimal back to f64, fix this.
let f = match e {
ExtendedBigDecimal::BigDecimal(bd) => bd.to_f64().unwrap(),
ExtendedBigDecimal::Infinity => f64::INFINITY,
ExtendedBigDecimal::MinusInfinity => f64::NEG_INFINITY,
ExtendedBigDecimal::MinusZero => -0.0,
ExtendedBigDecimal::Nan => f64::NAN,
ExtendedBigDecimal::MinusNan => -f64::NAN,
};
let x = f.abs();
let s = if x.is_finite() {
match self.variant {
FloatVariant::Decimal => {

View file

@ -12,7 +12,7 @@ use super::{
self, Case, FloatVariant, ForceDecimal, Formatter, NumberAlignment, PositiveSign, Prefix,
UnsignedIntVariant,
},
parse_escape_only, ArgumentIter, FormatChar, FormatError, OctalParsing,
parse_escape_only, ArgumentIter, ExtendedBigDecimal, FormatChar, FormatError, OctalParsing,
};
use std::{io::Write, ops::ControlFlow};
@ -432,7 +432,8 @@ impl Spec {
} => {
let width = resolve_asterisk(*width, &mut args).unwrap_or(0);
let precision = resolve_asterisk(*precision, &mut args).unwrap_or(6);
let f = args.get_f64();
// TODO: We should implement some get_extendedBigDecimal function in args to avoid losing precision.
let f: ExtendedBigDecimal = args.get_f64().into();
if precision as u64 > i32::MAX as u64 {
return Err(FormatError::InvalidPrecision(precision.to_string()));
@ -447,7 +448,7 @@ impl Spec {
positive_sign: *positive_sign,
alignment: *alignment,
}
.fmt(writer, f)
.fmt(writer, &f)
.map_err(FormatError::IoError)
}
}