Module polkadot_sdk_frame::arithmetic::fixed_point
Expand description
Decimal Fixed Point implementations for Substrate runtime.
Similar to types that implement PerThing
, these are also
fixed-point types, however, they are able to represent larger fractions:
ⓘ
#[test]
fn fixed_u64() {
// The difference between this and perthings is perthings operates within the relam of [0,
// 1] In cases where we need > 1, we can used fixed types such as FixedU64
let rational_1 = FixedU64::from_rational(10, 5); //" 200%" aka 2.
let rational_2 = FixedU64::from_rational_with_rounding(5, 10, Rounding::Down); // "50%" aka 0.50...
assert_eq!(rational_1, (2u64).into());
assert_eq!(rational_2.into_perbill(), Perbill::from_float(0.5));
}
§Fixed Point Types in Practice
If one needs to exceed the value of one (1), then
FixedU64
(and its signed and u128
counterparts) can be utilized.
Take for example this very rudimentary pricing mechanism, where we wish to calculate the demand
/ supply to get a price for some on-chain compute:
ⓘ
#[test]
fn fixed_u64_block_computation_example() {
// Calculate a very rudimentary on-chain price from supply / demand
// Supply: Cores available per block
// Demand: Cores being ordered per block
let price = FixedU64::from_rational(5u128, 10u128);
// 0.5 DOT per core
assert_eq!(price, FixedU64::from_float(0.5));
// Now, the story has changed - lots of demand means we buy as many cores as there
// available. This also means that price goes up! For the sake of simplicity, we don't care
// about who gets a core - just about our very simple price model
// Calculate a very rudimentary on-chain price from supply / demand
// Supply: Cores available per block
// Demand: Cores being ordered per block
let price = FixedU64::from_rational(19u128, 10u128);
// 1.9 DOT per core
assert_eq!(price, FixedU64::from_float(1.9));
}
For a much more comprehensive example, be sure to look at the source for broker (the “coretime”) pallet.
§Fixed Point Types in Practice
Just as with PerThing
, you can also perform regular mathematical
expressions:
ⓘ
#[test]
fn fixed_u64_operation_example() {
let rational_1 = FixedU64::from_rational(10, 5); // "200%" aka 2.
let rational_2 = FixedU64::from_rational(8, 5); // "160%" aka 1.6.
let addition = rational_1 + rational_2;
let multiplication = rational_1 * rational_2;
let division = rational_1 / rational_2;
let subtraction = rational_1 - rational_2;
assert_eq!(addition, FixedU64::from_float(3.6));
assert_eq!(multiplication, FixedU64::from_float(3.2));
assert_eq!(division, FixedU64::from_float(1.25));
assert_eq!(subtraction, FixedU64::from_float(0.4));
}
Structs§
- A fixed point number representation in the range. Fixed Point 64 bits signed, range = [-9223372036.854775808, 9223372036.854775807]
- A fixed point number representation in the range. Fixed Point 128 bits signed, range = [-170141183460469231731.687303715884105728, 170141183460469231731.687303715884105727]
- A fixed point number representation in the range. Fixed Point 64 bits unsigned, range = [0.000000000, 18446744073.709551615]
- A fixed point number representation in the range. Fixed Point 128 bits unsigned, range = [0.000000000000000000, 340282366920938463463.374607431768211455]
Traits§
- Something that implements a decimal fixed point number.
- Integer types that can be used to interact with
FixedPointNumber
implementations.