From 9a555f18588e0c75bd87bc03ce2ddb4c225fc52e Mon Sep 17 00:00:00 2001 From: mattsu Date: Sat, 29 Nov 2025 21:00:26 +0900 Subject: [PATCH 01/10] feat: add compact float formatting for half and bfloat16 in od Implement trim_float_repr() to remove trailing zeros from float strings while preserving signs and exponents, and pad_float_repr() to align trimmed floats to fixed width. Update format_item_f16() and format_item_bf16() to produce compact output matching GNU od. Add regression tests for float16 and bfloat16 compact printing. --- src/uu/od/src/prn_float.rs | 57 ++++++++++++++++++++++++++++++++++++-- tests/by-util/test_od.rs | 26 +++++++++++++++++ 2 files changed, 81 insertions(+), 2 deletions(-) diff --git a/src/uu/od/src/prn_float.rs b/src/uu/od/src/prn_float.rs index 155ce7d0794..71c3668f9fb 100644 --- a/src/uu/od/src/prn_float.rs +++ b/src/uu/od/src/prn_float.rs @@ -37,8 +37,60 @@ pub static FORMAT_ITEM_BF16: FormatterItemInfo = FormatterItemInfo { formatter: FormatWriter::BFloatWriter(format_item_bf16), }; +/// Trim trailing zeroes (and an optional decimal dot) from a floating-point +/// string representation while keeping the sign and any exponent suffix. +fn trim_float_repr(s: &str) -> String { + let s = s.trim(); + + // Fast path for special values + if s.eq_ignore_ascii_case("nan") + || s.eq_ignore_ascii_case("inf") + || s.eq_ignore_ascii_case("-inf") + || s == "0" + || s == "-0" + { + return s.to_string(); + } + + // Split mantissa and exponent if present + let (mantissa, exponent) = match s.find(['e', 'E']) { + Some(pos) => (&s[..pos], Some(&s[pos..])), + None => (s, None), + }; + + let mut mantissa = mantissa.to_string(); + + // Remove trailing zeroes from the mantissa's fractional part + if let Some(dot_pos) = mantissa.find('.') { + while mantissa.ends_with('0') { + mantissa.pop(); + } + if mantissa.ends_with('.') && mantissa.len() > dot_pos { + mantissa.pop(); + } + if mantissa.is_empty() { + mantissa.push('0'); + } + } + + if let Some(exp) = exponent { + mantissa.push_str(exp); + } + + mantissa +} + +/// Pad a trimmed floating value to a fixed width for column alignment. +fn pad_float_repr(raw: &str, width: usize) -> String { + let trimmed = trim_float_repr(raw); + format!("{trimmed:>width$}", width = width) +} + pub fn format_item_f16(f: f64) -> String { - format!(" {}", format_f16(f16::from_f64(f))) + // Keep the width used by FORMAT_ITEM_F16 (minus the leading space we add here), + // but print a compact representation to match GNU od output for 16‑bit floats. + let raw = format_f16(f16::from_f64(f)); + format!(" {}", pad_float_repr(&raw, FORMAT_ITEM_F16.print_width - 1)) } pub fn format_item_f32(f: f64) -> String { @@ -82,7 +134,8 @@ fn format_f64_exp_precision(f: f64, width: usize, precision: usize) -> String { pub fn format_item_bf16(f: f64) -> String { let bf = bf16::from_f32(f as f32); - format!(" {}", format_binary16_like(f, 15, 8, is_subnormal_bf16(bf))) + let raw = format_binary16_like(f, 15, 8, is_subnormal_bf16(bf)); + format!(" {}", pad_float_repr(&raw, FORMAT_ITEM_BF16.print_width - 1)) } fn format_f16(f: f16) -> String { diff --git a/tests/by-util/test_od.rs b/tests/by-util/test_od.rs index 54be3455178..133eac86621 100644 --- a/tests/by-util/test_od.rs +++ b/tests/by-util/test_od.rs @@ -197,6 +197,32 @@ fn test_hex32() { .stdout_only(expected_output); } +// Regression: 16-bit IEEE half should print compactly (no spurious digits) +#[test] +fn test_float16_compact() { + let input: [u8; 4] = [0x3c, 0x00, 0x3c, 0x00]; // two times 1.0 in big-endian half + new_ucmd!() + .arg("--endian=big") + .arg("-An") + .arg("-tfH") + .run_piped_stdin(&input[..]) + .success() + .stdout_only(" 1 1\n"); +} + +// Regression: 16-bit bfloat should print compactly (no spurious digits) +#[test] +fn test_bfloat16_compact() { + let input: [u8; 4] = [0x3f, 0x80, 0x3f, 0x80]; // two times 1.0 in big-endian bfloat16 + new_ucmd!() + .arg("--endian=big") + .arg("-An") + .arg("-tfB") + .run_piped_stdin(&input[..]) + .success() + .stdout_only(" 1 1\n"); +} + #[test] fn test_f16() { let input: [u8; 14] = [ From 24d1c6a7f543987751308c3a58746b0bbaf4f283 Mon Sep 17 00:00:00 2001 From: mattsu Date: Sat, 29 Nov 2025 21:00:41 +0900 Subject: [PATCH 02/10] refactor(od): format multiline format! in format_item_bf16 for readability Reformat the format! macro call in the format_item_bf16 function in prn_float.rs to span multiple lines, improving code readability without changing functionality. --- src/uu/od/src/prn_float.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/uu/od/src/prn_float.rs b/src/uu/od/src/prn_float.rs index 71c3668f9fb..44f8451fee8 100644 --- a/src/uu/od/src/prn_float.rs +++ b/src/uu/od/src/prn_float.rs @@ -135,7 +135,10 @@ fn format_f64_exp_precision(f: f64, width: usize, precision: usize) -> String { pub fn format_item_bf16(f: f64) -> String { let bf = bf16::from_f32(f as f32); let raw = format_binary16_like(f, 15, 8, is_subnormal_bf16(bf)); - format!(" {}", pad_float_repr(&raw, FORMAT_ITEM_BF16.print_width - 1)) + format!( + " {}", + pad_float_repr(&raw, FORMAT_ITEM_BF16.print_width - 1) + ) } fn format_f16(f: f16) -> String { From d073496605e2fec7645d164b33db5787d3d85bc0 Mon Sep 17 00:00:00 2001 From: mattsu Date: Sat, 29 Nov 2025 21:32:13 +0900 Subject: [PATCH 03/10] fix(od): preserve canonical precision for f16/bf16 float formats Remove trimming of trailing zeros from f16 and bf16 float representations in od output to maintain original precision and align behavior with f32/f64 formatters, ensuring stable output across platforms. Update corresponding tests to reflect the change in expected output. --- src/uu/od/src/prn_float.rs | 51 ++++---------------------------------- tests/by-util/test_od.rs | 8 +++--- 2 files changed, 9 insertions(+), 50 deletions(-) diff --git a/src/uu/od/src/prn_float.rs b/src/uu/od/src/prn_float.rs index 44f8451fee8..1995ac4a429 100644 --- a/src/uu/od/src/prn_float.rs +++ b/src/uu/od/src/prn_float.rs @@ -37,53 +37,12 @@ pub static FORMAT_ITEM_BF16: FormatterItemInfo = FormatterItemInfo { formatter: FormatWriter::BFloatWriter(format_item_bf16), }; -/// Trim trailing zeroes (and an optional decimal dot) from a floating-point -/// string representation while keeping the sign and any exponent suffix. -fn trim_float_repr(s: &str) -> String { - let s = s.trim(); - - // Fast path for special values - if s.eq_ignore_ascii_case("nan") - || s.eq_ignore_ascii_case("inf") - || s.eq_ignore_ascii_case("-inf") - || s == "0" - || s == "-0" - { - return s.to_string(); - } - - // Split mantissa and exponent if present - let (mantissa, exponent) = match s.find(['e', 'E']) { - Some(pos) => (&s[..pos], Some(&s[pos..])), - None => (s, None), - }; - - let mut mantissa = mantissa.to_string(); - - // Remove trailing zeroes from the mantissa's fractional part - if let Some(dot_pos) = mantissa.find('.') { - while mantissa.ends_with('0') { - mantissa.pop(); - } - if mantissa.ends_with('.') && mantissa.len() > dot_pos { - mantissa.pop(); - } - if mantissa.is_empty() { - mantissa.push('0'); - } - } - - if let Some(exp) = exponent { - mantissa.push_str(exp); - } - - mantissa -} - -/// Pad a trimmed floating value to a fixed width for column alignment. +/// Pad a floating value to a fixed width for column alignment while keeping +/// the original precision (including trailing zeros). This mirrors the +/// behavior of other float formatters (`f32`, `f64`) and keeps the output +/// stable across platforms. fn pad_float_repr(raw: &str, width: usize) -> String { - let trimmed = trim_float_repr(raw); - format!("{trimmed:>width$}", width = width) + format!("{raw:>width$}", width = width) } pub fn format_item_f16(f: f64) -> String { diff --git a/tests/by-util/test_od.rs b/tests/by-util/test_od.rs index 133eac86621..2dde20b2792 100644 --- a/tests/by-util/test_od.rs +++ b/tests/by-util/test_od.rs @@ -197,7 +197,7 @@ fn test_hex32() { .stdout_only(expected_output); } -// Regression: 16-bit IEEE half should print compactly (no spurious digits) +// Regression: 16-bit IEEE half should print with canonical precision (no spurious digits) #[test] fn test_float16_compact() { let input: [u8; 4] = [0x3c, 0x00, 0x3c, 0x00]; // two times 1.0 in big-endian half @@ -207,10 +207,10 @@ fn test_float16_compact() { .arg("-tfH") .run_piped_stdin(&input[..]) .success() - .stdout_only(" 1 1\n"); + .stdout_only(" 1.0000000 1.0000000\n"); } -// Regression: 16-bit bfloat should print compactly (no spurious digits) +// Regression: 16-bit bfloat should print with canonical precision (no spurious digits) #[test] fn test_bfloat16_compact() { let input: [u8; 4] = [0x3f, 0x80, 0x3f, 0x80]; // two times 1.0 in big-endian bfloat16 @@ -220,7 +220,7 @@ fn test_bfloat16_compact() { .arg("-tfB") .run_piped_stdin(&input[..]) .success() - .stdout_only(" 1 1\n"); + .stdout_only(" 1.0000000 1.0000000\n"); } #[test] From 93970ad118969401acad118e1e2973d94f85a595 Mon Sep 17 00:00:00 2001 From: mattsu Date: Sat, 29 Nov 2025 22:04:37 +0900 Subject: [PATCH 04/10] refactor(od): simplify float padding format and update tests - Remove redundant `width = width` parameter from `format!` macro in `pad_float_repr` - Add "bfloat" to spell-checker ignore list for better test coverage on bf16 format --- src/uu/od/src/prn_float.rs | 2 +- tests/by-util/test_od.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uu/od/src/prn_float.rs b/src/uu/od/src/prn_float.rs index 1995ac4a429..a0208a6a56e 100644 --- a/src/uu/od/src/prn_float.rs +++ b/src/uu/od/src/prn_float.rs @@ -42,7 +42,7 @@ pub static FORMAT_ITEM_BF16: FormatterItemInfo = FormatterItemInfo { /// behavior of other float formatters (`f32`, `f64`) and keeps the output /// stable across platforms. fn pad_float_repr(raw: &str, width: usize) -> String { - format!("{raw:>width$}", width = width) + format!("{raw:>width$}") } pub fn format_item_f16(f: f64) -> String { diff --git a/tests/by-util/test_od.rs b/tests/by-util/test_od.rs index 2dde20b2792..61334b127eb 100644 --- a/tests/by-util/test_od.rs +++ b/tests/by-util/test_od.rs @@ -3,7 +3,7 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore abcdefghijklmnopqrstuvwxyz Anone fdbb littl +// spell-checker:ignore abcdefghijklmnopqrstuvwxyz Anone fdbb littl bfloat #[cfg(unix)] use std::io::Read; From 84f1973028dc55ac403cb67c806ac8e4fc2e2401 Mon Sep 17 00:00:00 2001 From: mattsu Date: Mon, 1 Dec 2025 08:19:00 +0900 Subject: [PATCH 05/10] feat(od): trim trailing zeros in float outputs for GNU compatibility Add `trim_trailing_zeros` function to remove trailing zeros and redundant decimal points from formatted floats, ensuring compact output matching GNU od for f16 and bf16 types. Update `format_item_f16` and `format_item_bf16` to apply trimming before padding. --- src/uu/od/src/prn_float.rs | 52 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/src/uu/od/src/prn_float.rs b/src/uu/od/src/prn_float.rs index a0208a6a56e..608e513df34 100644 --- a/src/uu/od/src/prn_float.rs +++ b/src/uu/od/src/prn_float.rs @@ -45,11 +45,58 @@ fn pad_float_repr(raw: &str, width: usize) -> String { format!("{raw:>width$}") } +/// Strip trailing zeros and any redundant decimal point from `format_float` output. +/// GNU `od` prints 16-bit floats in a minimal `%g`-like form inside a fixed width, +/// so we trim the padding zeros added by `format_float` to match that layout. +fn trim_trailing_zeros(raw: &str) -> String { + // Leave special values untouched + if raw.eq_ignore_ascii_case("nan") + || raw.eq_ignore_ascii_case("inf") + || raw.eq_ignore_ascii_case("-inf") + { + return raw.to_string(); + } + + // Split mantissa/exponent when an exponent exists + let (mut mantissa, exp) = match raw.find(['e', 'E']) { + Some(pos) => (raw[..pos].to_string(), Some(&raw[pos..])), + None => (raw.to_string(), None), + }; + + if let Some(_dot_pos) = mantissa.find('.') { + // Remove trailing zeros after the decimal point + while mantissa.ends_with('0') { + mantissa.pop(); + } + // Drop a lone trailing decimal point + if mantissa.ends_with('.') { + mantissa.pop(); + } + + // Guard against trimming all the way down to "-0" + if mantissa.is_empty() { + mantissa.push('0'); + } else if mantissa == "-" { + mantissa.push_str("0"); + } + } + + if let Some(exp_part) = exp { + mantissa.push_str(exp_part); + } + + mantissa +} + pub fn format_item_f16(f: f64) -> String { // Keep the width used by FORMAT_ITEM_F16 (minus the leading space we add here), // but print a compact representation to match GNU od output for 16‑bit floats. let raw = format_f16(f16::from_f64(f)); - format!(" {}", pad_float_repr(&raw, FORMAT_ITEM_F16.print_width - 1)) + let trimmed = trim_trailing_zeros(&raw); + format!( + " {}", + pad_float_repr(&trimmed, FORMAT_ITEM_F16.print_width - 1) + ) } pub fn format_item_f32(f: f64) -> String { @@ -94,9 +141,10 @@ fn format_f64_exp_precision(f: f64, width: usize, precision: usize) -> String { pub fn format_item_bf16(f: f64) -> String { let bf = bf16::from_f32(f as f32); let raw = format_binary16_like(f, 15, 8, is_subnormal_bf16(bf)); + let trimmed = trim_trailing_zeros(&raw); format!( " {}", - pad_float_repr(&raw, FORMAT_ITEM_BF16.print_width - 1) + pad_float_repr(&trimmed, FORMAT_ITEM_BF16.print_width - 1) ) } From ce6c639a084ec4bc452a5f891f2444965e4b8ece Mon Sep 17 00:00:00 2001 From: mattsu Date: Mon, 1 Dec 2025 08:58:09 +0900 Subject: [PATCH 06/10] fix: preserve trailing zeros in F16 and BF16 float formats to match GNU od output Remove the `trim_trailing_zeros` function and update `format_item_f16` and `format_item_bf16` to keep the raw formatted strings without trimming trailing zeros. This ensures consistent column widths and aligns with GNU od behavior for 16-bit float representations, preventing misalignment in output tables. --- src/uu/od/src/prn_float.rs | 53 +++----------------------------------- 1 file changed, 4 insertions(+), 49 deletions(-) diff --git a/src/uu/od/src/prn_float.rs b/src/uu/od/src/prn_float.rs index 608e513df34..f654eda8b36 100644 --- a/src/uu/od/src/prn_float.rs +++ b/src/uu/od/src/prn_float.rs @@ -45,57 +45,13 @@ fn pad_float_repr(raw: &str, width: usize) -> String { format!("{raw:>width$}") } -/// Strip trailing zeros and any redundant decimal point from `format_float` output. -/// GNU `od` prints 16-bit floats in a minimal `%g`-like form inside a fixed width, -/// so we trim the padding zeros added by `format_float` to match that layout. -fn trim_trailing_zeros(raw: &str) -> String { - // Leave special values untouched - if raw.eq_ignore_ascii_case("nan") - || raw.eq_ignore_ascii_case("inf") - || raw.eq_ignore_ascii_case("-inf") - { - return raw.to_string(); - } - - // Split mantissa/exponent when an exponent exists - let (mut mantissa, exp) = match raw.find(['e', 'E']) { - Some(pos) => (raw[..pos].to_string(), Some(&raw[pos..])), - None => (raw.to_string(), None), - }; - - if let Some(_dot_pos) = mantissa.find('.') { - // Remove trailing zeros after the decimal point - while mantissa.ends_with('0') { - mantissa.pop(); - } - // Drop a lone trailing decimal point - if mantissa.ends_with('.') { - mantissa.pop(); - } - - // Guard against trimming all the way down to "-0" - if mantissa.is_empty() { - mantissa.push('0'); - } else if mantissa == "-" { - mantissa.push_str("0"); - } - } - - if let Some(exp_part) = exp { - mantissa.push_str(exp_part); - } - - mantissa -} - pub fn format_item_f16(f: f64) -> String { - // Keep the width used by FORMAT_ITEM_F16 (minus the leading space we add here), - // but print a compact representation to match GNU od output for 16‑bit floats. + // 16-bit floats should use the canonical 7-digit representation (matching GNU od) + // and keep trailing zeros so column widths stay stable. let raw = format_f16(f16::from_f64(f)); - let trimmed = trim_trailing_zeros(&raw); format!( " {}", - pad_float_repr(&trimmed, FORMAT_ITEM_F16.print_width - 1) + pad_float_repr(&raw, FORMAT_ITEM_F16.print_width - 1) ) } @@ -141,10 +97,9 @@ fn format_f64_exp_precision(f: f64, width: usize, precision: usize) -> String { pub fn format_item_bf16(f: f64) -> String { let bf = bf16::from_f32(f as f32); let raw = format_binary16_like(f, 15, 8, is_subnormal_bf16(bf)); - let trimmed = trim_trailing_zeros(&raw); format!( " {}", - pad_float_repr(&trimmed, FORMAT_ITEM_BF16.print_width - 1) + pad_float_repr(&raw, FORMAT_ITEM_BF16.print_width - 1) ) } From 36d73347abc4913056c194452265a6dceb5ca60d Mon Sep 17 00:00:00 2001 From: mattsu Date: Mon, 1 Dec 2025 09:37:14 +0900 Subject: [PATCH 07/10] refactor(od/prn_float): combine multiline format! into single line in format_item_f16 The format! macro call in format_item_f16 was split across multiple lines with newlines. This change consolidates it into a single line for improved code readability and consistency with similar patterns in the file, without altering the function's output or logic. --- src/uu/od/src/prn_float.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/uu/od/src/prn_float.rs b/src/uu/od/src/prn_float.rs index f654eda8b36..ca058dab821 100644 --- a/src/uu/od/src/prn_float.rs +++ b/src/uu/od/src/prn_float.rs @@ -49,10 +49,7 @@ pub fn format_item_f16(f: f64) -> String { // 16-bit floats should use the canonical 7-digit representation (matching GNU od) // and keep trailing zeros so column widths stay stable. let raw = format_f16(f16::from_f64(f)); - format!( - " {}", - pad_float_repr(&raw, FORMAT_ITEM_F16.print_width - 1) - ) + format!(" {}", pad_float_repr(&raw, FORMAT_ITEM_F16.print_width - 1)) } pub fn format_item_f32(f: f64) -> String { From 19e456575343588efe83aa1663dd7545ed445214 Mon Sep 17 00:00:00 2001 From: mattsu Date: Mon, 1 Dec 2025 13:23:01 +0900 Subject: [PATCH 08/10] feat(od): trim trailing zeros in half-precision and bfloat16 float outputs - Add `trim_float_repr` function to remove unnecessary trailing zeros and padding from normalized float strings, leaving exponents unchanged. - Update `format_item_f16` and `format_item_bf16` to apply trimming while maintaining column alignment via re-padding. - Update test expectations to reflect the more compact float representations (e.g., "1" instead of "1.0000000"). --- src/uu/od/src/prn_float.rs | 59 ++++++++++++++++++++++++++++++++------ tests/by-util/test_od.rs | 10 +++---- 2 files changed, 55 insertions(+), 14 deletions(-) diff --git a/src/uu/od/src/prn_float.rs b/src/uu/od/src/prn_float.rs index ca058dab821..d74ed70dc4e 100644 --- a/src/uu/od/src/prn_float.rs +++ b/src/uu/od/src/prn_float.rs @@ -37,6 +37,46 @@ pub static FORMAT_ITEM_BF16: FormatterItemInfo = FormatterItemInfo { formatter: FormatWriter::BFloatWriter(format_item_bf16), }; +/// Clean up a normalized float string by removing unnecessary padding and digits. +/// - Strip leading spaces. +/// - Trim trailing zeros after the decimal point (and the dot itself if empty). +/// - Leave the exponent part (e/E...) untouched. +fn trim_float_repr(raw: &str) -> String { + // Drop padding added by `format!` width specification + let mut s = raw.trim_start().to_string(); + + // Keep NaN/Inf representations as-is + let lower = s.to_ascii_lowercase(); + if lower == "nan" || lower == "inf" || lower == "-inf" { + return s; + } + + // Separate exponent from mantissa + let mut exp_part = String::new(); + if let Some(idx) = s.find(['e', 'E']) { + exp_part = s[idx..].to_string(); + s.truncate(idx); + } + + // Trim trailing zeros in mantissa, then remove trailing dot if left alone + if let Some(_) = s.find('.') { + while s.ends_with('0') { + s.pop(); + } + if s.ends_with('.') { + s.pop(); + } + } + + // If everything was trimmed, leave a single zero + if s.is_empty() || s == "-" || s == "+" { + s.push('0'); + } + + s.push_str(&exp_part); + s +} + /// Pad a floating value to a fixed width for column alignment while keeping /// the original precision (including trailing zeros). This mirrors the /// behavior of other float formatters (`f32`, `f64`) and keeps the output @@ -46,10 +86,12 @@ fn pad_float_repr(raw: &str, width: usize) -> String { } pub fn format_item_f16(f: f64) -> String { - // 16-bit floats should use the canonical 7-digit representation (matching GNU od) - // and keep trailing zeros so column widths stay stable. - let raw = format_f16(f16::from_f64(f)); - format!(" {}", pad_float_repr(&raw, FORMAT_ITEM_F16.print_width - 1)) + let value = f16::from_f64(f); + let width = FORMAT_ITEM_F16.print_width - 1; + // Format once, trim redundant zeros, then re-pad to the canonical width + let raw = format_f16(value); + let trimmed = trim_float_repr(&raw); + format!(" {}", pad_float_repr(&trimmed, width)) } pub fn format_item_f32(f: f64) -> String { @@ -93,11 +135,10 @@ fn format_f64_exp_precision(f: f64, width: usize, precision: usize) -> String { pub fn format_item_bf16(f: f64) -> String { let bf = bf16::from_f32(f as f32); - let raw = format_binary16_like(f, 15, 8, is_subnormal_bf16(bf)); - format!( - " {}", - pad_float_repr(&raw, FORMAT_ITEM_BF16.print_width - 1) - ) + let width = FORMAT_ITEM_BF16.print_width - 1; + let raw = format_binary16_like(f64::from(bf), width, 8, is_subnormal_bf16(bf)); + let trimmed = trim_float_repr(&raw); + format!(" {}", pad_float_repr(&trimmed, width)) } fn format_f16(f: f16) -> String { diff --git a/tests/by-util/test_od.rs b/tests/by-util/test_od.rs index 61334b127eb..fea019e3a6e 100644 --- a/tests/by-util/test_od.rs +++ b/tests/by-util/test_od.rs @@ -207,7 +207,7 @@ fn test_float16_compact() { .arg("-tfH") .run_piped_stdin(&input[..]) .success() - .stdout_only(" 1.0000000 1.0000000\n"); + .stdout_only(" 1 1\n"); } // Regression: 16-bit bfloat should print with canonical precision (no spurious digits) @@ -220,7 +220,7 @@ fn test_bfloat16_compact() { .arg("-tfB") .run_piped_stdin(&input[..]) .success() - .stdout_only(" 1.0000000 1.0000000\n"); + .stdout_only(" 1 1\n"); } #[test] @@ -236,7 +236,7 @@ fn test_f16() { ]; // 0x8400 -6.104e-5 let expected_output = unindent( " - 0000000 1.0000000 0 -0 inf + 0000000 1 0 -0 inf 0000010 -inf NaN -6.1035156e-5 0000016 ", @@ -263,7 +263,7 @@ fn test_fh() { ]; // 0x8400 -6.1035156e-5 let expected_output = unindent( " - 0000000 1.0000000 0 -0 inf + 0000000 1 0 -0 inf 0000010 -inf NaN -6.1035156e-5 0000016 ", @@ -290,7 +290,7 @@ fn test_fb() { ]; // -6.1035156e-5 let expected_output = unindent( " - 0000000 1.0000000 0 -0 inf + 0000000 1 0 -0 inf 0000010 -inf NaN -6.1035156e-5 0000016 ", From 8108594410465f77e40a1c4a095c9bed7716371d Mon Sep 17 00:00:00 2001 From: mattsu Date: Mon, 1 Dec 2025 13:38:39 +0900 Subject: [PATCH 09/10] refactor: simplify float trimming condition in prn_float.rs Replace `if let Some(_) = s.find('.')` with `s.find('.').is_some()` in the `trim_float_repr` function to improve code clarity and idiomatic Rust usage while maintaining the same logic for checking decimal presence=black. --- src/uu/od/src/prn_float.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/od/src/prn_float.rs b/src/uu/od/src/prn_float.rs index d74ed70dc4e..173a8d3b9f9 100644 --- a/src/uu/od/src/prn_float.rs +++ b/src/uu/od/src/prn_float.rs @@ -59,7 +59,7 @@ fn trim_float_repr(raw: &str) -> String { } // Trim trailing zeros in mantissa, then remove trailing dot if left alone - if let Some(_) = s.find('.') { + if s.find('.').is_some() { while s.ends_with('0') { s.pop(); } From 731ff6ff50c1ae1274785b2d7ec73da6d4d98ccc Mon Sep 17 00:00:00 2001 From: mattsu <35655889+mattsu2020@users.noreply.github.com> Date: Mon, 1 Dec 2025 19:43:11 +0900 Subject: [PATCH 10/10] Update src/uu/od/src/prn_float.rs Co-authored-by: Daniel Hofstetter --- src/uu/od/src/prn_float.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/od/src/prn_float.rs b/src/uu/od/src/prn_float.rs index 173a8d3b9f9..c93b02d25cb 100644 --- a/src/uu/od/src/prn_float.rs +++ b/src/uu/od/src/prn_float.rs @@ -59,7 +59,7 @@ fn trim_float_repr(raw: &str) -> String { } // Trim trailing zeros in mantissa, then remove trailing dot if left alone - if s.find('.').is_some() { + if s.contains('.') { while s.ends_with('0') { s.pop(); }