Skip to content

Commit 1a8f99f

Browse files
authored
Merge pull request #8352 from yonatan-linik/fix-od-positive-exp-fmt
od: Fixes float formatting in scientific notation
2 parents 73af958 + fe4e8e2 commit 1a8f99f

File tree

2 files changed

+47
-20
lines changed

2 files changed

+47
-20
lines changed

src/uu/od/src/prn_float.rs

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,33 @@ pub fn format_item_flo64(f: f64) -> String {
3737
format!(" {}", format_flo64(f))
3838
}
3939

40+
fn format_flo32_exp(f: f32, width: usize) -> String {
41+
if f.abs().log10() < 0.0 {
42+
return format!("{f:width$e}");
43+
}
44+
// Leave room for the '+' sign
45+
let formatted = format!("{f:width$e}", width = width - 1);
46+
formatted.replace('e', "e+")
47+
}
48+
49+
fn format_flo64_exp(f: f64, width: usize) -> String {
50+
if f.abs().log10() < 0.0 {
51+
return format!("{f:width$e}");
52+
}
53+
// Leave room for the '+' sign
54+
let formatted = format!("{f:width$e}", width = width - 1);
55+
formatted.replace('e', "e+")
56+
}
57+
58+
fn format_flo64_exp_precision(f: f64, width: usize, precision: usize) -> String {
59+
if f.abs().log10() < 0.0 {
60+
return format!("{f:width$.precision$e}");
61+
}
62+
// Leave room for the '+' sign
63+
let formatted = format!("{f:width$.precision$e}", width = width - 1);
64+
formatted.replace('e', "e+")
65+
}
66+
4067
fn format_flo16(f: f16) -> String {
4168
format_float(f64::from(f), 9, 4)
4269
}
@@ -49,7 +76,7 @@ fn format_flo32(f: f32) -> String {
4976

5077
if f.classify() == FpCategory::Subnormal {
5178
// subnormal numbers will be normal as f64, so will print with a wrong precision
52-
format!("{f:width$e}") // subnormal numbers
79+
format_flo32_exp(f, width) // subnormal numbers
5380
} else {
5481
format_float(f64::from(f), width, precision)
5582
}
@@ -67,7 +94,7 @@ fn format_float(f: f64, width: usize, precision: usize) -> String {
6794
if f == 0.0 || !f.is_finite() {
6895
return format!("{f:width$}");
6996
}
70-
return format!("{f:width$e}"); // subnormal numbers
97+
return format_flo64_exp(f, width); // subnormal numbers
7198
}
7299

73100
let mut l = f.abs().log10().floor() as i32;
@@ -83,7 +110,7 @@ fn format_float(f: f64, width: usize, precision: usize) -> String {
83110
} else if l == -1 {
84111
format!("{f:width$.precision$}")
85112
} else {
86-
format!("{f:width$.dec$e}", dec = precision - 1)
113+
return format_flo64_exp_precision(f, width, precision - 1); // subnormal numbers
87114
}
88115
}
89116

