|
2 | 2 | // |
3 | 3 | // For the full copyright and license information, please view the LICENSE |
4 | 4 | // file that was distributed with this source code. |
5 | | -// spell-checker:ignore (ToDO) extendedbigdecimal |
| 5 | +// spell-checker:ignore (ToDO) bigdecimal extendedbigdecimal |
6 | 6 |
|
7 | 7 | use half::f16; |
8 | 8 | use std::num::FpCategory; |
9 | 9 | use uucore::extendedbigdecimal::ExtendedBigDecimal; |
| 10 | +use uucore::format::num_format; |
| 11 | +use uucore::format::num_format::Formatter; |
10 | 12 |
|
11 | 13 | use crate::formatter_item_info::{FormatWriter, FormatterItemInfo}; |
12 | 14 |
|
@@ -36,7 +38,7 @@ pub static FORMAT_ITEM_BF16: FormatterItemInfo = FormatterItemInfo { |
36 | 38 |
|
37 | 39 | pub static FORMAT_ITEM_F128: FormatterItemInfo = FormatterItemInfo { |
38 | 40 | byte_size: 16, |
39 | | - print_width: 25, //TODO |
| 41 | + print_width: 30, |
40 | 42 | formatter: FormatWriter::ExtendedBigDecimalWriter(format_item_f128), |
41 | 43 | }; |
42 | 44 |
|
@@ -137,8 +139,22 @@ fn format_float(f: f64, width: usize, precision: usize) -> String { |
137 | 139 | } |
138 | 140 | } |
139 | 141 |
|
140 | | -fn format_f128(_ebd: &ExtendedBigDecimal) -> String { |
141 | | - "TODO".to_string() |
| 142 | +fn format_f128(ebd: &ExtendedBigDecimal) -> String { |
| 143 | + format_extended_big_decimal(ebd, 29, 20) |
| 144 | +} |
| 145 | + |
| 146 | +fn format_extended_big_decimal(ebd: &ExtendedBigDecimal, width: usize, precision: usize) -> String { |
| 147 | + let float = num_format::Float { |
| 148 | + variant: num_format::FloatVariant::Shortest, |
| 149 | + width, |
| 150 | + alignment: num_format::NumberAlignment::RightSpace, |
| 151 | + precision: Some(precision), |
| 152 | + ..Default::default() |
| 153 | + }; |
| 154 | + // TODO: For performance, it'd be best if `od` directly collected and printed Vec<u8>. |
| 155 | + let mut v = Vec::new(); |
| 156 | + float.fmt(&mut v, ebd).unwrap(); |
| 157 | + String::from_utf8(v).unwrap() |
142 | 158 | } |
143 | 159 |
|
144 | 160 | #[test] |
@@ -277,3 +293,92 @@ fn test_format_f16() { |
277 | 293 | assert_eq!(format_f16(f16::NEG_ZERO), " -0"); |
278 | 294 | assert_eq!(format_f16(f16::ZERO), " 0"); |
279 | 295 | } |
| 296 | + |
| 297 | +#[test] |
| 298 | +#[allow(clippy::cognitive_complexity)] |
| 299 | +fn test_format_f128() { |
| 300 | + use bigdecimal::BigDecimal; |
| 301 | + |
| 302 | + // Note: These tests print exact ExtendedBigDecimal values, so the results |
| 303 | + // maybe be different from an end-to-end test with a "native" f80/f128 input. |
| 304 | + // Padding and format is tested, though. |
| 305 | + |
| 306 | + assert_eq!(format_f128(&1.0.into()), " 1"); |
| 307 | + assert_eq!(format_f128(&10.0.into()), " 10"); |
| 308 | + assert_eq!( |
| 309 | + format_f128(&1_000_000_000_000_000.0.into()), |
| 310 | + " 1000000000000000" |
| 311 | + ); |
| 312 | + assert_eq!( |
| 313 | + format_f128(&10_000_000_000_000_000.0.into()), |
| 314 | + " 10000000000000000" |
| 315 | + ); |
| 316 | + // BigDecimal scale is -exponent |
| 317 | + assert_eq!( |
| 318 | + format_f128(&ExtendedBigDecimal::BigDecimal(BigDecimal::new( |
| 319 | + 1.into(), |
| 320 | + -100 |
| 321 | + ))), |
| 322 | + " 1e+100" |
| 323 | + ); |
| 324 | + |
| 325 | + assert_eq!( |
| 326 | + format_f128(&ExtendedBigDecimal::BigDecimal(BigDecimal::new( |
| 327 | + (-10_000_000_000_000_000_001i128).into(), |
| 328 | + 20 |
| 329 | + ))), |
| 330 | + " -0.10000000000000000001" |
| 331 | + ); |
| 332 | + assert_eq!( |
| 333 | + format_f128(&ExtendedBigDecimal::BigDecimal(BigDecimal::new( |
| 334 | + (-100_000_000_000_000_000_001i128).into(), |
| 335 | + 21 |
| 336 | + ))), |
| 337 | + " -0.1" |
| 338 | + ); |
| 339 | + |
| 340 | + // BigDecimal scale is -exponent |
| 341 | + assert_eq!( |
| 342 | + format_f128(&ExtendedBigDecimal::BigDecimal(BigDecimal::new( |
| 343 | + 12_345_678_901_234_567_890u128.into(), |
| 344 | + 0 |
| 345 | + ))), |
| 346 | + " 12345678901234567890" |
| 347 | + ); |
| 348 | + assert_eq!( |
| 349 | + format_f128(&ExtendedBigDecimal::BigDecimal(BigDecimal::new( |
| 350 | + 12_345_678_901_234_567_890u128.into(), |
| 351 | + 1100 |
| 352 | + ))), |
| 353 | + " 1.234567890123456789e-1081" |
| 354 | + ); |
| 355 | + assert_eq!( |
| 356 | + format_f128(&ExtendedBigDecimal::BigDecimal(BigDecimal::new( |
| 357 | + 12_345_678_901_234_567_890u128.into(), |
| 358 | + -1100 |
| 359 | + ))), |
| 360 | + " 1.234567890123456789e+1119" |
| 361 | + ); |
| 362 | + |
| 363 | + assert_eq!( |
| 364 | + format_f128(&ExtendedBigDecimal::BigDecimal(BigDecimal::new( |
| 365 | + 4.into(), |
| 366 | + 320 |
| 367 | + ))), |
| 368 | + " 4e-320" |
| 369 | + ); |
| 370 | + assert_eq!( |
| 371 | + format_f128(&f64::NAN.into()), |
| 372 | + " nan" |
| 373 | + ); |
| 374 | + assert_eq!( |
| 375 | + format_f128(&f64::INFINITY.into()), |
| 376 | + " inf" |
| 377 | + ); |
| 378 | + assert_eq!( |
| 379 | + format_f128(&f64::NEG_INFINITY.into()), |
| 380 | + " -inf" |
| 381 | + ); |
| 382 | + assert_eq!(format_f128(&(-0.0).into()), " -0"); |
| 383 | + assert_eq!(format_f128(&0.0.into()), " 0"); |
| 384 | +} |
0 commit comments