pezsp_arithmetic/
per_things.rs

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