# fixed 1.10.0

Fixed-point numbers
Documentation

# Fixed-point numbers

The fixed crate provides fixed-point numbers.

An n-bit fixed-point number has f = `Frac` fractional bits where 0 ≤ f ≤ n, and n − f integer bits. For example, FixedI32<U24> is a 32-bit signed fixed-point number with n = 32 total bits, f = 24 fractional bits, and n − f = 8 integer bits. FixedI32<U0> behaves like `i32`, and FixedU32<U0> behaves like `u32`.

The difference between any two successive representable numbers is constant throughout the possible range for a fixed-point number: Δ = 1/2f. When f = 0, like in FixedI32<U0>, Δ = 1 because representable numbers are integers, and the difference between two successive integers is 1. When f = n, Δ = 1/2n and the value lies in the range −0.5 ≤ x < 0.5 for signed numbers like FixedI32<U32>, and in the range 0 ≤ x < 1 for unsigned numbers like FixedU32<U32>.

In version 1 the typenum crate is used for the fractional bit count `Frac`; the plan is to to have a major version 2 with const generics instead when the Rust compiler support for them is powerful enough.

The main features are

• Representation of binary fixed-point numbers up to 128 bits wide.
• Conversions between fixed-point numbers and numeric primitives.
• Comparisons between fixed-point numbers and numeric primitives.
• Parsing from strings in decimal, binary, octal and hexadecimal.
• Display as decimal, binary, octal and hexadecimal.
• Arithmetic and logic operations.

This crate does not provide decimal fixed-point numbers. For example 0.001 cannot be represented exactly, as it is 1/103. It is binary fractions like 1/24 (0.0625) that can be represented exactly, provided there are enough fractional bits.

This crate does not provide general analytic functions.

• No algebraic functions are provided, for example no `sqrt` or `pow`.
• No trigonometric functions are provided, for example no `sin` or `cos`.
• No other transcendental functions are provided, for example no `log` or `exp`.

These functions are not provided because different implementations can have different trade-offs, for example trading some correctness for speed. Implementations can be provided in other crates.

The conversions supported cover the following cases.

## What’s new

### Other releases

Details on other releases can be found in RELEASES.md.

## Quick examples

``````use fixed::types::I20F12;

// 19/3 = 6 1/3
let six_and_third = I20F12::from_num(19) / 3;
// four decimal digits for 12 binary digits
assert_eq!(six_and_third.to_string(), "6.3333");
// find the ceil and convert to i32
assert_eq!(six_and_third.ceil().to_num::<i32>(), 7);
// we can also compare directly to integers
assert_eq!(six_and_third.ceil(), 7);
``````

The type `I20F12` is a 32-bit fixed-point signed number with 20 integer bits and 12 fractional bits. It is an alias to FixedI32<U12>. The unsigned counterpart would be `U20F12`. Aliases are provided for all combinations of integer and fractional bits adding up to a total of eight, 16, 32, 64 or 128 bits.

``````use fixed::types::{I4F4, I4F12};

// −8 ≤ I4F4 < 8 with steps of 1/16 (~0.06)
let a = I4F4::from_num(1);
// multiplication and division by integers are possible
let ans1 = a / 5 * 17;
// 1 / 5 × 17 = 3 2/5 (3.4), but we get 3 3/16 (~3.2)
assert_eq!(ans1, I4F4::from_bits((3 << 4) + 3));
assert_eq!(ans1.to_string(), "3.2");

// −8 ≤ I4F12 < 8 with steps of 1/4096 (~0.0002)
let wider_a = I4F12::from(a);
let wider_ans = wider_a / 5 * 17;
let ans2 = I4F4::from_num(wider_ans);
// now the answer is the much closer 3 6/16 (~3.4)
assert_eq!(ans2, I4F4::from_bits((3 << 4) + 6));
assert_eq!(ans2.to_string(), "3.4");
``````

The second example shows some precision and conversion issues. The low precision of `a` means that `a / 5` is 3⁄16 instead of 1⁄5, leading to an inaccurate result `ans1` = 3 3⁄16 (~3.2). With a higher precision, we get `wider_a / 5` equal to 819⁄4096, leading to a more accurate intermediate result `wider_ans` = 3 1635⁄4096. When we convert back to four fractional bits, we get `ans2` = 3 6⁄16 (~3.4).

Note that we can convert from `I4F4` to `I4F12` using `From`, as the target type has the same number of integer bits and a larger number of fractional bits. Converting from `I4F12` to `I4F4` cannot use `From` as we have less fractional bits, so we use `from_num` instead.

## Writing fixed-point constants and values literally

The fixed-macro crate provides a convenient macro to write down fixed-point constants literally in the code.

``````use fixed::types::I16F16;
use fixed_macro::fixed;

const NUM1: I16F16 = fixed!(12.75: I16F16);
let num2 = NUM1 + fixed!(13.125: I16F16);
assert_eq!(num2, 25.875);
``````

## Using the fixed crate

The fixed crate is available on crates.io. To use it in your crate, add it as a dependency inside Cargo.toml:

``````[dependencies]
fixed = "1.10"
``````

The fixed crate requires rustc version 1.53.0 or later.

## Optional features

The fixed crate has these optional feature:

1. `arbitrary`, disabled by default. This provides the generation of arbitrary fixed-point numbers from raw, unstructured data. This feature requires the arbitrary crate.
2. `serde`, disabled by default. This provides serialization support for the fixed-point types. This feature requires the serde crate.
3. `std`, disabled by default. This is for features that are not possible under `no_std`: currently the implementation of the `Error` trait for `ParseFixedError`.
4. `serde-str`, disabled by default. Fixed-point numbers are serialized as strings showing the value when using human-readable formats. This feature requires the `serde` and the `std` optional features. Warning: numbers serialized when this feature is enabled cannot be deserialized when this feature is disabled, and vice versa.

To enable features, you can add the dependency like this to Cargo.toml:

``````[dependencies.fixed]
version = "1.10"
features = ["serde"]
``````

## Experimental optional features

It is not considered a breaking change if the following experimental features are removed. The removal of experimental features would however require a minor version bump. Similarly, on a minor version bump, optional dependencies can be updated to an incompatible newer version.

1. `num-traits`, disabled by default. This implements some traits from the num-traits crate. (The plan is to promote this to an optional feature once the num-traits crate reaches version 1.0.0.)

## Deprecated optional features

The following optional features are deprecated and may be removed in the next major version of the crate.

1. `az`, has no effect. Previously required for the `az` cast traits. Now these cast traits are always provided.
2. `f16`, has no effect. Previously required for conversion to/from `f16` and `bf16`. Now these conversions are always provided.