sp_arithmetic/
fixed_point.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! Decimal Fixed Point implementations for Substrate runtime.
19//! Similar to types that implement [`PerThing`](crate::per_things), these are also
20//! fixed-point types, however, they are able to represent larger fractions:
21#![doc = docify::embed!("./src/lib.rs", fixed_u64)]
22//!
23//! ### Fixed Point Types in Practice
24//!
25//! If one needs to exceed the value of one (1), then
26//! [`FixedU64`](FixedU64) (and its signed and `u128` counterparts) can be utilized.
27//! Take for example this very rudimentary pricing mechanism, where we wish to calculate the demand
28//! / supply to get a price for some on-chain compute:
29#![doc = docify::embed!(
30	"./src/lib.rs",
31	fixed_u64_block_computation_example
32)]
33//!
34//! For a much more comprehensive example, be sure to look at the source for broker (the "coretime")
35//! pallet.
36//!
37//! #### Fixed Point Types in Practice
38//!
39//! Just as with [`PerThing`](PerThing), you can also perform regular mathematical
40//! expressions:
41#![doc = docify::embed!(
42	"./src/lib.rs",
43	fixed_u64_operation_example
44)]
45//!
46
47use crate::{
48	helpers_128bit::{multiply_by_rational_with_rounding, sqrt},
49	traits::{
50		Bounded, CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedSub, One,
51		SaturatedConversion, Saturating, UniqueSaturatedInto, Zero,
52	},
53	PerThing, Perbill, Rounding, SignedRounding,
54};
55use codec::{CompactAs, Decode, DecodeWithMemTracking, Encode};
56use core::{
57	fmt::Debug,
58	ops::{self, Add, Div, Mul, Sub},
59};
60
61#[cfg(feature = "serde")]
62use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
63
64#[cfg(all(not(feature = "std"), feature = "serde"))]
65use alloc::string::{String, ToString};
66
67/// Integer types that can be used to interact with `FixedPointNumber` implementations.
68pub trait FixedPointOperand:
69	Copy
70	+ Clone
71	+ Bounded
72	+ Zero
73	+ Saturating
74	+ PartialOrd<Self>
75	+ UniqueSaturatedInto<u128>
76	+ TryFrom<u128>
77	+ CheckedNeg
78{
79}
80
81impl<T> FixedPointOperand for T where
82	T: Copy
83		+ Clone
84		+ Bounded
85		+ Zero
86		+ Saturating
87		+ PartialOrd<Self>
88		+ UniqueSaturatedInto<u128>
89		+ TryFrom<u128>
90		+ CheckedNeg
91{
92}
93
94/// Something that implements a decimal fixed point number.
95///
96/// The precision is given by `Self::DIV`, i.e. `1 / DIV` can be represented.
97///
98/// Each type can store numbers from `Self::Inner::min_value() / Self::DIV`
99/// to `Self::Inner::max_value() / Self::DIV`.
100/// This is also referred to as the _accuracy_ of the type in the documentation.
101pub trait FixedPointNumber:
102	Sized
103	+ Copy
104	+ Default
105	+ Debug
106	+ Saturating
107	+ Bounded
108	+ Eq
109	+ PartialEq
110	+ Ord
111	+ PartialOrd
112	+ CheckedSub
113	+ CheckedAdd
114	+ CheckedMul
115	+ CheckedDiv
116	+ Add
117	+ Sub
118	+ Div
119	+ Mul
120	+ Zero
121	+ One
122{
123	/// The underlying data type used for this fixed point number.
124	type Inner: Debug + One + CheckedMul + CheckedDiv + FixedPointOperand;
125
126	/// Precision of this fixed point implementation. It should be a power of `10`.
127	const DIV: Self::Inner;
128
129	/// Indicates if this fixed point implementation is signed or not.
130	const SIGNED: bool;
131
132	/// Precision of this fixed point implementation.
133	fn accuracy() -> Self::Inner {
134		Self::DIV
135	}
136
137	/// Builds this type from an integer number.
138	fn from_inner(int: Self::Inner) -> Self;
139
140	/// Consumes `self` and returns the inner raw value.
141	fn into_inner(self) -> Self::Inner;
142
143	/// Compute the square root. If it overflows or is negative, then `None` is returned.
144	#[must_use]
145	fn checked_sqrt(self) -> Option<Self>;
146
147	/// Creates self from an integer number `int`.
148	///
149	/// Returns `Self::max` or `Self::min` if `int` exceeds accuracy.
150	#[must_use]
151	fn saturating_from_integer<N: FixedPointOperand>(int: N) -> Self {
152		let mut n: I129 = int.into();
153		n.value = n.value.saturating_mul(Self::DIV.saturated_into());
154		Self::from_inner(from_i129(n).unwrap_or_else(|| to_bound(int, 0)))
155	}
156
157	/// Creates `self` from an integer number `int`.
158	///
159	/// Returns `None` if `int` exceeds accuracy.
160	#[must_use]
161	fn checked_from_integer<N: Into<Self::Inner>>(int: N) -> Option<Self> {
162		let int: Self::Inner = int.into();
163		int.checked_mul(&Self::DIV).map(Self::from_inner)
164	}
165
166	/// Creates `self` from a rational number. Equal to `n / d`.
167	///
168	/// Panics if `d = 0`. Returns `Self::max` or `Self::min` if `n / d` exceeds accuracy.
169	#[must_use]
170	fn saturating_from_rational<N: FixedPointOperand, D: FixedPointOperand>(n: N, d: D) -> Self {
171		if d == D::zero() {
172			panic!("attempt to divide by zero")
173		}
174		Self::checked_from_rational(n, d).unwrap_or_else(|| to_bound(n, d))
175	}
176
177	/// Creates `self` from a rational number. Equal to `n / d`.
178	///
179	/// Returns `None` if `d == 0` or `n / d` exceeds accuracy.
180	#[must_use]
181	fn checked_from_rational<N: FixedPointOperand, D: FixedPointOperand>(
182		n: N,
183		d: D,
184	) -> Option<Self> {
185		if d == D::zero() {
186			return None
187		}
188
189		let n: I129 = n.into();
190		let d: I129 = d.into();
191		let negative = n.negative != d.negative;
192
193		multiply_by_rational_with_rounding(
194			n.value,
195			Self::DIV.unique_saturated_into(),
196			d.value,
197			Rounding::from_signed(SignedRounding::Minor, negative),
198		)
199		.and_then(|value| from_i129(I129 { value, negative }))
200		.map(Self::from_inner)
201	}
202
203	/// Checked multiplication for integer type `N`. Equal to `self * n`.
204	///
205	/// Returns `None` if the result does not fit in `N`.
206	#[must_use]
207	fn checked_mul_int<N: FixedPointOperand>(self, n: N) -> Option<N> {
208		let lhs: I129 = self.into_inner().into();
209		let rhs: I129 = n.into();
210		let negative = lhs.negative != rhs.negative;
211
212		multiply_by_rational_with_rounding(
213			lhs.value,
214			rhs.value,
215			Self::DIV.unique_saturated_into(),
216			Rounding::from_signed(SignedRounding::Minor, negative),
217		)
218		.and_then(|value| from_i129(I129 { value, negative }))
219	}
220
221	/// Saturating multiplication for integer type `N`. Equal to `self * n`.
222	///
223	/// Returns `N::min` or `N::max` if the result does not fit in `N`.
224	#[must_use]
225	fn saturating_mul_int<N: FixedPointOperand>(self, n: N) -> N {
226		self.checked_mul_int(n).unwrap_or_else(|| to_bound(self.into_inner(), n))
227	}
228
229	/// Checked division for integer type `N`. Equal to `self / d`.
230	///
231	/// Returns `None` if the result does not fit in `N` or `d == 0`.
232	#[must_use]
233	fn checked_div_int<N: FixedPointOperand>(self, d: N) -> Option<N> {
234		let lhs: I129 = self.into_inner().into();
235		let rhs: I129 = d.into();
236		let negative = lhs.negative != rhs.negative;
237
238		lhs.value
239			.checked_div(rhs.value)
240			.and_then(|n| n.checked_div(Self::DIV.unique_saturated_into()))
241			.and_then(|value| from_i129(I129 { value, negative }))
242	}
243
244	/// Saturating division for integer type `N`. Equal to `self / d`.
245	///
246	/// Panics if `d == 0`. Returns `N::min` or `N::max` if the result does not fit in `N`.
247	#[must_use]
248	fn saturating_div_int<N: FixedPointOperand>(self, d: N) -> N {
249		if d == N::zero() {
250			panic!("attempt to divide by zero")
251		}
252		self.checked_div_int(d).unwrap_or_else(|| to_bound(self.into_inner(), d))
253	}
254
255	/// Saturating multiplication for integer type `N`, adding the result back.
256	/// Equal to `self * n + n`.
257	///
258	/// Returns `N::min` or `N::max` if the multiplication or final result does not fit in `N`.
259	#[must_use]
260	fn saturating_mul_acc_int<N: FixedPointOperand>(self, n: N) -> N {
261		if self.is_negative() && n > N::zero() {
262			n.saturating_sub(Self::zero().saturating_sub(self).saturating_mul_int(n))
263		} else {
264			self.saturating_mul_int(n).saturating_add(n)
265		}
266	}
267
268	/// Saturating absolute value.
269	///
270	/// Returns `Self::max` if `self == Self::min`.
271	#[must_use]
272	fn saturating_abs(self) -> Self {
273		let inner = self.into_inner();
274		if inner >= Self::Inner::zero() {
275			self
276		} else {
277			Self::from_inner(inner.checked_neg().unwrap_or_else(Self::Inner::max_value))
278		}
279	}
280
281	/// Takes the reciprocal (inverse). Equal to `1 / self`.
282	///
283	/// Returns `None` if `self = 0`.
284	#[must_use]
285	fn reciprocal(self) -> Option<Self> {
286		Self::one().checked_div(&self)
287	}
288
289	/// Checks if the number is one.
290	fn is_one(&self) -> bool {
291		self.into_inner() == Self::Inner::one()
292	}
293
294	/// Returns `true` if `self` is positive and `false` if the number is zero or negative.
295	fn is_positive(self) -> bool {
296		self.into_inner() > Self::Inner::zero()
297	}
298
299	/// Returns `true` if `self` is negative and `false` if the number is zero or positive.
300	fn is_negative(self) -> bool {
301		self.into_inner() < Self::Inner::zero()
302	}
303
304	/// Returns the integer part.
305	#[must_use]
306	fn trunc(self) -> Self {
307		self.into_inner()
308			.checked_div(&Self::DIV)
309			.expect("panics only if DIV is zero, DIV is not zero; qed")
310			.checked_mul(&Self::DIV)
311			.map(Self::from_inner)
312			.expect("can not overflow since fixed number is >= integer part")
313	}
314
315	/// Returns the fractional part.
316	///
317	/// Note: the returned fraction will be non-negative for negative numbers,
318	/// except in the case where the integer part is zero.
319	#[must_use]
320	fn frac(self) -> Self {
321		let integer = self.trunc();
322		let fractional = self.saturating_sub(integer);
323		if integer == Self::zero() {
324			fractional
325		} else {
326			fractional.saturating_abs()
327		}
328	}
329
330	/// Returns the smallest integer greater than or equal to a number.
331	///
332	/// Saturates to `Self::max` (truncated) if the result does not fit.
333	#[must_use]
334	fn ceil(self) -> Self {
335		if self.is_negative() {
336			self.trunc()
337		} else if self.frac() == Self::zero() {
338			self
339		} else {
340			self.saturating_add(Self::one()).trunc()
341		}
342	}
343
344	/// Returns the largest integer less than or equal to a number.
345	///
346	/// Saturates to `Self::min` (truncated) if the result does not fit.
347	#[must_use]
348	fn floor(self) -> Self {
349		if self.is_negative() {
350			self.saturating_sub(Self::one()).trunc()
351		} else {
352			self.trunc()
353		}
354	}
355
356	/// Returns the number rounded to the nearest integer. Rounds half-way cases away from 0.0.
357	///
358	/// Saturates to `Self::min` or `Self::max` (truncated) if the result does not fit.
359	#[must_use]
360	fn round(self) -> Self {
361		let n = self.frac().saturating_mul(Self::saturating_from_integer(10));
362		if n < Self::saturating_from_integer(5) {
363			self.trunc()
364		} else if self.is_positive() {
365			self.saturating_add(Self::one()).trunc()
366		} else {
367			self.saturating_sub(Self::one()).trunc()
368		}
369	}
370}
371
372/// Data type used as intermediate storage in some computations to avoid overflow.
373struct I129 {
374	value: u128,
375	negative: bool,
376}
377
378impl<N: FixedPointOperand> From<N> for I129 {
379	fn from(n: N) -> I129 {
380		if n < N::zero() {
381			let value: u128 = n
382				.checked_neg()
383				.map(|n| n.unique_saturated_into())
384				.unwrap_or_else(|| N::max_value().unique_saturated_into().saturating_add(1));
385			I129 { value, negative: true }
386		} else {
387			I129 { value: n.unique_saturated_into(), negative: false }
388		}
389	}
390}
391
392/// Transforms an `I129` to `N` if it is possible.
393fn from_i129<N: FixedPointOperand>(n: I129) -> Option<N> {
394	let max_plus_one: u128 = N::max_value().unique_saturated_into().saturating_add(1);
395	if n.negative && N::min_value() < N::zero() && n.value == max_plus_one {
396		Some(N::min_value())
397	} else {
398		let unsigned_inner: N = n.value.try_into().ok()?;
399		let inner = if n.negative { unsigned_inner.checked_neg()? } else { unsigned_inner };
400		Some(inner)
401	}
402}
403
404/// Returns `R::max` if the sign of `n * m` is positive, `R::min` otherwise.
405fn to_bound<N: FixedPointOperand, D: FixedPointOperand, R: Bounded>(n: N, m: D) -> R {
406	if (n < N::zero()) != (m < D::zero()) {
407		R::min_value()
408	} else {
409		R::max_value()
410	}
411}
412
413macro_rules! implement_fixed {
414	(
415		$name:ident,
416		$test_mod:ident,
417		$inner_type:ty,
418		$signed:tt,
419		$div:tt,
420		$title:expr $(,)?
421	) => {
422		/// A fixed point number representation in the range.
423		#[doc = $title]
424		#[derive(
425			Encode,
426			Decode,
427			DecodeWithMemTracking,
428			CompactAs,
429			Default,
430			Copy,
431			Clone,
432			codec::MaxEncodedLen,
433			PartialEq,
434			Eq,
435			PartialOrd,
436			Ord,
437			scale_info::TypeInfo,
438		)]
439		pub struct $name($inner_type);
440
441		impl From<$inner_type> for $name {
442			fn from(int: $inner_type) -> Self {
443				$name::saturating_from_integer(int)
444			}
445		}
446
447		impl<N: FixedPointOperand, D: FixedPointOperand> From<(N, D)> for $name {
448			fn from(r: (N, D)) -> Self {
449				$name::saturating_from_rational(r.0, r.1)
450			}
451		}
452
453		impl FixedPointNumber for $name {
454			type Inner = $inner_type;
455
456			const DIV: Self::Inner = $div;
457			const SIGNED: bool = $signed;
458
459			fn from_inner(inner: Self::Inner) -> Self {
460				Self(inner)
461			}
462
463			fn into_inner(self) -> Self::Inner {
464				self.0
465			}
466
467			fn checked_sqrt(self) -> Option<Self> {
468				self.checked_sqrt()
469			}
470		}
471
472		impl $name {
473			/// Create a new instance from the given `inner` value.
474			///
475			/// `const` version of `FixedPointNumber::from_inner`.
476			pub const fn from_inner(inner: $inner_type) -> Self {
477				Self(inner)
478			}
479
480			/// Return the instance's inner value.
481			///
482			/// `const` version of `FixedPointNumber::into_inner`.
483			pub const fn into_inner(self) -> $inner_type {
484				self.0
485			}
486
487			/// Creates self from a `u32`.
488			///
489			/// WARNING: This is a `const` function designed for convenient use at build time and
490			/// will panic on overflow. Ensure that any inputs are sensible.
491			pub const fn from_u32(n: u32) -> Self {
492				Self::from_inner((n as $inner_type) * $div)
493			}
494
495			/// Convert from a `float` value.
496			#[cfg(any(feature = "std", test))]
497			pub fn from_float(x: f64) -> Self {
498				Self((x * (<Self as FixedPointNumber>::DIV as f64)) as $inner_type)
499			}
500
501			/// Convert from a `Perbill` value.
502			pub const fn from_perbill(n: Perbill) -> Self {
503				Self::from_rational(n.deconstruct() as u128, 1_000_000_000)
504			}
505
506			/// Convert into a `Perbill` value. Will saturate if above one or below zero.
507			pub const fn into_perbill(self) -> Perbill {
508				if self.0 <= 0 {
509					Perbill::zero()
510				} else if self.0 >= $div {
511					Perbill::one()
512				} else {
513					match multiply_by_rational_with_rounding(
514						self.0 as u128,
515						1_000_000_000,
516						Self::DIV as u128,
517						Rounding::NearestPrefDown,
518					) {
519						Some(value) => {
520							if value > (u32::max_value() as u128) {
521								panic!(
522									"prior logic ensures 0<self.0<DIV; \
523									multiply ensures 0<self.0<1000000000; \
524									qed"
525								);
526							}
527							Perbill::from_parts(value as u32)
528						},
529						None => Perbill::zero(),
530					}
531				}
532			}
533
534			/// Convert into a `float` value.
535			#[cfg(any(feature = "std", test))]
536			pub fn to_float(self) -> f64 {
537				self.0 as f64 / <Self as FixedPointNumber>::DIV as f64
538			}
539
540			/// Attempt to convert into a `PerThing`. This will succeed iff `self` is at least zero
541			/// and at most one. If it is out of bounds, it will result in an error returning the
542			/// clamped value.
543			pub fn try_into_perthing<P: PerThing>(self) -> Result<P, P> {
544				if self < Self::zero() {
545					Err(P::zero())
546				} else if self > Self::one() {
547					Err(P::one())
548				} else {
549					Ok(P::from_rational(self.0 as u128, $div))
550				}
551			}
552
553			/// Attempt to convert into a `PerThing`. This will always succeed resulting in a
554			/// clamped value if `self` is less than zero or greater than one.
555			pub fn into_clamped_perthing<P: PerThing>(self) -> P {
556				if self < Self::zero() {
557					P::zero()
558				} else if self > Self::one() {
559					P::one()
560				} else {
561					P::from_rational(self.0 as u128, $div)
562				}
563			}
564
565			/// Negate the value.
566			///
567			/// WARNING: This is a `const` function designed for convenient use at build time and
568			/// will panic on overflow. Ensure that any inputs are sensible.
569			pub const fn neg(self) -> Self {
570				Self(0 - self.0)
571			}
572
573			/// Take the square root of a positive value.
574			///
575			/// WARNING: This is a `const` function designed for convenient use at build time and
576			/// will panic on overflow. Ensure that any inputs are sensible.
577			pub const fn sqrt(self) -> Self {
578				match self.checked_sqrt() {
579					Some(v) => v,
580					None => panic!("sqrt overflow or negative input"),
581				}
582			}
583
584			#[deprecated(
585				note = "`try_sqrt` will be removed after October 2025. Use `checked_sqrt` instead."
586			)]
587			pub const fn try_sqrt(self) -> Option<Self> {
588				self.checked_sqrt()
589			}
590
591			/// Compute the square root. If it overflows or is negative, then `None` is returned.
592			pub const fn checked_sqrt(self) -> Option<Self> {
593				if self.0 == 0 {
594					return Some(Self(0))
595				}
596				if self.0 < 1 {
597					return None
598				}
599				let v = self.0 as u128;
600
601				// Want x' = sqrt(x) where x = n/D and x' = n'/D (D is fixed)
602				// Our preferred way is:
603				//   sqrt(n/D) = sqrt(nD / D^2) = sqrt(nD)/sqrt(D^2) = sqrt(nD)/D
604				//   ergo n' = sqrt(nD)
605				// but this requires nD to fit into our type.
606				// if nD doesn't fit then we can fall back on:
607				//   sqrt(nD) = sqrt(n)*sqrt(D)
608				// computing them individually and taking the product at the end. we will lose some
609				// precision though.
610				let maybe_vd = u128::checked_mul(v, $div);
611				let r = if let Some(vd) = maybe_vd { sqrt(vd) } else { sqrt(v) * sqrt($div) };
612				Some(Self(r as $inner_type))
613			}
614
615			/// Add a value and return the result.
616			///
617			/// WARNING: This is a `const` function designed for convenient use at build time and
618			/// will panic on overflow. Ensure that any inputs are sensible.
619			pub const fn add(self, rhs: Self) -> Self {
620				Self(self.0 + rhs.0)
621			}
622
623			/// Subtract a value and return the result.
624			///
625			/// WARNING: This is a `const` function designed for convenient use at build time and
626			/// will panic on overflow. Ensure that any inputs are sensible.
627			pub const fn sub(self, rhs: Self) -> Self {
628				Self(self.0 - rhs.0)
629			}
630
631			/// Multiply by a value and return the result.
632			///
633			/// Result will be rounded to the nearest representable value, rounding down if it is
634			/// equidistant between two neighbours.
635			///
636			/// WARNING: This is a `const` function designed for convenient use at build time and
637			/// will panic on overflow. Ensure that any inputs are sensible.
638			pub const fn mul(self, rhs: Self) -> Self {
639				match $name::const_checked_mul(self, rhs) {
640					Some(v) => v,
641					None => panic!("attempt to multiply with overflow"),
642				}
643			}
644
645			/// Divide by a value and return the result.
646			///
647			/// Result will be rounded to the nearest representable value, rounding down if it is
648			/// equidistant between two neighbours.
649			///
650			/// WARNING: This is a `const` function designed for convenient use at build time and
651			/// will panic on overflow. Ensure that any inputs are sensible.
652			pub const fn div(self, rhs: Self) -> Self {
653				match $name::const_checked_div(self, rhs) {
654					Some(v) => v,
655					None => panic!("attempt to divide with overflow or NaN"),
656				}
657			}
658
659			/// Convert into an `I129` format value.
660			///
661			/// WARNING: This is a `const` function designed for convenient use at build time and
662			/// will panic on overflow. Ensure that any inputs are sensible.
663			const fn into_i129(self) -> I129 {
664				#[allow(unused_comparisons)]
665				if self.0 < 0 {
666					let value = match self.0.checked_neg() {
667						Some(n) => n as u128,
668						None => u128::saturating_add(<$inner_type>::max_value() as u128, 1),
669					};
670					I129 { value, negative: true }
671				} else {
672					I129 { value: self.0 as u128, negative: false }
673				}
674			}
675
676			/// Convert from an `I129` format value.
677			///
678			/// WARNING: This is a `const` function designed for convenient use at build time and
679			/// will panic on overflow. Ensure that any inputs are sensible.
680			const fn from_i129(n: I129) -> Option<Self> {
681				let max_plus_one = u128::saturating_add(<$inner_type>::max_value() as u128, 1);
682				#[allow(unused_comparisons)]
683				let inner = if n.negative && <$inner_type>::min_value() < 0 && n.value == max_plus_one {
684					<$inner_type>::min_value()
685				} else {
686					let unsigned_inner = n.value as $inner_type;
687					if unsigned_inner as u128 != n.value || (unsigned_inner > 0) != (n.value > 0) {
688						return None
689					};
690					if n.negative {
691						match unsigned_inner.checked_neg() {
692							Some(v) => v,
693							None => return None,
694						}
695					} else {
696						unsigned_inner
697					}
698				};
699				Some(Self(inner))
700			}
701
702			/// Calculate an approximation of a rational.
703			///
704			/// Result will be rounded to the nearest representable value, rounding down if it is
705			/// equidistant between two neighbours.
706			///
707			/// WARNING: This is a `const` function designed for convenient use at build time and
708			/// will panic on overflow. Ensure that any inputs are sensible.
709			pub const fn from_rational(a: u128, b: u128) -> Self {
710				Self::from_rational_with_rounding(a, b, Rounding::NearestPrefDown)
711			}
712
713			/// Calculate an approximation of a rational with custom rounding.
714			///
715			/// WARNING: This is a `const` function designed for convenient use at build time and
716			/// will panic on overflow. Ensure that any inputs are sensible.
717			pub const fn from_rational_with_rounding(a: u128, b: u128, rounding: Rounding) -> Self {
718				if b == 0 {
719					panic!("attempt to divide by zero in from_rational")
720				}
721				match multiply_by_rational_with_rounding(Self::DIV as u128, a, b, rounding) {
722					Some(value) => match Self::from_i129(I129 { value, negative: false }) {
723						Some(x) => x,
724						None => panic!("overflow in from_rational"),
725					},
726					None => panic!("overflow in from_rational"),
727				}
728			}
729
730			/// Multiply by another value, returning `None` in the case of an error.
731			///
732			/// Result will be rounded to the nearest representable value, rounding down if it is
733			/// equidistant between two neighbours.
734			pub const fn const_checked_mul(self, other: Self) -> Option<Self> {
735				self.const_checked_mul_with_rounding(other, SignedRounding::NearestPrefLow)
736			}
737
738			/// Multiply by another value with custom rounding, returning `None` in the case of an
739			/// error.
740			///
741			/// Result will be rounded to the nearest representable value, rounding down if it is
742			/// equidistant between two neighbours.
743			pub const fn const_checked_mul_with_rounding(
744				self,
745				other: Self,
746				rounding: SignedRounding,
747			) -> Option<Self> {
748				let lhs = self.into_i129();
749				let rhs = other.into_i129();
750				let negative = lhs.negative != rhs.negative;
751
752				match multiply_by_rational_with_rounding(
753					lhs.value,
754					rhs.value,
755					Self::DIV as u128,
756					Rounding::from_signed(rounding, negative),
757				) {
758					Some(value) => Self::from_i129(I129 { value, negative }),
759					None => None,
760				}
761			}
762
763			/// Divide by another value, returning `None` in the case of an error.
764			///
765			/// Result will be rounded to the nearest representable value, rounding down if it is
766			/// equidistant between two neighbours.
767			pub const fn const_checked_div(self, other: Self) -> Option<Self> {
768				self.checked_rounding_div(other, SignedRounding::NearestPrefLow)
769			}
770
771			/// Divide by another value with custom rounding, returning `None` in the case of an
772			/// error.
773			///
774			/// Result will be rounded to the nearest representable value, rounding down if it is
775			/// equidistant between two neighbours.
776			pub const fn checked_rounding_div(
777				self,
778				other: Self,
779				rounding: SignedRounding,
780			) -> Option<Self> {
781				if other.0 == 0 {
782					return None
783				}
784
785				let lhs = self.into_i129();
786				let rhs = other.into_i129();
787				let negative = lhs.negative != rhs.negative;
788
789				match multiply_by_rational_with_rounding(
790					lhs.value,
791					Self::DIV as u128,
792					rhs.value,
793					Rounding::from_signed(rounding, negative),
794				) {
795					Some(value) => Self::from_i129(I129 { value, negative }),
796					None => None,
797				}
798			}
799		}
800
801		impl Saturating for $name {
802			fn saturating_add(self, rhs: Self) -> Self {
803				Self(self.0.saturating_add(rhs.0))
804			}
805
806			fn saturating_sub(self, rhs: Self) -> Self {
807				Self(self.0.saturating_sub(rhs.0))
808			}
809
810			fn saturating_mul(self, rhs: Self) -> Self {
811				self.checked_mul(&rhs).unwrap_or_else(|| to_bound(self.0, rhs.0))
812			}
813
814			fn saturating_pow(self, exp: usize) -> Self {
815				if exp == 0 {
816					return Self::saturating_from_integer(1)
817				}
818
819				let exp = exp as u32;
820				let msb_pos = 32 - exp.leading_zeros();
821
822				let mut result = Self::saturating_from_integer(1);
823				let mut pow_val = self;
824				for i in 0..msb_pos {
825					if ((1 << i) & exp) > 0 {
826						result = result.saturating_mul(pow_val);
827					}
828					pow_val = pow_val.saturating_mul(pow_val);
829				}
830				result
831			}
832		}
833
834		impl ops::Neg for $name {
835			type Output = Self;
836
837			fn neg(self) -> Self::Output {
838				Self(<Self as FixedPointNumber>::Inner::zero() - self.0)
839			}
840		}
841
842		impl ops::Add for $name {
843			type Output = Self;
844
845			fn add(self, rhs: Self) -> Self::Output {
846				Self(self.0 + rhs.0)
847			}
848		}
849
850		impl ops::Sub for $name {
851			type Output = Self;
852
853			fn sub(self, rhs: Self) -> Self::Output {
854				Self(self.0 - rhs.0)
855			}
856		}
857
858		impl ops::Mul for $name {
859			type Output = Self;
860
861			fn mul(self, rhs: Self) -> Self::Output {
862				self.checked_mul(&rhs)
863					.unwrap_or_else(|| panic!("attempt to multiply with overflow"))
864			}
865		}
866
867		impl ops::Div for $name {
868			type Output = Self;
869
870			fn div(self, rhs: Self) -> Self::Output {
871				if rhs.0 == 0 {
872					panic!("attempt to divide by zero")
873				}
874				self.checked_div(&rhs)
875					.unwrap_or_else(|| panic!("attempt to divide with overflow"))
876			}
877		}
878
879		impl CheckedSub for $name {
880			fn checked_sub(&self, rhs: &Self) -> Option<Self> {
881				self.0.checked_sub(rhs.0).map(Self)
882			}
883		}
884
885		impl CheckedAdd for $name {
886			fn checked_add(&self, rhs: &Self) -> Option<Self> {
887				self.0.checked_add(rhs.0).map(Self)
888			}
889		}
890
891		impl CheckedDiv for $name {
892			fn checked_div(&self, other: &Self) -> Option<Self> {
893				if other.0 == 0 {
894					return None
895				}
896
897				let lhs: I129 = self.0.into();
898				let rhs: I129 = other.0.into();
899				let negative = lhs.negative != rhs.negative;
900
901				// Note that this uses the old (well-tested) code with sign-ignorant rounding. This
902				// is equivalent to the `SignedRounding::NearestPrefMinor`. This means it is
903				// expected to give exactly the same result as `const_checked_div` when the result
904				// is positive and a result up to one epsilon greater when it is negative.
905				multiply_by_rational_with_rounding(
906					lhs.value,
907					Self::DIV as u128,
908					rhs.value,
909					Rounding::from_signed(SignedRounding::Minor, negative),
910				)
911				.and_then(|value| from_i129(I129 { value, negative }))
912				.map(Self)
913			}
914		}
915
916		impl CheckedMul for $name {
917			fn checked_mul(&self, other: &Self) -> Option<Self> {
918				let lhs: I129 = self.0.into();
919				let rhs: I129 = other.0.into();
920				let negative = lhs.negative != rhs.negative;
921
922				multiply_by_rational_with_rounding(
923					lhs.value,
924					rhs.value,
925					Self::DIV as u128,
926					Rounding::from_signed(SignedRounding::Minor, negative),
927				)
928				.and_then(|value| from_i129(I129 { value, negative }))
929				.map(Self)
930			}
931		}
932
933		impl Bounded for $name {
934			fn min_value() -> Self {
935				Self(<Self as FixedPointNumber>::Inner::min_value())
936			}
937
938			fn max_value() -> Self {
939				Self(<Self as FixedPointNumber>::Inner::max_value())
940			}
941		}
942
943		impl Zero for $name {
944			fn zero() -> Self {
945				Self::from_inner(<Self as FixedPointNumber>::Inner::zero())
946			}
947
948			fn is_zero(&self) -> bool {
949				self.into_inner() == <Self as FixedPointNumber>::Inner::zero()
950			}
951		}
952
953		impl One for $name {
954			fn one() -> Self {
955				Self::from_inner(Self::DIV)
956			}
957		}
958
959		impl ::core::fmt::Debug for $name {
960			#[cfg(feature = "std")]
961			fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
962				let integral = {
963					let int = self.0 / Self::accuracy();
964					let signum_for_zero = if int == 0 && self.is_negative() { "-" } else { "" };
965					format!("{}{}", signum_for_zero, int)
966				};
967				let precision = (Self::accuracy() as f64).log10() as usize;
968				let fractional = format!(
969					"{:0>weight$}",
970					((self.0 % Self::accuracy()) as i128).abs(),
971					weight = precision
972				);
973				write!(f, "{}({}.{})", stringify!($name), integral, fractional)
974			}
975
976			#[cfg(not(feature = "std"))]
977			fn fmt(&self, _: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
978				Ok(())
979			}
980		}
981
982		impl<P: PerThing> From<P> for $name
983		where
984			P::Inner: FixedPointOperand,
985		{
986			fn from(p: P) -> Self {
987				let accuracy = P::ACCURACY;
988				let value = p.deconstruct();
989				$name::saturating_from_rational(value, accuracy)
990			}
991		}
992
993		impl ::core::fmt::Display for $name {
994			fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
995				write!(f, "{}", self.0)
996			}
997		}
998
999		impl ::core::str::FromStr for $name {
1000			type Err = &'static str;
1001
1002			fn from_str(s: &str) -> Result<Self, Self::Err> {
1003				let inner: <Self as FixedPointNumber>::Inner =
1004					s.parse().map_err(|_| "invalid string input for fixed point number")?;
1005				Ok(Self::from_inner(inner))
1006			}
1007		}
1008
1009		// Manual impl `Serialize` as serde_json does not support i128.
1010		// TODO: remove impl if issue https://github.com/serde-rs/json/issues/548 fixed.
1011		#[cfg(feature = "serde")]
1012		impl Serialize for $name {
1013			fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1014			where
1015				S: Serializer,
1016			{
1017				serializer.serialize_str(&self.to_string())
1018			}
1019		}
1020
1021		// Manual impl `Deserialize` as serde_json does not support i128.
1022		// TODO: remove impl if issue https://github.com/serde-rs/json/issues/548 fixed.
1023		#[cfg(feature = "serde")]
1024		impl<'de> Deserialize<'de> for $name {
1025			fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1026			where
1027				D: Deserializer<'de>,
1028			{
1029				use ::core::str::FromStr;
1030				let s = String::deserialize(deserializer)?;
1031				$name::from_str(&s).map_err(de::Error::custom)
1032			}
1033		}
1034
1035		#[cfg(test)]
1036		mod $test_mod {
1037			use super::*;
1038			use crate::{Perbill, Percent, Permill, Perquintill};
1039
1040			fn max() -> $name {
1041				$name::max_value()
1042			}
1043
1044			fn min() -> $name {
1045				$name::min_value()
1046			}
1047
1048			fn precision() -> usize {
1049				($name::accuracy() as f64).log10() as usize
1050			}
1051
1052			#[test]
1053			fn macro_preconditions() {
1054				assert!($name::DIV > 0);
1055			}
1056
1057			#[test]
1058			fn has_max_encoded_len() {
1059				struct AsMaxEncodedLen<T: codec::MaxEncodedLen> {
1060					_data: T,
1061				}
1062
1063				let _ = AsMaxEncodedLen { _data: $name::min_value() };
1064			}
1065
1066			#[test]
1067			fn from_i129_works() {
1068				let a = I129 { value: 1, negative: true };
1069
1070				// Can't convert negative number to unsigned.
1071				assert_eq!(from_i129::<u128>(a), None);
1072
1073				let a = I129 { value: u128::MAX - 1, negative: false };
1074
1075				// Max - 1 value fits.
1076				assert_eq!(from_i129::<u128>(a), Some(u128::MAX - 1));
1077
1078				let a = I129 { value: u128::MAX, negative: false };
1079
1080				// Max value fits.
1081				assert_eq!(from_i129::<u128>(a), Some(u128::MAX));
1082
1083				let a = I129 { value: i128::MAX as u128 + 1, negative: true };
1084
1085				// Min value fits.
1086				assert_eq!(from_i129::<i128>(a), Some(i128::MIN));
1087
1088				let a = I129 { value: i128::MAX as u128 + 1, negative: false };
1089
1090				// Max + 1 does not fit.
1091				assert_eq!(from_i129::<i128>(a), None);
1092
1093				let a = I129 { value: i128::MAX as u128, negative: false };
1094
1095				// Max value fits.
1096				assert_eq!(from_i129::<i128>(a), Some(i128::MAX));
1097			}
1098
1099			#[test]
1100			fn to_bound_works() {
1101				let a = 1i32;
1102				let b = 1i32;
1103
1104				// Pos + Pos => Max.
1105				assert_eq!(to_bound::<_, _, i32>(a, b), i32::MAX);
1106
1107				let a = -1i32;
1108				let b = -1i32;
1109
1110				// Neg + Neg => Max.
1111				assert_eq!(to_bound::<_, _, i32>(a, b), i32::MAX);
1112
1113				let a = 1i32;
1114				let b = -1i32;
1115
1116				// Pos + Neg => Min.
1117				assert_eq!(to_bound::<_, _, i32>(a, b), i32::MIN);
1118
1119				let a = -1i32;
1120				let b = 1i32;
1121
1122				// Neg + Pos => Min.
1123				assert_eq!(to_bound::<_, _, i32>(a, b), i32::MIN);
1124
1125				let a = 1i32;
1126				let b = -1i32;
1127
1128				// Pos + Neg => Min (unsigned).
1129				assert_eq!(to_bound::<_, _, u32>(a, b), 0);
1130			}
1131
1132			#[test]
1133			fn op_neg_works() {
1134				let a = $name::zero();
1135				let b = -a;
1136
1137				// Zero.
1138				assert_eq!(a, b);
1139
1140				if $name::SIGNED {
1141					let a = $name::saturating_from_integer(5);
1142					let b = -a;
1143
1144					// Positive.
1145					assert_eq!($name::saturating_from_integer(-5), b);
1146
1147					let a = $name::saturating_from_integer(-5);
1148					let b = -a;
1149
1150					// Negative
1151					assert_eq!($name::saturating_from_integer(5), b);
1152
1153					let a = $name::max_value();
1154					let b = -a;
1155
1156					// Max.
1157					assert_eq!($name::min_value() + $name::from_inner(1), b);
1158
1159					let a = $name::min_value() + $name::from_inner(1);
1160					let b = -a;
1161
1162					// Min.
1163					assert_eq!($name::max_value(), b);
1164				}
1165			}
1166
1167			#[test]
1168			fn op_checked_add_overflow_works() {
1169				let a = $name::max_value();
1170				let b = 1.into();
1171				assert!(a.checked_add(&b).is_none());
1172			}
1173
1174			#[test]
1175			fn op_add_works() {
1176				let a = $name::saturating_from_rational(5, 2);
1177				let b = $name::saturating_from_rational(1, 2);
1178
1179				// Positive case: 6/2 = 3.
1180				assert_eq!($name::saturating_from_integer(3), a + b);
1181
1182				if $name::SIGNED {
1183					// Negative case: 4/2 = 2.
1184					let b = $name::saturating_from_rational(1, -2);
1185					assert_eq!($name::saturating_from_integer(2), a + b);
1186				}
1187			}
1188
1189			#[test]
1190			fn op_checked_sub_underflow_works() {
1191				let a = $name::min_value();
1192				let b = 1.into();
1193				assert!(a.checked_sub(&b).is_none());
1194			}
1195
1196			#[test]
1197			fn op_sub_works() {
1198				let a = $name::saturating_from_rational(5, 2);
1199				let b = $name::saturating_from_rational(1, 2);
1200
1201				assert_eq!($name::saturating_from_integer(2), a - b);
1202				assert_eq!($name::saturating_from_integer(-2), b.saturating_sub(a));
1203			}
1204
1205			#[test]
1206			fn op_checked_mul_overflow_works() {
1207				let a = $name::max_value();
1208				let b = 2.into();
1209				assert!(a.checked_mul(&b).is_none());
1210			}
1211
1212			#[test]
1213			fn op_mul_works() {
1214				let a = $name::saturating_from_integer(42);
1215				let b = $name::saturating_from_integer(2);
1216				assert_eq!($name::saturating_from_integer(84), a * b);
1217
1218				let a = $name::saturating_from_integer(42);
1219				let b = $name::saturating_from_integer(-2);
1220				assert_eq!($name::saturating_from_integer(-84), a * b);
1221			}
1222
1223			#[test]
1224			#[should_panic(expected = "attempt to divide by zero")]
1225			fn op_div_panics_on_zero_divisor() {
1226				let a = $name::saturating_from_integer(1);
1227				let b = 0.into();
1228				let _c = a / b;
1229			}
1230
1231			#[test]
1232			fn op_checked_div_overflow_works() {
1233				if $name::SIGNED {
1234					let a = $name::min_value();
1235					let b = $name::zero().saturating_sub($name::one());
1236					assert!(a.checked_div(&b).is_none());
1237				}
1238			}
1239
1240			#[test]
1241			fn op_sqrt_works() {
1242				for i in 1..1_000i64 {
1243					let x = $name::saturating_from_rational(i, 1_000i64);
1244					assert_eq!((x * x).checked_sqrt(), Some(x));
1245					let x = $name::saturating_from_rational(i, 1i64);
1246					assert_eq!((x * x).checked_sqrt(), Some(x));
1247				}
1248			}
1249
1250			#[test]
1251			fn op_div_works() {
1252				let a = $name::saturating_from_integer(42);
1253				let b = $name::saturating_from_integer(2);
1254				assert_eq!($name::saturating_from_integer(21), a / b);
1255
1256				if $name::SIGNED {
1257					let a = $name::saturating_from_integer(42);
1258					let b = $name::saturating_from_integer(-2);
1259					assert_eq!($name::saturating_from_integer(-21), a / b);
1260				}
1261			}
1262
1263			#[test]
1264			fn saturating_from_integer_works() {
1265				let inner_max = <$name as FixedPointNumber>::Inner::max_value();
1266				let inner_min = <$name as FixedPointNumber>::Inner::min_value();
1267				let accuracy = $name::accuracy();
1268
1269				// Cases where integer fits.
1270				let a = $name::saturating_from_integer(42);
1271				assert_eq!(a.into_inner(), 42 * accuracy);
1272
1273				let a = $name::saturating_from_integer(-42);
1274				assert_eq!(a.into_inner(), 0.saturating_sub(42 * accuracy));
1275
1276				// Max/min integers that fit.
1277				let a = $name::saturating_from_integer(inner_max / accuracy);
1278				assert_eq!(a.into_inner(), (inner_max / accuracy) * accuracy);
1279
1280				let a = $name::saturating_from_integer(inner_min / accuracy);
1281				assert_eq!(a.into_inner(), (inner_min / accuracy) * accuracy);
1282
1283				// Cases where integer doesn't fit, so it saturates.
1284				let a = $name::saturating_from_integer(inner_max / accuracy + 1);
1285				assert_eq!(a.into_inner(), inner_max);
1286
1287				let a = $name::saturating_from_integer((inner_min / accuracy).saturating_sub(1));
1288				assert_eq!(a.into_inner(), inner_min);
1289			}
1290
1291			#[test]
1292			fn checked_from_integer_works() {
1293				let inner_max = <$name as FixedPointNumber>::Inner::max_value();
1294				let inner_min = <$name as FixedPointNumber>::Inner::min_value();
1295				let accuracy = $name::accuracy();
1296
1297				// Case where integer fits.
1298				let a = $name::checked_from_integer::<$inner_type>(42)
1299					.expect("42 * accuracy <= inner_max; qed");
1300				assert_eq!(a.into_inner(), 42 * accuracy);
1301
1302				// Max integer that fit.
1303				let a = $name::checked_from_integer::<$inner_type>(inner_max / accuracy)
1304					.expect("(inner_max / accuracy) * accuracy <= inner_max; qed");
1305				assert_eq!(a.into_inner(), (inner_max / accuracy) * accuracy);
1306
1307				// Case where integer doesn't fit, so it returns `None`.
1308				let a = $name::checked_from_integer::<$inner_type>(inner_max / accuracy + 1);
1309				assert_eq!(a, None);
1310
1311				if $name::SIGNED {
1312					// Case where integer fits.
1313					let a = $name::checked_from_integer::<$inner_type>(0.saturating_sub(42))
1314						.expect("-42 * accuracy >= inner_min; qed");
1315					assert_eq!(a.into_inner(), 0 - 42 * accuracy);
1316
1317					// Min integer that fit.
1318					let a = $name::checked_from_integer::<$inner_type>(inner_min / accuracy)
1319						.expect("(inner_min / accuracy) * accuracy <= inner_min; qed");
1320					assert_eq!(a.into_inner(), (inner_min / accuracy) * accuracy);
1321
1322					// Case where integer doesn't fit, so it returns `None`.
1323					let a = $name::checked_from_integer::<$inner_type>(inner_min / accuracy - 1);
1324					assert_eq!(a, None);
1325				}
1326			}
1327
1328			#[test]
1329			fn from_inner_works() {
1330				let inner_max = <$name as FixedPointNumber>::Inner::max_value();
1331				let inner_min = <$name as FixedPointNumber>::Inner::min_value();
1332
1333				assert_eq!(max(), $name::from_inner(inner_max));
1334				assert_eq!(min(), $name::from_inner(inner_min));
1335			}
1336
1337			#[test]
1338			#[should_panic(expected = "attempt to divide by zero")]
1339			fn saturating_from_rational_panics_on_zero_divisor() {
1340				let _ = $name::saturating_from_rational(1, 0);
1341			}
1342
1343			#[test]
1344			fn saturating_from_rational_works() {
1345				let inner_max = <$name as FixedPointNumber>::Inner::max_value();
1346				let inner_min = <$name as FixedPointNumber>::Inner::min_value();
1347				let accuracy = $name::accuracy();
1348
1349				let a = $name::saturating_from_rational(5, 2);
1350
1351				// Positive case: 2.5
1352				assert_eq!(a.into_inner(), 25 * accuracy / 10);
1353
1354				// Max - 1.
1355				let a = $name::saturating_from_rational(inner_max - 1, accuracy);
1356				assert_eq!(a.into_inner(), inner_max - 1);
1357
1358				// Min + 1.
1359				let a = $name::saturating_from_rational(inner_min + 1, accuracy);
1360				assert_eq!(a.into_inner(), inner_min + 1);
1361
1362				// Max.
1363				let a = $name::saturating_from_rational(inner_max, accuracy);
1364				assert_eq!(a.into_inner(), inner_max);
1365
1366				// Min.
1367				let a = $name::saturating_from_rational(inner_min, accuracy);
1368				assert_eq!(a.into_inner(), inner_min);
1369
1370				// Zero.
1371				let a = $name::saturating_from_rational(0, 1);
1372				assert_eq!(a.into_inner(), 0);
1373
1374				if $name::SIGNED {
1375					// Negative case: -2.5
1376					let a = $name::saturating_from_rational(-5, 2);
1377					assert_eq!(a.into_inner(), 0 - 25 * accuracy / 10);
1378
1379					// Other negative case: -2.5
1380					let a = $name::saturating_from_rational(5, -2);
1381					assert_eq!(a.into_inner(), 0 - 25 * accuracy / 10);
1382
1383					// Other positive case: 2.5
1384					let a = $name::saturating_from_rational(-5, -2);
1385					assert_eq!(a.into_inner(), 25 * accuracy / 10);
1386
1387					// Max + 1, saturates.
1388					let a = $name::saturating_from_rational(inner_max as u128 + 1, accuracy);
1389					assert_eq!(a.into_inner(), inner_max);
1390
1391					// Min - 1, saturates.
1392					let a = $name::saturating_from_rational(inner_max as u128 + 2, 0 - accuracy);
1393					assert_eq!(a.into_inner(), inner_min);
1394
1395					let a = $name::saturating_from_rational(inner_max, 0 - accuracy);
1396					assert_eq!(a.into_inner(), 0 - inner_max);
1397
1398					let a = $name::saturating_from_rational(inner_min, 0 - accuracy);
1399					assert_eq!(a.into_inner(), inner_max);
1400
1401					let a = $name::saturating_from_rational(inner_min + 1, 0 - accuracy);
1402					assert_eq!(a.into_inner(), inner_max);
1403
1404					let a = $name::saturating_from_rational(inner_min, 0 - 1);
1405					assert_eq!(a.into_inner(), inner_max);
1406
1407					let a = $name::saturating_from_rational(inner_max, 0 - 1);
1408					assert_eq!(a.into_inner(), inner_min);
1409
1410					let a = $name::saturating_from_rational(inner_max, 0 - inner_max);
1411					assert_eq!(a.into_inner(), 0 - accuracy);
1412
1413					let a = $name::saturating_from_rational(0 - inner_max, inner_max);
1414					assert_eq!(a.into_inner(), 0 - accuracy);
1415
1416					let a = $name::saturating_from_rational(inner_max, 0 - 3 * accuracy);
1417					assert_eq!(a.into_inner(), 0 - inner_max / 3);
1418
1419					let a = $name::saturating_from_rational(inner_min, 0 - accuracy / 3);
1420					assert_eq!(a.into_inner(), inner_max);
1421
1422					let a = $name::saturating_from_rational(1, 0 - accuracy);
1423					assert_eq!(a.into_inner(), 0.saturating_sub(1));
1424
1425					let a = $name::saturating_from_rational(inner_min, inner_min);
1426					assert_eq!(a.into_inner(), accuracy);
1427
1428					// Out of accuracy.
1429					let a = $name::saturating_from_rational(1, 0 - accuracy - 1);
1430					assert_eq!(a.into_inner(), 0);
1431				}
1432
1433				let a = $name::saturating_from_rational(inner_max - 1, accuracy);
1434				assert_eq!(a.into_inner(), inner_max - 1);
1435
1436				let a = $name::saturating_from_rational(inner_min + 1, accuracy);
1437				assert_eq!(a.into_inner(), inner_min + 1);
1438
1439				let a = $name::saturating_from_rational(inner_max, 1);
1440				assert_eq!(a.into_inner(), inner_max);
1441
1442				let a = $name::saturating_from_rational(inner_min, 1);
1443				assert_eq!(a.into_inner(), inner_min);
1444
1445				let a = $name::saturating_from_rational(inner_max, inner_max);
1446				assert_eq!(a.into_inner(), accuracy);
1447
1448				let a = $name::saturating_from_rational(inner_max, 3 * accuracy);
1449				assert_eq!(a.into_inner(), inner_max / 3);
1450
1451				let a = $name::saturating_from_rational(inner_min, 2 * accuracy);
1452				assert_eq!(a.into_inner(), inner_min / 2);
1453
1454				let a = $name::saturating_from_rational(inner_min, accuracy / 3);
1455				assert_eq!(a.into_inner(), inner_min);
1456
1457				let a = $name::saturating_from_rational(1, accuracy);
1458				assert_eq!(a.into_inner(), 1);
1459
1460				// Out of accuracy.
1461				let a = $name::saturating_from_rational(1, accuracy + 1);
1462				assert_eq!(a.into_inner(), 0);
1463			}
1464
1465			#[test]
1466			fn checked_from_rational_works() {
1467				let inner_max = <$name as FixedPointNumber>::Inner::max_value();
1468				let inner_min = <$name as FixedPointNumber>::Inner::min_value();
1469				let accuracy = $name::accuracy();
1470
1471				// Divide by zero => None.
1472				let a = $name::checked_from_rational(1, 0);
1473				assert_eq!(a, None);
1474
1475				// Max - 1.
1476				let a = $name::checked_from_rational(inner_max - 1, accuracy).unwrap();
1477				assert_eq!(a.into_inner(), inner_max - 1);
1478
1479				// Min + 1.
1480				let a = $name::checked_from_rational(inner_min + 1, accuracy).unwrap();
1481				assert_eq!(a.into_inner(), inner_min + 1);
1482
1483				// Max.
1484				let a = $name::checked_from_rational(inner_max, accuracy).unwrap();
1485				assert_eq!(a.into_inner(), inner_max);
1486
1487				// Min.
1488				let a = $name::checked_from_rational(inner_min, accuracy).unwrap();
1489				assert_eq!(a.into_inner(), inner_min);
1490
1491				// Max + 1 => Overflow => None.
1492				let a = $name::checked_from_rational(inner_min, 0.saturating_sub(accuracy));
1493				assert_eq!(a, None);
1494
1495				if $name::SIGNED {
1496					// Min - 1 => Underflow => None.
1497					let a = $name::checked_from_rational(
1498						inner_max as u128 + 2,
1499						0.saturating_sub(accuracy),
1500					);
1501					assert_eq!(a, None);
1502
1503					let a = $name::checked_from_rational(inner_max, 0 - 3 * accuracy).unwrap();
1504					assert_eq!(a.into_inner(), 0 - inner_max / 3);
1505
1506					let a = $name::checked_from_rational(inner_min, 0 - accuracy / 3);
1507					assert_eq!(a, None);
1508
1509					let a = $name::checked_from_rational(1, 0 - accuracy).unwrap();
1510					assert_eq!(a.into_inner(), 0.saturating_sub(1));
1511
1512					let a = $name::checked_from_rational(1, 0 - accuracy - 1).unwrap();
1513					assert_eq!(a.into_inner(), 0);
1514
1515					let a = $name::checked_from_rational(inner_min, accuracy / 3);
1516					assert_eq!(a, None);
1517				}
1518
1519				let a = $name::checked_from_rational(inner_max, 3 * accuracy).unwrap();
1520				assert_eq!(a.into_inner(), inner_max / 3);
1521
1522				let a = $name::checked_from_rational(inner_min, 2 * accuracy).unwrap();
1523				assert_eq!(a.into_inner(), inner_min / 2);
1524
1525				let a = $name::checked_from_rational(1, accuracy).unwrap();
1526				assert_eq!(a.into_inner(), 1);
1527
1528				let a = $name::checked_from_rational(1, accuracy + 1).unwrap();
1529				assert_eq!(a.into_inner(), 0);
1530			}
1531
1532			#[test]
1533			fn from_rational_works() {
1534				let inner_max: u128 = <$name as FixedPointNumber>::Inner::max_value() as u128;
1535				let inner_min: u128 = 0;
1536				let accuracy: u128 = $name::accuracy() as u128;
1537
1538				// Max - 1.
1539				let a = $name::from_rational(inner_max - 1, accuracy);
1540				assert_eq!(a.into_inner() as u128, inner_max - 1);
1541
1542				// Min + 1.
1543				let a = $name::from_rational(inner_min + 1, accuracy);
1544				assert_eq!(a.into_inner() as u128, inner_min + 1);
1545
1546				// Max.
1547				let a = $name::from_rational(inner_max, accuracy);
1548				assert_eq!(a.into_inner() as u128, inner_max);
1549
1550				// Min.
1551				let a = $name::from_rational(inner_min, accuracy);
1552				assert_eq!(a.into_inner() as u128, inner_min);
1553
1554				let a = $name::from_rational(inner_max, 3 * accuracy);
1555				assert_eq!(a.into_inner() as u128, inner_max / 3);
1556
1557				let a = $name::from_rational(1, accuracy);
1558				assert_eq!(a.into_inner() as u128, 1);
1559
1560				let a = $name::from_rational(1, accuracy + 1);
1561				assert_eq!(a.into_inner() as u128, 1);
1562
1563				let a = $name::from_rational_with_rounding(1, accuracy + 1, Rounding::Down);
1564				assert_eq!(a.into_inner() as u128, 0);
1565			}
1566
1567			#[test]
1568			fn checked_mul_int_works() {
1569				let a = $name::saturating_from_integer(2);
1570				// Max - 1.
1571				assert_eq!(a.checked_mul_int((i128::MAX - 1) / 2), Some(i128::MAX - 1));
1572				// Max.
1573				assert_eq!(a.checked_mul_int(i128::MAX / 2), Some(i128::MAX - 1));
1574				// Max + 1 => None.
1575				assert_eq!(a.checked_mul_int(i128::MAX / 2 + 1), None);
1576
1577				if $name::SIGNED {
1578					// Min - 1.
1579					assert_eq!(a.checked_mul_int((i128::MIN + 1) / 2), Some(i128::MIN + 2));
1580					// Min.
1581					assert_eq!(a.checked_mul_int(i128::MIN / 2), Some(i128::MIN));
1582					// Min + 1 => None.
1583					assert_eq!(a.checked_mul_int(i128::MIN / 2 - 1), None);
1584
1585					let b = $name::saturating_from_rational(1, -2);
1586					assert_eq!(b.checked_mul_int(42i128), Some(-21));
1587					assert_eq!(b.checked_mul_int(u128::MAX), None);
1588					assert_eq!(b.checked_mul_int(i128::MAX), Some(i128::MAX / -2));
1589					assert_eq!(b.checked_mul_int(i128::MIN), Some(i128::MIN / -2));
1590				}
1591
1592				let a = $name::saturating_from_rational(1, 2);
1593				assert_eq!(a.checked_mul_int(42i128), Some(21));
1594				assert_eq!(a.checked_mul_int(i128::MAX), Some(i128::MAX / 2));
1595				assert_eq!(a.checked_mul_int(i128::MIN), Some(i128::MIN / 2));
1596
1597				let c = $name::saturating_from_integer(255);
1598				assert_eq!(c.checked_mul_int(2i8), None);
1599				assert_eq!(c.checked_mul_int(2i128), Some(510));
1600				assert_eq!(c.checked_mul_int(i128::MAX), None);
1601				assert_eq!(c.checked_mul_int(i128::MIN), None);
1602			}
1603
1604			#[test]
1605			fn saturating_mul_int_works() {
1606				let a = $name::saturating_from_integer(2);
1607				// Max - 1.
1608				assert_eq!(a.saturating_mul_int((i128::MAX - 1) / 2), i128::MAX - 1);
1609				// Max.
1610				assert_eq!(a.saturating_mul_int(i128::MAX / 2), i128::MAX - 1);
1611				// Max + 1 => saturates to max.
1612				assert_eq!(a.saturating_mul_int(i128::MAX / 2 + 1), i128::MAX);
1613
1614				// Min - 1.
1615				assert_eq!(a.saturating_mul_int((i128::MIN + 1) / 2), i128::MIN + 2);
1616				// Min.
1617				assert_eq!(a.saturating_mul_int(i128::MIN / 2), i128::MIN);
1618				// Min + 1 => saturates to min.
1619				assert_eq!(a.saturating_mul_int(i128::MIN / 2 - 1), i128::MIN);
1620
1621				if $name::SIGNED {
1622					let b = $name::saturating_from_rational(1, -2);
1623					assert_eq!(b.saturating_mul_int(42i32), -21);
1624					assert_eq!(b.saturating_mul_int(i128::MAX), i128::MAX / -2);
1625					assert_eq!(b.saturating_mul_int(i128::MIN), i128::MIN / -2);
1626					assert_eq!(b.saturating_mul_int(u128::MAX), u128::MIN);
1627				}
1628
1629				let a = $name::saturating_from_rational(1, 2);
1630				assert_eq!(a.saturating_mul_int(42i32), 21);
1631				assert_eq!(a.saturating_mul_int(i128::MAX), i128::MAX / 2);
1632				assert_eq!(a.saturating_mul_int(i128::MIN), i128::MIN / 2);
1633
1634				let c = $name::saturating_from_integer(255);
1635				assert_eq!(c.saturating_mul_int(2i8), i8::MAX);
1636				assert_eq!(c.saturating_mul_int(-2i8), i8::MIN);
1637				assert_eq!(c.saturating_mul_int(i128::MAX), i128::MAX);
1638				assert_eq!(c.saturating_mul_int(i128::MIN), i128::MIN);
1639			}
1640
1641			#[test]
1642			fn checked_mul_works() {
1643				let inner_max = <$name as FixedPointNumber>::Inner::max_value();
1644				let inner_min = <$name as FixedPointNumber>::Inner::min_value();
1645
1646				let a = $name::saturating_from_integer(2);
1647
1648				// Max - 1.
1649				let b = $name::from_inner(inner_max - 1);
1650				assert_eq!(a.checked_mul(&(b / 2.into())), Some(b));
1651
1652				// Max.
1653				let c = $name::from_inner(inner_max);
1654				assert_eq!(a.checked_mul(&(c / 2.into())), Some(b));
1655
1656				// Max + 1 => None.
1657				let e = $name::from_inner(1);
1658				assert_eq!(a.checked_mul(&(c / 2.into() + e)), None);
1659
1660				if $name::SIGNED {
1661					// Min + 1.
1662					let b = $name::from_inner(inner_min + 1) / 2.into();
1663					let c = $name::from_inner(inner_min + 2);
1664					assert_eq!(a.checked_mul(&b), Some(c));
1665
1666					// Min.
1667					let b = $name::from_inner(inner_min) / 2.into();
1668					let c = $name::from_inner(inner_min);
1669					assert_eq!(a.checked_mul(&b), Some(c));
1670
1671					// Min - 1 => None.
1672					let b = $name::from_inner(inner_min) / 2.into() - $name::from_inner(1);
1673					assert_eq!(a.checked_mul(&b), None);
1674
1675					let c = $name::saturating_from_integer(255);
1676					let b = $name::saturating_from_rational(1, -2);
1677
1678					assert_eq!(b.checked_mul(&42.into()), Some(0.saturating_sub(21).into()));
1679					assert_eq!(
1680						b.checked_mul(&$name::max_value()),
1681						$name::max_value().checked_div(&0.saturating_sub(2).into())
1682					);
1683					assert_eq!(
1684						b.checked_mul(&$name::min_value()),
1685						$name::min_value().checked_div(&0.saturating_sub(2).into())
1686					);
1687					assert_eq!(c.checked_mul(&$name::min_value()), None);
1688				}
1689
1690				let a = $name::saturating_from_rational(1, 2);
1691				let c = $name::saturating_from_integer(255);
1692
1693				assert_eq!(a.checked_mul(&42.into()), Some(21.into()));
1694				assert_eq!(c.checked_mul(&2.into()), Some(510.into()));
1695				assert_eq!(c.checked_mul(&$name::max_value()), None);
1696				assert_eq!(
1697					a.checked_mul(&$name::max_value()),
1698					$name::max_value().checked_div(&2.into())
1699				);
1700				assert_eq!(
1701					a.checked_mul(&$name::min_value()),
1702					$name::min_value().checked_div(&2.into())
1703				);
1704			}
1705
1706			#[test]
1707			fn const_checked_mul_works() {
1708				let inner_max = <$name as FixedPointNumber>::Inner::max_value();
1709				let inner_min = <$name as FixedPointNumber>::Inner::min_value();
1710
1711				let a = $name::saturating_from_integer(2u32);
1712
1713				// Max - 1.
1714				let b = $name::from_inner(inner_max - 1);
1715				assert_eq!(a.const_checked_mul((b / 2.into())), Some(b));
1716
1717				// Max.
1718				let c = $name::from_inner(inner_max);
1719				assert_eq!(a.const_checked_mul((c / 2.into())), Some(b));
1720
1721				// Max + 1 => None.
1722				let e = $name::from_inner(1);
1723				assert_eq!(a.const_checked_mul((c / 2.into() + e)), None);
1724
1725				if $name::SIGNED {
1726					// Min + 1.
1727					let b = $name::from_inner(inner_min + 1) / 2.into();
1728					let c = $name::from_inner(inner_min + 2);
1729					assert_eq!(a.const_checked_mul(b), Some(c));
1730
1731					// Min.
1732					let b = $name::from_inner(inner_min) / 2.into();
1733					let c = $name::from_inner(inner_min);
1734					assert_eq!(a.const_checked_mul(b), Some(c));
1735
1736					// Min - 1 => None.
1737					let b = $name::from_inner(inner_min) / 2.into() - $name::from_inner(1);
1738					assert_eq!(a.const_checked_mul(b), None);
1739
1740					let b = $name::saturating_from_rational(1i32, -2i32);
1741					let c = $name::saturating_from_integer(-21i32);
1742					let d = $name::saturating_from_integer(42);
1743
1744					assert_eq!(b.const_checked_mul(d), Some(c));
1745
1746					let minus_two = $name::saturating_from_integer(-2i32);
1747					assert_eq!(
1748						b.const_checked_mul($name::max_value()),
1749						$name::max_value().const_checked_div(minus_two)
1750					);
1751					assert_eq!(
1752						b.const_checked_mul($name::min_value()),
1753						$name::min_value().const_checked_div(minus_two)
1754					);
1755
1756					let c = $name::saturating_from_integer(255u32);
1757					assert_eq!(c.const_checked_mul($name::min_value()), None);
1758				}
1759
1760				let a = $name::saturating_from_rational(1i32, 2i32);
1761				let c = $name::saturating_from_integer(255i32);
1762
1763				assert_eq!(a.const_checked_mul(42.into()), Some(21.into()));
1764				assert_eq!(c.const_checked_mul(2.into()), Some(510.into()));
1765				assert_eq!(c.const_checked_mul($name::max_value()), None);
1766				assert_eq!(
1767					a.const_checked_mul($name::max_value()),
1768					$name::max_value().checked_div(&2.into())
1769				);
1770				assert_eq!(
1771					a.const_checked_mul($name::min_value()),
1772					$name::min_value().const_checked_div($name::saturating_from_integer(2))
1773				);
1774			}
1775
1776			#[test]
1777			fn checked_div_int_works() {
1778				let inner_max = <$name as FixedPointNumber>::Inner::max_value();
1779				let inner_min = <$name as FixedPointNumber>::Inner::min_value();
1780				let accuracy = $name::accuracy();
1781
1782				let a = $name::from_inner(inner_max);
1783				let b = $name::from_inner(inner_min);
1784				let c = $name::zero();
1785				let d = $name::one();
1786				let e = $name::saturating_from_integer(6);
1787				let f = $name::saturating_from_integer(5);
1788
1789				assert_eq!(e.checked_div_int(2.into()), Some(3));
1790				assert_eq!(f.checked_div_int(2.into()), Some(2));
1791
1792				assert_eq!(a.checked_div_int(i128::MAX), Some(0));
1793				assert_eq!(a.checked_div_int(2), Some(inner_max / (2 * accuracy)));
1794				assert_eq!(a.checked_div_int(inner_max / accuracy), Some(1));
1795				assert_eq!(a.checked_div_int(1i8), None);
1796
1797				if b < c {
1798					// Not executed by unsigned inners.
1799					assert_eq!(
1800						a.checked_div_int(0.saturating_sub(2)),
1801						Some(0.saturating_sub(inner_max / (2 * accuracy)))
1802					);
1803					assert_eq!(
1804						a.checked_div_int(0.saturating_sub(inner_max / accuracy)),
1805						Some(0.saturating_sub(1))
1806					);
1807					assert_eq!(b.checked_div_int(i128::MIN), Some(0));
1808					assert_eq!(b.checked_div_int(inner_min / accuracy), Some(1));
1809					assert_eq!(b.checked_div_int(1i8), None);
1810					assert_eq!(
1811						b.checked_div_int(0.saturating_sub(2)),
1812						Some(0.saturating_sub(inner_min / (2 * accuracy)))
1813					);
1814					assert_eq!(
1815						b.checked_div_int(0.saturating_sub(inner_min / accuracy)),
1816						Some(0.saturating_sub(1))
1817					);
1818					assert_eq!(c.checked_div_int(i128::MIN), Some(0));
1819					assert_eq!(d.checked_div_int(i32::MIN), Some(0));
1820				}
1821
1822				assert_eq!(b.checked_div_int(2), Some(inner_min / (2 * accuracy)));
1823
1824				assert_eq!(c.checked_div_int(1), Some(0));
1825				assert_eq!(c.checked_div_int(i128::MAX), Some(0));
1826				assert_eq!(c.checked_div_int(1i8), Some(0));
1827
1828				assert_eq!(d.checked_div_int(1), Some(1));
1829				assert_eq!(d.checked_div_int(i32::MAX), Some(0));
1830				assert_eq!(d.checked_div_int(1i8), Some(1));
1831
1832				assert_eq!(a.checked_div_int(0), None);
1833				assert_eq!(b.checked_div_int(0), None);
1834				assert_eq!(c.checked_div_int(0), None);
1835				assert_eq!(d.checked_div_int(0), None);
1836			}
1837
1838			#[test]
1839			#[should_panic(expected = "attempt to divide by zero")]
1840			fn saturating_div_int_panics_when_divisor_is_zero() {
1841				let _ = $name::one().saturating_div_int(0);
1842			}
1843
1844			#[test]
1845			fn saturating_div_int_works() {
1846				let inner_max = <$name as FixedPointNumber>::Inner::max_value();
1847				let inner_min = <$name as FixedPointNumber>::Inner::min_value();
1848				let accuracy = $name::accuracy();
1849
1850				let a = $name::saturating_from_integer(5);
1851				assert_eq!(a.saturating_div_int(2), 2);
1852
1853				let a = $name::min_value();
1854				assert_eq!(a.saturating_div_int(1i128), (inner_min / accuracy) as i128);
1855
1856				if $name::SIGNED {
1857					let a = $name::saturating_from_integer(5);
1858					assert_eq!(a.saturating_div_int(-2), -2);
1859
1860					let a = $name::min_value();
1861					assert_eq!(a.saturating_div_int(-1i128), (inner_max / accuracy) as i128);
1862				}
1863			}
1864
1865			#[test]
1866			fn saturating_abs_works() {
1867				let inner_max = <$name as FixedPointNumber>::Inner::max_value();
1868				let inner_min = <$name as FixedPointNumber>::Inner::min_value();
1869
1870				assert_eq!($name::from_inner(inner_max).saturating_abs(), $name::max_value());
1871				assert_eq!($name::zero().saturating_abs(), 0.into());
1872
1873				if $name::SIGNED {
1874					assert_eq!($name::from_inner(inner_min).saturating_abs(), $name::max_value());
1875					assert_eq!(
1876						$name::saturating_from_rational(-1, 2).saturating_abs(),
1877						(1, 2).into()
1878					);
1879				}
1880			}
1881
1882			#[test]
1883			fn saturating_mul_acc_int_works() {
1884				assert_eq!($name::zero().saturating_mul_acc_int(42i8), 42i8);
1885				assert_eq!($name::one().saturating_mul_acc_int(42i8), 2 * 42i8);
1886
1887				assert_eq!($name::one().saturating_mul_acc_int(i128::MAX), i128::MAX);
1888				assert_eq!($name::one().saturating_mul_acc_int(i128::MIN), i128::MIN);
1889
1890				assert_eq!($name::one().saturating_mul_acc_int(u128::MAX / 2), u128::MAX - 1);
1891				assert_eq!($name::one().saturating_mul_acc_int(u128::MIN), u128::MIN);
1892
1893				if $name::SIGNED {
1894					let a = $name::saturating_from_rational(-1, 2);
1895					assert_eq!(a.saturating_mul_acc_int(42i8), 21i8);
1896					assert_eq!(a.saturating_mul_acc_int(42u8), 21u8);
1897					assert_eq!(a.saturating_mul_acc_int(u128::MAX - 1), u128::MAX / 2);
1898				}
1899			}
1900
1901			#[test]
1902			fn saturating_pow_should_work() {
1903				assert_eq!(
1904					$name::saturating_from_integer(2).saturating_pow(0),
1905					$name::saturating_from_integer(1)
1906				);
1907				assert_eq!(
1908					$name::saturating_from_integer(2).saturating_pow(1),
1909					$name::saturating_from_integer(2)
1910				);
1911				assert_eq!(
1912					$name::saturating_from_integer(2).saturating_pow(2),
1913					$name::saturating_from_integer(4)
1914				);
1915				assert_eq!(
1916					$name::saturating_from_integer(2).saturating_pow(3),
1917					$name::saturating_from_integer(8)
1918				);
1919				assert_eq!(
1920					$name::saturating_from_integer(2).saturating_pow(50),
1921					$name::saturating_from_integer(1125899906842624i64)
1922				);
1923
1924				assert_eq!($name::saturating_from_integer(1).saturating_pow(1000), (1).into());
1925				assert_eq!(
1926					$name::saturating_from_integer(1).saturating_pow(usize::MAX),
1927					(1).into()
1928				);
1929
1930				if $name::SIGNED {
1931					// Saturating.
1932					assert_eq!(
1933						$name::saturating_from_integer(2).saturating_pow(68),
1934						$name::max_value()
1935					);
1936
1937					assert_eq!($name::saturating_from_integer(-1).saturating_pow(1000), (1).into());
1938					assert_eq!(
1939						$name::saturating_from_integer(-1).saturating_pow(1001),
1940						0.saturating_sub(1).into()
1941					);
1942					assert_eq!(
1943						$name::saturating_from_integer(-1).saturating_pow(usize::MAX),
1944						0.saturating_sub(1).into()
1945					);
1946					assert_eq!(
1947						$name::saturating_from_integer(-1).saturating_pow(usize::MAX - 1),
1948						(1).into()
1949					);
1950				}
1951
1952				assert_eq!(
1953					$name::saturating_from_integer(114209).saturating_pow(5),
1954					$name::max_value()
1955				);
1956
1957				assert_eq!(
1958					$name::saturating_from_integer(1).saturating_pow(usize::MAX),
1959					(1).into()
1960				);
1961				assert_eq!(
1962					$name::saturating_from_integer(0).saturating_pow(usize::MAX),
1963					(0).into()
1964				);
1965				assert_eq!(
1966					$name::saturating_from_integer(2).saturating_pow(usize::MAX),
1967					$name::max_value()
1968				);
1969			}
1970
1971			#[test]
1972			fn checked_div_works() {
1973				let inner_max = <$name as FixedPointNumber>::Inner::max_value();
1974				let inner_min = <$name as FixedPointNumber>::Inner::min_value();
1975
1976				let a = $name::from_inner(inner_max);
1977				let b = $name::from_inner(inner_min);
1978				let c = $name::zero();
1979				let d = $name::one();
1980				let e = $name::saturating_from_integer(6);
1981				let f = $name::saturating_from_integer(5);
1982
1983				assert_eq!(e.checked_div(&2.into()), Some(3.into()));
1984				assert_eq!(f.checked_div(&2.into()), Some((5, 2).into()));
1985
1986				assert_eq!(a.checked_div(&inner_max.into()), Some(1.into()));
1987				assert_eq!(a.checked_div(&2.into()), Some($name::from_inner(inner_max / 2)));
1988				assert_eq!(a.checked_div(&$name::max_value()), Some(1.into()));
1989				assert_eq!(a.checked_div(&d), Some(a));
1990
1991				if b < c {
1992					// Not executed by unsigned inners.
1993					assert_eq!(
1994						a.checked_div(&0.saturating_sub(2).into()),
1995						Some($name::from_inner(0.saturating_sub(inner_max / 2)))
1996					);
1997					assert_eq!(
1998						a.checked_div(&-$name::max_value()),
1999						Some(0.saturating_sub(1).into())
2000					);
2001					assert_eq!(
2002						b.checked_div(&0.saturating_sub(2).into()),
2003						Some($name::from_inner(0.saturating_sub(inner_min / 2)))
2004					);
2005					assert_eq!(c.checked_div(&$name::max_value()), Some(0.into()));
2006					assert_eq!(b.checked_div(&b), Some($name::one()));
2007				}
2008
2009				assert_eq!(b.checked_div(&2.into()), Some($name::from_inner(inner_min / 2)));
2010				assert_eq!(b.checked_div(&a), Some(0.saturating_sub(1).into()));
2011				assert_eq!(c.checked_div(&1.into()), Some(0.into()));
2012				assert_eq!(d.checked_div(&1.into()), Some(1.into()));
2013
2014				assert_eq!(a.checked_div(&$name::one()), Some(a));
2015				assert_eq!(b.checked_div(&$name::one()), Some(b));
2016				assert_eq!(c.checked_div(&$name::one()), Some(c));
2017				assert_eq!(d.checked_div(&$name::one()), Some(d));
2018
2019				assert_eq!(a.checked_div(&$name::zero()), None);
2020				assert_eq!(b.checked_div(&$name::zero()), None);
2021				assert_eq!(c.checked_div(&$name::zero()), None);
2022				assert_eq!(d.checked_div(&$name::zero()), None);
2023			}
2024
2025			#[test]
2026			fn is_positive_negative_works() {
2027				let one = $name::one();
2028				assert!(one.is_positive());
2029				assert!(!one.is_negative());
2030
2031				let zero = $name::zero();
2032				assert!(!zero.is_positive());
2033				assert!(!zero.is_negative());
2034
2035				if $signed {
2036					let minus_one = $name::saturating_from_integer(-1);
2037					assert!(minus_one.is_negative());
2038					assert!(!minus_one.is_positive());
2039				}
2040			}
2041
2042			#[test]
2043			fn trunc_works() {
2044				let n = $name::saturating_from_rational(5, 2).trunc();
2045				assert_eq!(n, $name::saturating_from_integer(2));
2046
2047				if $name::SIGNED {
2048					let n = $name::saturating_from_rational(-5, 2).trunc();
2049					assert_eq!(n, $name::saturating_from_integer(-2));
2050				}
2051			}
2052
2053			#[test]
2054			fn frac_works() {
2055				let n = $name::saturating_from_rational(5, 2);
2056				let i = n.trunc();
2057				let f = n.frac();
2058
2059				assert_eq!(n, i + f);
2060
2061				let n = $name::saturating_from_rational(5, 2).frac().saturating_mul(10.into());
2062				assert_eq!(n, 5.into());
2063
2064				let n = $name::saturating_from_rational(1, 2).frac().saturating_mul(10.into());
2065				assert_eq!(n, 5.into());
2066
2067				if $name::SIGNED {
2068					let n = $name::saturating_from_rational(-5, 2);
2069					let i = n.trunc();
2070					let f = n.frac();
2071					assert_eq!(n, i - f);
2072
2073					// The sign is attached to the integer part unless it is zero.
2074					let n = $name::saturating_from_rational(-5, 2).frac().saturating_mul(10.into());
2075					assert_eq!(n, 5.into());
2076
2077					let n = $name::saturating_from_rational(-1, 2).frac().saturating_mul(10.into());
2078					assert_eq!(n, 0.saturating_sub(5).into());
2079				}
2080			}
2081
2082			#[test]
2083			fn ceil_works() {
2084				let n = $name::saturating_from_rational(5, 2);
2085				assert_eq!(n.ceil(), 3.into());
2086
2087				let n = $name::saturating_from_rational(-5, 2);
2088				assert_eq!(n.ceil(), 0.saturating_sub(2).into());
2089
2090				// On the limits:
2091				let n = $name::max_value();
2092				assert_eq!(n.ceil(), n.trunc());
2093
2094				let n = $name::min_value();
2095				assert_eq!(n.ceil(), n.trunc());
2096			}
2097
2098			#[test]
2099			fn floor_works() {
2100				let n = $name::saturating_from_rational(5, 2);
2101				assert_eq!(n.floor(), 2.into());
2102
2103				let n = $name::saturating_from_rational(-5, 2);
2104				assert_eq!(n.floor(), 0.saturating_sub(3).into());
2105
2106				// On the limits:
2107				let n = $name::max_value();
2108				assert_eq!(n.floor(), n.trunc());
2109
2110				let n = $name::min_value();
2111				assert_eq!(n.floor(), n.trunc());
2112			}
2113
2114			#[test]
2115			fn round_works() {
2116				let n = $name::zero();
2117				assert_eq!(n.round(), n);
2118
2119				let n = $name::one();
2120				assert_eq!(n.round(), n);
2121
2122				let n = $name::saturating_from_rational(5, 2);
2123				assert_eq!(n.round(), 3.into());
2124
2125				let n = $name::saturating_from_rational(-5, 2);
2126				assert_eq!(n.round(), 0.saturating_sub(3).into());
2127
2128				// Saturating:
2129				let n = $name::max_value();
2130				assert_eq!(n.round(), n.trunc());
2131
2132				let n = $name::min_value();
2133				assert_eq!(n.round(), n.trunc());
2134
2135				// On the limit:
2136
2137				// floor(max - 1) + 0.33..
2138				let n = $name::max_value()
2139					.saturating_sub(1.into())
2140					.trunc()
2141					.saturating_add((1, 3).into());
2142
2143				assert_eq!(n.round(), ($name::max_value() - 1.into()).trunc());
2144
2145				// floor(max - 1) + 0.5
2146				let n = $name::max_value()
2147					.saturating_sub(1.into())
2148					.trunc()
2149					.saturating_add((1, 2).into());
2150
2151				assert_eq!(n.round(), $name::max_value().trunc());
2152
2153				if $name::SIGNED {
2154					// floor(min + 1) - 0.33..
2155					let n = $name::min_value()
2156						.saturating_add(1.into())
2157						.trunc()
2158						.saturating_sub((1, 3).into());
2159
2160					assert_eq!(n.round(), ($name::min_value() + 1.into()).trunc());
2161
2162					// floor(min + 1) - 0.5
2163					let n = $name::min_value()
2164						.saturating_add(1.into())
2165						.trunc()
2166						.saturating_sub((1, 2).into());
2167
2168					assert_eq!(n.round(), $name::min_value().trunc());
2169				}
2170			}
2171
2172			#[test]
2173			fn perthing_into_works() {
2174				let ten_percent_percent: $name = Percent::from_percent(10).into();
2175				assert_eq!(ten_percent_percent.into_inner(), $name::accuracy() / 10);
2176
2177				let ten_percent_permill: $name = Permill::from_percent(10).into();
2178				assert_eq!(ten_percent_permill.into_inner(), $name::accuracy() / 10);
2179
2180				let ten_percent_perbill: $name = Perbill::from_percent(10).into();
2181				assert_eq!(ten_percent_perbill.into_inner(), $name::accuracy() / 10);
2182
2183				let ten_percent_perquintill: $name = Perquintill::from_percent(10).into();
2184				assert_eq!(ten_percent_perquintill.into_inner(), $name::accuracy() / 10);
2185			}
2186
2187			#[test]
2188			fn fmt_should_work() {
2189				let zero = $name::zero();
2190				assert_eq!(
2191					format!("{:?}", zero),
2192					format!("{}(0.{:0>weight$})", stringify!($name), 0, weight = precision())
2193				);
2194
2195				let one = $name::one();
2196				assert_eq!(
2197					format!("{:?}", one),
2198					format!("{}(1.{:0>weight$})", stringify!($name), 0, weight = precision())
2199				);
2200
2201				let frac = $name::saturating_from_rational(1, 2);
2202				assert_eq!(
2203					format!("{:?}", frac),
2204					format!("{}(0.{:0<weight$})", stringify!($name), 5, weight = precision())
2205				);
2206
2207				let frac = $name::saturating_from_rational(5, 2);
2208				assert_eq!(
2209					format!("{:?}", frac),
2210					format!("{}(2.{:0<weight$})", stringify!($name), 5, weight = precision())
2211				);
2212
2213				let frac = $name::saturating_from_rational(314, 100);
2214				assert_eq!(
2215					format!("{:?}", frac),
2216					format!("{}(3.{:0<weight$})", stringify!($name), 14, weight = precision())
2217				);
2218
2219				if $name::SIGNED {
2220					let neg = -$name::one();
2221					assert_eq!(
2222						format!("{:?}", neg),
2223						format!("{}(-1.{:0>weight$})", stringify!($name), 0, weight = precision())
2224					);
2225
2226					let frac = $name::saturating_from_rational(-314, 100);
2227					assert_eq!(
2228						format!("{:?}", frac),
2229						format!("{}(-3.{:0<weight$})", stringify!($name), 14, weight = precision())
2230					);
2231				}
2232			}
2233		}
2234	};
2235}
2236
2237implement_fixed!(
2238	FixedI64,
2239	test_fixed_i64,
2240	i64,
2241	true,
2242	1_000_000_000,
2243	"_Fixed Point 64 bits signed, range = [-9223372036.854775808, 9223372036.854775807]_",
2244);
2245
2246implement_fixed!(
2247	FixedU64,
2248	test_fixed_u64,
2249	u64,
2250	false,
2251	1_000_000_000,
2252	"_Fixed Point 64 bits unsigned, range = [0.000000000, 18446744073.709551615]_",
2253);
2254
2255implement_fixed!(
2256	FixedI128,
2257	test_fixed_i128,
2258	i128,
2259	true,
2260	1_000_000_000_000_000_000,
2261	"_Fixed Point 128 bits signed, range = \
2262		[-170141183460469231731.687303715884105728, 170141183460469231731.687303715884105727]_",
2263);
2264
2265implement_fixed!(
2266	FixedU128,
2267	test_fixed_u128,
2268	u128,
2269	false,
2270	1_000_000_000_000_000_000,
2271	"_Fixed Point 128 bits unsigned, range = \
2272		[0.000000000000000000, 340282366920938463463.374607431768211455]_",
2273);