multiply and divide was straight up wrong, and bruh this needs const generics so bad

This commit is contained in:
Quaternions 2024-08-29 11:16:38 -07:00
parent 491de52f17
commit 3d3eb966a4

View File

@ -1,4 +1,4 @@
use bnum::BInt;
use bnum::{BInt,cast::As};
use typenum::Unsigned;
use std::marker::PhantomData;
@ -60,7 +60,7 @@ impl<const CHUNKS:usize,Frac> std::ops::Neg for Fixed<CHUNKS,Frac>{
}
}
macro_rules! impl_operator {
macro_rules! impl_additive_operator {
( $struct: ident, $trait: ident, $method: ident, $output: ty ) => {
impl<const CHUNKS:usize,Frac> core::ops::$trait for $struct<CHUNKS,Frac>{
type Output = $output;
@ -87,7 +87,7 @@ macro_rules! impl_operator {
}
};
}
macro_rules! impl_assign_operator {
macro_rules! impl_additive_assign_operator {
( $struct: ident, $trait: ident, $method: ident ) => {
impl<const CHUNKS:usize,Frac> core::ops::$trait for $struct<CHUNKS,Frac>{
fn $method(&mut self, other: Self) {
@ -106,24 +106,155 @@ macro_rules! impl_assign_operator {
}
// Impl arithmetic pperators
impl_assign_operator!( Fixed, AddAssign, add_assign );
impl_operator!( Fixed, Add, add, Self );
impl_assign_operator!( Fixed, SubAssign, sub_assign );
impl_operator!( Fixed, Sub, sub, Self );
impl_assign_operator!( Fixed, MulAssign, mul_assign );
impl_operator!( Fixed, Mul, mul, Self );
impl_assign_operator!( Fixed, DivAssign, div_assign );
impl_operator!( Fixed, Div, div, Self );
impl_assign_operator!( Fixed, RemAssign, rem_assign );
impl_operator!( Fixed, Rem, rem, Self );
impl_additive_assign_operator!( Fixed, AddAssign, add_assign );
impl_additive_operator!( Fixed, Add, add, Self );
impl_additive_assign_operator!( Fixed, SubAssign, sub_assign );
impl_additive_operator!( Fixed, Sub, sub, Self );
impl_additive_assign_operator!( Fixed, RemAssign, rem_assign );
impl_additive_operator!( Fixed, Rem, rem, Self );
// Impl bitwise operators
impl_assign_operator!( Fixed, BitAndAssign, bitand_assign );
impl_operator!( Fixed, BitAnd, bitand, Self );
impl_assign_operator!( Fixed, BitOrAssign, bitor_assign );
impl_operator!( Fixed, BitOr, bitor, Self );
impl_assign_operator!( Fixed, BitXorAssign, bitxor_assign );
impl_operator!( Fixed, BitXor, bitxor, Self );
impl_additive_assign_operator!( Fixed, BitAndAssign, bitand_assign );
impl_additive_operator!( Fixed, BitAnd, bitand, Self );
impl_additive_assign_operator!( Fixed, BitOrAssign, bitor_assign );
impl_additive_operator!( Fixed, BitOr, bitor, Self );
impl_additive_assign_operator!( Fixed, BitXorAssign, bitxor_assign );
impl_additive_operator!( Fixed, BitXor, bitxor, Self );
macro_rules! impl_multiply_operator_const {
( $width:expr, $struct: ident, $trait: ident, $method: ident, $output: ty ) => {
impl<Frac:Unsigned> core::ops::$trait for $struct<$width,Frac>{
type Output = $output;
fn $method(self, other: Self) -> Self::Output {
//this can be done better but that is a job for later
let lhs=self.bits.as_::<BInt::<{$width*2}>>();
let rhs=other.bits.as_::<BInt::<{$width*2}>>();
Self {
bits:lhs.mul(rhs).shr(Frac::U32).as_(),
frac:PhantomData,
}
}
}
};
}
macro_rules! impl_multiply_assign_operator_const {
( $width:expr, $struct: ident, $trait: ident, $method: ident ) => {
impl<Frac> core::ops::$trait for $struct<$width,Frac>{
fn $method(&mut self, other: Self) {
self.bits.$method(other.bits);
}
}
};
}
macro_rules! impl_divide_operator_const {
( $width:expr, $struct: ident, $trait: ident, $method: ident, $output: ty ) => {
impl<Frac:Unsigned> core::ops::$trait for $struct<$width,Frac>{
type Output = $output;
fn $method(self, other: Self) -> Self::Output {
//this can be done better but that is a job for later
//this only needs to be $width+Frac::U32/64+1 but MUH CONST GENERICS!!!!!
let lhs=self.bits.as_::<BInt::<{$width*2}>>().shl(Frac::U32);
let rhs=other.bits.as_::<BInt::<{$width*2}>>();
Self {
bits:lhs.div(rhs).as_(),
frac:PhantomData,
}
}
}
};
}
macro_rules! impl_divide_assign_operator_const {
( $width:expr, $struct: ident, $trait: ident, $method: ident ) => {
impl<Frac> core::ops::$trait for $struct<$width,Frac>{
fn $method(&mut self, other: Self) {
self.bits.$method(other.bits);
}
}
};
}
macro_rules! impl_multiplicatave_operator {
( $struct: ident, $trait: ident, $method: ident, $output: ty ) => {
impl<const CHUNKS:usize,Frac,U> core::ops::$trait<U> for $struct<CHUNKS,Frac>
where
BInt::<CHUNKS>:From<U>+core::ops::$trait,
{
type Output = $output;
fn $method(self, other: U) -> Self::Output {
Self {
bits:self.bits.$method(BInt::<CHUNKS>::from(other)),
frac:PhantomData,
}
}
}
};
}
macro_rules! impl_multiplicatave_assign_operator {
( $struct: ident, $trait: ident, $method: ident ) => {
impl<const CHUNKS:usize,Frac,U> core::ops::$trait<U> for $struct<CHUNKS,Frac>
where
BInt::<CHUNKS>:From<U>+core::ops::$trait,
{
fn $method(&mut self, other: U) {
self.bits.$method(BInt::<CHUNKS>::from(other));
}
}
};
}
macro_rules! impl_operator_16 {
( $macro: ident, $struct: ident, $trait: ident, $method: ident, $output: ty ) => {
$macro!(1,$struct,$trait,$method,$output);
$macro!(2,$struct,$trait,$method,$output);
$macro!(3,$struct,$trait,$method,$output);
$macro!(4,$struct,$trait,$method,$output);
$macro!(5,$struct,$trait,$method,$output);
$macro!(6,$struct,$trait,$method,$output);
$macro!(7,$struct,$trait,$method,$output);
$macro!(8,$struct,$trait,$method,$output);
$macro!(9,$struct,$trait,$method,$output);
$macro!(10,$struct,$trait,$method,$output);
$macro!(11,$struct,$trait,$method,$output);
$macro!(12,$struct,$trait,$method,$output);
$macro!(13,$struct,$trait,$method,$output);
$macro!(14,$struct,$trait,$method,$output);
$macro!(15,$struct,$trait,$method,$output);
$macro!(16,$struct,$trait,$method,$output);
}
}
macro_rules! impl_assign_operator_16 {
( $macro: ident, $struct: ident, $trait: ident, $method: ident ) => {
$macro!(1,$struct,$trait,$method);
$macro!(2,$struct,$trait,$method);
$macro!(3,$struct,$trait,$method);
$macro!(4,$struct,$trait,$method);
$macro!(5,$struct,$trait,$method);
$macro!(6,$struct,$trait,$method);
$macro!(7,$struct,$trait,$method);
$macro!(8,$struct,$trait,$method);
$macro!(9,$struct,$trait,$method);
$macro!(10,$struct,$trait,$method);
$macro!(11,$struct,$trait,$method);
$macro!(12,$struct,$trait,$method);
$macro!(13,$struct,$trait,$method);
$macro!(14,$struct,$trait,$method);
$macro!(15,$struct,$trait,$method);
$macro!(16,$struct,$trait,$method);
}
}
impl_assign_operator_16!( impl_multiply_assign_operator_const, Fixed, MulAssign, mul_assign );
impl_operator_16!( impl_multiply_operator_const, Fixed, Mul, mul, Self );
impl_assign_operator_16!( impl_divide_assign_operator_const, Fixed, DivAssign, div_assign );
impl_operator_16!( impl_divide_operator_const, Fixed, Div, div, Self );
impl_multiplicatave_assign_operator!( Fixed, MulAssign, mul_assign );
impl_multiplicatave_operator!( Fixed, Mul, mul, Self );
impl_multiplicatave_assign_operator!( Fixed, DivAssign, div_assign );
impl_multiplicatave_operator!( Fixed, Div, div, Self );
macro_rules! impl_shift_operator {
( $struct: ident, $trait: ident, $method: ident, $output: ty ) => {
@ -153,7 +284,10 @@ impl_shift_operator!( Fixed, Shl, shl, Self );
impl_shift_assign_operator!( Fixed, ShrAssign, shr_assign );
impl_shift_operator!( Fixed, Shr, shr, Self );
impl<const CHUNKS:usize,Frac:Unsigned> Fixed<CHUNKS,Frac>{
impl<const CHUNKS:usize,Frac:Unsigned> Fixed<CHUNKS,Frac>
where
Fixed::<CHUNKS,Frac>:std::ops::Mul<Fixed<CHUNKS,Frac>,Output=Fixed<CHUNKS,Frac>>,
{
pub fn sqrt_unchecked(self)->Self{
//find pow2 more powerful than self
let mut pow2=if Self::ONE<self{