mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 02:57:44 +00:00
od: implement 16-bit floating point type
This commit is contained in:
parent
fd5879dcf2
commit
99f70ba648
7 changed files with 76 additions and 1 deletions
6
Cargo.lock
generated
6
Cargo.lock
generated
|
@ -392,6 +392,11 @@ dependencies = [
|
||||||
"uucore 0.0.1",
|
"uucore 0.0.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "half"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashsum"
|
name = "hashsum"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
|
@ -665,6 +670,7 @@ version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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)",
|
"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)",
|
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"uucore 0.0.1",
|
"uucore 0.0.1",
|
||||||
]
|
]
|
||||||
|
|
|
@ -11,6 +11,7 @@ path = "od.rs"
|
||||||
getopts = "*"
|
getopts = "*"
|
||||||
libc = "*"
|
libc = "*"
|
||||||
byteorder = "*"
|
byteorder = "*"
|
||||||
|
half = "*"
|
||||||
uucore = { path="../uucore" }
|
uucore = { path="../uucore" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
|
|
|
@ -2,6 +2,7 @@ use std::io;
|
||||||
use byteorder_io::ByteOrder;
|
use byteorder_io::ByteOrder;
|
||||||
use multifilereader::HasError;
|
use multifilereader::HasError;
|
||||||
use peekreader::PeekRead;
|
use peekreader::PeekRead;
|
||||||
|
use half::f16;
|
||||||
|
|
||||||
/// Processes an input and provides access to the data read in various formats
|
/// 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`.
|
/// Returns a f32/f64 from the internal buffer at position `start`.
|
||||||
pub fn read_float(&self, start: usize, byte_size: usize) -> f64 {
|
pub fn read_float(&self, start: usize, byte_size: usize) -> f64 {
|
||||||
match byte_size {
|
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,
|
4 => self.byte_order.read_f32(&self.data[start..start + 4]) as f64,
|
||||||
8 => self.byte_order.read_f64(&self.data[start..start + 8]),
|
8 => self.byte_order.read_f64(&self.data[start..start + 8]),
|
||||||
_ => panic!("Invalid byte_size: {}", byte_size),
|
_ => panic!("Invalid byte_size: {}", byte_size),
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
extern crate getopts;
|
extern crate getopts;
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
|
extern crate half;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate uucore;
|
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, 4) => Some(FORMAT_ITEM_HEX32),
|
||||||
(FormatType::HexadecimalInt, 8) => Some(FORMAT_ITEM_HEX64),
|
(FormatType::HexadecimalInt, 8) => Some(FORMAT_ITEM_HEX64),
|
||||||
|
|
||||||
|
(FormatType::Float, 2) => Some(FORMAT_ITEM_F16),
|
||||||
(FormatType::Float, 0) |
|
(FormatType::Float, 0) |
|
||||||
(FormatType::Float, 4) => Some(FORMAT_ITEM_F32),
|
(FormatType::Float, 4) => Some(FORMAT_ITEM_F32),
|
||||||
(FormatType::Float, 8) => Some(FORMAT_ITEM_F64),
|
(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=c1")).unwrap_err();
|
||||||
parse_format_flags_str(&vec!("od", "--format=x256")).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=d5")).unwrap_err();
|
||||||
parse_format_flags_str(&vec!("od", "--format=f2")).unwrap_err();
|
parse_format_flags_str(&vec!("od", "--format=f1")).unwrap_err();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -1,8 +1,15 @@
|
||||||
use std::num::FpCategory;
|
use std::num::FpCategory;
|
||||||
|
use half::f16;
|
||||||
use std::f32;
|
use std::f32;
|
||||||
use std::f64;
|
use std::f64;
|
||||||
use formatteriteminfo::*;
|
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 {
|
pub static FORMAT_ITEM_F32: FormatterItemInfo = FormatterItemInfo {
|
||||||
byte_size: 4,
|
byte_size: 4,
|
||||||
print_width: 15,
|
print_width: 15,
|
||||||
|
@ -15,6 +22,9 @@ pub static FORMAT_ITEM_F64: FormatterItemInfo = FormatterItemInfo {
|
||||||
formatter: FormatWriter::FloatWriter(format_item_flo64),
|
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 {
|
pub fn format_item_flo32(f: f64) -> String {
|
||||||
format!(" {}", format_flo32(f as f32))
|
format!(" {}", format_flo32(f as f32))
|
||||||
|
@ -24,6 +34,10 @@ pub fn format_item_flo64(f: f64) -> String {
|
||||||
format!(" {}", format_flo64(f))
|
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
|
// formats float with 8 significant digits, eg 12345678 or -1.2345678e+12
|
||||||
// always retuns a string of 14 characters
|
// always retuns a string of 14 characters
|
||||||
fn format_flo32(f: f32) -> String {
|
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");
|
||||||
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);
|
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]
|
#[test]
|
||||||
fn test_f32(){
|
fn test_f32(){
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue