mirror of
https://github.com/uutils/coreutils.git
synced 2025-12-23 08:47:37 +00:00
fix(od):fix GNU coreutils test od float.sh (#9534)
Some checks are pending
CICD / Style/cargo-deny (push) Waiting to run
CICD / Style/deps (push) Waiting to run
CICD / Documentation/warnings (push) Waiting to run
CICD / MinRustV (push) Waiting to run
CICD / Separate Builds (push) Waiting to run
CICD / Dependencies (push) Waiting to run
CICD / Build/Makefile (push) Blocked by required conditions
CICD / Build/stable (push) Blocked by required conditions
CICD / Build/nightly (push) Blocked by required conditions
CICD / Binary sizes (push) Blocked by required conditions
CICD / Build (push) Blocked by required conditions
CICD / Tests/BusyBox test suite (push) Blocked by required conditions
CICD / Tests/Toybox test suite (push) Blocked by required conditions
CICD / Code Coverage (push) Waiting to run
CICD / Test all features separately (push) Blocked by required conditions
CICD / Build/SELinux (push) Blocked by required conditions
CICD / Build/SELinux-Stubs (Non-Linux) (push) Blocked by required conditions
CICD / Safe Traversal Security Check (push) Blocked by required conditions
GnuTests / Run GNU tests (native) (push) Waiting to run
GnuTests / Run GNU tests (SELinux) (push) Waiting to run
GnuTests / Aggregate GNU test results (push) Blocked by required conditions
Android / Test builds (push) Waiting to run
Benchmarks / Run benchmarks (CodSpeed) (push) Waiting to run
Code Quality / Style/format (push) Waiting to run
Code Quality / Style/lint (push) Waiting to run
Code Quality / Style/spelling (push) Waiting to run
Code Quality / Style/toml (push) Waiting to run
Code Quality / Style/Python (push) Waiting to run
Code Quality / Pre-commit hooks (push) Waiting to run
Devcontainer / Verify devcontainer (push) Waiting to run
FreeBSD / Style and Lint (push) Waiting to run
FreeBSD / Tests (push) Waiting to run
OpenBSD / Style and Lint (push) Waiting to run
OpenBSD / Tests (push) Waiting to run
WSL2 / Test (push) Waiting to run
Some checks are pending
CICD / Style/cargo-deny (push) Waiting to run
CICD / Style/deps (push) Waiting to run
CICD / Documentation/warnings (push) Waiting to run
CICD / MinRustV (push) Waiting to run
CICD / Separate Builds (push) Waiting to run
CICD / Dependencies (push) Waiting to run
CICD / Build/Makefile (push) Blocked by required conditions
CICD / Build/stable (push) Blocked by required conditions
CICD / Build/nightly (push) Blocked by required conditions
CICD / Binary sizes (push) Blocked by required conditions
CICD / Build (push) Blocked by required conditions
CICD / Tests/BusyBox test suite (push) Blocked by required conditions
CICD / Tests/Toybox test suite (push) Blocked by required conditions
CICD / Code Coverage (push) Waiting to run
CICD / Test all features separately (push) Blocked by required conditions
CICD / Build/SELinux (push) Blocked by required conditions
CICD / Build/SELinux-Stubs (Non-Linux) (push) Blocked by required conditions
CICD / Safe Traversal Security Check (push) Blocked by required conditions
GnuTests / Run GNU tests (native) (push) Waiting to run
GnuTests / Run GNU tests (SELinux) (push) Waiting to run
GnuTests / Aggregate GNU test results (push) Blocked by required conditions
Android / Test builds (push) Waiting to run
Benchmarks / Run benchmarks (CodSpeed) (push) Waiting to run
Code Quality / Style/format (push) Waiting to run
Code Quality / Style/lint (push) Waiting to run
Code Quality / Style/spelling (push) Waiting to run
Code Quality / Style/toml (push) Waiting to run
Code Quality / Style/Python (push) Waiting to run
Code Quality / Pre-commit hooks (push) Waiting to run
Devcontainer / Verify devcontainer (push) Waiting to run
FreeBSD / Style and Lint (push) Waiting to run
FreeBSD / Tests (push) Waiting to run
OpenBSD / Style and Lint (push) Waiting to run
OpenBSD / Tests (push) Waiting to run
WSL2 / Test (push) Waiting to run
* 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.
* 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.
* 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.
* 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
* 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.
* 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.
* 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.
* 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").
* 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.
* Update src/uu/od/src/prn_float.rs
Co-authored-by: Daniel Hofstetter <daniel.hofstetter@42dh.com>
---------
Co-authored-by: Daniel Hofstetter <daniel.hofstetter@42dh.com>
This commit is contained in:
parent
ee39b358e7
commit
003f21aa58
2 changed files with 88 additions and 6 deletions
|
|
@ -37,8 +37,61 @@ 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 s.contains('.') {
|
||||
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
|
||||
/// stable across platforms.
|
||||
fn pad_float_repr(raw: &str, width: usize) -> String {
|
||||
format!("{raw:>width$}")
|
||||
}
|
||||
|
||||
pub fn format_item_f16(f: f64) -> String {
|
||||
format!(" {}", format_f16(f16::from_f64(f)))
|
||||
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 {
|
||||
|
|
@ -82,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);
|
||||
format!(" {}", format_binary16_like(f, 15, 8, is_subnormal_bf16(bf)))
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -197,6 +197,32 @@ fn test_hex32() {
|
|||
.stdout_only(expected_output);
|
||||
}
|
||||
|
||||
// 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
|
||||
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 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
|
||||
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] = [
|
||||
|
|
@ -210,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
|
||||
",
|
||||
|
|
@ -237,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
|
||||
",
|
||||
|
|
@ -264,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
|
||||
",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue