Module eos_rs::api::fixed

source ·
Expand description

Dealing with fixed-point numbers used in the game.

Note that this module currently only deals with binary fixed-point representations. The game also sometimes uses decimal representations of fixed-point numbers (eg. 0x64 -> 100 -> ‘01.00’).

This pulls in parts of the fixed crate, which describes these numbers as follows:

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>.

Think of these similar to floats, but instead of having an arbitrary amount of fractional digits/bits and arbitrary precision, fixed-point numbers have a set amount of fractional digits/bits that are fully accurate.

Commonly used fixed numbers:

  • I24F8: 32-bit number that has 24 integer bits and eight fractional bits.

You have several options to create a fixed-point number:

let n1 = I24F8::from_num(10);
assert_eq!(n1, 10.0);

// This will round to the nearest possible fixed representation. In this case,
// this value will fit, since 2 fits in a 24-bit integer and 75 fits in an
// 8-bit integer.
let n2 = I24F8::from_num(2.75);
// Note that due to precision differences this assertion can fail with some values.
assert_eq!(n2, 2.75);

// It's also possible (and probably faster) to directly use a number already encoded
// as a fixed number. This has the lower byte set to 0, which means the fractional
// bit will be 0, and the upper byte to 1, which means this is "1.0".
let n3 = I24F8::from_bits(0x01_00);
assert_eq!(n3, 1.0);

let n4 = I24F8::from_bits(0x01_AB);
// Using strings here to compare, due to the before mentioned accuracy issues.
assert_eq!(format!("{}", n4), "1.668");

let n5 = I24F8::from_bits(0x01_FF);
assert_eq!(format!("{}", n5), "1.996");

Modules

  • Extra types that do not need to be handled directly.

Structs

  • An eight-bit signed number with Frac fractional bits.
  • A 16-bit signed number with Frac fractional bits.
  • A 32-bit signed number with Frac fractional bits.
  • An eight-bit unsigned number with Frac fractional bits.
  • A 16-bit unsigned number with Frac fractional bits.
  • A 32-bit unsigned number with Frac fractional bits.

Type Definitions