@@ -108,11 +135,11 @@ fn test_format_flo32() {
108135
assert_eq!(format_flo32(9_999_999.0), " 9999999.0");
109136
assert_eq!(format_flo32(10_000_000.0), " 10000000");
110137
assert_eq!(format_flo32(99_999_992.0), " 99999992");
111-
assert_eq!(format_flo32(100_000_000.0), " 1.0000000e8");
112-
assert_eq!(format_flo32(9.999_999_4e8), " 9.9999994e8");
113-
assert_eq!(format_flo32(1.0e9), " 1.0000000e9");
114-
assert_eq!(format_flo32(9.999_999_0e9), " 9.9999990e9");
115-
assert_eq!(format_flo32(1.0e10), " 1.0000000e10");
138+
assert_eq!(format_flo32(100_000_000.0), " 1.0000000e+8");
139+
assert_eq!(format_flo32(9.999_999_4e8), " 9.9999994e+8");
140+
assert_eq!(format_flo32(1.0e9), " 1.0000000e+9");
141+
assert_eq!(format_flo32(9.999_999_0e9), " 9.9999990e+9");
142+
assert_eq!(format_flo32(1.0e10), " 1.0000000e+10");
116143

117144
assert_eq!(format_flo32(0.1), " 0.10000000");
118145
assert_eq!(format_flo32(0.999_999_94), " 0.99999994");
@@ -138,11 +165,11 @@ fn test_format_flo32() {
138165
assert_eq!(format_flo32(-9_999_999.0), " -9999999.0");
139166
assert_eq!(format_flo32(-10_000_000.0), " -10000000");
140167
assert_eq!(format_flo32(-99_999_992.0), " -99999992");
141-
assert_eq!(format_flo32(-100_000_000.0), " -1.0000000e8");
142-
assert_eq!(format_flo32(-9.999_999_4e8), " -9.9999994e8");
143-
assert_eq!(format_flo32(-1.0e9), " -1.0000000e9");
144-
assert_eq!(format_flo32(-9.999_999_0e9), " -9.9999990e9");
145-
assert_eq!(format_flo32(-1.0e10), " -1.0000000e10");
168+
assert_eq!(format_flo32(-100_000_000.0), " -1.0000000e+8");
169+
assert_eq!(format_flo32(-9.999_999_4e8), " -9.9999994e+8");
170+
assert_eq!(format_flo32(-1.0e9), " -1.0000000e+9");
171+
assert_eq!(format_flo32(-9.999_999_0e9), " -9.9999990e+9");
172+
assert_eq!(format_flo32(-1.0e10), "-1.0000000e+10");
146173

147174
assert_eq!(format_flo32(-0.1), " -0.10000000");
148175
assert_eq!(format_flo32(-0.999_999_94), " -0.99999994");
@@ -151,13 +178,13 @@ fn test_format_flo32() {
151178
assert_eq!(format_flo32(-0.001), " -1.0000000e-3");
152179
assert_eq!(format_flo32(-0.009_999_999_8), " -9.9999998e-3");
153180

154-
assert_eq!(format_flo32(3.402_823_3e38), " 3.4028233e38");
155-
assert_eq!(format_flo32(-3.402_823_3e38), " -3.4028233e38");
181+
assert_eq!(format_flo32(3.402_823_3e38), " 3.4028233e+38");
182+
assert_eq!(format_flo32(-3.402_823_3e38), "-3.4028233e+38");
156183
assert_eq!(format_flo32(-1.166_310_8e-38), "-1.1663108e-38");
157184
assert_eq!(format_flo32(-4.701_977_1e-38), "-4.7019771e-38");
158185
assert_eq!(format_flo32(1e-45), " 1e-45");
159186

160-
assert_eq!(format_flo32(-3.402_823_466e+38), " -3.4028235e38");
187+
assert_eq!(format_flo32(-3.402_823_466e+38), "-3.4028235e+38");
161188
assert_eq!(format_flo32(f32::NAN), " NaN");
162189
assert_eq!(format_flo32(f32::INFINITY), " inf");
163190
assert_eq!(format_flo32(f32::NEG_INFINITY), " -inf");
@@ -180,7 +207,7 @@ fn test_format_flo64() {
180207
);
181208
assert_eq!(
182209
format_flo64(100_000_000_000_000_000.0),
183-
" 1.0000000000000000e17"
210+
" 1.0000000000000000e+17"
184211
);
185212

186213
assert_eq!(format_flo64(-0.1), " -0.10000000000000001");
@@ -210,13 +237,13 @@ fn test_format_flo16() {
210237
assert_eq!(format_flo16(f16::from_f32(10.0)), " 10.00");
211238
assert_eq!(format_flo16(f16::from_f32(100.0)), " 100.0");
212239
assert_eq!(format_flo16(f16::from_f32(1000.0)), " 1000");
213-
assert_eq!(format_flo16(f16::from_f32(10000.0)), " 1.000e4");
240+
assert_eq!(format_flo16(f16::from_f32(10000.0)), " 1.000e+4");
214241

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

218245
assert_eq!(format_flo16(f16::MIN_POSITIVE_SUBNORMAL), " 5.960e-8");
219-
assert_eq!(format_flo16(f16::MIN), " -6.550e4");
246+
assert_eq!(format_flo16(f16::MIN), "-6.550e+4");
220247
assert_eq!(format_flo16(f16::NAN), " NaN");
221248
assert_eq!(format_flo16(f16::INFINITY), " inf");
222249
assert_eq!(format_flo16(f16::NEG_INFINITY), " -inf");

tests/by-util/test_od.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ fn test_f32() {
234234
]; // 0x807f0000 -1.1663108E-38
235235
let expected_output = unindent(
236236
"
237-
0000000 -1.2345679 12345678 -9.8765427e37 -0
237+
0000000 -1.2345679 12345678 -9.8765427e+37 -0
238238
0000020 NaN 1e-40 -1.1663108e-38
239239
0000034
240240
",

0 commit comments

Comments
 (0)