2 个版本
0.1.1 | 2020 年 1 月 19 日 |
---|---|
0.1.0 | 2020 年 1 月 19 日 |
#903 在 算法 中
每月 1,176 次下载
在 3 个crate中使用了(通过 giga-segy-core)
57KB
1K SLoC
ibmfloat
A Rust 库,用于处理 IBM 浮点数,特别关注将其转换为 IEEE-754 浮点值。
这个crate没有Rust依赖,没有C依赖,并且没有 unsafe
代码。它的 std
功能默认启用,可以通过禁用来支持 #![no_std]
环境。
转换过程和大部分测试套件来自 Python ibm2ieee
库。
性能
笔记本电脑的代表性结果
F32 to f32 time: [6.7092 ns 6.7734 ns 6.8454 ns]
F32 to f64 time: [2.4642 ns 2.4965 ns 2.5326 ns]
F64 to f32 time: [7.2500 ns 7.3315 ns 7.4169 ns]
F64 to f64 time: [2.7761 ns 2.8028 ns 2.8342 ns]
转换为 f32
的开销比转换为 f64
要高。
用法
32位浮点数
ibmfloat::F32
表示一个32位IBM浮点数。它支持以下转换
- 通过
from_bits()
和to_bits()
将其转换为/从u32
- 通过
from_be_bytes()
/to_be_bytes()
将其转换为/从大端[u8; 4]
- 通过
From
/Into
损失性地转换为f32
- 通过
From
/Into
无损性地转换为f64
IBM F32
单精度浮点数比 IEEE-754 f32
单精度浮点数的精度略低,但其覆盖的范围略大。典型大小的 F32
可以转换为 f32
而不会出现舍入或其他精度损失。将大范围的 F32
转换为 f32
将导致舍入;极大幅度的 F32
也可能导致溢出和下溢。
每个 F32
都可以精确地表示为一个 f64
,不会出现舍入、溢出或下溢。那些寻求无损路径到 IEEE-754 的人应该将 F32
转换为 f64
。
// Use the example -118.625:
// https://en.wikipedia.org/wiki/IBM_hexadecimal_floating_point#Example
let foreign_float = ibmfloat::F32::from_bits(0b1_1000010_0111_0110_1010_0000_0000_0000);
let native_float = f32::from(foreign_float);
assert_eq!(native_float, -118.625f32);
let native_float: f32 = foreign_float.into();
assert_eq!(native_float, -118.625f32);
64位浮点数
ibmfloat::64
表示一个 64 位 IBM 浮点数。它支持以下转换
- 通过
from_bits()
、to_bits()
将其转换为/从u64
- 通过
from_be_bytes()
/to_be_bytes()
将其转换为/从大端[u8; 8]
- 通过
From
/Into
损失性地转换为f32
- 通过
From
/Into
无损地将其转换为f64
IBM F64
浮点数的精度略高于 IEEE-754 f64
浮点数,但它们的覆盖范围略小。大多数转换将需要舍入,但不会出现溢出或下溢的风险。
let foreign_float = ibmfloat::F64::from_bits(0x4110000000000000);
let native_float = f64::from(foreign_float);
assert_eq!(native_float, 1.0f64);
let native_float: f64 = foreign_float.into();
assert_eq!(native_float, 1.0f64);
开发
请使用 cargo test
、cargo clippy
和 cargo fmt
逐步进行。请还使用 cargo test --no-default-features
以防止意外破坏 #![no_std]
用户。GitHub Actions 在推送时运行这些命令。
ibm2ieee-sys/
包含一个封装 ibm2ieee.c
的 crate,测试比较 ibm2ieee.c
对随机值的转换与 ibmfloat
的转换,以及两个库的基准测试。
$ cd ibm2ieee-sys/
$ cargo test
$ cargo bench
cargo fuzz
覆盖了四个 IBM 到 IEEE 转换路径,并将它们与 ibm2ieee-sys
进行比较。如果您对该逻辑进行修改,请按需运行它们。
$ cargo +nightly fuzz run ibm32ieee32
$ cargo +nightly fuzz run ibm32ieee64
$ cargo +nightly fuzz run ibm64ieee32
$ cargo +nightly fuzz run ibm64ieee64
其他参考
- ESA/390 增强浮点支持:概述 是一个很好的入门介绍
- Hercules 使用 C 实现了 IBM 浮点硬件