1pub extern crate muldiv;
68pub extern crate num_traits;
69pub extern crate typenum;
70
71pub mod aliases;
72pub mod fix_value;
73pub mod prelude;
74pub mod util;
75
76use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
77use core::fmt::{Debug, Error, Formatter};
78use core::hash::{Hash, Hasher};
79use core::marker::PhantomData;
80use core::ops::{Add, Div, Mul, Neg, Rem, Sub};
81use core::ops::{AddAssign, DivAssign, MulAssign, RemAssign, SubAssign};
82
83use muldiv::MulDiv;
84use num_traits::{CheckedAdd, CheckedDiv, CheckedMul, CheckedSub, SaturatingAdd, SaturatingSub};
85use paste::paste;
86use typenum::consts::Z0;
87use typenum::marker_traits::{Bit, Integer, Unsigned};
88use typenum::operator_aliases::{AbsVal, Diff, Le, Sum};
89use typenum::type_operators::{Abs, IsLess};
90
91pub struct Fix<Bits, Base, Exp> {
119 pub bits: Bits,
121
122 marker: PhantomData<(Base, Exp)>,
123}
124
125impl<Bits, Base, Exp> Fix<Bits, Base, Exp> {
126 pub fn new(bits: Bits) -> Self {
136 Fix {
137 bits,
138 marker: PhantomData,
139 }
140 }
141
142 pub const fn constant(bits: Bits) -> Self {
144 Fix {
145 bits,
146 marker: PhantomData,
147 }
148 }
149
150 pub fn convert<ToExp>(self) -> Fix<Bits, Base, ToExp>
162 where
163 Bits: FromUnsigned + Pow + Mul<Output = Bits> + Div<Output = Bits>,
164 Base: Unsigned,
165 Exp: Sub<ToExp>,
166 Diff<Exp, ToExp>: Abs + IsLess<Z0>,
167 AbsVal<Diff<Exp, ToExp>>: Integer,
168 {
169 let base = Bits::from_unsigned::<Base>();
170 let diff = AbsVal::<Diff<Exp, ToExp>>::to_i32();
171 let inverse = Le::<Diff<Exp, ToExp>, Z0>::to_bool();
172
173 let ratio = base.pow(diff.unsigned_abs());
176
177 if inverse {
178 Fix::new(self.bits / ratio)
179 } else {
180 Fix::new(self.bits * ratio)
181 }
182 }
183
184 pub fn widen<ToBits>(self) -> Fix<ToBits, Base, Exp>
196 where
197 ToBits: From<Bits>,
198 {
199 Fix::<ToBits, Base, Exp>::new(self.bits.into())
200 }
201
202 pub fn narrow<ToBits>(self) -> Option<Fix<ToBits, Base, Exp>>
215 where
216 ToBits: TryFrom<Bits>,
217 {
218 self.bits.try_into().ok().map(Fix::<ToBits, Base, Exp>::new)
219 }
220}
221
222pub trait FromUnsigned {
229 fn from_unsigned<U>() -> Self
231 where
232 U: Unsigned;
233}
234
235macro_rules! impl_from_unsigned {
236 ($ty:ident) => {
237 impl FromUnsigned for $ty {
238 fn from_unsigned<U: Unsigned>() -> Self {
239 paste! { U::[<to_$ty>]() }
240 }
241 }
242 };
243}
244
245impl_from_unsigned!(u8);
246impl_from_unsigned!(u16);
247impl_from_unsigned!(u32);
248impl_from_unsigned!(u64);
249impl_from_unsigned!(u128);
250impl_from_unsigned!(usize);
251impl_from_unsigned!(i8);
252impl_from_unsigned!(i16);
253impl_from_unsigned!(i32);
254impl_from_unsigned!(i64);
255impl_from_unsigned!(i128);
256impl_from_unsigned!(isize);
257
258pub trait Pow {
263 #[must_use]
265 fn pow(self, exp: u32) -> Self;
266}
267
268macro_rules! impl_pow {
269 ($ty:ident) => {
270 impl Pow for $ty {
271 #[inline]
272 fn pow(self, exp: u32) -> Self {
273 self.pow(exp)
274 }
275 }
276 };
277}
278
279impl_pow!(u8);
280impl_pow!(u16);
281impl_pow!(u32);
282impl_pow!(u64);
283impl_pow!(u128);
284impl_pow!(usize);
285impl_pow!(i8);
286impl_pow!(i16);
287impl_pow!(i32);
288impl_pow!(i64);
289impl_pow!(i128);
290impl_pow!(isize);
291
292impl<Bits, Base, Exp> Copy for Fix<Bits, Base, Exp> where Bits: Copy {}
295
296impl<Bits, Base, Exp> Clone for Fix<Bits, Base, Exp>
297where
298 Bits: Clone,
299{
300 fn clone(&self) -> Self {
301 Self::new(self.bits.clone())
302 }
303}
304
305impl<Bits, Base, Exp> Default for Fix<Bits, Base, Exp>
306where
307 Bits: Default,
308{
309 fn default() -> Self {
310 Self::new(Bits::default())
311 }
312}
313
314impl<Bits, Base, Exp> Hash for Fix<Bits, Base, Exp>
315where
316 Bits: Hash,
317{
318 fn hash<H>(&self, state: &mut H)
319 where
320 H: Hasher,
321 {
322 self.bits.hash(state);
323 }
324}
325
326impl<Bits, Base, Exp> Debug for Fix<Bits, Base, Exp>
327where
328 Bits: Debug,
329 Base: Unsigned,
330 Exp: Integer,
331{
332 fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
333 write!(f, "{:?}x{}^{}", self.bits, Base::to_u64(), Exp::to_i64())
334 }
335}
336
337impl<Bits, Base, Exp> Eq for Fix<Bits, Base, Exp> where Bits: Eq {}
340impl<Bits, Base, Exp> PartialEq for Fix<Bits, Base, Exp>
341where
342 Bits: PartialEq,
343{
344 fn eq(&self, rhs: &Self) -> bool {
345 self.bits == rhs.bits
346 }
347}
348
349impl<Bits, Base, Exp> PartialOrd for Fix<Bits, Base, Exp>
350where
351 Bits: PartialOrd,
352{
353 fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
354 self.bits.partial_cmp(&rhs.bits)
355 }
356}
357
358impl<Bits, Base, Exp> Ord for Fix<Bits, Base, Exp>
359where
360 Bits: Ord,
361{
362 fn cmp(&self, rhs: &Self) -> Ordering {
363 self.bits.cmp(&rhs.bits)
364 }
365}
366
367impl<Bits, Base, Exp> Neg for Fix<Bits, Base, Exp>
370where
371 Bits: Neg<Output = Bits>,
372{
373 type Output = Self;
374 fn neg(self) -> Self {
375 Self::new(-self.bits)
376 }
377}
378
379impl<Bits, Base, Exp> Add for Fix<Bits, Base, Exp>
380where
381 Bits: Add<Output = Bits>,
382{
383 type Output = Self;
384 fn add(self, rhs: Self) -> Self {
385 Self::new(self.bits + rhs.bits)
386 }
387}
388
389impl<Bits, Base, Exp> Sub for Fix<Bits, Base, Exp>
390where
391 Bits: Sub<Output = Bits>,
392{
393 type Output = Self;
394 fn sub(self, rhs: Self) -> Self {
395 Self::new(self.bits - rhs.bits)
396 }
397}
398
399impl<Bits, Base, LExp, RExp> Mul<Fix<Bits, Base, RExp>> for Fix<Bits, Base, LExp>
400where
401 Bits: Mul<Output = Bits>,
402 LExp: Add<RExp>,
403{
404 type Output = Fix<Bits, Base, Sum<LExp, RExp>>;
405 fn mul(self, rhs: Fix<Bits, Base, RExp>) -> Self::Output {
406 Self::Output::new(self.bits * rhs.bits)
407 }
408}
409
410impl<Bits, Base, LExp, RExp> Div<Fix<Bits, Base, RExp>> for Fix<Bits, Base, LExp>
411where
412 Bits: Div<Output = Bits>,
413 LExp: Sub<RExp>,
414{
415 type Output = Fix<Bits, Base, Diff<LExp, RExp>>;
416 fn div(self, rhs: Fix<Bits, Base, RExp>) -> Self::Output {
417 Self::Output::new(self.bits / rhs.bits)
418 }
419}
420
421impl<Bits, Base, Exp> Rem for Fix<Bits, Base, Exp>
422where
423 Bits: Rem<Output = Bits>,
424{
425 type Output = Self;
426 fn rem(self, rhs: Self) -> Self {
427 Self::new(self.bits % rhs.bits)
428 }
429}
430
431impl<Bits, Base, Exp> Mul<Bits> for Fix<Bits, Base, Exp>
432where
433 Bits: Mul<Output = Bits>,
434{
435 type Output = Self;
436 fn mul(self, rhs: Bits) -> Self {
437 Self::new(self.bits * rhs)
438 }
439}
440
441impl<Bits, Base, Exp> Div<Bits> for Fix<Bits, Base, Exp>
442where
443 Bits: Div<Output = Bits>,
444{
445 type Output = Self;
446 fn div(self, rhs: Bits) -> Self {
447 Self::new(self.bits / rhs)
448 }
449}
450
451impl<Bits, Base, Exp> Rem<Bits> for Fix<Bits, Base, Exp>
452where
453 Bits: Rem<Output = Bits>,
454{
455 type Output = Self;
456 fn rem(self, rhs: Bits) -> Self {
457 Self::new(self.bits % rhs)
458 }
459}
460
461impl<Bits, Base, Exp> AddAssign for Fix<Bits, Base, Exp>
462where
463 Bits: AddAssign,
464{
465 fn add_assign(&mut self, rhs: Self) {
466 self.bits += rhs.bits;
467 }
468}
469
470impl<Bits, Base, Exp> SubAssign for Fix<Bits, Base, Exp>
471where
472 Bits: SubAssign,
473{
474 fn sub_assign(&mut self, rhs: Self) {
475 self.bits -= rhs.bits;
476 }
477}
478
479impl<Bits, Base, Exp> MulAssign<Bits> for Fix<Bits, Base, Exp>
480where
481 Bits: MulAssign,
482{
483 fn mul_assign(&mut self, rhs: Bits) {
484 self.bits *= rhs;
485 }
486}
487
488impl<Bits, Base, Exp> DivAssign<Bits> for Fix<Bits, Base, Exp>
489where
490 Bits: DivAssign,
491{
492 fn div_assign(&mut self, rhs: Bits) {
493 self.bits /= rhs;
494 }
495}
496
497impl<Bits, Base, LExp, RExp> RemAssign<Fix<Bits, Base, RExp>> for Fix<Bits, Base, LExp>
498where
499 Bits: RemAssign,
500{
501 fn rem_assign(&mut self, rhs: Fix<Bits, Base, RExp>) {
502 self.bits %= rhs.bits;
503 }
504}
505
506impl<Bits, Base, Exp> RemAssign<Bits> for Fix<Bits, Base, Exp>
507where
508 Bits: RemAssign,
509{
510 fn rem_assign(&mut self, rhs: Bits) {
511 self.bits %= rhs;
512 }
513}
514
515impl<Bits, Base, Exp> CheckedAdd for Fix<Bits, Base, Exp>
518where
519 Bits: CheckedAdd,
520{
521 fn checked_add(&self, v: &Self) -> Option<Self> {
522 self.bits.checked_add(&v.bits).map(Self::new)
523 }
524}
525
526impl<Bits, Base, Exp> CheckedSub for Fix<Bits, Base, Exp>
527where
528 Bits: CheckedSub,
529{
530 fn checked_sub(&self, v: &Self) -> Option<Self> {
531 self.bits.checked_sub(&v.bits).map(Self::new)
532 }
533}
534
535impl<Bits, Base, Exp> Fix<Bits, Base, Exp>
536where
537 Self: CheckedSub,
538 Bits: Copy,
539{
540 #[must_use]
541 pub fn abs_diff(&self, v: &Self) -> Fix<Bits, Base, Exp> {
542 self.checked_sub(v).unwrap_or_else(|| *v - *self)
543 }
544}
545
546pub trait CheckedMulFix<Rhs> {
548 type Output;
549 fn checked_mul(&self, v: &Rhs) -> Option<Self::Output>;
550}
551
552impl<Bits, Base, LExp, RExp> CheckedMulFix<Fix<Bits, Base, RExp>> for Fix<Bits, Base, LExp>
553where
554 Bits: CheckedMul,
555 LExp: Add<RExp>,
556{
557 type Output = Fix<Bits, Base, Sum<LExp, RExp>>;
558 fn checked_mul(&self, v: &Fix<Bits, Base, RExp>) -> Option<Self::Output> {
559 self.bits.checked_mul(&v.bits).map(Self::Output::new)
560 }
561}
562
563pub trait CheckedDivFix<Rhs> {
565 type Output;
566 fn checked_div(&self, v: &Rhs) -> Option<Self::Output>;
567}
568
569impl<Bits, Base, LExp, RExp> CheckedDivFix<Fix<Bits, Base, RExp>> for Fix<Bits, Base, LExp>
570where
571 Bits: CheckedDiv,
572 LExp: Sub<RExp>,
573{
574 type Output = Fix<Bits, Base, Diff<LExp, RExp>>;
575 fn checked_div(&self, v: &Fix<Bits, Base, RExp>) -> Option<Self::Output> {
576 self.bits.checked_div(&v.bits).map(Self::Output::new)
577 }
578}
579
580impl<Bits, Base, LExp, RExp> MulDiv<Fix<Bits, Base, RExp>> for Fix<Bits, Base, LExp>
581where
582 Bits: MulDiv,
583{
584 type Output = Fix<<Bits as MulDiv>::Output, Base, LExp>;
585 fn mul_div_ceil(
586 self,
587 num: Fix<Bits, Base, RExp>,
588 denom: Fix<Bits, Base, RExp>,
589 ) -> Option<Self::Output> {
590 self.bits
591 .mul_div_ceil(num.bits, denom.bits)
592 .map(Self::Output::new)
593 }
594 fn mul_div_floor(
595 self,
596 num: Fix<Bits, Base, RExp>,
597 denom: Fix<Bits, Base, RExp>,
598 ) -> Option<Self::Output> {
599 self.bits
600 .mul_div_floor(num.bits, denom.bits)
601 .map(Self::Output::new)
602 }
603 fn mul_div_round(
604 self,
605 num: Fix<Bits, Base, RExp>,
606 denom: Fix<Bits, Base, RExp>,
607 ) -> Option<Self::Output> {
608 self.bits
609 .mul_div_round(num.bits, denom.bits)
610 .map(Self::Output::new)
611 }
612}
613
614impl<Bits, Base, Exp> SaturatingAdd for Fix<Bits, Base, Exp>
617where
618 Bits: SaturatingAdd,
619{
620 fn saturating_add(&self, v: &Self) -> Self {
621 Self::new(self.bits.saturating_add(&v.bits))
622 }
623}
624
625impl<Bits, Base, Exp> SaturatingSub for Fix<Bits, Base, Exp>
626where
627 Bits: SaturatingSub,
628{
629 fn saturating_sub(&self, v: &Self) -> Self {
630 Self::new(self.bits.saturating_sub(&v.bits))
631 }
632}
633
634#[cfg(test)]
635mod tests {
636 use num_traits::{SaturatingAdd, SaturatingSub};
637
638 use crate::aliases::si::{Kilo, Milli, Unit};
639 use crate::{CheckedAdd, CheckedDivFix, CheckedMulFix, CheckedSub, MulDiv};
640
641 #[test]
642 fn convert_milli_to_kilo() {
643 assert_eq!(Kilo::new(15), Milli::new(15_000_000).convert());
644 }
645
646 #[test]
647 fn convert_kilo_to_milli() {
648 assert_eq!(Milli::new(15_000_000), Kilo::new(15).convert());
649 }
650
651 #[test]
652 fn cmp() {
653 assert!(Kilo::new(1) < Kilo::new(2));
654 }
655
656 #[test]
657 fn neg() {
658 assert_eq!(Kilo::new(-1), -Kilo::new(1i32));
659 }
660
661 #[test]
662 fn add() {
663 assert_eq!(Kilo::new(3), Kilo::new(1) + Kilo::new(2));
664 }
665
666 #[test]
667 fn sub() {
668 assert_eq!(Kilo::new(1), Kilo::new(3) - Kilo::new(2));
669 }
670
671 #[test]
672 fn mul() {
673 assert_eq!(Unit::new(6), Kilo::new(2) * Milli::new(3));
674 }
675
676 #[test]
677 fn div() {
678 assert_eq!(Unit::new(3), Kilo::new(6) / Kilo::new(2));
679 }
680
681 #[test]
682 fn rem() {
683 assert_eq!(Kilo::new(1), Kilo::new(6) % Kilo::new(5));
684 }
685
686 #[test]
687 fn mul_bits() {
688 assert_eq!(Kilo::new(6), Kilo::new(2) * 3);
689 }
690
691 #[test]
692 fn div_bits() {
693 assert_eq!(Kilo::new(3), Kilo::new(6) / 2);
694 }
695
696 #[test]
697 fn rem_bits() {
698 assert_eq!(Kilo::new(1), Kilo::new(6) % 5);
699 }
700
701 #[test]
702 fn add_assign() {
703 let mut a = Kilo::new(1);
704 a += Kilo::new(2);
705 assert_eq!(Kilo::new(3), a);
706 }
707
708 #[test]
709 fn sub_assign() {
710 let mut a = Kilo::new(3);
711 a -= Kilo::new(2);
712 assert_eq!(Kilo::new(1), a);
713 }
714
715 #[test]
716 fn mul_assign_bits() {
717 let mut a = Kilo::new(2);
718 a *= 3;
719 assert_eq!(Kilo::new(6), a);
720 }
721
722 #[test]
723 fn div_assign_bits() {
724 let mut a = Kilo::new(6);
725 a /= 2;
726 assert_eq!(Kilo::new(3), a);
727 }
728
729 #[test]
730 fn rem_assign() {
731 let mut a = Kilo::new(6);
732 a %= Milli::new(5);
733 assert_eq!(Kilo::new(1), a);
734 }
735
736 #[test]
737 fn rem_assign_bits() {
738 let mut a = Kilo::new(6);
739 a %= 5;
740 assert_eq!(Kilo::new(1), a);
741 }
742
743 #[test]
744 fn checked_add_neg() {
745 let max = Kilo::new(u8::MAX);
746 let one = Kilo::new(1);
747 assert!(max.checked_add(&one).is_none())
748 }
749
750 #[test]
751 fn checked_add_pos() {
752 let forty = Kilo::new(40);
753 let two = Kilo::new(2);
754 assert_eq!(forty.checked_add(&two), Some(Kilo::new(42)))
755 }
756
757 #[test]
758 fn checked_sub_neg() {
759 let one = Kilo::new(1);
760 let max = Kilo::new(u8::MAX);
761 assert!(one.checked_sub(&max).is_none())
762 }
763
764 #[test]
765 fn checked_sub_pos() {
766 let fifty = Kilo::new(50);
767 let eight = Kilo::new(8);
768 assert_eq!(fifty.checked_sub(&eight), Some(Kilo::new(42)))
769 }
770
771 #[test]
772 fn checked_mul_neg() {
773 let fifty = Kilo::new(50);
774 let max = Kilo::new(u8::MAX);
775 assert!(fifty.checked_mul(&max).is_none())
776 }
777
778 #[test]
779 fn checked_mul_pos() {
780 let fifty = Kilo::new(50_u64);
781 assert_eq!(
782 fifty.checked_mul(&fifty).map(|out| out.convert()),
783 Some(Kilo::new(2_500_000_u64))
784 )
785 }
786
787 #[test]
788 fn checked_div_neg() {
789 let one = Unit::new(0);
790 assert!(one.checked_div(&one).is_none())
791 }
792
793 #[test]
794 fn checked_div_pos() {
795 let hundred = Kilo::new(100);
796 let five = Kilo::new(5);
797 assert_eq!(hundred.checked_div(&five), Some(Unit::new(20)))
798 }
799
800 #[test]
801 fn narrow_succeeds() {
802 let one = Milli::new(1000u128);
803 let mapped = one.narrow::<u64>();
804 assert_eq!(mapped, Some(Milli::new(1000u64)));
805 }
806
807 #[test]
808 fn narrow_fails() {
809 let one = Milli::new(1699u64);
810 let mapped = one.narrow::<u8>();
811 assert_eq!(mapped, None);
812 }
813
814 #[test]
815 fn widen_succeeds() {
816 let one = Milli::new(1340191u64);
817 let mapped = one.widen::<u128>();
818 assert_eq!(mapped, Milli::new(1340191u128));
819 }
820
821 #[test]
822 fn mul_div_ceil() {
823 let start = Milli::new(313459u64);
824 let mul = Milli::new(1200u64);
825 let div = Milli::new(2450u64);
826 assert_eq!(start.mul_div_ceil(mul, div), Some(Milli::new(153531)));
827 }
828
829 #[test]
830 fn mul_div_ceil_unit() {
831 let start = Milli::new(31345934u64);
832 let mul = Milli::new(1000u64);
833 let div = Milli::new(2000u64);
834 assert_eq!(start.mul_div_ceil(mul, div), Some(Milli::new(15672967u64)));
835 }
836
837 #[test]
838 fn mul_div_floor() {
839 let start = Milli::new(69_693u64);
840 let mul = Milli::new(5_192u64);
841 let div = Milli::new(190u64);
842 assert_eq!(start.mul_div_floor(mul, div), Some(Milli::new(1904452u64)));
843 }
844
845 #[test]
846 fn mul_div_floor_unit() {
847 let start = Milli::new(69_693u64);
848 let mul = Milli::new(1000u64);
849 let div = Milli::new(9u64);
850 assert_eq!(start.mul_div_floor(mul, div), Some(Milli::new(7743666u64)));
851 }
852
853 #[test]
854 fn mul_div_round() {
855 let start = Milli::new(1892u64);
856 let mul = Milli::new(3222u64);
857 let div = Milli::new(9999u64);
858 assert_eq!(start.mul_div_round(mul, div), Some(Milli::new(610u64)));
859 }
860
861 #[test]
862 fn mul_div_round_unit() {
863 let start = Milli::new(1892u64);
864 let mul = Milli::new(1000u64);
865 let div = Milli::new(322u64);
866 assert_eq!(start.mul_div_round(mul, div), Some(Milli::new(5876u64)));
867 }
868
869 #[test]
870 fn abs_diff() {
871 let start = Milli::new(u128::MIN);
872 let end = Milli::new(u128::MAX);
873 assert_eq!(start.abs_diff(&end), end);
874 }
875
876 #[test]
877 fn constant() {
878 assert_eq!(Kilo::constant(69u64), Kilo::new(69u64));
879 }
880
881 #[test]
882 fn saturating_sub() {
883 let zero = Kilo::constant(0);
884 let result = zero.saturating_sub(&Kilo::new(69u64));
885 assert_eq!(zero, result);
886 }
887
888 #[test]
889 fn saturating_add() {
890 let max = Kilo::new(u64::MAX);
891 let result = max.saturating_add(&Kilo::new(69u64));
892 assert_eq!(max, result);
893 }
894}