1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-08-01 05:27: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, variant: FloatVariant::Shortest,
..Default::default() ..Default::default()
} }
.fmt(&mut duration_str, duration)?; .fmt(&mut duration_str, &duration.into())?;
// We assume that printf will output valid UTF-8 // We assume that printf will output valid UTF-8
let duration_str = std::str::from_utf8(&duration_str).unwrap(); 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 let format = options
.format .format
.map(Format::<num_format::Float, f64>::parse) .map(Format::<num_format::Float, &ExtendedBigDecimal>::parse)
.transpose()?; .transpose()?;
let result = print_seq( let result = print_seq(
@ -258,7 +258,7 @@ fn print_seq(
terminator: &str, terminator: &str,
pad: bool, pad: bool,
padding: usize, padding: usize,
format: Option<&Format<num_format::Float, f64>>, format: Option<&Format<num_format::Float, &ExtendedBigDecimal>>,
) -> std::io::Result<()> { ) -> std::io::Result<()> {
let stdout = stdout().lock(); let stdout = stdout().lock();
let mut stdout = BufWriter::new(stdout); 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 // shouldn't have to do so much converting back and forth via
// strings. // strings.
match &format { match &format {
Some(f) => { Some(f) => f.fmt(&mut stdout, &value)?,
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)?;
}
None => write_value_float(&mut stdout, &value, padding, precision)?, None => write_value_float(&mut stdout, &value, padding, precision)?,
} }
// TODO Implement augmenting addition. // TODO Implement augmenting addition.

View file

@ -5,12 +5,13 @@
//! Utilities for formatting numbers in various formats //! Utilities for formatting numbers in various formats
use num_traits::ToPrimitive;
use std::cmp::min; use std::cmp::min;
use std::io::Write; use std::io::Write;
use super::{ use super::{
spec::{CanAsterisk, Spec}, spec::{CanAsterisk, Spec},
FormatError, ExtendedBigDecimal, FormatError,
}; };
pub trait Formatter<T> { pub trait Formatter<T> {
@ -231,9 +232,19 @@ impl Default for Float {
} }
} }
impl Formatter<f64> for Float { impl Formatter<&ExtendedBigDecimal> for Float {
fn fmt(&self, writer: impl Write, f: f64) -> std::io::Result<()> { 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 x = f.abs();
let s = if x.is_finite() { let s = if x.is_finite() {
match self.variant { match self.variant {
FloatVariant::Decimal => { FloatVariant::Decimal => {

View file

@ -12,7 +12,7 @@ use super::{
self, Case, FloatVariant, ForceDecimal, Formatter, NumberAlignment, PositiveSign, Prefix, self, Case, FloatVariant, ForceDecimal, Formatter, NumberAlignment, PositiveSign, Prefix,
UnsignedIntVariant, UnsignedIntVariant,
}, },
parse_escape_only, ArgumentIter, FormatChar, FormatError, OctalParsing, parse_escape_only, ArgumentIter, ExtendedBigDecimal, FormatChar, FormatError, OctalParsing,
}; };
use std::{io::Write, ops::ControlFlow}; use std::{io::Write, ops::ControlFlow};
@ -432,7 +432,8 @@ impl Spec {
} => { } => {
let width = resolve_asterisk(*width, &mut args).unwrap_or(0); let width = resolve_asterisk(*width, &mut args).unwrap_or(0);
let precision = resolve_asterisk(*precision, &mut args).unwrap_or(6); 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 { if precision as u64 > i32::MAX as u64 {
return Err(FormatError::InvalidPrecision(precision.to_string())); return Err(FormatError::InvalidPrecision(precision.to_string()));
@ -447,7 +448,7 @@ impl Spec {
positive_sign: *positive_sign, positive_sign: *positive_sign,
alignment: *alignment, alignment: *alignment,
} }
.fmt(writer, f) .fmt(writer, &f)
.map_err(FormatError::IoError) .map_err(FormatError::IoError)
} }
} }