referrerpolicy=no-referrer-when-downgrade

sp_arithmetic/
fixed_point.rs

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