Module sp_arithmetic::fixed_point

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