arithmetic/
fixed_point.rs

1// This file is part of Tetcore.
2
3// Copyright (C) 2019-2021 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 Tetcore runtime.
19
20use tetcore_std::{ops::{self, Add, Sub, Mul, Div}, fmt::Debug, prelude::*, convert::{TryInto, TryFrom}};
21use codec::{Encode, Decode, CompactAs};
22use crate::{
23	helpers_128bit::multiply_by_rational, PerThing,
24	traits::{
25		SaturatedConversion, CheckedSub, CheckedAdd, CheckedMul, CheckedDiv, CheckedNeg,
26		Bounded, Saturating, UniqueSaturatedInto, Zero, One
27	},
28};
29
30#[cfg(feature = "std")]
31use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
32
33/// Integer types that can be used to interact with `FixedPointNumber` implementations.
34pub trait FixedPointOperand: Copy + Clone + Bounded + Zero + Saturating
35	+ PartialOrd + UniqueSaturatedInto<u128> + TryFrom<u128> + CheckedNeg {}
36
37impl FixedPointOperand for i128 {}
38impl FixedPointOperand for u128 {}
39impl FixedPointOperand for i64 {}
40impl FixedPointOperand for u64 {}
41impl FixedPointOperand for i32 {}
42impl FixedPointOperand for u32 {}
43impl FixedPointOperand for i16 {}
44impl FixedPointOperand for u16 {}
45impl FixedPointOperand for i8 {}
46impl FixedPointOperand for u8 {}
47
48/// Something that implements a decimal fixed point number.
49///
50/// The precision is given by `Self::DIV`, i.e. `1 / DIV` can be represented.
51///
52/// Each type can store numbers from `Self::Inner::min_value() / Self::DIV`
53/// to `Self::Inner::max_value() / Self::DIV`.
54/// This is also referred to as the _accuracy_ of the type in the documentation.
55pub trait FixedPointNumber:
56	Sized + Copy + Default + Debug
57	+ Saturating + Bounded
58	+ Eq + PartialEq + Ord + PartialOrd
59	+ CheckedSub + CheckedAdd + CheckedMul + CheckedDiv
60	+ Add + Sub + Div + Mul
61{
62	/// The underlying data type used for this fixed point number.
63	type Inner: Debug + One + CheckedMul + CheckedDiv + FixedPointOperand;
64
65	/// Precision of this fixed point implementation. It should be a power of `10`.
66	const DIV: Self::Inner;
67
68	/// Indicates if this fixed point implementation is signed or not.
69	const SIGNED: bool;
70
71	/// Precision of this fixed point implementation.
72	fn accuracy() -> Self::Inner {
73		Self::DIV
74	}
75
76	/// Builds this type from an integer number.
77	fn from_inner(int: Self::Inner) -> Self;
78
79	/// Consumes `self` and returns the inner raw value.
80	fn into_inner(self) -> Self::Inner;
81
82	/// Creates self from an integer number `int`.
83	///
84	/// Returns `Self::max` or `Self::min` if `int` exceeds accuracy.
85	fn saturating_from_integer<N: FixedPointOperand>(int: N) -> Self {
86		let mut n: I129 = int.into();
87		n.value = n.value.saturating_mul(Self::DIV.saturated_into());
88		Self::from_inner(from_i129(n).unwrap_or_else(|| to_bound(int, 0)))
89	}
90
91	/// Creates `self` from an integer number `int`.
92	///
93	/// Returns `None` if `int` exceeds accuracy.
94	fn checked_from_integer(int: Self::Inner) -> Option<Self> {
95		int.checked_mul(&Self::DIV).map(|inner| Self::from_inner(inner))
96	}
97
98	/// Creates `self` from a rational number. Equal to `n / d`.
99	///
100	/// Panics if `d = 0`. Returns `Self::max` or `Self::min` if `n / d` exceeds accuracy.
101	fn saturating_from_rational<N: FixedPointOperand, D: FixedPointOperand>(n: N, d: D) -> Self {
102		if d == D::zero() {
103			panic!("attempt to divide by zero")
104		}
105		Self::checked_from_rational(n, d).unwrap_or_else(|| to_bound(n, d))
106	}
107
108	/// Creates `self` from a rational number. Equal to `n / d`.
109	///
110	/// Returns `None` if `d == 0` or `n / d` exceeds accuracy.
111	fn checked_from_rational<N: FixedPointOperand, D: FixedPointOperand>(n: N, d: D) -> Option<Self> {
112		if d == D::zero() {
113			return None
114		}
115
116		let n: I129 = n.into();
117		let d: I129 = d.into();
118		let negative = n.negative != d.negative;
119
120		multiply_by_rational(n.value, Self::DIV.unique_saturated_into(), d.value).ok()
121			.and_then(|value| from_i129(I129 { value, negative }))
122			.map(|inner| Self::from_inner(inner))
123	}
124
125	/// Checked multiplication for integer type `N`. Equal to `self * n`.
126	///
127	/// Returns `None` if the result does not fit in `N`.
128	fn checked_mul_int<N: FixedPointOperand>(self, n: N) -> Option<N> {
129		let lhs: I129 = self.into_inner().into();
130		let rhs: I129 = n.into();
131		let negative = lhs.negative != rhs.negative;
132
133		multiply_by_rational(lhs.value, rhs.value, Self::DIV.unique_saturated_into()).ok()
134			.and_then(|value| from_i129(I129 { value, negative }))
135	}
136
137	/// Saturating multiplication for integer type `N`. Equal to `self * n`.
138	///
139	/// Returns `N::min` or `N::max` if the result does not fit in `N`.
140	fn saturating_mul_int<N: FixedPointOperand>(self, n: N) -> N {
141		self.checked_mul_int(n).unwrap_or_else(|| to_bound(self.into_inner(), n))
142	}
143
144	/// Checked division for integer type `N`. Equal to `self / d`.
145	///
146	/// Returns `None` if the result does not fit in `N` or `d == 0`.
147	fn checked_div_int<N: FixedPointOperand>(self, d: N) -> Option<N> {
148		let lhs: I129 = self.into_inner().into();
149		let rhs: I129 = d.into();
150		let negative = lhs.negative != rhs.negative;
151
152		lhs.value.checked_div(rhs.value)
153			.and_then(|n| n.checked_div(Self::DIV.unique_saturated_into()))
154			.and_then(|value| from_i129(I129 { value, negative }))
155	}
156
157	/// Saturating division for integer type `N`. Equal to `self / d`.
158	///
159	/// Panics if `d == 0`. Returns `N::min` or `N::max` if the result does not fit in `N`.
160	fn saturating_div_int<N: FixedPointOperand>(self, d: N) -> N {
161		if d == N::zero() {
162			panic!("attempt to divide by zero")
163		}
164		self.checked_div_int(d).unwrap_or_else(|| to_bound(self.into_inner(), d))
165	}
166
167	/// Saturating multiplication for integer type `N`, adding the result back.
168	/// Equal to `self * n + n`.
169	///
170	/// Returns `N::min` or `N::max` if the multiplication or final result does not fit in `N`.
171	fn saturating_mul_acc_int<N: FixedPointOperand>(self, n: N) -> N {
172		if self.is_negative() && n > N::zero() {
173			n.saturating_sub(Self::zero().saturating_sub(self).saturating_mul_int(n))
174		} else {
175			self.saturating_mul_int(n).saturating_add(n)
176		}
177	}
178
179	/// Saturating absolute value.
180	///
181	/// Returns `Self::max` if `self == Self::min`.
182	fn saturating_abs(self) -> Self {
183		let inner = self.into_inner();
184		if inner >= Self::Inner::zero() {
185			self
186		} else {
187			Self::from_inner(inner.checked_neg().unwrap_or_else(|| Self::Inner::max_value()))
188		}
189	}
190
191	/// Takes the reciprocal (inverse). Equal to `1 / self`.
192	///
193	/// Returns `None` if `self = 0`.
194	fn reciprocal(self) -> Option<Self> {
195		Self::one().checked_div(&self)
196	}
197
198	/// Returns zero.
199	fn zero() -> Self {
200		Self::from_inner(Self::Inner::zero())
201	}
202
203	/// Checks if the number is zero.
204	fn is_zero(&self) -> bool {
205		self.into_inner() == Self::Inner::zero()
206	}
207
208	/// Returns one.
209	fn one() -> Self {
210		Self::from_inner(Self::DIV)
211	}
212
213	/// Checks if the number is one.
214	fn is_one(&self) -> bool {
215		self.into_inner() == Self::Inner::one()
216	}
217
218	/// Returns `true` if `self` is positive and `false` if the number is zero or negative.
219	fn is_positive(self) -> bool {
220		self.into_inner() > Self::Inner::zero()
221	}
222
223	/// Returns `true` if `self` is negative and `false` if the number is zero or positive.
224	fn is_negative(self) -> bool {
225		self.into_inner() < Self::Inner::zero()
226	}
227
228	/// Returns the integer part.
229	fn trunc(self) -> Self {
230		self.into_inner().checked_div(&Self::DIV)
231			.expect("panics only if DIV is zero, DIV is not zero; qed")
232			.checked_mul(&Self::DIV)
233			.map(|inner| Self::from_inner(inner))
234			.expect("can not overflow since fixed number is >= integer part")
235	}
236
237	/// Returns the fractional part.
238	///
239	/// Note: the returned fraction will be non-negative for negative numbers,
240	/// except in the case where the integer part is zero.
241	fn frac(self) -> Self {
242		let integer = self.trunc();
243		let fractional = self.saturating_sub(integer);
244		if integer == Self::zero() {
245			fractional
246		} else {
247			fractional.saturating_abs()
248		}
249	}
250
251	/// Returns the smallest integer greater than or equal to a number.
252	///
253	/// Saturates to `Self::max` (truncated) if the result does not fit.
254	fn ceil(self) -> Self {
255		if self.is_negative() {
256			self.trunc()
257		} else {
258			if self.frac() == Self::zero() {
259				self
260			} else {
261				self.saturating_add(Self::one()).trunc()
262			}
263		}
264	}
265
266	/// Returns the largest integer less than or equal to a number.
267	///
268	/// Saturates to `Self::min` (truncated) if the result does not fit.
269	fn floor(self) -> Self {
270		if self.is_negative() {
271			self.saturating_sub(Self::one()).trunc()
272		} else {
273			self.trunc()
274		}
275	}
276
277	/// Returns the number rounded to the nearest integer. Rounds half-way cases away from 0.0.
278	///
279	/// Saturates to `Self::min` or `Self::max` (truncated) if the result does not fit.
280	fn round(self) -> Self {
281		let n = self.frac().saturating_mul(Self::saturating_from_integer(10));
282		if n < Self::saturating_from_integer(5) {
283			self.trunc()
284		} else {
285			if self.is_positive() {
286				self.saturating_add(Self::one()).trunc()
287			} else {
288				self.saturating_sub(Self::one()).trunc()
289			}
290		}
291	}
292}
293
294/// Data type used as intermediate storage in some computations to avoid overflow.
295struct I129 {
296	value: u128,
297	negative: bool,
298}
299
300impl<N: FixedPointOperand> From<N> for I129 {
301	fn from(n: N) -> I129 {
302		if n < N::zero() {
303			let value: u128 = n.checked_neg()
304				.map(|n| n.unique_saturated_into())
305				.unwrap_or_else(|| N::max_value().unique_saturated_into().saturating_add(1));
306			I129 { value, negative: true }
307		} else {
308			I129 { value: n.unique_saturated_into(), negative: false }
309		}
310	}
311}
312
313/// Transforms an `I129` to `N` if it is possible.
314fn from_i129<N: FixedPointOperand>(n: I129) -> Option<N> {
315	let max_plus_one: u128 = N::max_value().unique_saturated_into().saturating_add(1);
316	if n.negative && N::min_value() < N::zero() && n.value == max_plus_one {
317		Some(N::min_value())
318	} else {
319		let unsigned_inner: N = n.value.try_into().ok()?;
320		let inner = if n.negative { unsigned_inner.checked_neg()? } else { unsigned_inner };
321		Some(inner)
322	}
323}
324
325/// Returns `R::max` if the sign of `n * m` is positive, `R::min` otherwise.
326fn to_bound<N: FixedPointOperand, D: FixedPointOperand, R: Bounded>(n: N, m: D) -> R {
327	if (n < N::zero()) != (m < D::zero()) {
328		R::min_value()
329	} else {
330		R::max_value()
331	}
332}
333
334macro_rules! implement_fixed {
335	(
336		$name:ident,
337		$test_mod:ident,
338		$inner_type:ty,
339		$signed:tt,
340		$div:tt,
341		$title:expr $(,)?
342	) => {
343		/// A fixed point number representation in the range.
344		///
345		#[doc = $title]
346		#[derive(Encode, Decode, CompactAs, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
347		pub struct $name($inner_type);
348
349		impl From<$inner_type> for $name {
350			fn from(int: $inner_type) -> Self {
351				$name::saturating_from_integer(int)
352			}
353		}
354
355		impl<N: FixedPointOperand, D: FixedPointOperand> From<(N, D)> for $name {
356			fn from(r: (N, D)) -> Self {
357				$name::saturating_from_rational(r.0, r.1)
358			}
359		}
360
361		impl FixedPointNumber for $name {
362			type Inner = $inner_type;
363
364			const DIV: Self::Inner = $div;
365			const SIGNED: bool = $signed;
366
367			fn from_inner(inner: Self::Inner) -> Self {
368				Self(inner)
369			}
370
371			fn into_inner(self) -> Self::Inner {
372				self.0
373			}
374		}
375
376		impl $name {
377			/// const version of `FixedPointNumber::from_inner`.
378			pub const fn from_inner(inner: $inner_type) -> Self {
379				Self(inner)
380			}
381
382			#[cfg(any(feature = "std", test))]
383			pub fn from_fraction(x: f64) -> Self {
384				Self((x * (<Self as FixedPointNumber>::DIV as f64)) as $inner_type)
385			}
386
387			#[cfg(any(feature = "std", test))]
388			pub fn to_fraction(self) -> f64 {
389				self.0 as f64 / <Self as FixedPointNumber>::DIV as f64
390			}
391		}
392
393		impl Saturating for $name {
394			fn saturating_add(self, rhs: Self) -> Self {
395				Self(self.0.saturating_add(rhs.0))
396			}
397
398			fn saturating_sub(self, rhs: Self) -> Self {
399				Self(self.0.saturating_sub(rhs.0))
400			}
401
402			fn saturating_mul(self, rhs: Self) -> Self {
403				self.checked_mul(&rhs).unwrap_or_else(|| to_bound(self.0, rhs.0))
404			}
405
406			fn saturating_pow(self, exp: usize) -> Self {
407				if exp == 0 {
408					return Self::saturating_from_integer(1);
409				}
410
411				let exp = exp as u32;
412				let msb_pos = 32 - exp.leading_zeros();
413
414				let mut result = Self::saturating_from_integer(1);
415				let mut pow_val = self;
416				for i in 0..msb_pos {
417					if ((1 << i) & exp) > 0 {
418						result = result.saturating_mul(pow_val);
419					}
420					pow_val = pow_val.saturating_mul(pow_val);
421				}
422				result
423			}
424		}
425
426		impl ops::Neg for $name {
427			type Output = Self;
428
429			fn neg(self) -> Self::Output {
430				Self(<Self as FixedPointNumber>::Inner::zero() - self.0)
431			}
432		}
433
434		impl ops::Add for $name {
435			type Output = Self;
436
437			fn add(self, rhs: Self) -> Self::Output {
438				Self(self.0 + rhs.0)
439			}
440		}
441
442		impl ops::Sub for $name {
443			type Output = Self;
444
445			fn sub(self, rhs: Self) -> Self::Output {
446				Self(self.0 - rhs.0)
447			}
448		}
449
450		impl ops::Mul for $name {
451			type Output = Self;
452
453			fn mul(self, rhs: Self) -> Self::Output {
454				self.checked_mul(&rhs)
455					.unwrap_or_else(|| panic!("attempt to multiply with overflow"))
456			}
457		}
458
459		impl ops::Div for $name {
460			type Output = Self;
461
462			fn div(self, rhs: Self) -> Self::Output {
463				if rhs.0 == 0 {
464					panic!("attempt to divide by zero")
465				}
466				self.checked_div(&rhs)
467					.unwrap_or_else(|| panic!("attempt to divide with overflow"))
468			}
469		}
470
471		impl CheckedSub for $name {
472			fn checked_sub(&self, rhs: &Self) -> Option<Self> {
473				self.0.checked_sub(rhs.0).map(Self)
474			}
475		}
476
477		impl CheckedAdd for $name {
478			fn checked_add(&self, rhs: &Self) -> Option<Self> {
479				self.0.checked_add(rhs.0).map(Self)
480			}
481		}
482
483		impl CheckedDiv for $name {
484			fn checked_div(&self, other: &Self) -> Option<Self> {
485				if other.0 == 0 {
486					return None
487				}
488
489				let lhs: I129 = self.0.into();
490				let rhs: I129 = other.0.into();
491				let negative = lhs.negative != rhs.negative;
492
493				multiply_by_rational(lhs.value, Self::DIV as u128, rhs.value).ok()
494					.and_then(|value| from_i129(I129 { value, negative }))
495					.map(Self)
496			}
497		}
498
499		impl CheckedMul for $name {
500			fn checked_mul(&self, other: &Self) -> Option<Self> {
501				let lhs: I129 = self.0.into();
502				let rhs: I129 = other.0.into();
503				let negative = lhs.negative != rhs.negative;
504
505				multiply_by_rational(lhs.value, rhs.value, Self::DIV as u128).ok()
506					.and_then(|value| from_i129(I129 { value, negative }))
507					.map(Self)
508			}
509		}
510
511		impl Bounded for $name {
512			fn min_value() -> Self {
513				Self(<Self as FixedPointNumber>::Inner::min_value())
514			}
515
516			fn max_value() -> Self {
517				Self(<Self as FixedPointNumber>::Inner::max_value())
518			}
519		}
520
521		impl tetcore_std::fmt::Debug for $name {
522			#[cfg(feature = "std")]
523			fn fmt(&self, f: &mut tetcore_std::fmt::Formatter) -> tetcore_std::fmt::Result {
524				let integral = {
525					let int = self.0 / Self::accuracy();
526					let signum_for_zero = if int == 0 && self.is_negative() { "-" } else { "" };
527					format!("{}{}", signum_for_zero, int)
528				};
529				let precision = (Self::accuracy() as f64).log10() as usize;
530				let fractional = format!("{:0>weight$}", ((self.0 % Self::accuracy()) as i128).abs(), weight=precision);
531				write!(f, "{}({}.{})", stringify!($name), integral, fractional)
532			}
533
534			#[cfg(not(feature = "std"))]
535			fn fmt(&self, _: &mut tetcore_std::fmt::Formatter) -> tetcore_std::fmt::Result {
536				Ok(())
537			}
538		}
539
540		impl<P: PerThing> From<P> for $name where P::Inner: FixedPointOperand {
541			fn from(p: P) -> Self {
542				let accuracy = P::ACCURACY;
543				let value = p.deconstruct();
544				$name::saturating_from_rational(value, accuracy)
545			}
546		}
547
548		#[cfg(feature = "std")]
549		impl tetcore_std::fmt::Display for $name {
550			fn fmt(&self, f: &mut tetcore_std::fmt::Formatter) -> tetcore_std::fmt::Result {
551				write!(f, "{}", self.0)
552			}
553		}
554
555		#[cfg(feature = "std")]
556		impl tetcore_std::str::FromStr for $name {
557			type Err = &'static str;
558
559			fn from_str(s: &str) -> Result<Self, Self::Err> {
560				let inner: <Self as FixedPointNumber>::Inner = s.parse()
561					.map_err(|_| "invalid string input for fixed point number")?;
562				Ok(Self::from_inner(inner))
563			}
564		}
565
566		// Manual impl `Serialize` as serde_json does not support i128.
567		// TODO: remove impl if issue https://github.com/serde-rs/json/issues/548 fixed.
568		#[cfg(feature = "std")]
569		impl Serialize for $name {
570			fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
571			where
572				S: Serializer,
573			{
574				serializer.serialize_str(&self.to_string())
575			}
576		}
577
578		// Manual impl `Deserialize` as serde_json does not support i128.
579		// TODO: remove impl if issue https://github.com/serde-rs/json/issues/548 fixed.
580		#[cfg(feature = "std")]
581		impl<'de> Deserialize<'de> for $name {
582			fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
583			where
584				D: Deserializer<'de>,
585			{
586				use tetcore_std::str::FromStr;
587				let s = String::deserialize(deserializer)?;
588				$name::from_str(&s).map_err(|err_str| de::Error::custom(err_str))
589			}
590		}
591
592		#[cfg(test)]
593		mod $test_mod {
594			use super::*;
595			use crate::{Perbill, Percent, Permill, Perquintill};
596
597			fn max() -> $name {
598				$name::max_value()
599			}
600
601			fn min() -> $name {
602				$name::min_value()
603			}
604
605			fn precision() -> usize {
606				($name::accuracy() as f64).log10() as usize
607			}
608
609			#[test]
610			fn macro_preconditions() {
611				assert!($name::DIV > 0);
612			}
613
614			#[test]
615			fn from_i129_works() {
616				let a = I129 {
617					value: 1,
618					negative: true,
619				};
620
621				// Can't convert negative number to unsigned.
622				assert_eq!(from_i129::<u128>(a), None);
623
624				let a = I129 {
625					value: u128::max_value() - 1,
626					negative: false,
627				};
628
629				// Max - 1 value fits.
630				assert_eq!(from_i129::<u128>(a), Some(u128::max_value() - 1));
631
632				let a = I129 {
633					value: u128::max_value(),
634					negative: false,
635				};
636
637				// Max value fits.
638				assert_eq!(from_i129::<u128>(a), Some(u128::max_value()));
639
640				let a = I129 {
641					value: i128::max_value() as u128 + 1,
642					negative: true,
643				};
644
645				// Min value fits.
646				assert_eq!(from_i129::<i128>(a), Some(i128::min_value()));
647
648				let a = I129 {
649					value: i128::max_value() as u128 + 1,
650					negative: false,
651				};
652
653				// Max + 1 does not fit.
654				assert_eq!(from_i129::<i128>(a), None);
655
656				let a = I129 {
657					value: i128::max_value() as u128,
658					negative: false,
659				};
660
661				// Max value fits.
662				assert_eq!(from_i129::<i128>(a), Some(i128::max_value()));
663			}
664
665			#[test]
666			fn to_bound_works() {
667				let a = 1i32;
668				let b = 1i32;
669
670				// Pos + Pos => Max.
671				assert_eq!(to_bound::<_, _, i32>(a, b), i32::max_value());
672
673				let a = -1i32;
674				let b = -1i32;
675
676				// Neg + Neg => Max.
677				assert_eq!(to_bound::<_, _, i32>(a, b), i32::max_value());
678
679				let a = 1i32;
680				let b = -1i32;
681
682				// Pos + Neg => Min.
683				assert_eq!(to_bound::<_, _, i32>(a, b), i32::min_value());
684
685				let a = -1i32;
686				let b = 1i32;
687
688				// Neg + Pos => Min.
689				assert_eq!(to_bound::<_, _, i32>(a, b), i32::min_value());
690
691				let a = 1i32;
692				let b = -1i32;
693
694				// Pos + Neg => Min (unsigned).
695				assert_eq!(to_bound::<_, _, u32>(a, b), 0);
696			}
697
698			#[test]
699			fn op_neg_works() {
700				let a = $name::zero();
701				let b = -a;
702
703				// Zero.
704				assert_eq!(a, b);
705
706				if $name::SIGNED {
707					let a = $name::saturating_from_integer(5);
708					let b = -a;
709
710					// Positive.
711					assert_eq!($name::saturating_from_integer(-5), b);
712
713					let a = $name::saturating_from_integer(-5);
714					let b = -a;
715
716					// Negative
717					assert_eq!($name::saturating_from_integer(5), b);
718
719					let a = $name::max_value();
720					let b = -a;
721
722					// Max.
723					assert_eq!($name::min_value() + $name::from_inner(1), b);
724
725					let a = $name::min_value() + $name::from_inner(1);
726					let b = -a;
727
728					// Min.
729					assert_eq!($name::max_value(), b);
730
731				}
732			}
733
734			#[test]
735			fn op_checked_add_overflow_works() {
736				let a = $name::max_value();
737				let b = 1.into();
738				assert!(a.checked_add(&b).is_none());
739			}
740
741			#[test]
742			fn op_add_works() {
743				let a = $name::saturating_from_rational(5, 2);
744				let b = $name::saturating_from_rational(1, 2);
745
746				// Positive case: 6/2 = 3.
747				assert_eq!($name::saturating_from_integer(3), a + b);
748
749				if $name::SIGNED {
750					// Negative case: 4/2 = 2.
751					let b = $name::saturating_from_rational(1, -2);
752					assert_eq!($name::saturating_from_integer(2), a + b);
753				}
754			}
755
756			#[test]
757			fn op_checked_sub_underflow_works() {
758				let a = $name::min_value();
759				let b = 1.into();
760				assert!(a.checked_sub(&b).is_none());
761			}
762
763			#[test]
764			fn op_sub_works() {
765				let a = $name::saturating_from_rational(5, 2);
766				let b = $name::saturating_from_rational(1, 2);
767
768				assert_eq!($name::saturating_from_integer(2), a - b);
769				assert_eq!($name::saturating_from_integer(-2), b.saturating_sub(a));
770			}
771
772			#[test]
773			fn op_checked_mul_overflow_works() {
774				let a = $name::max_value();
775				let b = 2.into();
776				assert!(a.checked_mul(&b).is_none());
777			}
778
779			#[test]
780			fn op_mul_works() {
781				let a = $name::saturating_from_integer(42);
782				let b = $name::saturating_from_integer(2);
783				assert_eq!($name::saturating_from_integer(84), a * b);
784
785				let a = $name::saturating_from_integer(42);
786				let b = $name::saturating_from_integer(-2);
787				assert_eq!($name::saturating_from_integer(-84), a * b);
788			}
789
790			#[test]
791			#[should_panic(expected = "attempt to divide by zero")]
792			fn op_div_panics_on_zero_divisor() {
793				let a = $name::saturating_from_integer(1);
794				let b = 0.into();
795				let _c = a / b;
796			}
797
798			#[test]
799			fn op_checked_div_overflow_works() {
800				if $name::SIGNED {
801					let a = $name::min_value();
802					let b = $name::zero().saturating_sub($name::one());
803					assert!(a.checked_div(&b).is_none());
804				}
805			}
806
807			#[test]
808			fn op_div_works() {
809				let a = $name::saturating_from_integer(42);
810				let b = $name::saturating_from_integer(2);
811				assert_eq!($name::saturating_from_integer(21), a / b);
812
813				if $name::SIGNED {
814					let a = $name::saturating_from_integer(42);
815					let b = $name::saturating_from_integer(-2);
816					assert_eq!($name::saturating_from_integer(-21), a / b);
817				}
818			}
819
820			#[test]
821			fn saturating_from_integer_works() {
822				let inner_max = <$name as FixedPointNumber>::Inner::max_value();
823				let inner_min = <$name as FixedPointNumber>::Inner::min_value();
824				let accuracy = $name::accuracy();
825
826				// Cases where integer fits.
827				let a = $name::saturating_from_integer(42);
828				assert_eq!(a.into_inner(), 42 * accuracy);
829
830				let a = $name::saturating_from_integer(-42);
831				assert_eq!(a.into_inner(), 0.saturating_sub(42 * accuracy));
832
833				// Max/min integers that fit.
834				let a = $name::saturating_from_integer(inner_max / accuracy);
835				assert_eq!(a.into_inner(), (inner_max / accuracy) * accuracy);
836
837				let a = $name::saturating_from_integer(inner_min / accuracy);
838				assert_eq!(a.into_inner(), (inner_min / accuracy) * accuracy);
839
840				// Cases where integer doesn't fit, so it saturates.
841				let a = $name::saturating_from_integer(inner_max / accuracy + 1);
842				assert_eq!(a.into_inner(), inner_max);
843
844				let a = $name::saturating_from_integer((inner_min / accuracy).saturating_sub(1));
845				assert_eq!(a.into_inner(), inner_min);
846			}
847
848			#[test]
849			fn checked_from_integer_works() {
850				let inner_max = <$name as FixedPointNumber>::Inner::max_value();
851				let inner_min = <$name as FixedPointNumber>::Inner::min_value();
852				let accuracy = $name::accuracy();
853
854				// Case where integer fits.
855				let a = $name::checked_from_integer(42)
856					.expect("42 * accuracy <= inner_max; qed");
857				assert_eq!(a.into_inner(), 42 * accuracy);
858
859				// Max integer that fit.
860				let a = $name::checked_from_integer(inner_max / accuracy)
861					.expect("(inner_max / accuracy) * accuracy <= inner_max; qed");
862				assert_eq!(a.into_inner(), (inner_max / accuracy) * accuracy);
863
864				// Case where integer doesn't fit, so it returns `None`.
865				let a = $name::checked_from_integer(inner_max / accuracy + 1);
866				assert_eq!(a, None);
867
868				if $name::SIGNED {
869					// Case where integer fits.
870					let a = $name::checked_from_integer(0.saturating_sub(42))
871						.expect("-42 * accuracy >= inner_min; qed");
872					assert_eq!(a.into_inner(), 0 - 42 * accuracy);
873
874					// Min integer that fit.
875					let a = $name::checked_from_integer(inner_min / accuracy)
876						.expect("(inner_min / accuracy) * accuracy <= inner_min; qed");
877					assert_eq!(a.into_inner(), (inner_min / accuracy) * accuracy);
878
879					// Case where integer doesn't fit, so it returns `None`.
880					let a = $name::checked_from_integer(inner_min / accuracy - 1);
881					assert_eq!(a, None);
882				}
883			}
884
885			#[test]
886			fn from_inner_works() {
887				let inner_max = <$name as FixedPointNumber>::Inner::max_value();
888				let inner_min = <$name as FixedPointNumber>::Inner::min_value();
889
890				assert_eq!(max(), $name::from_inner(inner_max));
891				assert_eq!(min(), $name::from_inner(inner_min));
892			}
893
894			#[test]
895			#[should_panic(expected = "attempt to divide by zero")]
896			fn saturating_from_rational_panics_on_zero_divisor() {
897				let _ = $name::saturating_from_rational(1, 0);
898			}
899
900			#[test]
901			fn saturating_from_rational_works() {
902				let inner_max = <$name as FixedPointNumber>::Inner::max_value();
903				let inner_min = <$name as FixedPointNumber>::Inner::min_value();
904				let accuracy = $name::accuracy();
905
906				let a = $name::saturating_from_rational(5, 2);
907
908				// Positive case: 2.5
909				assert_eq!(a.into_inner(), 25 * accuracy / 10);
910
911				// Max - 1.
912				let a = $name::saturating_from_rational(inner_max - 1, accuracy);
913				assert_eq!(a.into_inner(), inner_max - 1);
914
915				// Min + 1.
916				let a = $name::saturating_from_rational(inner_min + 1, accuracy);
917				assert_eq!(a.into_inner(), inner_min + 1);
918
919				// Max.
920				let a = $name::saturating_from_rational(inner_max, accuracy);
921				assert_eq!(a.into_inner(), inner_max);
922
923				// Min.
924				let a = $name::saturating_from_rational(inner_min, accuracy);
925				assert_eq!(a.into_inner(), inner_min);
926
927				// Zero.
928				let a = $name::saturating_from_rational(0, 1);
929				assert_eq!(a.into_inner(), 0);
930
931				if $name::SIGNED {
932					// Negative case: -2.5
933					let a = $name::saturating_from_rational(-5, 2);
934					assert_eq!(a.into_inner(),  0 - 25 * accuracy / 10);
935
936					// Other negative case: -2.5
937					let a = $name::saturating_from_rational(5, -2);
938					assert_eq!(a.into_inner(), 0 - 25 * accuracy / 10);
939
940					// Other positive case: 2.5
941					let a = $name::saturating_from_rational(-5, -2);
942					assert_eq!(a.into_inner(), 25 * accuracy / 10);
943
944					// Max + 1, saturates.
945					let a = $name::saturating_from_rational(inner_max as u128 + 1, accuracy);
946					assert_eq!(a.into_inner(), inner_max);
947
948					// Min - 1, saturates.
949					let a = $name::saturating_from_rational(inner_max as u128 + 2, 0 - accuracy);
950					assert_eq!(a.into_inner(), inner_min);
951
952					let a = $name::saturating_from_rational(inner_max, 0 - accuracy);
953					assert_eq!(a.into_inner(), 0 - inner_max);
954
955					let a = $name::saturating_from_rational(inner_min, 0 - accuracy);
956					assert_eq!(a.into_inner(), inner_max);
957
958					let a = $name::saturating_from_rational(inner_min + 1, 0 - accuracy);
959					assert_eq!(a.into_inner(), inner_max);
960
961					let a = $name::saturating_from_rational(inner_min, 0 - 1);
962					assert_eq!(a.into_inner(), inner_max);
963
964					let a = $name::saturating_from_rational(inner_max, 0 - 1);
965					assert_eq!(a.into_inner(), inner_min);
966
967					let a = $name::saturating_from_rational(inner_max, 0 - inner_max);
968					assert_eq!(a.into_inner(), 0 - accuracy);
969
970					let a = $name::saturating_from_rational(0 - inner_max, inner_max);
971					assert_eq!(a.into_inner(), 0 - accuracy);
972
973					let a = $name::saturating_from_rational(inner_max, 0 - 3 * accuracy);
974					assert_eq!(a.into_inner(), 0 - inner_max / 3);
975
976					let a = $name::saturating_from_rational(inner_min, 0 - accuracy / 3);
977					assert_eq!(a.into_inner(), inner_max);
978
979					let a = $name::saturating_from_rational(1, 0 - accuracy);
980					assert_eq!(a.into_inner(), 0.saturating_sub(1));
981
982					let a = $name::saturating_from_rational(inner_min, inner_min);
983					assert_eq!(a.into_inner(), accuracy);
984
985					// Out of accuracy.
986					let a = $name::saturating_from_rational(1, 0 - accuracy - 1);
987					assert_eq!(a.into_inner(), 0);
988				}
989
990				let a = $name::saturating_from_rational(inner_max - 1, accuracy);
991				assert_eq!(a.into_inner(), inner_max - 1);
992
993				let a = $name::saturating_from_rational(inner_min + 1, accuracy);
994				assert_eq!(a.into_inner(), inner_min + 1);
995
996				let a = $name::saturating_from_rational(inner_max, 1);
997				assert_eq!(a.into_inner(), inner_max);
998
999				let a = $name::saturating_from_rational(inner_min, 1);
1000				assert_eq!(a.into_inner(), inner_min);
1001
1002				let a = $name::saturating_from_rational(inner_max, inner_max);
1003				assert_eq!(a.into_inner(), accuracy);
1004
1005				let a = $name::saturating_from_rational(inner_max, 3 * accuracy);
1006				assert_eq!(a.into_inner(), inner_max / 3);
1007
1008				let a = $name::saturating_from_rational(inner_min, 2 * accuracy);
1009				assert_eq!(a.into_inner(), inner_min / 2);
1010
1011				let a = $name::saturating_from_rational(inner_min, accuracy / 3);
1012				assert_eq!(a.into_inner(), inner_min);
1013
1014				let a = $name::saturating_from_rational(1, accuracy);
1015				assert_eq!(a.into_inner(), 1);
1016
1017				// Out of accuracy.
1018				let a = $name::saturating_from_rational(1, accuracy + 1);
1019				assert_eq!(a.into_inner(), 0);
1020			}
1021
1022			#[test]
1023			fn checked_from_rational_works() {
1024				let inner_max = <$name as FixedPointNumber>::Inner::max_value();
1025				let inner_min = <$name as FixedPointNumber>::Inner::min_value();
1026				let accuracy = $name::accuracy();
1027
1028				// Divide by zero => None.
1029				let a = $name::checked_from_rational(1, 0);
1030				assert_eq!(a, None);
1031
1032				// Max - 1.
1033				let a = $name::checked_from_rational(inner_max - 1, accuracy).unwrap();
1034				assert_eq!(a.into_inner(), inner_max - 1);
1035
1036				// Min + 1.
1037				let a = $name::checked_from_rational(inner_min + 1, accuracy).unwrap();
1038				assert_eq!(a.into_inner(), inner_min + 1);
1039
1040				// Max.
1041				let a = $name::checked_from_rational(inner_max, accuracy).unwrap();
1042				assert_eq!(a.into_inner(), inner_max);
1043
1044				// Min.
1045				let a = $name::checked_from_rational(inner_min, accuracy).unwrap();
1046				assert_eq!(a.into_inner(), inner_min);
1047
1048				// Max + 1 => Overflow => None.
1049				let a = $name::checked_from_rational(inner_min, 0.saturating_sub(accuracy));
1050				assert_eq!(a, None);
1051
1052				if $name::SIGNED {
1053					// Min - 1 => Underflow => None.
1054					let a = $name::checked_from_rational(inner_max as u128 + 2, 0.saturating_sub(accuracy));
1055					assert_eq!(a, None);
1056
1057					let a = $name::checked_from_rational(inner_max, 0 - 3 * accuracy).unwrap();
1058					assert_eq!(a.into_inner(), 0 - inner_max / 3);
1059
1060					let a = $name::checked_from_rational(inner_min, 0 - accuracy / 3);
1061					assert_eq!(a, None);
1062
1063					let a = $name::checked_from_rational(1, 0 - accuracy).unwrap();
1064					assert_eq!(a.into_inner(), 0.saturating_sub(1));
1065
1066					let a = $name::checked_from_rational(1, 0 - accuracy - 1).unwrap();
1067					assert_eq!(a.into_inner(), 0);
1068
1069					let a = $name::checked_from_rational(inner_min, accuracy / 3);
1070					assert_eq!(a, None);
1071				}
1072
1073				let a = $name::checked_from_rational(inner_max, 3 * accuracy).unwrap();
1074				assert_eq!(a.into_inner(), inner_max / 3);
1075
1076				let a = $name::checked_from_rational(inner_min, 2 * accuracy).unwrap();
1077				assert_eq!(a.into_inner(), inner_min / 2);
1078
1079				let a = $name::checked_from_rational(1, accuracy).unwrap();
1080				assert_eq!(a.into_inner(), 1);
1081
1082				let a = $name::checked_from_rational(1, accuracy + 1).unwrap();
1083				assert_eq!(a.into_inner(), 0);
1084			}
1085
1086			#[test]
1087			fn checked_mul_int_works() {
1088				let a = $name::saturating_from_integer(2);
1089				// Max - 1.
1090				assert_eq!(a.checked_mul_int((i128::max_value() - 1) / 2), Some(i128::max_value() - 1));
1091				// Max.
1092				assert_eq!(a.checked_mul_int(i128::max_value() / 2), Some(i128::max_value() - 1));
1093				// Max + 1 => None.
1094				assert_eq!(a.checked_mul_int(i128::max_value() / 2 + 1), None);
1095
1096				if $name::SIGNED {
1097					// Min - 1.
1098					assert_eq!(a.checked_mul_int((i128::min_value() + 1) / 2), Some(i128::min_value() + 2));
1099					// Min.
1100					assert_eq!(a.checked_mul_int(i128::min_value() / 2), Some(i128::min_value()));
1101					// Min + 1 => None.
1102					assert_eq!(a.checked_mul_int(i128::min_value() / 2 - 1), None);
1103
1104					let b = $name::saturating_from_rational(1, -2);
1105					assert_eq!(b.checked_mul_int(42i128), Some(-21));
1106					assert_eq!(b.checked_mul_int(u128::max_value()), None);
1107					assert_eq!(b.checked_mul_int(i128::max_value()), Some(i128::max_value() / -2));
1108					assert_eq!(b.checked_mul_int(i128::min_value()), Some(i128::min_value() / -2));
1109				}
1110
1111				let a = $name::saturating_from_rational(1, 2);
1112				assert_eq!(a.checked_mul_int(42i128), Some(21));
1113				assert_eq!(a.checked_mul_int(i128::max_value()), Some(i128::max_value() / 2));
1114				assert_eq!(a.checked_mul_int(i128::min_value()), Some(i128::min_value() / 2));
1115
1116				let c = $name::saturating_from_integer(255);
1117				assert_eq!(c.checked_mul_int(2i8), None);
1118				assert_eq!(c.checked_mul_int(2i128), Some(510));
1119				assert_eq!(c.checked_mul_int(i128::max_value()), None);
1120				assert_eq!(c.checked_mul_int(i128::min_value()), None);
1121			}
1122
1123			#[test]
1124			fn saturating_mul_int_works() {
1125				let a = $name::saturating_from_integer(2);
1126				// Max - 1.
1127				assert_eq!(a.saturating_mul_int((i128::max_value() - 1) / 2), i128::max_value() - 1);
1128				// Max.
1129				assert_eq!(a.saturating_mul_int(i128::max_value() / 2), i128::max_value() - 1);
1130				// Max + 1 => saturates to max.
1131				assert_eq!(a.saturating_mul_int(i128::max_value() / 2 + 1), i128::max_value());
1132
1133				// Min - 1.
1134				assert_eq!(a.saturating_mul_int((i128::min_value() + 1) / 2), i128::min_value() + 2);
1135				// Min.
1136				assert_eq!(a.saturating_mul_int(i128::min_value() / 2), i128::min_value());
1137				// Min + 1 => saturates to min.
1138				assert_eq!(a.saturating_mul_int(i128::min_value() / 2 - 1), i128::min_value());
1139
1140				if $name::SIGNED {
1141					let b = $name::saturating_from_rational(1, -2);
1142					assert_eq!(b.saturating_mul_int(42i32), -21);
1143					assert_eq!(b.saturating_mul_int(i128::max_value()), i128::max_value() / -2);
1144					assert_eq!(b.saturating_mul_int(i128::min_value()), i128::min_value() / -2);
1145					assert_eq!(b.saturating_mul_int(u128::max_value()), u128::min_value());
1146				}
1147
1148				let a = $name::saturating_from_rational(1, 2);
1149				assert_eq!(a.saturating_mul_int(42i32), 21);
1150				assert_eq!(a.saturating_mul_int(i128::max_value()), i128::max_value() / 2);
1151				assert_eq!(a.saturating_mul_int(i128::min_value()), i128::min_value() / 2);
1152
1153				let c = $name::saturating_from_integer(255);
1154				assert_eq!(c.saturating_mul_int(2i8), i8::max_value());
1155				assert_eq!(c.saturating_mul_int(-2i8), i8::min_value());
1156				assert_eq!(c.saturating_mul_int(i128::max_value()), i128::max_value());
1157				assert_eq!(c.saturating_mul_int(i128::min_value()), i128::min_value());
1158			}
1159
1160			#[test]
1161			fn checked_mul_works() {
1162				let inner_max = <$name as FixedPointNumber>::Inner::max_value();
1163				let inner_min = <$name as FixedPointNumber>::Inner::min_value();
1164
1165				let a = $name::saturating_from_integer(2);
1166
1167				// Max - 1.
1168				let b = $name::from_inner(inner_max - 1);
1169				assert_eq!(a.checked_mul(&(b/2.into())), Some(b));
1170
1171				// Max.
1172				let c = $name::from_inner(inner_max);
1173				assert_eq!(a.checked_mul(&(c/2.into())), Some(b));
1174
1175				// Max + 1 => None.
1176				let e = $name::from_inner(1);
1177				assert_eq!(a.checked_mul(&(c/2.into()+e)), None);
1178
1179				if $name::SIGNED {
1180					// Min + 1.
1181					let b = $name::from_inner(inner_min + 1) / 2.into();
1182					let c = $name::from_inner(inner_min + 2);
1183					assert_eq!(a.checked_mul(&b), Some(c));
1184
1185					// Min.
1186					let b = $name::from_inner(inner_min) / 2.into();
1187					let c = $name::from_inner(inner_min);
1188					assert_eq!(a.checked_mul(&b), Some(c));
1189
1190					// Min - 1 => None.
1191					let b = $name::from_inner(inner_min) / 2.into() - $name::from_inner(1);
1192					assert_eq!(a.checked_mul(&b), None);
1193
1194					let c = $name::saturating_from_integer(255);
1195					let b = $name::saturating_from_rational(1, -2);
1196
1197					assert_eq!(b.checked_mul(&42.into()), Some(0.saturating_sub(21).into()));
1198					assert_eq!(b.checked_mul(&$name::max_value()), $name::max_value().checked_div(&0.saturating_sub(2).into()));
1199					assert_eq!(b.checked_mul(&$name::min_value()), $name::min_value().checked_div(&0.saturating_sub(2).into()));
1200					assert_eq!(c.checked_mul(&$name::min_value()), None);
1201				}
1202
1203				let a = $name::saturating_from_rational(1, 2);
1204				let c = $name::saturating_from_integer(255);
1205
1206				assert_eq!(a.checked_mul(&42.into()), Some(21.into()));
1207				assert_eq!(c.checked_mul(&2.into()), Some(510.into()));
1208				assert_eq!(c.checked_mul(&$name::max_value()), None);
1209				assert_eq!(a.checked_mul(&$name::max_value()), $name::max_value().checked_div(&2.into()));
1210				assert_eq!(a.checked_mul(&$name::min_value()), $name::min_value().checked_div(&2.into()));
1211			}
1212
1213			#[test]
1214			fn checked_div_int_works() {
1215				let inner_max = <$name as FixedPointNumber>::Inner::max_value();
1216				let inner_min = <$name as FixedPointNumber>::Inner::min_value();
1217				let accuracy = $name::accuracy();
1218
1219				let a = $name::from_inner(inner_max);
1220				let b = $name::from_inner(inner_min);
1221				let c = $name::zero();
1222				let d = $name::one();
1223				let e = $name::saturating_from_integer(6);
1224				let f = $name::saturating_from_integer(5);
1225
1226				assert_eq!(e.checked_div_int(2.into()), Some(3));
1227				assert_eq!(f.checked_div_int(2.into()), Some(2));
1228
1229				assert_eq!(a.checked_div_int(i128::max_value()), Some(0));
1230				assert_eq!(a.checked_div_int(2), Some(inner_max / (2 * accuracy)));
1231				assert_eq!(a.checked_div_int(inner_max / accuracy), Some(1));
1232				assert_eq!(a.checked_div_int(1i8), None);
1233
1234				if b < c {
1235					// Not executed by unsigned inners.
1236					assert_eq!(a.checked_div_int(0.saturating_sub(2)), Some(0.saturating_sub(inner_max / (2 * accuracy))));
1237					assert_eq!(a.checked_div_int(0.saturating_sub(inner_max / accuracy)), Some(0.saturating_sub(1)));
1238					assert_eq!(b.checked_div_int(i128::min_value()), Some(0));
1239					assert_eq!(b.checked_div_int(inner_min / accuracy), Some(1));
1240					assert_eq!(b.checked_div_int(1i8), None);
1241					assert_eq!(b.checked_div_int(0.saturating_sub(2)), Some(0.saturating_sub(inner_min / (2 * accuracy))));
1242					assert_eq!(b.checked_div_int(0.saturating_sub(inner_min / accuracy)), Some(0.saturating_sub(1)));
1243					assert_eq!(c.checked_div_int(i128::min_value()), Some(0));
1244					assert_eq!(d.checked_div_int(i32::min_value()), Some(0));
1245				}
1246
1247				assert_eq!(b.checked_div_int(2), Some(inner_min / (2 * accuracy)));
1248
1249				assert_eq!(c.checked_div_int(1), Some(0));
1250				assert_eq!(c.checked_div_int(i128::max_value()), Some(0));
1251				assert_eq!(c.checked_div_int(1i8), Some(0));
1252
1253				assert_eq!(d.checked_div_int(1), Some(1));
1254				assert_eq!(d.checked_div_int(i32::max_value()), Some(0));
1255				assert_eq!(d.checked_div_int(1i8), Some(1));
1256
1257				assert_eq!(a.checked_div_int(0), None);
1258				assert_eq!(b.checked_div_int(0), None);
1259				assert_eq!(c.checked_div_int(0), None);
1260				assert_eq!(d.checked_div_int(0), None);
1261			}
1262
1263			#[test]
1264			#[should_panic(expected = "attempt to divide by zero")]
1265			fn saturating_div_int_panics_when_divisor_is_zero() {
1266				let _ = $name::one().saturating_div_int(0);
1267			}
1268
1269			#[test]
1270			fn saturating_div_int_works() {
1271				let inner_max = <$name as FixedPointNumber>::Inner::max_value();
1272				let inner_min = <$name as FixedPointNumber>::Inner::min_value();
1273				let accuracy = $name::accuracy();
1274
1275				let a = $name::saturating_from_integer(5);
1276				assert_eq!(a.saturating_div_int(2), 2);
1277
1278				let a = $name::min_value();
1279				assert_eq!(a.saturating_div_int(1i128), (inner_min / accuracy) as i128);
1280
1281				if $name::SIGNED {
1282					let a = $name::saturating_from_integer(5);
1283					assert_eq!(a.saturating_div_int(-2), -2);
1284
1285					let a = $name::min_value();
1286					assert_eq!(a.saturating_div_int(-1i128), (inner_max / accuracy) as i128);
1287				}
1288			}
1289
1290			#[test]
1291			fn saturating_abs_works() {
1292				let inner_max = <$name as FixedPointNumber>::Inner::max_value();
1293				let inner_min = <$name as FixedPointNumber>::Inner::min_value();
1294
1295				assert_eq!($name::from_inner(inner_max).saturating_abs(), $name::max_value());
1296				assert_eq!($name::zero().saturating_abs(), 0.into());
1297
1298				if $name::SIGNED {
1299					assert_eq!($name::from_inner(inner_min).saturating_abs(), $name::max_value());
1300					assert_eq!($name::saturating_from_rational(-1, 2).saturating_abs(), (1, 2).into());
1301				}
1302			}
1303
1304			#[test]
1305			fn saturating_mul_acc_int_works() {
1306				assert_eq!($name::zero().saturating_mul_acc_int(42i8), 42i8);
1307				assert_eq!($name::one().saturating_mul_acc_int(42i8), 2 * 42i8);
1308
1309				assert_eq!($name::one().saturating_mul_acc_int(i128::max_value()), i128::max_value());
1310				assert_eq!($name::one().saturating_mul_acc_int(i128::min_value()), i128::min_value());
1311
1312				assert_eq!($name::one().saturating_mul_acc_int(u128::max_value() / 2), u128::max_value() - 1);
1313				assert_eq!($name::one().saturating_mul_acc_int(u128::min_value()), u128::min_value());
1314
1315				if $name::SIGNED {
1316					let a = $name::saturating_from_rational(-1, 2);
1317					assert_eq!(a.saturating_mul_acc_int(42i8), 21i8);
1318					assert_eq!(a.saturating_mul_acc_int(42u8), 21u8);
1319					assert_eq!(a.saturating_mul_acc_int(u128::max_value() - 1), u128::max_value() / 2);
1320				}
1321			}
1322
1323			#[test]
1324			fn saturating_pow_should_work() {
1325				assert_eq!($name::saturating_from_integer(2).saturating_pow(0), $name::saturating_from_integer(1));
1326				assert_eq!($name::saturating_from_integer(2).saturating_pow(1), $name::saturating_from_integer(2));
1327				assert_eq!($name::saturating_from_integer(2).saturating_pow(2), $name::saturating_from_integer(4));
1328				assert_eq!($name::saturating_from_integer(2).saturating_pow(3), $name::saturating_from_integer(8));
1329				assert_eq!($name::saturating_from_integer(2).saturating_pow(50),
1330					$name::saturating_from_integer(1125899906842624i64));
1331
1332				assert_eq!($name::saturating_from_integer(1).saturating_pow(1000), (1).into());
1333				assert_eq!($name::saturating_from_integer(1).saturating_pow(usize::max_value()), (1).into());
1334
1335				if $name::SIGNED {
1336					// Saturating.
1337					assert_eq!($name::saturating_from_integer(2).saturating_pow(68), $name::max_value());
1338
1339					assert_eq!($name::saturating_from_integer(-1).saturating_pow(1000), (1).into());
1340					assert_eq!($name::saturating_from_integer(-1).saturating_pow(1001), 0.saturating_sub(1).into());
1341					assert_eq!($name::saturating_from_integer(-1).saturating_pow(usize::max_value()), 0.saturating_sub(1).into());
1342					assert_eq!($name::saturating_from_integer(-1).saturating_pow(usize::max_value() - 1), (1).into());
1343				}
1344
1345				assert_eq!($name::saturating_from_integer(114209).saturating_pow(5), $name::max_value());
1346
1347				assert_eq!($name::saturating_from_integer(1).saturating_pow(usize::max_value()), (1).into());
1348				assert_eq!($name::saturating_from_integer(0).saturating_pow(usize::max_value()), (0).into());
1349				assert_eq!($name::saturating_from_integer(2).saturating_pow(usize::max_value()), $name::max_value());
1350			}
1351
1352			#[test]
1353			fn checked_div_works() {
1354				let inner_max = <$name as FixedPointNumber>::Inner::max_value();
1355				let inner_min = <$name as FixedPointNumber>::Inner::min_value();
1356
1357				let a = $name::from_inner(inner_max);
1358				let b = $name::from_inner(inner_min);
1359				let c = $name::zero();
1360				let d = $name::one();
1361				let e = $name::saturating_from_integer(6);
1362				let f = $name::saturating_from_integer(5);
1363
1364				assert_eq!(e.checked_div(&2.into()), Some(3.into()));
1365				assert_eq!(f.checked_div(&2.into()), Some((5, 2).into()));
1366
1367				assert_eq!(a.checked_div(&inner_max.into()), Some(1.into()));
1368				assert_eq!(a.checked_div(&2.into()), Some($name::from_inner(inner_max / 2)));
1369				assert_eq!(a.checked_div(&$name::max_value()), Some(1.into()));
1370				assert_eq!(a.checked_div(&d), Some(a));
1371
1372				if b < c {
1373					// Not executed by unsigned inners.
1374					assert_eq!(a.checked_div(&0.saturating_sub(2).into()), Some($name::from_inner(0.saturating_sub(inner_max / 2))));
1375					assert_eq!(a.checked_div(&-$name::max_value()), Some(0.saturating_sub(1).into()));
1376					assert_eq!(b.checked_div(&0.saturating_sub(2).into()), Some($name::from_inner(0.saturating_sub(inner_min / 2))));
1377					assert_eq!(c.checked_div(&$name::max_value()), Some(0.into()));
1378					assert_eq!(b.checked_div(&b), Some($name::one()));
1379				}
1380
1381				assert_eq!(b.checked_div(&2.into()), Some($name::from_inner(inner_min / 2)));
1382				assert_eq!(b.checked_div(&a), Some(0.saturating_sub(1).into()));
1383				assert_eq!(c.checked_div(&1.into()), Some(0.into()));
1384				assert_eq!(d.checked_div(&1.into()), Some(1.into()));
1385
1386				assert_eq!(a.checked_div(&$name::one()), Some(a));
1387				assert_eq!(b.checked_div(&$name::one()), Some(b));
1388				assert_eq!(c.checked_div(&$name::one()), Some(c));
1389				assert_eq!(d.checked_div(&$name::one()), Some(d));
1390
1391				assert_eq!(a.checked_div(&$name::zero()), None);
1392				assert_eq!(b.checked_div(&$name::zero()), None);
1393				assert_eq!(c.checked_div(&$name::zero()), None);
1394				assert_eq!(d.checked_div(&$name::zero()), None);
1395			}
1396
1397			#[test]
1398			fn is_positive_negative_works() {
1399				let one = $name::one();
1400				assert!(one.is_positive());
1401				assert!(!one.is_negative());
1402
1403				let zero = $name::zero();
1404				assert!(!zero.is_positive());
1405				assert!(!zero.is_negative());
1406
1407				if $signed {
1408					let minus_one = $name::saturating_from_integer(-1);
1409					assert!(minus_one.is_negative());
1410					assert!(!minus_one.is_positive());
1411				}
1412			}
1413
1414			#[test]
1415			fn trunc_works() {
1416				let n = $name::saturating_from_rational(5, 2).trunc();
1417				assert_eq!(n, $name::saturating_from_integer(2));
1418
1419				if $name::SIGNED {
1420					let n = $name::saturating_from_rational(-5, 2).trunc();
1421					assert_eq!(n, $name::saturating_from_integer(-2));
1422				}
1423			}
1424
1425			#[test]
1426			fn frac_works() {
1427				let n = $name::saturating_from_rational(5, 2);
1428				let i = n.trunc();
1429				let f = n.frac();
1430
1431				assert_eq!(n, i + f);
1432
1433				let n = $name::saturating_from_rational(5, 2)
1434					.frac()
1435					.saturating_mul(10.into());
1436				assert_eq!(n, 5.into());
1437
1438				let n = $name::saturating_from_rational(1, 2)
1439					.frac()
1440					.saturating_mul(10.into());
1441				assert_eq!(n, 5.into());
1442
1443				if $name::SIGNED {
1444					let n = $name::saturating_from_rational(-5, 2);
1445					let i = n.trunc();
1446					let f = n.frac();
1447					assert_eq!(n, i - f);
1448
1449					// The sign is attached to the integer part unless it is zero.
1450					let n = $name::saturating_from_rational(-5, 2)
1451						.frac()
1452						.saturating_mul(10.into());
1453					assert_eq!(n, 5.into());
1454
1455					let n = $name::saturating_from_rational(-1, 2)
1456						.frac()
1457						.saturating_mul(10.into());
1458					assert_eq!(n, 0.saturating_sub(5).into());
1459				}
1460			}
1461
1462			#[test]
1463			fn ceil_works() {
1464				let n = $name::saturating_from_rational(5, 2);
1465				assert_eq!(n.ceil(), 3.into());
1466
1467				let n = $name::saturating_from_rational(-5, 2);
1468				assert_eq!(n.ceil(), 0.saturating_sub(2).into());
1469
1470				// On the limits:
1471				let n = $name::max_value();
1472				assert_eq!(n.ceil(), n.trunc());
1473
1474				let n = $name::min_value();
1475				assert_eq!(n.ceil(), n.trunc());
1476			}
1477
1478			#[test]
1479			fn floor_works() {
1480				let n = $name::saturating_from_rational(5, 2);
1481				assert_eq!(n.floor(), 2.into());
1482
1483				let n = $name::saturating_from_rational(-5, 2);
1484				assert_eq!(n.floor(), 0.saturating_sub(3).into());
1485
1486				// On the limits:
1487				let n = $name::max_value();
1488				assert_eq!(n.floor(), n.trunc());
1489
1490				let n = $name::min_value();
1491				assert_eq!(n.floor(), n.trunc());
1492			}
1493
1494			#[test]
1495			fn round_works() {
1496				let n = $name::zero();
1497				assert_eq!(n.round(), n);
1498
1499				let n = $name::one();
1500				assert_eq!(n.round(), n);
1501
1502				let n = $name::saturating_from_rational(5, 2);
1503				assert_eq!(n.round(), 3.into());
1504
1505				let n = $name::saturating_from_rational(-5, 2);
1506				assert_eq!(n.round(), 0.saturating_sub(3).into());
1507
1508				// Saturating:
1509				let n = $name::max_value();
1510				assert_eq!(n.round(), n.trunc());
1511
1512				let n = $name::min_value();
1513				assert_eq!(n.round(), n.trunc());
1514
1515				// On the limit:
1516
1517				// floor(max - 1) + 0.33..
1518				let n = $name::max_value()
1519					.saturating_sub(1.into())
1520					.trunc()
1521					.saturating_add((1, 3).into());
1522
1523				assert_eq!(n.round(), ($name::max_value() - 1.into()).trunc());
1524
1525				// floor(max - 1) + 0.5
1526				let n = $name::max_value()
1527					.saturating_sub(1.into())
1528					.trunc()
1529					.saturating_add((1, 2).into());
1530
1531				assert_eq!(n.round(), $name::max_value().trunc());
1532
1533				if $name::SIGNED {
1534					// floor(min + 1) - 0.33..
1535					let n = $name::min_value()
1536						.saturating_add(1.into())
1537						.trunc()
1538						.saturating_sub((1, 3).into());
1539
1540					assert_eq!(n.round(), ($name::min_value() + 1.into()).trunc());
1541
1542					// floor(min + 1) - 0.5
1543					let n = $name::min_value()
1544						.saturating_add(1.into())
1545						.trunc()
1546						.saturating_sub((1, 2).into());
1547
1548					assert_eq!(n.round(), $name::min_value().trunc());
1549				}
1550			}
1551
1552			#[test]
1553			fn perthing_into_works() {
1554				let ten_percent_percent: $name = Percent::from_percent(10).into();
1555				assert_eq!(ten_percent_percent.into_inner(), $name::accuracy() / 10);
1556
1557				let ten_percent_permill: $name = Permill::from_percent(10).into();
1558				assert_eq!(ten_percent_permill.into_inner(), $name::accuracy() / 10);
1559
1560				let ten_percent_perbill: $name = Perbill::from_percent(10).into();
1561				assert_eq!(ten_percent_perbill.into_inner(), $name::accuracy() / 10);
1562
1563				let ten_percent_perquintill: $name = Perquintill::from_percent(10).into();
1564				assert_eq!(ten_percent_perquintill.into_inner(), $name::accuracy() / 10);
1565			}
1566
1567			#[test]
1568			fn fmt_should_work() {
1569				let zero = $name::zero();
1570				assert_eq!(format!("{:?}", zero), format!("{}(0.{:0>weight$})", stringify!($name), 0, weight=precision()));
1571
1572				let one = $name::one();
1573				assert_eq!(format!("{:?}", one), format!("{}(1.{:0>weight$})", stringify!($name), 0, weight=precision()));
1574
1575				let frac = $name::saturating_from_rational(1, 2);
1576				assert_eq!(format!("{:?}", frac), format!("{}(0.{:0<weight$})", stringify!($name), 5, weight=precision()));
1577
1578				let frac = $name::saturating_from_rational(5, 2);
1579				assert_eq!(format!("{:?}", frac), format!("{}(2.{:0<weight$})", stringify!($name), 5, weight=precision()));
1580
1581				let frac = $name::saturating_from_rational(314, 100);
1582				assert_eq!(format!("{:?}", frac), format!("{}(3.{:0<weight$})", stringify!($name), 14, weight=precision()));
1583
1584				if $name::SIGNED {
1585					let neg = -$name::one();
1586					assert_eq!(format!("{:?}", neg), format!("{}(-1.{:0>weight$})", stringify!($name), 0, weight=precision()));
1587
1588					let frac = $name::saturating_from_rational(-314, 100);
1589					assert_eq!(format!("{:?}", frac), format!("{}(-3.{:0<weight$})", stringify!($name), 14, weight=precision()));
1590				}
1591			}
1592		}
1593	}
1594}
1595
1596implement_fixed!(
1597	FixedI64,
1598	test_fixed_i64,
1599	i64,
1600	true,
1601	1_000_000_000,
1602	"_Fixed Point 64 bits signed, range = [-9223372036.854775808, 9223372036.854775807]_",
1603);
1604
1605implement_fixed!(
1606	FixedI128,
1607	test_fixed_i128,
1608	i128,
1609	true,
1610	1_000_000_000_000_000_000,
1611	"_Fixed Point 128 bits signed, range = \
1612		[-170141183460469231731.687303715884105728, 170141183460469231731.687303715884105727]_",
1613);
1614
1615implement_fixed!(
1616	FixedU128,
1617	test_fixed_u128,
1618	u128,
1619	false,
1620	1_000_000_000_000_000_000,
1621	"_Fixed Point 128 bits unsigned, range = \
1622		[0.000000000000000000, 340282366920938463463.374607431768211455]_",
1623);