ibmfloat
A Rust library for IBM floating point numbers, specifically focused on converting them to IEEE-754 floating point values.
This library has no C dependencies or unsafe
code.
The conversion processes and much of the test suite are derived from the
Python ibm2ieee
library.
Usage
32-bit floats
ibmfloat::F32
represents a 32-bit IBM floating point number. It supports the conversions:
- Transmuting to/from a
u32
viafrom_bits()
,to_bits()
- Transmuting to/from a big-endian
[u8; 4]
viafrom_be_bytes()
/to_be_bytes()
- Lossily converting to an
f32
viaFrom
/Into
- Losslessly converting to an
f64
viaFrom
/Into
IBM F32
floats have slightly less precision than IEEE-754 f32
floats, but it covers a slightly larger domain. F32
s
of typical magnitude can be converted to f32
without rounding or other loss of precision. Converting F32
s of large
magnitude to f32
will cause rounding; F32
s of extreme magnitude can also cause overflow and underflow to occur.
Every F32
can be precisely represented as an f64
, without rounding, overflow, or underflow. Those seeking a lossless
path to IEEE-754 should convert F32
to f64
.
// Use the example -118.625:
// https://en.wikipedia.org/wiki/IBM_hexadecimal_floating_point#Example
let foreign_float = F32 from_bits;
let native_float = f32 from;
assert_eq!;
let native_float: f32 = foreign_float.into;
assert_eq!;
64-bit floats
ibmfloat::64
represents a 64-bit IBM floating point number. It supports the conversions:
- Transmuting to/from a
u64
viafrom_bits()
,to_bits()
- Transmuting to/from a big-endian
[u8; 8]
viafrom_be_bytes()
/to_be_bytes()
- Lossily converting to an
f32
viaFrom
/Into
- Lossily converting to an
f64
viaFrom
/Into
IBM F64
floats have slightly more precision than IEEE-754 f64
floats, but they cover a slightly smaller domain. Most
conversions will require rounding, but there is no risk of overflow or underflow.
let foreign_float = F64 from_bits;
let native_float = f64 from;
assert_eq!;
let native_float: f64 = foreign_float.into;
assert_eq!;
Development
Please use cargo test
, cargo clippy
, and rustfmt
as you go.
cargo fuzz
covers each of the four IBM to IEEE conversion paths, comparing
them to ibm2ieee.c
's output. Please run them as needed if you tinker with that logic.
$ cargo +nightly fuzz run ibm32ieee32
$ cargo +nightly fuzz run ibm32ieee64
$ cargo +nightly fuzz run ibm64ieee32
$ cargo +nightly fuzz run ibm64ieee64