1 unstable release
Uses old Rust 2015
0.1.0 | Apr 1, 2017 |
---|
#53 in #fixed-point
309 downloads per month
Used in 12 crates
(3 directly)
74KB
2K
SLoC
fpa
Fixed Point Arithmetic
License
Licensed under either of
-
Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
-
MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
lib.rs
:
Fixed point arithmetic
A fixed point number is an alternative representation for a real number.
IEEE floats, f32
and f64
, being the standard format in processors with
Floating Point Units (FPU). You should consider using fixed numbers on
systems where there's no FPU and performance is critical as fixed point
arithmetic is faster than software emulated IEEE float arithmetic. Do note
that fixed point numbers tend to be more prone to overflows as they operate
in ranges much smaller than floats.
The fixed point numbers exposed in this library use the following naming
convention: IxFy
, where x
is the number of bits used for the integer
part and y
is the number of bits used for the fractional part.
Unlike IEEE floats, fixed points numbers have fixed precision. One can
exchange range for precision by selecting different values for x
and y
:
- Range:
[-2 ^ (y - 1), 2 ^ (y - 1) - 2 ^ (-x)]
- Precision:
2 ^ (-x)
For example, the type I1F7
has range [-1, 0.9921875]
and precision
0.0078125
.
Examples
- Casts
// https://crates.io/crates/cast
extern crate cast;
extern crate fpa;
use cast::f64;
// 32-bit fixed point number, 16 bits for the integer part and 16 bits for
// the fractional part
use fpa::I16F16;
fn main() {
// casts an integer into a fixed point number (infallible)
let q = I16F16(1i8);
// casts the fixed point number into a float (infallible)
let f = f64(q);
assert_eq!(f, 1.);
}
- Arithmetic
use fpa::I16F16;
// NOTE the `f64` -> `I16F16` cast is fallible because of NaN and infinity
assert_eq!(I16F16(1.25_f64).unwrap() + I16F16(2.75_f64).unwrap(),
I16F16(4_f64).unwrap());
assert_eq!(I16F16(2_f64).unwrap() / I16F16(0.5_f64).unwrap(),
I16F16(4_f64).unwrap());
assert_eq!(I16F16(2_f64).unwrap() * I16F16(0.5_f64).unwrap(),
I16F16(1_f64).unwrap());
- Trigonometry
extern crate cast;
extern crate fpa;
use cast::f64;
use fpa::I2F30;
fn main() {
let (r, _) = I2F30(0.3_f64).unwrap().polar(I2F30(0.4_f64).unwrap());
assert!((f64(r) - 0.5).abs() < 1e-5);
}
Dependencies
~195KB