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:
parent
241e2291bd
commit
8e11dab995
4 changed files with 22 additions and 20 deletions
|
@ -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();
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 => {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue