Thanks to visit codestin.com
Credit goes to lib.rs

2 releases

0.1.1 Jan 19, 2020
0.1.0 Jan 19, 2020

#9 in #ibm

Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App Codestin Search App

2,057 downloads per month
Used in 3 crates (via giga-segy-core)

BSD-3-Clause

57KB
1K SLoC

ibmfloat

A Rust library for IBM floating point numbers, specifically focused on converting them to IEEE-754 floating point values.

This crate has no Rust dependencies, no C dependencies, and no unsafe code. Its std feature is enabled by default, and it can be disabled to support #![no_std] environments.

The conversion processes and much of the test suite are derived from the Python ibm2ieee library.

Performance

Representative results from a laptop:

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]                        

Conversions to f32 are more expensive than conversions to f64.

Usage

32-bit floats

ibmfloat::F32 represents a 32-bit IBM floating point number. It supports the conversions:

  • Transmuting to/from a u32 via from_bits(), to_bits()
  • Transmuting to/from a big-endian [u8; 4] via from_be_bytes()/to_be_bytes()
  • Lossily converting to an f32 via From/Into
  • Losslessly converting to an f64 via From/Into

IBM F32 floats have slightly less precision than IEEE-754 f32 floats, but it covers a slightly larger domain. F32s of typical magnitude can be converted to f32 without rounding or other loss of precision. Converting F32s of large magnitude to f32 will cause rounding; F32s 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 = 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-bit floats

ibmfloat::64 represents a 64-bit IBM floating point number. It supports the conversions:

  • Transmuting to/from a u64 via from_bits(), to_bits()
  • Transmuting to/from a big-endian [u8; 8] via from_be_bytes()/to_be_bytes()
  • Lossily converting to an f32 via From/Into
  • Lossily converting to an f64 via From/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 = 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);

Development

Please use cargo test, cargo clippy, and cargo fmt as you go. Please also cargo test --no-default-features to prevent accidental breakage for #![no_std] users. GitHub Actions runs each of these commands on push.

ibm2ieee-sys/ contains a crate wrapping ibm2ieee.c, tests which compare ibm2ieee.c's conversion to ibmfloat's conversions over random values, and benchmarks of both libraries.

$ cd ibm2ieee-sys/
$ cargo test
$ cargo bench

cargo fuzz covers each of the four IBM to IEEE conversion paths, comparing them to ibm2ieee-sys. 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

Additional references:

No runtime deps

Features