mirror of
https://github.com/uutils/coreutils
synced 2024-07-23 19:04:18 +00:00
od: implement 16-bit floating point type
This commit is contained in:
parent
fd5879dcf2
commit
99f70ba648
6
Cargo.lock
generated
6
Cargo.lock
generated
|
@ -392,6 +392,11 @@ dependencies = [
|
|||
"uucore 0.0.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "hashsum"
|
||||
version = "0.0.1"
|
||||
|
@ -665,6 +670,7 @@ version = "0.0.1"
|
|||
dependencies = [
|
||||
"byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"half 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"uucore 0.0.1",
|
||||
]
|
||||
|
|
|
@ -11,6 +11,7 @@ path = "od.rs"
|
|||
getopts = "*"
|
||||
libc = "*"
|
||||
byteorder = "*"
|
||||
half = "*"
|
||||
uucore = { path="../uucore" }
|
||||
|
||||
[[bin]]
|
||||
|
|
|
@ -2,6 +2,7 @@ use std::io;
|
|||
use byteorder_io::ByteOrder;
|
||||
use multifilereader::HasError;
|
||||
use peekreader::PeekRead;
|
||||
use half::f16;
|
||||
|
||||
/// Processes an input and provides access to the data read in various formats
|
||||
///
|
||||
|
@ -128,6 +129,7 @@ impl<'a> MemoryDecoder<'a> {
|
|||
/// Returns a f32/f64 from the internal buffer at position `start`.
|
||||
pub fn read_float(&self, start: usize, byte_size: usize) -> f64 {
|
||||
match byte_size {
|
||||
2 => f64::from(f16::from_bits(self.byte_order.read_u16(&self.data[start..start + 2]))),
|
||||
4 => self.byte_order.read_f32(&self.data[start..start + 4]) as f64,
|
||||
8 => self.byte_order.read_f64(&self.data[start..start + 8]),
|
||||
_ => panic!("Invalid byte_size: {}", byte_size),
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
extern crate getopts;
|
||||
extern crate byteorder;
|
||||
extern crate half;
|
||||
|
||||
#[macro_use]
|
||||
extern crate uucore;
|
||||
|
|
|
@ -73,6 +73,7 @@ fn od_format_type(type_char: FormatType, byte_size: u8) -> Option<FormatterItemI
|
|||
(FormatType::HexadecimalInt, 4) => Some(FORMAT_ITEM_HEX32),
|
||||
(FormatType::HexadecimalInt, 8) => Some(FORMAT_ITEM_HEX64),
|
||||
|
||||
(FormatType::Float, 2) => Some(FORMAT_ITEM_F16),
|
||||
(FormatType::Float, 0) |
|
||||
(FormatType::Float, 4) => Some(FORMAT_ITEM_F32),
|
||||
(FormatType::Float, 8) => Some(FORMAT_ITEM_F64),
|
||||
|
@ -402,7 +403,7 @@ fn test_invalid_long_format() {
|
|||
parse_format_flags_str(&vec!("od", "--format=c1")).unwrap_err();
|
||||
parse_format_flags_str(&vec!("od", "--format=x256")).unwrap_err();
|
||||
parse_format_flags_str(&vec!("od", "--format=d5")).unwrap_err();
|
||||
parse_format_flags_str(&vec!("od", "--format=f2")).unwrap_err();
|
||||
parse_format_flags_str(&vec!("od", "--format=f1")).unwrap_err();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
use std::num::FpCategory;
|
||||
use half::f16;
|
||||
use std::f32;
|
||||
use std::f64;
|
||||
use formatteriteminfo::*;
|
||||
|
||||
pub static FORMAT_ITEM_F16: FormatterItemInfo = FormatterItemInfo {
|
||||
byte_size: 2,
|
||||
print_width: 10,
|
||||
formatter: FormatWriter::FloatWriter(format_item_flo16),
|
||||
};
|
||||
|
||||
pub static FORMAT_ITEM_F32: FormatterItemInfo = FormatterItemInfo {
|
||||
byte_size: 4,
|
||||
print_width: 15,
|
||||
|
@ -15,6 +22,9 @@ pub static FORMAT_ITEM_F64: FormatterItemInfo = FormatterItemInfo {
|
|||
formatter: FormatWriter::FloatWriter(format_item_flo64),
|
||||
};
|
||||
|
||||
pub fn format_item_flo16(f: f64) -> String {
|
||||
format!(" {}", format_flo16(f16::from_f64(f)))
|
||||
}
|
||||
|
||||
pub fn format_item_flo32(f: f64) -> String {
|
||||
format!(" {}", format_flo32(f as f32))
|
||||
|
@ -24,6 +34,10 @@ pub fn format_item_flo64(f: f64) -> String {
|
|||
format!(" {}", format_flo64(f))
|
||||
}
|
||||
|
||||
fn format_flo16(f: f16) -> String {
|
||||
format_float(f64::from(f), 9, 4)
|
||||
}
|
||||
|
||||
// formats float with 8 significant digits, eg 12345678 or -1.2345678e+12
|
||||
// always retuns a string of 14 characters
|
||||
fn format_flo32(f: f32) -> String {
|
||||
|
@ -171,3 +185,30 @@ fn test_format_flo64() {
|
|||
assert_eq!(format_flo64(-0.0), " -0");
|
||||
assert_eq!(format_flo64(0.0), " 0");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_format_flo16() {
|
||||
use half::consts::*;
|
||||
|
||||
assert_eq!(format_flo16(f16::from_bits(0x8400u16)), "-6.104e-5");
|
||||
assert_eq!(format_flo16(f16::from_bits(0x8401u16)), "-6.109e-5");
|
||||
assert_eq!(format_flo16(f16::from_bits(0x8402u16)), "-6.115e-5");
|
||||
assert_eq!(format_flo16(f16::from_bits(0x8403u16)), "-6.121e-5");
|
||||
|
||||
assert_eq!(format_flo16(f16::from_f32(1.0)), " 1.000");
|
||||
assert_eq!(format_flo16(f16::from_f32(10.0)), " 10.00");
|
||||
assert_eq!(format_flo16(f16::from_f32(100.0)), " 100.0");
|
||||
assert_eq!(format_flo16(f16::from_f32(1000.0)), " 1000");
|
||||
assert_eq!(format_flo16(f16::from_f32(10000.0)), " 1.000e4");
|
||||
|
||||
assert_eq!(format_flo16(f16::from_f32(-0.2)), " -0.2000");
|
||||
assert_eq!(format_flo16(f16::from_f32(-0.02)), "-2.000e-2");
|
||||
|
||||
assert_eq!(format_flo16(MIN_POSITIVE_SUBNORMAL), " 5.966e-8");
|
||||
assert_eq!(format_flo16(MIN), " -6.550e4");
|
||||
assert_eq!(format_flo16(NAN), " NaN");
|
||||
assert_eq!(format_flo16(INFINITY), " inf");
|
||||
assert_eq!(format_flo16(NEG_INFINITY), " -inf");
|
||||
assert_eq!(format_flo16(NEG_ZERO), " -0");
|
||||
assert_eq!(format_flo16(ZERO), " 0");
|
||||
}
|
||||
|
|
|
@ -198,6 +198,29 @@ fn test_hex32(){
|
|||
assert_eq!(result.stdout, expected_output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_f16(){
|
||||
|
||||
let input : [u8; 14] = [
|
||||
0x00, 0x3c, // 0x3C00 1.0
|
||||
0x00, 0x00, // 0x0000 0.0
|
||||
0x00, 0x80, // 0x8000 -0.0
|
||||
0x00, 0x7c, // 0x7C00 Inf
|
||||
0x00, 0xfc, // 0xFC00 -Inf
|
||||
0x00, 0xfe, // 0xFE00 NaN
|
||||
0x00, 0x84];// 0x8400 -6.104e-5
|
||||
let expected_output = unindent("
|
||||
0000000 1.000 0 -0 inf
|
||||
0000010 -inf NaN -6.104e-5
|
||||
0000016
|
||||
");
|
||||
let result = new_ucmd!().arg("--endian=little").arg("-tf2").arg("-w8").run_piped_stdin(&input[..]);
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, expected_output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_f32(){
|
||||
|
||||
|
|
Loading…
Reference in a new issue