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