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