From 991ba21510e1b9c231044886c2c3fb0da88d274c Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Sun, 3 Aug 2025 21:33:35 +0800 Subject: [PATCH] od: Switch f16 print to width=15/16, precision=8 While I think precision=4 is enough to print f16 unambiguously, being consistent with GNU implementation does not hurt. Also, change width to 16 for f32 as well. Fixes #8370. --- src/uu/od/src/prn_float.rs | 196 ++++++++++++++++++------------------- tests/by-util/test_od.rs | 26 ++--- 2 files changed, 111 insertions(+), 111 deletions(-) diff --git a/src/uu/od/src/prn_float.rs b/src/uu/od/src/prn_float.rs index f99ebc6382a..37059e226d8 100644 --- a/src/uu/od/src/prn_float.rs +++ b/src/uu/od/src/prn_float.rs @@ -9,13 +9,13 @@ use crate::formatter_item_info::{FormatWriter, FormatterItemInfo}; pub static FORMAT_ITEM_F16: FormatterItemInfo = FormatterItemInfo { byte_size: 2, - print_width: 10, + print_width: 16, formatter: FormatWriter::FloatWriter(format_item_f16), }; pub static FORMAT_ITEM_F32: FormatterItemInfo = FormatterItemInfo { byte_size: 4, - print_width: 15, + print_width: 16, formatter: FormatWriter::FloatWriter(format_item_f32), }; @@ -27,7 +27,7 @@ pub static FORMAT_ITEM_F64: FormatterItemInfo = FormatterItemInfo { pub static FORMAT_ITEM_BF16: FormatterItemInfo = FormatterItemInfo { byte_size: 2, - print_width: 15, + print_width: 16, formatter: FormatWriter::BFloatWriter(format_item_bf16), }; @@ -75,13 +75,13 @@ pub fn format_item_bf16(f: f64) -> String { } fn format_f16(f: f16) -> String { - format_float(f64::from(f), 9, 4) + format_float(f64::from(f), 15, 8) } /// formats float with 8 significant digits, eg 12345678 or -1.2345678e+12 /// always returns a string of 14 characters fn format_f32(f: f32) -> String { - let width: usize = 14; + let width: usize = 15; let precision: usize = 8; if f.classify() == FpCategory::Subnormal { @@ -128,78 +128,78 @@ fn format_float(f: f64, width: usize, precision: usize) -> String { #[allow(clippy::excessive_precision)] #[allow(clippy::cognitive_complexity)] 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"); + 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] @@ -238,25 +238,25 @@ fn test_format_f64() { #[test] #[allow(clippy::cognitive_complexity)] 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"); + assert_eq!(format_f16(f16::from_bits(0x8400u16)), " -6.1035156e-5"); + assert_eq!(format_f16(f16::from_bits(0x8401u16)), " -6.1094761e-5"); + assert_eq!(format_f16(f16::from_bits(0x8402u16)), " -6.1154366e-5"); + assert_eq!(format_f16(f16::from_bits(0x8403u16)), " -6.1213970e-5"); + + assert_eq!(format_f16(f16::from_f32(1.0)), " 1.0000000"); + assert_eq!(format_f16(f16::from_f32(10.0)), " 10.000000"); + assert_eq!(format_f16(f16::from_f32(100.0)), " 100.00000"); + assert_eq!(format_f16(f16::from_f32(1000.0)), " 1000.0000"); + assert_eq!(format_f16(f16::from_f32(10000.0)), " 10000.000"); + + assert_eq!(format_f16(f16::from_f32(-0.2)), " -0.19995117"); + assert_eq!(format_f16(f16::from_f32(-0.02)), " -2.0004272e-2"); + + assert_eq!(format_f16(f16::MIN_POSITIVE_SUBNORMAL), " 5.9604645e-8"); + assert_eq!(format_f16(f16::MIN), " -65504.000"); + 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"); } diff --git a/tests/by-util/test_od.rs b/tests/by-util/test_od.rs index 2c3ae2a959f..2d76a8dd8b3 100644 --- a/tests/by-util/test_od.rs +++ b/tests/by-util/test_od.rs @@ -206,8 +206,8 @@ fn test_f16() { ]; // 0x8400 -6.104e-5 let expected_output = unindent( " - 0000000 1.000 0 -0 inf - 0000010 -inf NaN -6.104e-5 + 0000000 1.0000000 0 -0 inf + 0000010 -inf NaN -6.1035156e-5 0000016 ", ); @@ -231,11 +231,11 @@ fn test_fh() { 0x00, 0xfc, // 0xFC00 -Inf 0x00, 0xfe, // 0xFE00 NaN 0x00, 0x84, - ]; // 0x8400 -6.104e-5 + ]; // 0x8400 -6.1035156e-5 let expected_output = unindent( " - 0000000 1.000 0 -0 inf - 0000010 -inf NaN -6.104e-5 + 0000000 1.0000000 0 -0 inf + 0000010 -inf NaN -6.1035156e-5 0000016 ", ); @@ -262,8 +262,8 @@ fn test_fb() { ]; // -6.1035156e-5 let expected_output = unindent( " - 0000000 1.0000000 0 -0 inf - 0000010 -inf NaN -6.1035156e-5 + 0000000 1.0000000 0 -0 inf + 0000010 -inf NaN -6.1035156e-5 0000016 ", ); @@ -290,8 +290,8 @@ fn test_f32() { ]; // 0x807f0000 -1.1663108E-38 let expected_output = unindent( " - 0000000 -1.2345679 12345678 -9.8765427e+37 -0 - 0000020 NaN 1e-40 -1.1663108e-38 + 0000000 -1.2345679 12345678 -9.8765427e+37 -0 + 0000020 NaN 1e-40 -1.1663108e-38 0000034 ", ); @@ -467,10 +467,10 @@ fn test_big_endian() { let expected_output = unindent( " - 0000000 -2.0000000000000000 - -2.0000000 0 - c0000000 00000000 - c000 0000 0000 0000 + 0000000 -2.0000000000000000 + -2.0000000 0 + c0000000 00000000 + c000 0000 0000 0000 0000010 ", );