Skip to main content

subsoil/arithmetic/
per_things.rs

1// This file is part of Soil.
2
3// Copyright (C) Soil contributors.
4// Copyright (C) Parity Technologies (UK) Ltd.
5// SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later WITH Classpath-exception-2.0
6
7//! Types that implement [`PerThing`](PerThing) can be used as a floating-point alternative for
8//! numbers that operate within the realm of `[0, 1]`. The primary types may you encounter in
9//! Substrate would be the following:
10//! - [`Percent`](Percent) - parts of one hundred.
11//! - [`Permill`](Permill) - parts of a million.
12//! - [`Perbill`](Perbill) - parts of a billion.
13//!
14//! In use, you may see them being used as follows:
15//!
16//! > **[`Perbill`](Perbill), parts of a billion**
17#![doc = docify::embed!("./src/arithmetic/mod.rs", perbill_example)]
18//! > **[`Percent`](Percent), parts of a hundred**
19#![doc = docify::embed!("./src/arithmetic/mod.rs", percent_example)]
20//! Note that `Percent` is represented as a _rounded down_, fixed point
21//! number (see the example above). Unlike primitive types, types that implement
22//! [`PerThing`](PerThing) will also not overflow, and are therefore safe to use.
23//! They adopt the same behavior that a saturated calculation would provide, meaning that if one is
24//! to go over "100%", it wouldn't overflow, but simply stop at the upper or lower bound.
25//!
26//! For use cases which require precision beyond the range of `[0, 1]`, there are fixed-point types
27//! which can be used.
28//!
29//! Each of these can be used to construct and represent ratios within our runtime.
30//! You will find types like [`Perbill`](Perbill) being used often in pallet
31//! development.  `plant_referenda` is a good example of a pallet which makes good use of fixed
32//! point arithmetic, as it relies on representing various curves and thresholds relating to
33//! governance.
34//!
35//! #### Fixed Point Arithmetic with [`PerThing`](PerThing)
36//!
37//! As stated, one can also perform mathematics using these types directly. For example, finding the
38//! percentage of a particular item:
39
40#![doc = docify::embed!("./src/arithmetic/mod.rs", percent_mult)]
41
42#[cfg(feature = "serde")]
43use serde::{Deserialize, Serialize};
44
45use crate::arithmetic::traits::{
46	BaseArithmetic, Bounded, CheckedAdd, CheckedMul, CheckedSub, One, SaturatedConversion,
47	Saturating, UniqueSaturatedInto, Unsigned, Zero,
48};
49use codec::{CompactAs, DecodeWithMemTracking, Encode};
50use core::{
51	fmt, ops,
52	ops::{Add, Sub},
53};
54use num_traits::{Pow, SaturatingAdd, SaturatingSub};
55
56/// Get the inner type of a `PerThing`.
57pub type InnerOf<P> = <P as PerThing>::Inner;
58
59/// Get the upper type of a `PerThing`.
60pub type UpperOf<P> = <P as PerThing>::Upper;
61
62pub trait RationalArg:
63	Clone
64	+ Ord
65	+ ops::Div<Self, Output = Self>
66	+ ops::Rem<Self, Output = Self>
67	+ ops::Add<Self, Output = Self>
68	+ ops::AddAssign<Self>
69	+ Unsigned
70	+ Zero
71	+ One
72	+ crate::arithmetic::MultiplyRational
73{
74}
75
76impl<
77		T: Clone
78			+ Ord
79			+ ops::Div<Self, Output = Self>
80			+ ops::Rem<Self, Output = Self>
81			+ ops::Add<Self, Output = Self>
82			+ ops::AddAssign<Self>
83			+ Unsigned
84			+ Zero
85			+ One
86			+ crate::arithmetic::MultiplyRational,
87	> RationalArg for T
88{
89}
90
91pub trait MultiplyArg:
92	Clone
93	+ ops::Rem<Self, Output = Self>
94	+ ops::Div<Self, Output = Self>
95	+ ops::Mul<Self, Output = Self>
96	+ ops::Add<Self, Output = Self>
97	+ Unsigned
98{
99}
100
101impl<
102		T: Clone
103			+ ops::Rem<Self, Output = Self>
104			+ ops::Div<Self, Output = Self>
105			+ ops::Mul<Self, Output = Self>
106			+ ops::Add<Self, Output = Self>
107			+ Unsigned,
108	> MultiplyArg for T
109{
110}
111
112pub trait ReciprocalArg: MultiplyArg + Saturating {}
113impl<T: MultiplyArg + Saturating> ReciprocalArg for T {}
114
115/// Something that implements a fixed point ration with an arbitrary granularity `X`, as _parts per
116/// `X`_.
117pub trait PerThing:
118	Sized
119	+ Saturating
120	+ Copy
121	+ Default
122	+ Eq
123	+ PartialEq
124	+ Ord
125	+ PartialOrd
126	+ Bounded
127	+ fmt::Debug
128	+ ops::Div<Output = Self>
129	+ ops::Mul<Output = Self>
130	+ Pow<usize, Output = Self>
131{
132	/// The data type used to build this per-thingy.
133	type Inner: BaseArithmetic
134		+ Unsigned
135		+ Copy
136		+ Into<u128>
137		+ fmt::Debug
138		+ crate::arithmetic::MultiplyRational;
139
140	/// A data type larger than `Self::Inner`, used to avoid overflow in some computations.
141	/// It must be able to compute `ACCURACY^2`.
142	type Upper: BaseArithmetic
143		+ Copy
144		+ From<Self::Inner>
145		+ TryInto<Self::Inner>
146		+ UniqueSaturatedInto<Self::Inner>
147		+ Unsigned
148		+ fmt::Debug
149		+ crate::arithmetic::MultiplyRational;
150
151	/// The accuracy of this type.
152	const ACCURACY: Self::Inner;
153
154	/// Equivalent to `Self::from_parts(0)`.
155	fn zero() -> Self {
156		Self::from_parts(Self::Inner::zero())
157	}
158
159	/// Return `true` if this is nothing.
160	fn is_zero(&self) -> bool {
161		self.deconstruct() == Self::Inner::zero()
162	}
163
164	/// Equivalent to `Self::from_parts(Self::ACCURACY)`.
165	fn one() -> Self {
166		Self::from_parts(Self::ACCURACY)
167	}
168
169	/// Return `true` if this is one.
170	fn is_one(&self) -> bool {
171		self.deconstruct() == Self::ACCURACY
172	}
173
174	/// Return the next lower value to `self` or `self` if it is already zero.
175	#[must_use]
176	fn less_epsilon(self) -> Self {
177		if self.is_zero() {
178			return self;
179		}
180		Self::from_parts(self.deconstruct() - One::one())
181	}
182
183	/// Return the next lower value to `self` or an error with the same value if `self` is already
184	/// zero.
185	fn try_less_epsilon(self) -> Result<Self, Self> {
186		if self.is_zero() {
187			return Err(self);
188		}
189		Ok(Self::from_parts(self.deconstruct() - One::one()))
190	}
191
192	/// Return the next higher value to `self` or `self` if it is already one.
193	#[must_use]
194	fn plus_epsilon(self) -> Self {
195		if self.is_one() {
196			return self;
197		}
198		Self::from_parts(self.deconstruct() + One::one())
199	}
200
201	/// Return the next higher value to `self` or an error with the same value if `self` is already
202	/// one.
203	fn try_plus_epsilon(self) -> Result<Self, Self> {
204		if self.is_one() {
205			return Err(self);
206		}
207		Ok(Self::from_parts(self.deconstruct() + One::one()))
208	}
209
210	/// Build this type from a percent. Equivalent to `Self::from_parts(x * Self::ACCURACY / 100)`
211	/// but more accurate and can cope with potential type overflows.
212	#[must_use]
213	fn from_percent(x: Self::Inner) -> Self {
214		let a: Self::Inner = x.min(100.into());
215		let b: Self::Inner = 100.into();
216		Self::from_rational::<Self::Inner>(a, b)
217	}
218
219	/// Return the product of multiplication of this value by itself.
220	#[must_use]
221	fn square(self) -> Self {
222		let p = Self::Upper::from(self.deconstruct());
223		let q = Self::Upper::from(Self::ACCURACY);
224		Self::from_rational::<Self::Upper>(p * p, q * q)
225	}
226
227	/// Return the part left when `self` is saturating-subtracted from `Self::one()`.
228	#[must_use]
229	fn left_from_one(self) -> Self {
230		Self::one().saturating_sub(self)
231	}
232
233	/// Multiplication that always rounds down to a whole number. The standard `Mul` rounds to the
234	/// nearest whole number.
235	///
236	/// ```rust
237	/// # use subsoil::arithmetic::{Percent, PerThing};
238	/// # fn main () {
239	/// // round to nearest
240	/// assert_eq!(Percent::from_percent(34) * 10u64, 3);
241	/// assert_eq!(Percent::from_percent(36) * 10u64, 4);
242	///
243	/// // round down
244	/// assert_eq!(Percent::from_percent(34).mul_floor(10u64), 3);
245	/// assert_eq!(Percent::from_percent(36).mul_floor(10u64), 3);
246	/// # }
247	/// ```
248	#[must_use]
249	fn mul_floor<N>(self, b: N) -> N
250	where
251		N: MultiplyArg + UniqueSaturatedInto<Self::Inner>,
252		Self::Inner: Into<N>,
253	{
254		overflow_prune_mul::<N, Self>(b, self.deconstruct(), Rounding::Down)
255	}
256
257	/// Multiplication that always rounds the result up to a whole number. The standard `Mul`
258	/// rounds to the nearest whole number.
259	///
260	/// ```rust
261	/// # use subsoil::arithmetic::{Percent, PerThing};
262	/// # fn main () {
263	/// // round to nearest
264	/// assert_eq!(Percent::from_percent(34) * 10u64, 3);
265	/// assert_eq!(Percent::from_percent(36) * 10u64, 4);
266	///
267	/// // round up
268	/// assert_eq!(Percent::from_percent(34).mul_ceil(10u64), 4);
269	/// assert_eq!(Percent::from_percent(36).mul_ceil(10u64), 4);
270	/// # }
271	/// ```
272	#[must_use]
273	fn mul_ceil<N>(self, b: N) -> N
274	where
275		N: MultiplyArg + UniqueSaturatedInto<Self::Inner>,
276		Self::Inner: Into<N>,
277	{
278		overflow_prune_mul::<N, Self>(b, self.deconstruct(), Rounding::Up)
279	}
280
281	/// Saturating multiplication by the reciprocal of `self`.	The result is rounded to the
282	/// nearest whole number and saturates at the numeric bounds instead of overflowing.
283	///
284	/// ```rust
285	/// # use subsoil::arithmetic::{Percent, PerThing};
286	/// # fn main () {
287	/// assert_eq!(Percent::from_percent(50).saturating_reciprocal_mul(10u64), 20);
288	/// # }
289	/// ```
290	#[must_use]
291	fn saturating_reciprocal_mul<N>(self, b: N) -> N
292	where
293		N: ReciprocalArg + UniqueSaturatedInto<Self::Inner>,
294		Self::Inner: Into<N>,
295	{
296		saturating_reciprocal_mul::<N, Self>(b, self.deconstruct(), Rounding::NearestPrefUp)
297	}
298
299	/// Saturating multiplication by the reciprocal of `self`.	The result is rounded down to the
300	/// nearest whole number and saturates at the numeric bounds instead of overflowing.
301	///
302	/// ```rust
303	/// # use subsoil::arithmetic::{Percent, PerThing};
304	/// # fn main () {
305	/// // round to nearest
306	/// assert_eq!(Percent::from_percent(60).saturating_reciprocal_mul(10u64), 17);
307	/// // round down
308	/// assert_eq!(Percent::from_percent(60).saturating_reciprocal_mul_floor(10u64), 16);
309	/// # }
310	/// ```
311	#[must_use]
312	fn saturating_reciprocal_mul_floor<N>(self, b: N) -> N
313	where
314		N: ReciprocalArg + UniqueSaturatedInto<Self::Inner>,
315		Self::Inner: Into<N>,
316	{
317		saturating_reciprocal_mul::<N, Self>(b, self.deconstruct(), Rounding::Down)
318	}
319
320	/// Saturating multiplication by the reciprocal of `self`.	The result is rounded up to the
321	/// nearest whole number and saturates at the numeric bounds instead of overflowing.
322	///
323	/// ```rust
324	/// # use subsoil::arithmetic::{Percent, PerThing};
325	/// # fn main () {
326	/// // round to nearest
327	/// assert_eq!(Percent::from_percent(61).saturating_reciprocal_mul(10u64), 16);
328	/// // round up
329	/// assert_eq!(Percent::from_percent(61).saturating_reciprocal_mul_ceil(10u64), 17);
330	/// # }
331	/// ```
332	#[must_use]
333	fn saturating_reciprocal_mul_ceil<N>(self, b: N) -> N
334	where
335		N: ReciprocalArg + UniqueSaturatedInto<Self::Inner>,
336		Self::Inner: Into<N>,
337	{
338		saturating_reciprocal_mul::<N, Self>(b, self.deconstruct(), Rounding::Up)
339	}
340
341	/// Consume self and return the number of parts per thing.
342	fn deconstruct(self) -> Self::Inner;
343
344	/// Build this type from a number of parts per thing.
345	#[must_use]
346	fn from_parts(parts: Self::Inner) -> Self;
347
348	/// Converts a fraction into `Self`.
349	#[must_use]
350	#[cfg(feature = "std")]
351	fn from_float(x: f64) -> Self;
352
353	/// Same as `Self::from_float`.
354	#[deprecated = "Use from_float instead"]
355	#[cfg(feature = "std")]
356	fn from_fraction(x: f64) -> Self {
357		Self::from_float(x)
358	}
359
360	/// Approximate the fraction `p/q` into a per-thing fraction. This will never overflow.
361	///
362	/// The computation of this approximation is performed in the generic type `N`. Given
363	/// `M` as the data type that can hold the maximum value of this per-thing (e.g. u32 for
364	/// perbill), this can only work if `N == M` or `N: From<M> + TryInto<M>`.
365	///
366	/// Note that this always rounds _down_, i.e.
367	///
368	/// ```rust
369	/// # use subsoil::arithmetic::{Percent, PerThing};
370	/// # fn main () {
371	/// // 989/1000 is technically closer to 99%.
372	/// assert_eq!(
373	/// 	Percent::from_rational(989u64, 1000),
374	/// 	Percent::from_parts(98),
375	/// );
376	/// # }
377	/// ```
378	#[must_use]
379	fn from_rational<N>(p: N, q: N) -> Self
380	where
381		N: RationalArg + TryInto<Self::Inner> + TryInto<Self::Upper>,
382		Self::Inner: Into<N>,
383	{
384		Self::from_rational_with_rounding(p, q, Rounding::Down).unwrap_or_else(|_| Self::one())
385	}
386
387	/// Approximate the fraction `p/q` into a per-thing fraction.
388	///
389	/// The computation of this approximation is performed in the generic type `N`. Given
390	/// `M` as the data type that can hold the maximum value of this per-thing (e.g. `u32` for
391	/// `Perbill`), this can only work if `N == M` or `N: From<M> + TryInto<M>`.
392	///
393	/// In the case of an overflow (or divide by zero), an `Err` is returned.
394	///
395	/// Rounding is determined by the parameter `rounding`, i.e.
396	///
397	/// ```rust
398	/// # use subsoil::arithmetic::{Percent, PerThing, Rounding::*};
399	/// # fn main () {
400	/// // 989/100 is technically closer to 99%.
401	/// assert_eq!(
402	/// 	Percent::from_rational_with_rounding(989u64, 1000, Down).unwrap(),
403	/// 	Percent::from_parts(98),
404	/// );
405	/// assert_eq!(
406	/// 	Percent::from_rational_with_rounding(984u64, 1000, NearestPrefUp).unwrap(),
407	/// 	Percent::from_parts(98),
408	/// );
409	/// assert_eq!(
410	/// 	Percent::from_rational_with_rounding(985u64, 1000, NearestPrefDown).unwrap(),
411	/// 	Percent::from_parts(98),
412	/// );
413	/// assert_eq!(
414	/// 	Percent::from_rational_with_rounding(985u64, 1000, NearestPrefUp).unwrap(),
415	/// 	Percent::from_parts(99),
416	/// );
417	/// assert_eq!(
418	/// 	Percent::from_rational_with_rounding(986u64, 1000, NearestPrefDown).unwrap(),
419	/// 	Percent::from_parts(99),
420	/// );
421	/// assert_eq!(
422	/// 	Percent::from_rational_with_rounding(981u64, 1000, Up).unwrap(),
423	/// 	Percent::from_parts(99),
424	/// );
425	/// assert_eq!(
426	/// 	Percent::from_rational_with_rounding(1001u64, 1000, Up),
427	/// 	Err(()),
428	/// );
429	/// # }
430	/// ```
431	///
432	/// ```rust
433	/// # use subsoil::arithmetic::{Percent, PerThing, Rounding::*};
434	/// # fn main () {
435	/// assert_eq!(
436	/// 	Percent::from_rational_with_rounding(981u64, 1000, Up).unwrap(),
437	/// 	Percent::from_parts(99),
438	/// );
439	/// # }
440	/// ```
441	fn from_rational_with_rounding<N>(p: N, q: N, rounding: Rounding) -> Result<Self, ()>
442	where
443		N: RationalArg + TryInto<Self::Inner> + TryInto<Self::Upper>,
444		Self::Inner: Into<N>;
445
446	/// Same as `Self::from_rational`.
447	#[deprecated = "Use from_rational instead"]
448	fn from_rational_approximation<N>(p: N, q: N) -> Self
449	where
450		N: RationalArg + TryInto<Self::Inner> + TryInto<Self::Upper>,
451		Self::Inner: Into<N>,
452	{
453		Self::from_rational(p, q)
454	}
455}
456
457/// The rounding method to use for unsigned quantities.
458#[derive(Copy, Clone, core::fmt::Debug)]
459pub enum Rounding {
460	// Towards infinity.
461	Up,
462	// Towards zero.
463	Down,
464	// Nearest integer, rounding as `Up` when equidistant.
465	NearestPrefUp,
466	// Nearest integer, rounding as `Down` when equidistant.
467	NearestPrefDown,
468}
469
470/// The rounding method to use.
471#[derive(Copy, Clone, core::fmt::Debug)]
472pub enum SignedRounding {
473	// Towards positive infinity.
474	High,
475	// Towards negative infinity.
476	Low,
477	// Nearest integer, rounding as `High` when exactly equidistant.
478	NearestPrefHigh,
479	// Nearest integer, rounding as `Low` when exactly equidistant.
480	NearestPrefLow,
481	// Away from zero (up when positive, down when negative). When positive, equivalent to `High`.
482	Major,
483	// Towards zero (down when positive, up when negative). When positive, equivalent to `Low`.
484	Minor,
485	// Nearest integer, rounding as `Major` when exactly equidistant.
486	NearestPrefMajor,
487	// Nearest integer, rounding as `Minor` when exactly equidistant.
488	NearestPrefMinor,
489}
490
491impl Rounding {
492	/// Returns the value for `Rounding` which would give the same result ignorant of the sign.
493	pub const fn from_signed(rounding: SignedRounding, negative: bool) -> Self {
494		use Rounding::*;
495		use SignedRounding::*;
496		match (rounding, negative) {
497			(Low, true) | (Major, _) | (High, false) => Up,
498			(High, true) | (Minor, _) | (Low, false) => Down,
499			(NearestPrefMajor, _) | (NearestPrefHigh, false) | (NearestPrefLow, true) => {
500				NearestPrefUp
501			},
502			(NearestPrefMinor, _) | (NearestPrefLow, false) | (NearestPrefHigh, true) => {
503				NearestPrefDown
504			},
505		}
506	}
507}
508
509/// Saturating reciprocal multiplication. Compute `x / self`, saturating at the numeric
510/// bounds instead of overflowing.
511fn saturating_reciprocal_mul<N, P>(x: N, part: P::Inner, rounding: Rounding) -> N
512where
513	N: Clone
514		+ UniqueSaturatedInto<P::Inner>
515		+ ops::Div<N, Output = N>
516		+ ops::Mul<N, Output = N>
517		+ ops::Add<N, Output = N>
518		+ ops::Rem<N, Output = N>
519		+ Saturating
520		+ Unsigned,
521	P: PerThing,
522	P::Inner: Into<N>,
523{
524	let maximum: N = P::ACCURACY.into();
525	let c = rational_mul_correction::<N, P>(x.clone(), P::ACCURACY, part, rounding);
526	(x / part.into()).saturating_mul(maximum).saturating_add(c)
527}
528
529/// Overflow-prune multiplication. Accurately multiply a value by `self` without overflowing.
530fn overflow_prune_mul<N, P>(x: N, part: P::Inner, rounding: Rounding) -> N
531where
532	N: MultiplyArg + UniqueSaturatedInto<P::Inner>,
533	P: PerThing,
534	P::Inner: Into<N>,
535{
536	let maximum: N = P::ACCURACY.into();
537	let part_n: N = part.into();
538	let c = rational_mul_correction::<N, P>(x.clone(), part, P::ACCURACY, rounding);
539	(x / maximum) * part_n + c
540}
541
542/// Compute the error due to integer division in the expression `x / denom * numer`.
543///
544/// Take the remainder of `x / denom` and multiply by  `numer / denom`. The result can be added
545/// to `x / denom * numer` for an accurate result.
546fn rational_mul_correction<N, P>(x: N, numer: P::Inner, denom: P::Inner, rounding: Rounding) -> N
547where
548	N: MultiplyArg + UniqueSaturatedInto<P::Inner>,
549	P: PerThing,
550	P::Inner: Into<N>,
551{
552	let numer_upper = P::Upper::from(numer);
553	let denom_n: N = denom.into();
554	let denom_upper = P::Upper::from(denom);
555	let rem = x.rem(denom_n);
556	// `rem` is less than `denom`, which fits in `P::Inner`.
557	let rem_inner = rem.saturated_into::<P::Inner>();
558	// `P::Upper` always fits `P::Inner::max_value().pow(2)`, thus it fits `rem * numer`.
559	let rem_mul_upper = P::Upper::from(rem_inner) * numer_upper;
560	// `rem` is less than `denom`, so `rem * numer / denom` is less than `numer`, which fits in
561	// `P::Inner`.
562	let mut rem_mul_div_inner = (rem_mul_upper / denom_upper).saturated_into::<P::Inner>();
563	match rounding {
564		// Already rounded down
565		Rounding::Down => {},
566		// Round up if the fractional part of the result is non-zero.
567		Rounding::Up => {
568			if rem_mul_upper % denom_upper > 0.into() {
569				// `rem * numer / denom` is less than `numer`, so this will not overflow.
570				rem_mul_div_inner += 1.into();
571			}
572		},
573		Rounding::NearestPrefDown => {
574			if rem_mul_upper % denom_upper > denom_upper / 2.into() {
575				// `rem * numer / denom` is less than `numer`, so this will not overflow.
576				rem_mul_div_inner += 1.into();
577			}
578		},
579		Rounding::NearestPrefUp => {
580			if rem_mul_upper % denom_upper >= denom_upper / 2.into() + denom_upper % 2.into() {
581				// `rem * numer / denom` is less than `numer`, so this will not overflow.
582				rem_mul_div_inner += 1.into();
583			}
584		},
585	}
586	rem_mul_div_inner.into()
587}
588
589macro_rules! implement_per_thing {
590	(
591		$name:ident,
592		$test_mod:ident,
593		[$($test_units:tt),+],
594		$max:tt,
595		$type:ty,
596		$upper_type:ty,
597		$title:expr $(,)?
598	) => {
599		/// A fixed point representation of a number in the range [0, 1].
600		///
601		#[doc = $title]
602		#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
603		#[derive(Encode, DecodeWithMemTracking, Copy, Clone, PartialEq, Eq, codec::MaxEncodedLen, PartialOrd, Ord, scale_info::TypeInfo)]
604		pub struct $name($type);
605
606		/// Implementation makes any compact encoding of `PerThing::Inner` valid,
607		/// when decoding it will saturate up to `PerThing::ACCURACY`.
608		impl CompactAs for $name {
609			type As = $type;
610			fn encode_as(&self) -> &Self::As {
611				&self.0
612			}
613			fn decode_from(x: Self::As) -> Result<Self, codec::Error> {
614				// Saturates if `x` is more than `$max` internally.
615				Ok(Self::from_parts(x))
616			}
617		}
618
619		impl From<codec::Compact<$name>> for $name {
620			fn from(x: codec::Compact<$name>) -> $name {
621				x.0
622			}
623		}
624
625		#[cfg(feature = "std")]
626		impl core::fmt::Debug for $name {
627			fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
628				if $max == <$type>::max_value() {
629					// Not a power of ten: show as N/D and approx %
630					let pc = (self.0 as f64) / (self.0 as f64) * 100f64;
631					write!(fmt, "{:.2}% ({}/{})", pc, self.0, $max)
632				} else {
633					// A power of ten: calculate exact percent
634					let divisor = $max / 100;
635					let units = self.0 / divisor;
636					let rest = self.0 % divisor;
637					write!(fmt, "{}", units)?;
638					if rest > 0 {
639						write!(fmt, ".")?;
640						let mut m = $max / 100;
641						while rest % m > 0 {
642							m /= 10;
643							write!(fmt, "{:01}", rest / m % 10)?;
644						}
645					}
646					write!(fmt, "%")
647				}
648			}
649		}
650
651		#[cfg(not(feature = "std"))]
652		impl core::fmt::Debug for $name {
653			fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
654				if $max == <$type>::max_value() {
655					// Not a power of ten: show as N/D and approx %
656					write!(fmt, "{}/{}", self.0, $max)
657				} else {
658					// A power of ten: calculate exact percent
659					let units = self.0 / ($max / 100);
660					let rest = self.0 % ($max / 100);
661					write!(fmt, "{}", units)?;
662					if rest > 0 {
663						write!(fmt, ".")?;
664						let mut m = $max / 100;
665						while rest % m > 0 {
666							m /= 10;
667							write!(fmt, "{:01}", rest / m % 10)?;
668						}
669					}
670					write!(fmt, "%")
671				}
672			}
673		}
674
675		impl PerThing for $name {
676			type Inner = $type;
677			type Upper = $upper_type;
678
679			const ACCURACY: Self::Inner = $max;
680
681			/// Consume self and return the number of parts per thing.
682			fn deconstruct(self) -> Self::Inner { self.0 }
683
684			/// Build this type from a number of parts per thing.
685			fn from_parts(parts: Self::Inner) -> Self { Self(parts.min($max)) }
686
687			/// NOTE: saturate to 0 or 1 if x is beyond `[0, 1]`
688			#[cfg(feature = "std")]
689			fn from_float(x: f64) -> Self {
690				Self::from_parts((x.max(0.).min(1.) * $max as f64) as Self::Inner)
691			}
692
693			fn from_rational_with_rounding<N>(p: N, q: N, r: Rounding) -> Result<Self, ()>
694			where
695				N: Clone
696					+ Ord
697					+ TryInto<Self::Inner>
698					+ TryInto<Self::Upper>
699					+ ops::Div<N, Output = N>
700					+ ops::Rem<N, Output = N>
701					+ ops::Add<N, Output = N>
702					+ ops::AddAssign<N>
703					+ Unsigned
704					+ Zero
705					+ One
706					+ $crate::arithmetic::MultiplyRational,
707				Self::Inner: Into<N>
708			{
709				// q cannot be zero.
710				if q.is_zero() { return Err(()) }
711				// p should not be bigger than q.
712				if p > q { return Err(()) }
713
714				let max: N = $max.into();
715				max.multiply_rational(p, q, r).ok_or(())?.try_into().map(|x| $name(x)).map_err(|_| ())
716			}
717		}
718
719		impl $name {
720			/// From an explicitly defined number of parts per maximum of the type.
721			///
722			// needed only for peru16. Since peru16 is the only type in which $max ==
723			// $type::max_value(), rustc is being a smart-a** here by warning that the comparison
724			// is not needed.
725			#[allow(unused_comparisons)]
726			pub const fn from_parts(parts: $type) -> Self {
727				Self([parts, $max][(parts > $max) as usize])
728			}
729
730			/// Converts a percent into `Self`. Equal to `x / 100`.
731			///
732			/// This can be created at compile time.
733			pub const fn from_percent(x: $type) -> Self {
734				Self(([x, 100][(x > 100) as usize] as $upper_type * $max as $upper_type / 100) as $type)
735			}
736
737			/// See [`PerThing::one`]
738			pub const fn one() -> Self {
739				Self::from_parts($max)
740			}
741
742			/// See [`PerThing::is_one`].
743			pub fn is_one(&self) -> bool {
744				PerThing::is_one(self)
745			}
746
747			/// See [`PerThing::zero`].
748			pub const fn zero() -> Self {
749				Self::from_parts(0)
750			}
751
752			/// See [`PerThing::is_zero`].
753			pub fn is_zero(&self) -> bool {
754				PerThing::is_zero(self)
755			}
756
757			/// See [`PerThing::deconstruct`].
758			pub const fn deconstruct(self) -> $type {
759				self.0
760			}
761
762			/// See [`PerThing::square`].
763			pub fn square(self) -> Self {
764				PerThing::square(self)
765			}
766
767			/// See [`PerThing::from_float`].
768			#[cfg(feature = "std")]
769			pub fn from_float(x: f64) -> Self {
770				<Self as PerThing>::from_float(x)
771			}
772
773			/// See [`PerThing::from_rational`].
774			#[deprecated = "Use `PerThing::from_rational` instead"]
775			pub fn from_rational_approximation<N>(p: N, q: N) -> Self
776			where
777				N: RationalArg+ TryInto<$type> + TryInto<$upper_type>,
778				$type: Into<N>
779			{
780				<Self as PerThing>::from_rational(p, q)
781			}
782
783			/// See [`PerThing::from_rational`].
784			pub fn from_rational<N>(p: N, q: N) -> Self
785			where
786				N: RationalArg+ TryInto<$type> + TryInto<$upper_type>,
787				$type: Into<N>
788			{
789				<Self as PerThing>::from_rational(p, q)
790			}
791
792			/// Integer multiplication with another value, saturating at 1.
793			pub fn int_mul(self, b: $type) -> Self {
794				PerThing::from_parts(self.0.saturating_mul(b))
795			}
796
797			/// Integer division with another value, rounding down.
798			pub fn int_div(self, b: Self) -> $type {
799				self.0 / b.0
800			}
801
802			/// See [`PerThing::mul_floor`].
803			pub fn mul_floor<N>(self, b: N) -> N
804				where
805					N: MultiplyArg + UniqueSaturatedInto<$type>,
806					$type: Into<N>,
807
808			{
809				PerThing::mul_floor(self, b)
810			}
811
812			/// See [`PerThing::mul_ceil`].
813			pub fn mul_ceil<N>(self, b: N) -> N
814				where
815					N: MultiplyArg + UniqueSaturatedInto<$type>,
816					$type: Into<N>,
817			{
818				PerThing::mul_ceil(self, b)
819			}
820
821			/// See [`PerThing::saturating_reciprocal_mul`].
822			pub fn saturating_reciprocal_mul<N>(self, b: N) -> N
823				where
824					N: ReciprocalArg + UniqueSaturatedInto<$type>,
825					$type: Into<N>,
826			{
827				PerThing::saturating_reciprocal_mul(self, b)
828			}
829
830			/// See [`PerThing::saturating_reciprocal_mul_floor`].
831			pub fn saturating_reciprocal_mul_floor<N>(self, b: N) -> N
832				where
833					N: ReciprocalArg + UniqueSaturatedInto<$type>,
834					$type: Into<N>,
835			{
836				PerThing::saturating_reciprocal_mul_floor(self, b)
837			}
838
839			/// See [`PerThing::saturating_reciprocal_mul_ceil`].
840			pub fn saturating_reciprocal_mul_ceil<N>(self, b: N) -> N
841				where
842					N: ReciprocalArg + UniqueSaturatedInto<$type>,
843					$type: Into<N>,
844			{
845				PerThing::saturating_reciprocal_mul_ceil(self, b)
846			}
847
848			/// Saturating division. Compute `self / rhs`, saturating at one if `rhs < self`.
849			///
850			/// The `rounding` method must be specified. e.g.:
851			///
852			/// ```rust
853			/// # use subsoil::arithmetic::{Percent, PerThing, Rounding::*};
854			/// # fn main () {
855			/// let pc = |x| Percent::from_percent(x);
856			/// assert_eq!(
857			/// 	pc(2).saturating_div(pc(3), Down),
858			/// 	pc(66),
859			/// );
860			/// assert_eq!(
861			/// 	pc(1).saturating_div(pc(3), NearestPrefUp),
862			/// 	pc(33),
863			/// );
864			/// assert_eq!(
865			/// 	pc(2).saturating_div(pc(3), NearestPrefDown),
866			/// 	pc(67),
867			/// );
868			/// assert_eq!(
869			/// 	pc(1).saturating_div(pc(3), Up),
870			/// 	pc(34),
871			/// );
872			/// # }
873			/// ```
874			pub fn saturating_div(self, rhs: Self, r: Rounding) -> Self {
875				let p = self.0;
876				let q = rhs.0;
877				Self::from_rational_with_rounding(p, q, r).unwrap_or_else(|_| Self::one())
878			}
879		}
880
881		impl Saturating for $name {
882			/// Saturating addition. Compute `self + rhs`, saturating at the numeric bounds instead of
883			/// overflowing. This operation is lossless if it does not saturate.
884			fn saturating_add(self, rhs: Self) -> Self {
885				// defensive-only: since `$max * 2 < $type::max_value()`, this can never overflow.
886				Self::from_parts(self.0.saturating_add(rhs.0))
887			}
888
889			/// Saturating subtraction. Compute `self - rhs`, saturating at the numeric bounds instead of
890			/// overflowing. This operation is lossless if it does not saturate.
891			fn saturating_sub(self, rhs: Self) -> Self {
892				Self::from_parts(self.0.saturating_sub(rhs.0))
893			}
894
895			/// Saturating multiply. Compute `self * rhs`, saturating at the numeric bounds instead of
896			/// overflowing. This operation is lossy.
897			fn saturating_mul(self, rhs: Self) -> Self {
898				self * rhs
899			}
900
901			/// Saturating exponentiation. Computes `self.pow(exp)`, saturating at the numeric
902			/// bounds instead of overflowing. This operation is lossy.
903			fn saturating_pow(self, exp: usize) -> Self {
904				self.pow(exp)
905			}
906		}
907
908		impl codec::Decode for $name {
909			fn decode<I: codec::Input>(input: &mut I) -> Result<Self, codec::Error> {
910				let inner = <$type as codec::Decode>::decode(input)?;
911
912				if inner <= <Self as PerThing>::ACCURACY {
913					Ok(Self(inner))
914				} else {
915					Err("Value is greater than allowed maximum!".into())
916				}
917			}
918		}
919
920		impl Bounded for $name {
921			fn min_value() -> Self {
922				<Self as PerThing>::zero()
923			}
924
925			fn max_value() -> Self {
926				<Self as PerThing>::one()
927			}
928		}
929
930		impl ops::Mul for $name {
931			type Output = Self;
932
933			fn mul(self, rhs: Self) -> Self::Output {
934				let a = self.0 as $upper_type;
935				let b = rhs.0 as $upper_type;
936				let m = <$upper_type>::from($max);
937				let parts = a * b / m;
938				// This will always fit into $type.
939				Self::from_parts(parts as $type)
940			}
941		}
942
943		impl Pow<usize> for $name {
944			type Output = Self;
945
946			fn pow(mut self, exp: usize) -> Self::Output {
947				if exp == 0 || self.is_one() {
948					return Self::one()
949				}
950
951				let mut result = self;
952				let mut exp = exp - 1;
953				while exp > 0 && !result.is_zero() {
954					if exp % 2 != 0 {
955						result = result * self;
956						exp -= 1;
957					}
958					self = self.square();
959					exp /= 2;
960				}
961				result
962			}
963		}
964
965		impl ops::Div for $name {
966			type Output = Self;
967
968			fn div(self, rhs: Self) -> Self::Output {
969				let p = self.0;
970				let q = rhs.0;
971				Self::from_rational(p, q)
972			}
973		}
974
975		impl Default for $name {
976			fn default() -> Self {
977				<Self as PerThing>::zero()
978			}
979		}
980
981		/// Non-overflow multiplication.
982		///
983		/// This is tailored to be used with a balance type.
984		impl<N> ops::Mul<N> for $name
985		where
986			N: Clone + UniqueSaturatedInto<$type> + ops::Rem<N, Output=N>
987				+ ops::Div<N, Output=N> + ops::Mul<N, Output=N> + ops::Add<N, Output=N> + Unsigned,
988			$type: Into<N>,
989		{
990			type Output = N;
991			fn mul(self, b: N) -> Self::Output {
992				overflow_prune_mul::<N, Self>(b, self.deconstruct(), Rounding::NearestPrefDown)
993			}
994		}
995
996		impl<N> ops::Div<N> for $name where $type: TryFrom<N> {
997			type Output = Self;
998			fn div(self, b: N) -> Self::Output {
999				<$type>::try_from(b).map_or(Self::zero(), |d| Self::from_parts(self.0 / d))
1000			}
1001		}
1002
1003		impl Add<Self> for $name {
1004			type Output = $name;
1005
1006			// For PerU16, $max == u16::MAX, so we need this `allow`.
1007			#[allow(unused_comparisons)]
1008			#[inline]
1009			fn add(self, rhs: Self) -> Self::Output {
1010				let inner = self.deconstruct().add(rhs.deconstruct());
1011				debug_assert!(inner <= $max);
1012				$name::from_parts(inner)
1013			}
1014		}
1015
1016		impl CheckedAdd for $name {
1017			// For PerU16, $max == u16::MAX, so we need this `allow`.
1018			#[allow(unused_comparisons)]
1019			#[inline]
1020			fn checked_add(&self, rhs: &Self) -> Option<Self> {
1021				self.deconstruct()
1022					.checked_add(rhs.deconstruct())
1023					.map(|inner| if inner > $max { None } else { Some($name::from_parts(inner)) })
1024					.flatten()
1025			}
1026		}
1027
1028		impl Sub<Self> for $name {
1029			type Output = $name;
1030
1031			#[inline]
1032			fn sub(self, rhs: Self) -> Self::Output {
1033				$name::from_parts(self.deconstruct().sub(rhs.deconstruct()))
1034			}
1035		}
1036
1037		impl CheckedSub for $name {
1038			#[inline]
1039			fn checked_sub(&self, v: &Self) -> Option<Self> {
1040				self.deconstruct().checked_sub(v.deconstruct()).map($name::from_parts)
1041			}
1042		}
1043
1044		impl SaturatingAdd for $name {
1045			#[inline]
1046			fn saturating_add(&self, v: &Self) -> Self {
1047				$name::from_parts(self.deconstruct().saturating_add(v.deconstruct()))
1048			}
1049		}
1050
1051		impl SaturatingSub for $name {
1052			#[inline]
1053			fn saturating_sub(&self, v: &Self) -> Self {
1054				$name::from_parts(self.deconstruct().saturating_sub(v.deconstruct()))
1055			}
1056		}
1057
1058		/// # Note
1059		/// CheckedMul will never fail for PerThings.
1060		impl CheckedMul for $name {
1061			#[inline]
1062			fn checked_mul(&self, rhs: &Self) -> Option<Self> {
1063				Some(*self * *rhs)
1064			}
1065		}
1066
1067		impl $crate::arithmetic::traits::Zero for $name {
1068			fn zero() -> Self {
1069				Self::zero()
1070			}
1071
1072			fn is_zero(&self) -> bool {
1073				self == &Self::zero()
1074			}
1075		}
1076
1077		impl $crate::arithmetic::traits::One for $name {
1078			fn one() -> Self {
1079				Self::one()
1080			}
1081		}
1082
1083		#[cfg(test)]
1084		mod $test_mod {
1085			use codec::{Encode, Decode};
1086			use super::{$name, Saturating, PerThing};
1087			use crate::arithmetic::traits::Zero;
1088
1089			#[test]
1090			fn macro_expanded_correctly() {
1091				// needed for the `from_percent` to work. UPDATE: this is no longer needed; yet note
1092				// that tests that use percentage or fractions such as $name::from_float(0.2) to
1093				// create values will most likely be inaccurate when used with per_things that are
1094				// not multiples of 100.
1095				// assert!($max >= 100);
1096				// assert!($max % 100 == 0);
1097
1098				// needed for `from_rational`
1099				assert!(2 * ($max as $upper_type) < <$upper_type>::max_value());
1100				assert!(<$upper_type>::from($max) < <$upper_type>::max_value());
1101
1102				// for something like percent they can be the same.
1103				assert!((<$type>::max_value() as $upper_type) <= <$upper_type>::max_value());
1104				assert!(<$upper_type>::from($max).checked_mul($max.into()).is_some());
1105
1106				// make sure saturating_pow won't overflow the upper type
1107				assert!(<$upper_type>::from($max) * <$upper_type>::from($max) < <$upper_type>::max_value());
1108			}
1109
1110			#[derive(Encode, Decode, PartialEq, Eq, Debug)]
1111			struct WithCompact<T: codec::HasCompact> {
1112				data: T,
1113			}
1114
1115			#[test]
1116			fn has_compact() {
1117				let data = WithCompact { data: $name(1) };
1118				let encoded = data.encode();
1119				assert_eq!(data, WithCompact::<$name>::decode(&mut &encoded[..]).unwrap());
1120			}
1121
1122			#[test]
1123			fn compact_encoding() {
1124				let tests = [
1125					// assume all per_things have the size u8 at least.
1126					(0 as $type, 1usize),
1127					(1 as $type, 1usize),
1128					(63, 1),
1129					(64, 2),
1130					(65, 2),
1131					// (<$type>::max_value(), <$type>::max_value().encode().len() + 1)
1132				];
1133				for &(n, l) in &tests {
1134					let compact: codec::Compact<$name> = $name(n).into();
1135					let encoded = compact.encode();
1136					assert_eq!(encoded.len(), l);
1137					let decoded = <codec::Compact<$name>>::decode(&mut & encoded[..])
1138						.unwrap();
1139					let per_thingy: $name = decoded.into();
1140					assert_eq!(per_thingy, $name(n));
1141				}
1142			}
1143
1144			#[test]
1145			fn from_parts_cannot_overflow() {
1146				assert_eq!(<$name>::from_parts($max.saturating_add(1)), <$name>::one());
1147			}
1148
1149			#[test]
1150			fn has_max_encoded_len() {
1151				struct AsMaxEncodedLen<T: codec::MaxEncodedLen> {
1152					_data: T,
1153				}
1154
1155				let _ = AsMaxEncodedLen { _data: $name(1) };
1156			}
1157
1158			#[test]
1159			fn fail_on_invalid_encoded_value() {
1160				let value = <$upper_type>::from($max) * 2;
1161				let casted = value as $type;
1162				let encoded = casted.encode();
1163
1164				// For types where `$max == $type::maximum()` we can not
1165				if <$upper_type>::from(casted) == value {
1166					assert_eq!(
1167						$name::decode(&mut &encoded[..]),
1168						Err("Value is greater than allowed maximum!".into()),
1169					);
1170				}
1171			}
1172
1173			#[test]
1174			fn per_thing_api_works() {
1175				// some really basic stuff
1176				assert_eq!($name::zero(), $name::from_parts(Zero::zero()));
1177				assert_eq!($name::one(), $name::from_parts($max));
1178				assert_eq!($name::ACCURACY, $max);
1179
1180				assert_eq!($name::from_percent(0), $name::from_parts(Zero::zero()));
1181				assert_eq!($name::from_percent(10), $name::from_parts($max / 10));
1182				assert_eq!($name::from_percent(50), $name::from_parts($max / 2));
1183				assert_eq!($name::from_percent(100), $name::from_parts($max));
1184				assert_eq!($name::from_percent(200), $name::from_parts($max));
1185
1186				assert_eq!($name::from_float(0.0), $name::from_parts(Zero::zero()));
1187				assert_eq!($name::from_float(0.1), $name::from_parts($max / 10));
1188				assert_eq!($name::from_float(1.0), $name::from_parts($max));
1189				assert_eq!($name::from_float(2.0), $name::from_parts($max));
1190				assert_eq!($name::from_float(-1.0), $name::from_parts(Zero::zero()));
1191			}
1192
1193			#[test]
1194			fn percent_trait_impl_works() {
1195				assert_eq!(<$name as PerThing>::from_percent(0), $name::from_parts(Zero::zero()));
1196				assert_eq!(<$name as PerThing>::from_percent(10), $name::from_parts($max / 10));
1197				assert_eq!(<$name as PerThing>::from_percent(50), $name::from_parts($max / 2));
1198				assert_eq!(<$name as PerThing>::from_percent(100), $name::from_parts($max));
1199				assert_eq!(<$name as PerThing>::from_percent(200), $name::from_parts($max));
1200			}
1201
1202			macro_rules! u256ify {
1203				($val:expr) => {
1204					Into::<U256>::into($val)
1205				};
1206			}
1207
1208			macro_rules! per_thing_mul_test {
1209				($num_type:tt) => {
1210					// multiplication from all sort of from_percent
1211					assert_eq!(
1212						$name::from_float(1.0) * $num_type::max_value(),
1213						$num_type::max_value()
1214					);
1215					if $max % 100 == 0 {
1216						assert_eq_error_rate!(
1217							$name::from_percent(99) * $num_type::max_value(),
1218							((Into::<U256>::into($num_type::max_value()) * 99u32) / 100u32).as_u128() as $num_type,
1219							1,
1220						);
1221						assert_eq!(
1222							$name::from_float(0.5) * $num_type::max_value(),
1223							$num_type::max_value() / 2,
1224						);
1225						assert_eq_error_rate!(
1226							$name::from_percent(1) * $num_type::max_value(),
1227							$num_type::max_value() / 100,
1228							1,
1229						);
1230					} else {
1231						assert_eq!(
1232							$name::from_float(0.99) * <$num_type>::max_value(),
1233							(
1234								(
1235									u256ify!($name::from_float(0.99).0) *
1236									u256ify!(<$num_type>::max_value()) /
1237									u256ify!($max)
1238								).as_u128()
1239							) as $num_type,
1240						);
1241						assert_eq!(
1242							$name::from_float(0.50) * <$num_type>::max_value(),
1243							(
1244								(
1245									u256ify!($name::from_float(0.50).0) *
1246									u256ify!(<$num_type>::max_value()) /
1247									u256ify!($max)
1248								).as_u128()
1249							) as $num_type,
1250						);
1251						assert_eq!(
1252							$name::from_float(0.01) * <$num_type>::max_value(),
1253							(
1254								(
1255									u256ify!($name::from_float(0.01).0) *
1256									u256ify!(<$num_type>::max_value()) /
1257									u256ify!($max)
1258								).as_u128()
1259							) as $num_type,
1260						);
1261					}
1262
1263					assert_eq!($name::from_float(0.0) * $num_type::max_value(), 0);
1264
1265					// // multiplication with bounds
1266					assert_eq!($name::one() * $num_type::max_value(), $num_type::max_value());
1267					assert_eq!($name::zero() * $num_type::max_value(), 0);
1268				}
1269			}
1270
1271			#[test]
1272			fn per_thing_mul_works() {
1273				use primitive_types::U256;
1274
1275				// accuracy test
1276				assert_eq!(
1277					$name::from_rational(1 as $type, 3) * 30 as $type,
1278					10,
1279				);
1280
1281				$(per_thing_mul_test!($test_units);)*
1282			}
1283
1284			#[test]
1285			fn per_thing_mul_rounds_to_nearest_number() {
1286				assert_eq!($name::from_percent(33) * 10u64, 3);
1287				assert_eq!($name::from_percent(34) * 10u64, 3);
1288				assert_eq!($name::from_percent(35) * 10u64, 3);
1289				assert_eq!($name::from_percent(36) * 10u64, 4);
1290			}
1291
1292			#[test]
1293			fn per_thing_multiplication_with_large_number() {
1294				use primitive_types::U256;
1295				let max_minus_one = $max - 1;
1296				assert_eq_error_rate!(
1297					$name::from_parts(max_minus_one) * std::u128::MAX,
1298					((Into::<U256>::into(std::u128::MAX) * max_minus_one) / $max).as_u128(),
1299					1,
1300				);
1301			}
1302
1303			macro_rules! per_thing_from_rationale_approx_test {
1304				($num_type:tt) => {
1305					// within accuracy boundary
1306					assert_eq!(
1307						$name::from_rational(1 as $num_type, 0),
1308						$name::one(),
1309					);
1310					assert_eq!(
1311						$name::from_rational(1 as $num_type, 1),
1312						$name::one(),
1313					);
1314					assert_eq_error_rate!(
1315						$name::from_rational(1 as $num_type, 3).0,
1316						$name::from_parts($max / 3).0,
1317						2
1318					);
1319					assert_eq!(
1320						$name::from_rational(1 as $num_type, 10),
1321						$name::from_float(0.10),
1322					);
1323					assert_eq!(
1324						$name::from_rational(1 as $num_type, 4),
1325						$name::from_float(0.25),
1326					);
1327					assert_eq!(
1328						$name::from_rational(1 as $num_type, 4),
1329						$name::from_rational(2 as $num_type, 8),
1330					);
1331					// no accurate anymore but won't overflow.
1332					assert_eq_error_rate!(
1333						$name::from_rational(
1334							$num_type::max_value() - 1,
1335							$num_type::max_value()
1336						).0 as $upper_type,
1337						$name::one().0 as $upper_type,
1338						2,
1339					);
1340					assert_eq_error_rate!(
1341						$name::from_rational(
1342							$num_type::max_value() / 3,
1343							$num_type::max_value()
1344						).0 as $upper_type,
1345						$name::from_parts($max / 3).0 as $upper_type,
1346						2,
1347					);
1348					assert_eq!(
1349						$name::from_rational(1, $num_type::max_value()),
1350						$name::zero(),
1351					);
1352				};
1353			}
1354
1355			#[test]
1356			fn per_thing_from_rationale_approx_works() {
1357				// This is just to make sure something like Percent which _might_ get built from a
1358				// u8 does not overflow in the context of this test.
1359				let max_value = <$upper_type>::from($max);
1360
1361				// almost at the edge
1362				assert_eq!(
1363					$name::from_rational(max_value - 1, max_value + 1),
1364					$name::from_parts($max - 2),
1365				);
1366				assert_eq!(
1367					$name::from_rational(1, $max - 1),
1368					$name::from_parts(1),
1369				);
1370				assert_eq!(
1371					$name::from_rational(1, $max),
1372					$name::from_parts(1),
1373				);
1374				assert_eq!(
1375					$name::from_rational(2, 2 * max_value - 1),
1376					$name::from_parts(1),
1377				);
1378				assert_eq!(
1379					$name::from_rational(1, max_value + 1),
1380					$name::zero(),
1381				);
1382				assert_eq!(
1383					$name::from_rational(3 * max_value / 2, 3 * max_value),
1384					$name::from_float(0.5),
1385				);
1386
1387				$(per_thing_from_rationale_approx_test!($test_units);)*
1388			}
1389
1390			#[test]
1391			fn per_things_mul_operates_in_output_type() {
1392				// assert_eq!($name::from_float(0.5) * 100u32, 50u32);
1393				assert_eq!($name::from_float(0.5) * 100u64, 50u64);
1394				assert_eq!($name::from_float(0.5) * 100u128, 50u128);
1395			}
1396
1397			#[test]
1398			fn per_thing_saturating_op_works() {
1399				assert_eq_error_rate!(
1400					$name::from_float(0.5).saturating_add($name::from_float(0.4)).0 as $upper_type,
1401					$name::from_float(0.9).0 as $upper_type,
1402					2,
1403				);
1404				assert_eq_error_rate!(
1405					$name::from_float(0.5).saturating_add($name::from_float(0.5)).0 as $upper_type,
1406					$name::one().0 as $upper_type,
1407					2,
1408				);
1409				assert_eq!(
1410					$name::from_float(0.6).saturating_add($name::from_float(0.5)),
1411					$name::one(),
1412				);
1413
1414				assert_eq_error_rate!(
1415					$name::from_float(0.6).saturating_sub($name::from_float(0.5)).0 as $upper_type,
1416					$name::from_float(0.1).0 as $upper_type,
1417					2,
1418				);
1419				assert_eq!(
1420					$name::from_float(0.6).saturating_sub($name::from_float(0.6)),
1421					$name::from_float(0.0),
1422				);
1423				assert_eq!(
1424					$name::from_float(0.6).saturating_sub($name::from_float(0.7)),
1425					$name::from_float(0.0),
1426				);
1427
1428				assert_eq_error_rate!(
1429					$name::from_float(0.5).saturating_mul($name::from_float(0.5)).0 as $upper_type,
1430					$name::from_float(0.25).0 as $upper_type,
1431					2,
1432				);
1433				assert_eq_error_rate!(
1434					$name::from_float(0.2).saturating_mul($name::from_float(0.2)).0 as $upper_type,
1435					$name::from_float(0.04).0 as $upper_type,
1436					2,
1437				);
1438				assert_eq_error_rate!(
1439					$name::from_float(0.1).saturating_mul($name::from_float(0.1)).0 as $upper_type,
1440					$name::from_float(0.01).0 as $upper_type,
1441					1,
1442				);
1443			}
1444
1445			#[test]
1446			fn per_thing_square_works() {
1447				assert_eq!($name::from_float(1.0).square(), $name::from_float(1.0));
1448				assert_eq!($name::from_float(0.5).square(), $name::from_float(0.25));
1449				assert_eq!($name::from_float(0.1).square(), $name::from_float(0.01));
1450				assert_eq!(
1451					$name::from_float(0.02).square(),
1452					$name::from_parts((4 * <$upper_type>::from($max) / 100 / 100) as $type)
1453				);
1454			}
1455
1456			#[test]
1457			fn per_things_div_works() {
1458				// normal
1459				assert_eq_error_rate!(
1460					($name::from_float(0.1) / $name::from_float(0.20)).0 as $upper_type,
1461					$name::from_float(0.50).0 as $upper_type,
1462					2,
1463				);
1464				assert_eq_error_rate!(
1465					($name::from_float(0.1) / $name::from_float(0.10)).0 as $upper_type,
1466					$name::from_float(1.0).0 as $upper_type,
1467					2,
1468				);
1469				assert_eq_error_rate!(
1470					($name::from_float(0.1) / $name::from_float(0.0)).0 as $upper_type,
1471					$name::from_float(1.0).0 as $upper_type,
1472					2,
1473				);
1474
1475				// will not overflow
1476				assert_eq_error_rate!(
1477					($name::from_float(0.10) / $name::from_float(0.05)).0 as $upper_type,
1478					$name::from_float(1.0).0 as $upper_type,
1479					2,
1480				);
1481				assert_eq_error_rate!(
1482					($name::from_float(1.0) / $name::from_float(0.5)).0 as $upper_type,
1483					$name::from_float(1.0).0 as $upper_type,
1484					2,
1485				);
1486			}
1487
1488			#[test]
1489			fn saturating_pow_works() {
1490				// x^0 == 1
1491				assert_eq!(
1492					$name::from_parts($max / 2).saturating_pow(0),
1493					$name::from_parts($max),
1494				);
1495
1496				// x^1 == x
1497				assert_eq!(
1498					$name::from_parts($max / 2).saturating_pow(1),
1499					$name::from_parts($max / 2),
1500				);
1501
1502				// x^2
1503				assert_eq!(
1504					$name::from_parts($max / 2).saturating_pow(2),
1505					$name::from_parts($max / 2).square(),
1506				);
1507
1508				// x^2 .. x^16
1509				for n in 1..=16 {
1510					assert_eq!(
1511						$name::from_parts($max / 2).saturating_pow(n),
1512						$name::from_parts(($max as u128 / 2u128.pow(n as u32)) as $type),
1513					);
1514				}
1515
1516				// 0^n == 0
1517				assert_eq!(
1518					$name::from_parts(0).saturating_pow(3),
1519					$name::from_parts(0),
1520				);
1521
1522				// 1^n == 1
1523				assert_eq!(
1524					$name::from_parts($max).saturating_pow(3),
1525					$name::from_parts($max),
1526				);
1527
1528				// (x < 1)^inf == 0 (where 2.pow(31) ~ inf)
1529				assert_eq!(
1530					$name::from_parts($max / 2).saturating_pow(2usize.pow(31)),
1531					$name::from_parts(0),
1532				);
1533			}
1534
1535			#[test]
1536			fn saturating_reciprocal_mul_works() {
1537				// divide by 1
1538				assert_eq!(
1539					$name::from_parts($max).saturating_reciprocal_mul(<$type>::from(10u8)),
1540					10,
1541				);
1542				// divide by 1/2
1543				assert_eq!(
1544					$name::from_parts($max / 2).saturating_reciprocal_mul(<$type>::from(10u8)),
1545					20,
1546				);
1547				// saturate
1548				assert_eq!(
1549					$name::from_parts(1).saturating_reciprocal_mul($max),
1550					<$type>::max_value(),
1551				);
1552				// round to nearest
1553				assert_eq!(
1554					$name::from_percent(60).saturating_reciprocal_mul(<$type>::from(10u8)),
1555					17,
1556				);
1557				// round down
1558				assert_eq!(
1559					$name::from_percent(60).saturating_reciprocal_mul_floor(<$type>::from(10u8)),
1560					16,
1561				);
1562				// round to nearest
1563				assert_eq!(
1564					$name::from_percent(61).saturating_reciprocal_mul(<$type>::from(10u8)),
1565					16,
1566				);
1567				// round up
1568				assert_eq!(
1569					$name::from_percent(61).saturating_reciprocal_mul_ceil(<$type>::from(10u8)),
1570					17,
1571				);
1572			}
1573
1574			#[test]
1575			fn saturating_truncating_mul_works() {
1576				assert_eq!(
1577					$name::from_percent(49).mul_floor(10 as $type),
1578					4,
1579				);
1580				let a: $upper_type = $name::from_percent(50).mul_floor(($max as $upper_type).pow(2));
1581				let b: $upper_type = ($max as $upper_type).pow(2) / 2;
1582				if $max % 2 == 0 {
1583					assert_eq!(a, b);
1584				} else {
1585					// difference should be less that 1%, IE less than the error in `from_percent`
1586					assert!(b - a < ($max as $upper_type).pow(2) / 100 as $upper_type);
1587				}
1588			}
1589
1590			#[test]
1591			fn rational_mul_correction_works() {
1592				assert_eq!(
1593					super::rational_mul_correction::<$type, $name>(
1594						<$type>::max_value(),
1595						<$type>::max_value(),
1596						<$type>::max_value(),
1597						super::Rounding::NearestPrefDown,
1598					),
1599					0,
1600				);
1601				assert_eq!(
1602					super::rational_mul_correction::<$type, $name>(
1603						<$type>::max_value() - 1,
1604						<$type>::max_value(),
1605						<$type>::max_value(),
1606						super::Rounding::NearestPrefDown,
1607					),
1608					<$type>::max_value() - 1,
1609				);
1610				assert_eq!(
1611					super::rational_mul_correction::<$upper_type, $name>(
1612						((<$type>::max_value() - 1) as $upper_type).pow(2),
1613						<$type>::max_value(),
1614						<$type>::max_value(),
1615						super::Rounding::NearestPrefDown,
1616					),
1617					1,
1618				);
1619				// ((max^2 - 1) % max) * max / max == max - 1
1620				assert_eq!(
1621					super::rational_mul_correction::<$upper_type, $name>(
1622						(<$type>::max_value() as $upper_type).pow(2) - 1,
1623						<$type>::max_value(),
1624						<$type>::max_value(),
1625						super::Rounding::NearestPrefDown,
1626					),
1627					<$upper_type>::from(<$type>::max_value() - 1),
1628				);
1629				// (max % 2) * max / 2 == max / 2
1630				assert_eq!(
1631					super::rational_mul_correction::<$upper_type, $name>(
1632						(<$type>::max_value() as $upper_type).pow(2),
1633						<$type>::max_value(),
1634						2 as $type,
1635						super::Rounding::NearestPrefDown,
1636					),
1637					<$type>::max_value() as $upper_type / 2,
1638				);
1639				// ((max^2 - 1) % max) * 2 / max == 2 (rounded up)
1640				assert_eq!(
1641					super::rational_mul_correction::<$upper_type, $name>(
1642						(<$type>::max_value() as $upper_type).pow(2) - 1,
1643						2 as $type,
1644						<$type>::max_value(),
1645						super::Rounding::NearestPrefDown,
1646					),
1647					2,
1648				);
1649				// ((max^2 - 1) % max) * 2 / max == 1 (rounded down)
1650				assert_eq!(
1651					super::rational_mul_correction::<$upper_type, $name>(
1652						(<$type>::max_value() as $upper_type).pow(2) - 1,
1653						2 as $type,
1654						<$type>::max_value(),
1655						super::Rounding::Down,
1656					),
1657					1,
1658				);
1659			}
1660
1661			#[test]
1662			#[allow(unused)]
1663			fn const_fns_work() {
1664				const C1: $name = $name::from_percent(50);
1665				const C2: $name = $name::one();
1666				const C3: $name = $name::zero();
1667				const C4: $name = $name::from_parts(1);
1668
1669				// deconstruct is also const, hence it can be called in const rhs.
1670				const C5: bool = C1.deconstruct() == 0;
1671			}
1672
1673			#[test]
1674			fn compact_decoding_saturate_when_beyond_accuracy() {
1675				use num_traits::Bounded;
1676				use codec::Compact;
1677
1678				let p = Compact::<$name>::decode(&mut &Compact(<$type>::max_value()).encode()[..])
1679					.unwrap();
1680				assert_eq!((p.0).0, $max);
1681				assert_eq!($name::from(p), $name::max_value());
1682			}
1683
1684			#[allow(unused_imports)]
1685			use super::*;
1686
1687			#[test]
1688			fn test_add_basic() {
1689				assert_eq!($name::from_parts(1) + $name::from_parts(1), $name::from_parts(2));
1690				assert_eq!($name::from_parts(10) + $name::from_parts(10), $name::from_parts(20));
1691			}
1692
1693			#[test]
1694			fn test_basic_checked_add() {
1695				assert_eq!(
1696					$name::from_parts(1).checked_add(&$name::from_parts(1)),
1697					Some($name::from_parts(2))
1698				);
1699				assert_eq!(
1700					$name::from_parts(10).checked_add(&$name::from_parts(10)),
1701					Some($name::from_parts(20))
1702				);
1703				assert_eq!(
1704					$name::from_parts(<$type>::MAX).checked_add(&$name::from_parts(<$type>::MAX)),
1705					None
1706				);
1707				assert_eq!(
1708					$name::from_parts($max).checked_add(&$name::from_parts(1)),
1709					None
1710				);
1711			}
1712
1713			#[test]
1714			fn test_basic_saturating_add() {
1715				assert_eq!(
1716					$name::from_parts(1).saturating_add($name::from_parts(1)),
1717					$name::from_parts(2)
1718				);
1719				assert_eq!(
1720					$name::from_parts(10).saturating_add($name::from_parts(10)),
1721					$name::from_parts(20)
1722				);
1723				assert_eq!(
1724					$name::from_parts(<$type>::MAX).saturating_add($name::from_parts(<$type>::MAX)),
1725					$name::from_parts(<$type>::MAX)
1726				);
1727			}
1728
1729			#[test]
1730			fn test_basic_sub() {
1731				assert_eq!($name::from_parts(2) - $name::from_parts(1), $name::from_parts(1));
1732				assert_eq!($name::from_parts(20) - $name::from_parts(10), $name::from_parts(10));
1733			}
1734
1735			#[test]
1736			fn test_basic_checked_sub() {
1737				assert_eq!(
1738					$name::from_parts(2).checked_sub(&$name::from_parts(1)),
1739					Some($name::from_parts(1))
1740				);
1741				assert_eq!(
1742					$name::from_parts(20).checked_sub(&$name::from_parts(10)),
1743					Some($name::from_parts(10))
1744				);
1745				assert_eq!($name::from_parts(0).checked_sub(&$name::from_parts(1)), None);
1746			}
1747
1748			#[test]
1749			fn test_basic_saturating_sub() {
1750				assert_eq!(
1751					$name::from_parts(2).saturating_sub($name::from_parts(1)),
1752					$name::from_parts(1)
1753				);
1754				assert_eq!(
1755					$name::from_parts(20).saturating_sub($name::from_parts(10)),
1756					$name::from_parts(10)
1757				);
1758				assert_eq!(
1759					$name::from_parts(0).saturating_sub($name::from_parts(1)),
1760					$name::from_parts(0)
1761				);
1762			}
1763
1764			#[test]
1765			fn test_basic_checked_mul() {
1766				assert_eq!(
1767					$name::from_parts($max).checked_mul(&$name::from_parts($max)),
1768					Some($name::from_percent(100))
1769				);
1770				assert_eq!(
1771					$name::from_percent(100).checked_mul(&$name::from_percent(100)),
1772					Some($name::from_percent(100))
1773				);
1774				assert_eq!(
1775					$name::from_percent(50).checked_mul(&$name::from_percent(26)),
1776					Some($name::from_percent(13))
1777				);
1778				assert_eq!(
1779					$name::from_percent(0).checked_mul(&$name::from_percent(0)),
1780					Some($name::from_percent(0))
1781				);
1782			}
1783		}
1784	};
1785}
1786
1787macro_rules! implement_per_thing_with_perthousand {
1788	(
1789		$name:ident,
1790		$test_mod:ident,
1791		$pt_test_mod:ident,
1792		[$($test_units:tt),+],
1793		$max:tt,
1794		$type:ty,
1795		$upper_type:ty,
1796		$title:expr $(,)?
1797	) => {
1798		implement_per_thing! {
1799			$name, $test_mod, [ $( $test_units ),+ ], $max, $type, $upper_type, $title,
1800		}
1801		impl $name {
1802			/// Converts a percent into `Self`. Equal to `x / 1000`.
1803			///
1804			/// This can be created at compile time.
1805			pub const fn from_perthousand(x: $type) -> Self {
1806				Self(([x, 1000][(x > 1000) as usize] as $upper_type * $max as $upper_type / 1000) as $type)
1807			}
1808		}
1809		#[cfg(test)]
1810		mod $pt_test_mod {
1811			use super::$name;
1812			use crate::arithmetic::traits::Zero;
1813
1814			#[test]
1815			fn from_perthousand_works() {
1816				// some really basic stuff
1817				assert_eq!($name::from_perthousand(00), $name::from_parts(Zero::zero()));
1818				assert_eq!($name::from_perthousand(100), $name::from_parts($max / 10));
1819				assert_eq!($name::from_perthousand(1000), $name::from_parts($max));
1820				assert_eq!($name::from_perthousand(2000), $name::from_parts($max));
1821			}
1822
1823			#[test]
1824			#[allow(unused)]
1825			fn const_fns_work() {
1826				const C1: $name = $name::from_perthousand(500);
1827			}
1828		}
1829	}
1830}
1831
1832#[test]
1833fn from_rational_with_rounding_works_in_extreme_case() {
1834	use Rounding::*;
1835	for &r in [Down, NearestPrefDown, NearestPrefUp, Up].iter() {
1836		Percent::from_rational_with_rounding(1, u64::max_value(), r).unwrap();
1837		Percent::from_rational_with_rounding(1, u32::max_value(), r).unwrap();
1838		Percent::from_rational_with_rounding(1, u16::max_value(), r).unwrap();
1839		Percent::from_rational_with_rounding(u64::max_value() - 1, u64::max_value(), r).unwrap();
1840		Percent::from_rational_with_rounding(u32::max_value() - 1, u32::max_value(), r).unwrap();
1841		Percent::from_rational_with_rounding(u16::max_value() - 1, u16::max_value(), r).unwrap();
1842		PerU16::from_rational_with_rounding(1, u64::max_value(), r).unwrap();
1843		PerU16::from_rational_with_rounding(1, u32::max_value(), r).unwrap();
1844		PerU16::from_rational_with_rounding(1, u16::max_value(), r).unwrap();
1845		PerU16::from_rational_with_rounding(u64::max_value() - 1, u64::max_value(), r).unwrap();
1846		PerU16::from_rational_with_rounding(u32::max_value() - 1, u32::max_value(), r).unwrap();
1847		PerU16::from_rational_with_rounding(u16::max_value() - 1, u16::max_value(), r).unwrap();
1848		Permill::from_rational_with_rounding(1, u64::max_value(), r).unwrap();
1849		Permill::from_rational_with_rounding(1, u32::max_value(), r).unwrap();
1850		Permill::from_rational_with_rounding(u64::max_value() - 1, u64::max_value(), r).unwrap();
1851		Permill::from_rational_with_rounding(u32::max_value() - 1, u32::max_value(), r).unwrap();
1852		Perbill::from_rational_with_rounding(1, u64::max_value(), r).unwrap();
1853		Perbill::from_rational_with_rounding(1, u32::max_value(), r).unwrap();
1854		Perbill::from_rational_with_rounding(u64::max_value() - 1, u64::max_value(), r).unwrap();
1855		Perbill::from_rational_with_rounding(u32::max_value() - 1, u32::max_value(), r).unwrap();
1856	}
1857}
1858
1859#[test]
1860fn from_rational_with_rounding_breakage() {
1861	let n = 372633774963620730670986667244911905u128;
1862	let d = 512593663333074177468745541591173060u128;
1863	let q = Perquintill::from_rational_with_rounding(n, d, Rounding::Down).unwrap();
1864	assert!(q * d <= n);
1865}
1866
1867#[test]
1868fn from_rational_with_rounding_breakage_2() {
1869	let n = 36893488147419103230u128;
1870	let d = 36893488147419103630u128;
1871	let q = Perquintill::from_rational_with_rounding(n, d, Rounding::Up).unwrap();
1872	assert!(q * d >= n);
1873}
1874
1875implement_per_thing!(Percent, test_per_cent, [u32, u64, u128], 100u8, u8, u16, "_Percent_",);
1876implement_per_thing_with_perthousand!(
1877	PerU16,
1878	test_peru16,
1879	test_peru16_extra,
1880	[u32, u64, u128],
1881	65535_u16,
1882	u16,
1883	u32,
1884	"_Parts per 65535_",
1885);
1886implement_per_thing_with_perthousand!(
1887	Permill,
1888	test_permill,
1889	test_permill_extra,
1890	[u32, u64, u128],
1891	1_000_000u32,
1892	u32,
1893	u64,
1894	"_Parts per Million_",
1895);
1896implement_per_thing_with_perthousand!(
1897	Perbill,
1898	test_perbill,
1899	test_perbill_extra,
1900	[u32, u64, u128],
1901	1_000_000_000u32,
1902	u32,
1903	u64,
1904	"_Parts per Billion_",
1905);
1906implement_per_thing_with_perthousand!(
1907	Perquintill,
1908	test_perquintill,
1909	test_perquintill_extra,
1910	[u64, u128],
1911	1_000_000_000_000_000_000u64,
1912	u64,
1913	u128,
1914	"_Parts per Quintillion_",
1915);