Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
258 changes: 129 additions & 129 deletions src/uu/od/src/prn_float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ use crate::formatteriteminfo::{FormatWriter, FormatterItemInfo};
pub static FORMAT_ITEM_F16: FormatterItemInfo = FormatterItemInfo {
byte_size: 2,
print_width: 10,
formatter: FormatWriter::FloatWriter(format_item_flo16),
formatter: FormatWriter::FloatWriter(format_item_f16),
};

pub static FORMAT_ITEM_F32: FormatterItemInfo = FormatterItemInfo {
byte_size: 4,
print_width: 15,
formatter: FormatWriter::FloatWriter(format_item_flo32),
formatter: FormatWriter::FloatWriter(format_item_f32),
};

pub static FORMAT_ITEM_F64: FormatterItemInfo = FormatterItemInfo {
byte_size: 8,
print_width: 25,
formatter: FormatWriter::FloatWriter(format_item_flo64),
formatter: FormatWriter::FloatWriter(format_item_f64),
};

pub static FORMAT_ITEM_BF16: FormatterItemInfo = FormatterItemInfo {
Expand All @@ -31,19 +31,19 @@ pub static FORMAT_ITEM_BF16: FormatterItemInfo = FormatterItemInfo {
formatter: FormatWriter::BFloatWriter(format_item_bf16),
};

pub fn format_item_flo16(f: f64) -> String {
format!(" {}", format_flo16(f16::from_f64(f)))
pub fn format_item_f16(f: f64) -> String {
format!(" {}", format_f16(f16::from_f64(f)))
}

pub fn format_item_flo32(f: f64) -> String {
format!(" {}", format_flo32(f as f32))
pub fn format_item_f32(f: f64) -> String {
format!(" {}", format_f32(f as f32))
}

pub fn format_item_flo64(f: f64) -> String {
format!(" {}", format_flo64(f))
pub fn format_item_f64(f: f64) -> String {
format!(" {}", format_f64(f))
}

fn format_flo32_exp(f: f32, width: usize) -> String {
fn format_f32_exp(f: f32, width: usize) -> String {
if f.abs().log10() < 0.0 {
return format!("{f:width$e}");
}
Expand All @@ -52,7 +52,7 @@ fn format_flo32_exp(f: f32, width: usize) -> String {
formatted.replace('e', "e+")
}

fn format_flo64_exp(f: f64, width: usize) -> String {
fn format_f64_exp(f: f64, width: usize) -> String {
if f.abs().log10() < 0.0 {
return format!("{f:width$e}");
}
Expand All @@ -61,7 +61,7 @@ fn format_flo64_exp(f: f64, width: usize) -> String {
formatted.replace('e', "e+")
}

fn format_flo64_exp_precision(f: f64, width: usize, precision: usize) -> String {
fn format_f64_exp_precision(f: f64, width: usize, precision: usize) -> String {
if f.abs().log10() < 0.0 {
return format!("{f:width$.precision$e}");
}
Expand All @@ -71,28 +71,28 @@ fn format_flo64_exp_precision(f: f64, width: usize, precision: usize) -> String
}

pub fn format_item_bf16(f: f64) -> String {
format!(" {}", format_flo32(f as f32))
format!(" {}", format_f32(f as f32))
}

fn format_flo16(f: f16) -> String {
fn format_f16(f: f16) -> String {
format_float(f64::from(f), 9, 4)
}

/// formats float with 8 significant digits, eg 12345678 or -1.2345678e+12
/// always returns a string of 14 characters
fn format_flo32(f: f32) -> String {
fn format_f32(f: f32) -> String {
let width: usize = 14;
let precision: usize = 8;

if f.classify() == FpCategory::Subnormal {
// subnormal numbers will be normal as f64, so will print with a wrong precision
format_flo32_exp(f, width) // subnormal numbers
format_f32_exp(f, width) // subnormal numbers
} else {
format_float(f64::from(f), width, precision)
}
}

fn format_flo64(f: f64) -> String {
fn format_f64(f: f64) -> String {
format_float(f, 24, 17)
}

Expand All @@ -104,7 +104,7 @@ fn format_float(f: f64, width: usize, precision: usize) -> String {
if f == 0.0 || !f.is_finite() {
return format!("{f:width$}");
}
return format_flo64_exp(f, width); // subnormal numbers
return format_f64_exp(f, width); // subnormal numbers
}

let mut l = f.abs().log10().floor() as i32;
Expand All @@ -120,143 +120,143 @@ fn format_float(f: f64, width: usize, precision: usize) -> String {
} else if l == -1 {
format!("{f:width$.precision$}")
} else {
return format_flo64_exp_precision(f, width, precision - 1); // subnormal numbers
return format_f64_exp_precision(f, width, precision - 1); // subnormal numbers
}
}

#[test]
#[allow(clippy::excessive_precision)]
#[allow(clippy::cognitive_complexity)]
fn test_format_flo32() {
assert_eq!(format_flo32(1.0), " 1.0000000");
assert_eq!(format_flo32(9.999_999_0), " 9.9999990");
assert_eq!(format_flo32(10.0), " 10.000000");
assert_eq!(format_flo32(99.999_977), " 99.999977");
assert_eq!(format_flo32(99.999_992), " 99.999992");
assert_eq!(format_flo32(100.0), " 100.00000");
assert_eq!(format_flo32(999.99994), " 999.99994");
assert_eq!(format_flo32(1000.0), " 1000.0000");
assert_eq!(format_flo32(9999.9990), " 9999.9990");
assert_eq!(format_flo32(10000.0), " 10000.000");
assert_eq!(format_flo32(99999.992), " 99999.992");
assert_eq!(format_flo32(100_000.0), " 100000.00");
assert_eq!(format_flo32(999_999.94), " 999999.94");
assert_eq!(format_flo32(1_000_000.0), " 1000000.0");
assert_eq!(format_flo32(9_999_999.0), " 9999999.0");
assert_eq!(format_flo32(10_000_000.0), " 10000000");
assert_eq!(format_flo32(99_999_992.0), " 99999992");
assert_eq!(format_flo32(100_000_000.0), " 1.0000000e+8");
assert_eq!(format_flo32(9.999_999_4e8), " 9.9999994e+8");
assert_eq!(format_flo32(1.0e9), " 1.0000000e+9");
assert_eq!(format_flo32(9.999_999_0e9), " 9.9999990e+9");
assert_eq!(format_flo32(1.0e10), " 1.0000000e+10");

assert_eq!(format_flo32(0.1), " 0.10000000");
assert_eq!(format_flo32(0.999_999_94), " 0.99999994");
assert_eq!(format_flo32(0.010_000_001), " 1.0000001e-2");
assert_eq!(format_flo32(0.099_999_994), " 9.9999994e-2");
assert_eq!(format_flo32(0.001), " 1.0000000e-3");
assert_eq!(format_flo32(0.009_999_999_8), " 9.9999998e-3");

assert_eq!(format_flo32(-1.0), " -1.0000000");
assert_eq!(format_flo32(-9.999_999_0), " -9.9999990");
assert_eq!(format_flo32(-10.0), " -10.000000");
assert_eq!(format_flo32(-99.999_977), " -99.999977");
assert_eq!(format_flo32(-99.999_992), " -99.999992");
assert_eq!(format_flo32(-100.0), " -100.00000");
assert_eq!(format_flo32(-999.99994), " -999.99994");
assert_eq!(format_flo32(-1000.0), " -1000.0000");
assert_eq!(format_flo32(-9999.9990), " -9999.9990");
assert_eq!(format_flo32(-10000.0), " -10000.000");
assert_eq!(format_flo32(-99999.992), " -99999.992");
assert_eq!(format_flo32(-100_000.0), " -100000.00");
assert_eq!(format_flo32(-999_999.94), " -999999.94");
assert_eq!(format_flo32(-1_000_000.0), " -1000000.0");
assert_eq!(format_flo32(-9_999_999.0), " -9999999.0");
assert_eq!(format_flo32(-10_000_000.0), " -10000000");
assert_eq!(format_flo32(-99_999_992.0), " -99999992");
assert_eq!(format_flo32(-100_000_000.0), " -1.0000000e+8");
assert_eq!(format_flo32(-9.999_999_4e8), " -9.9999994e+8");
assert_eq!(format_flo32(-1.0e9), " -1.0000000e+9");
assert_eq!(format_flo32(-9.999_999_0e9), " -9.9999990e+9");
assert_eq!(format_flo32(-1.0e10), "-1.0000000e+10");

assert_eq!(format_flo32(-0.1), " -0.10000000");
assert_eq!(format_flo32(-0.999_999_94), " -0.99999994");
assert_eq!(format_flo32(-0.010_000_001), " -1.0000001e-2");
assert_eq!(format_flo32(-0.099_999_994), " -9.9999994e-2");
assert_eq!(format_flo32(-0.001), " -1.0000000e-3");
assert_eq!(format_flo32(-0.009_999_999_8), " -9.9999998e-3");

assert_eq!(format_flo32(3.402_823_3e38), " 3.4028233e+38");
assert_eq!(format_flo32(-3.402_823_3e38), "-3.4028233e+38");
assert_eq!(format_flo32(-1.166_310_8e-38), "-1.1663108e-38");
assert_eq!(format_flo32(-4.701_977_1e-38), "-4.7019771e-38");
assert_eq!(format_flo32(1e-45), " 1e-45");

assert_eq!(format_flo32(-3.402_823_466e+38), "-3.4028235e+38");
assert_eq!(format_flo32(f32::NAN), " NaN");
assert_eq!(format_flo32(f32::INFINITY), " inf");
assert_eq!(format_flo32(f32::NEG_INFINITY), " -inf");
assert_eq!(format_flo32(-0.0), " -0");
assert_eq!(format_flo32(0.0), " 0");
fn test_format_f32() {
assert_eq!(format_f32(1.0), " 1.0000000");
assert_eq!(format_f32(9.999_999_0), " 9.9999990");
assert_eq!(format_f32(10.0), " 10.000000");
assert_eq!(format_f32(99.999_977), " 99.999977");
assert_eq!(format_f32(99.999_992), " 99.999992");
assert_eq!(format_f32(100.0), " 100.00000");
assert_eq!(format_f32(999.99994), " 999.99994");
assert_eq!(format_f32(1000.0), " 1000.0000");
assert_eq!(format_f32(9999.9990), " 9999.9990");
assert_eq!(format_f32(10000.0), " 10000.000");
assert_eq!(format_f32(99999.992), " 99999.992");
assert_eq!(format_f32(100_000.0), " 100000.00");
assert_eq!(format_f32(999_999.94), " 999999.94");
assert_eq!(format_f32(1_000_000.0), " 1000000.0");
assert_eq!(format_f32(9_999_999.0), " 9999999.0");
assert_eq!(format_f32(10_000_000.0), " 10000000");
assert_eq!(format_f32(99_999_992.0), " 99999992");
assert_eq!(format_f32(100_000_000.0), " 1.0000000e+8");
assert_eq!(format_f32(9.999_999_4e8), " 9.9999994e+8");
assert_eq!(format_f32(1.0e9), " 1.0000000e+9");
assert_eq!(format_f32(9.999_999_0e9), " 9.9999990e+9");
assert_eq!(format_f32(1.0e10), " 1.0000000e+10");

assert_eq!(format_f32(0.1), " 0.10000000");
assert_eq!(format_f32(0.999_999_94), " 0.99999994");
assert_eq!(format_f32(0.010_000_001), " 1.0000001e-2");
assert_eq!(format_f32(0.099_999_994), " 9.9999994e-2");
assert_eq!(format_f32(0.001), " 1.0000000e-3");
assert_eq!(format_f32(0.009_999_999_8), " 9.9999998e-3");

assert_eq!(format_f32(-1.0), " -1.0000000");
assert_eq!(format_f32(-9.999_999_0), " -9.9999990");
assert_eq!(format_f32(-10.0), " -10.000000");
assert_eq!(format_f32(-99.999_977), " -99.999977");
assert_eq!(format_f32(-99.999_992), " -99.999992");
assert_eq!(format_f32(-100.0), " -100.00000");
assert_eq!(format_f32(-999.99994), " -999.99994");
assert_eq!(format_f32(-1000.0), " -1000.0000");
assert_eq!(format_f32(-9999.9990), " -9999.9990");
assert_eq!(format_f32(-10000.0), " -10000.000");
assert_eq!(format_f32(-99999.992), " -99999.992");
assert_eq!(format_f32(-100_000.0), " -100000.00");
assert_eq!(format_f32(-999_999.94), " -999999.94");
assert_eq!(format_f32(-1_000_000.0), " -1000000.0");
assert_eq!(format_f32(-9_999_999.0), " -9999999.0");
assert_eq!(format_f32(-10_000_000.0), " -10000000");
assert_eq!(format_f32(-99_999_992.0), " -99999992");
assert_eq!(format_f32(-100_000_000.0), " -1.0000000e+8");
assert_eq!(format_f32(-9.999_999_4e8), " -9.9999994e+8");
assert_eq!(format_f32(-1.0e9), " -1.0000000e+9");
assert_eq!(format_f32(-9.999_999_0e9), " -9.9999990e+9");
assert_eq!(format_f32(-1.0e10), "-1.0000000e+10");

assert_eq!(format_f32(-0.1), " -0.10000000");
assert_eq!(format_f32(-0.999_999_94), " -0.99999994");
assert_eq!(format_f32(-0.010_000_001), " -1.0000001e-2");
assert_eq!(format_f32(-0.099_999_994), " -9.9999994e-2");
assert_eq!(format_f32(-0.001), " -1.0000000e-3");
assert_eq!(format_f32(-0.009_999_999_8), " -9.9999998e-3");

assert_eq!(format_f32(3.402_823_3e38), " 3.4028233e+38");
assert_eq!(format_f32(-3.402_823_3e38), "-3.4028233e+38");
assert_eq!(format_f32(-1.166_310_8e-38), "-1.1663108e-38");
assert_eq!(format_f32(-4.701_977_1e-38), "-4.7019771e-38");
assert_eq!(format_f32(1e-45), " 1e-45");

assert_eq!(format_f32(-3.402_823_466e+38), "-3.4028235e+38");
assert_eq!(format_f32(f32::NAN), " NaN");
assert_eq!(format_f32(f32::INFINITY), " inf");
assert_eq!(format_f32(f32::NEG_INFINITY), " -inf");
assert_eq!(format_f32(-0.0), " -0");
assert_eq!(format_f32(0.0), " 0");
}

#[test]
#[allow(clippy::cognitive_complexity)]
fn test_format_flo64() {
assert_eq!(format_flo64(1.0), " 1.0000000000000000");
assert_eq!(format_flo64(10.0), " 10.000000000000000");
fn test_format_f64() {
assert_eq!(format_f64(1.0), " 1.0000000000000000");
assert_eq!(format_f64(10.0), " 10.000000000000000");
assert_eq!(
format_flo64(1_000_000_000_000_000.0),
format_f64(1_000_000_000_000_000.0),
" 1000000000000000.0"
);
assert_eq!(
format_flo64(10_000_000_000_000_000.0),
format_f64(10_000_000_000_000_000.0),
" 10000000000000000"
);
assert_eq!(
format_flo64(100_000_000_000_000_000.0),
format_f64(100_000_000_000_000_000.0),
" 1.0000000000000000e+17"
);

assert_eq!(format_flo64(-0.1), " -0.10000000000000001");
assert_eq!(format_flo64(-0.01), " -1.0000000000000000e-2");
assert_eq!(format_f64(-0.1), " -0.10000000000000001");
assert_eq!(format_f64(-0.01), " -1.0000000000000000e-2");

assert_eq!(
format_flo64(-2.225_073_858_507_201_4e-308),
format_f64(-2.225_073_858_507_201_4e-308),
"-2.2250738585072014e-308"
);
assert_eq!(format_flo64(4e-320), " 4e-320");
assert_eq!(format_flo64(f64::NAN), " NaN");
assert_eq!(format_flo64(f64::INFINITY), " inf");
assert_eq!(format_flo64(f64::NEG_INFINITY), " -inf");
assert_eq!(format_flo64(-0.0), " -0");
assert_eq!(format_flo64(0.0), " 0");
assert_eq!(format_f64(4e-320), " 4e-320");
assert_eq!(format_f64(f64::NAN), " NaN");
assert_eq!(format_f64(f64::INFINITY), " inf");
assert_eq!(format_f64(f64::NEG_INFINITY), " -inf");
assert_eq!(format_f64(-0.0), " -0");
assert_eq!(format_f64(0.0), " 0");
}

#[test]
#[allow(clippy::cognitive_complexity)]
fn test_format_flo16() {
assert_eq!(format_flo16(f16::from_bits(0x8400u16)), "-6.104e-5");
assert_eq!(format_flo16(f16::from_bits(0x8401u16)), "-6.109e-5");
assert_eq!(format_flo16(f16::from_bits(0x8402u16)), "-6.115e-5");
assert_eq!(format_flo16(f16::from_bits(0x8403u16)), "-6.121e-5");

assert_eq!(format_flo16(f16::from_f32(1.0)), " 1.000");
assert_eq!(format_flo16(f16::from_f32(10.0)), " 10.00");
assert_eq!(format_flo16(f16::from_f32(100.0)), " 100.0");
assert_eq!(format_flo16(f16::from_f32(1000.0)), " 1000");
assert_eq!(format_flo16(f16::from_f32(10000.0)), " 1.000e+4");

assert_eq!(format_flo16(f16::from_f32(-0.2)), " -0.2000");
assert_eq!(format_flo16(f16::from_f32(-0.02)), "-2.000e-2");

assert_eq!(format_flo16(f16::MIN_POSITIVE_SUBNORMAL), " 5.960e-8");
assert_eq!(format_flo16(f16::MIN), "-6.550e+4");
assert_eq!(format_flo16(f16::NAN), " NaN");
assert_eq!(format_flo16(f16::INFINITY), " inf");
assert_eq!(format_flo16(f16::NEG_INFINITY), " -inf");
assert_eq!(format_flo16(f16::NEG_ZERO), " -0");
assert_eq!(format_flo16(f16::ZERO), " 0");
fn test_format_f16() {
assert_eq!(format_f16(f16::from_bits(0x8400u16)), "-6.104e-5");
assert_eq!(format_f16(f16::from_bits(0x8401u16)), "-6.109e-5");
assert_eq!(format_f16(f16::from_bits(0x8402u16)), "-6.115e-5");
assert_eq!(format_f16(f16::from_bits(0x8403u16)), "-6.121e-5");

assert_eq!(format_f16(f16::from_f32(1.0)), " 1.000");
assert_eq!(format_f16(f16::from_f32(10.0)), " 10.00");
assert_eq!(format_f16(f16::from_f32(100.0)), " 100.0");
assert_eq!(format_f16(f16::from_f32(1000.0)), " 1000");
assert_eq!(format_f16(f16::from_f32(10000.0)), " 1.000e+4");

assert_eq!(format_f16(f16::from_f32(-0.2)), " -0.2000");
assert_eq!(format_f16(f16::from_f32(-0.02)), "-2.000e-2");

assert_eq!(format_f16(f16::MIN_POSITIVE_SUBNORMAL), " 5.960e-8");
assert_eq!(format_f16(f16::MIN), "-6.550e+4");
assert_eq!(format_f16(f16::NAN), " NaN");
assert_eq!(format_f16(f16::INFINITY), " inf");
assert_eq!(format_f16(f16::NEG_INFINITY), " -inf");
assert_eq!(format_f16(f16::NEG_ZERO), " -0");
assert_eq!(format_f16(f16::ZERO), " 0");
}
Loading