Add support for scaling numbers by primitive types.
This commit is contained in:
@@ -4,6 +4,7 @@ subtraction_impls!(I192, I256, U256);
|
||||
mul_impls!(I192, I384);
|
||||
div_impls!(I192, U192);
|
||||
smodinv_impls!(I192, I256);
|
||||
scale_impls!(I192, I256);
|
||||
conversion_impls!(I192, U192, I256, U256);
|
||||
conversion_impls!(I192, U192, I384, U384);
|
||||
conversion_impls!(I192, U192, I512, U512);
|
||||
@@ -18,6 +19,7 @@ subtraction_impls!(I256, I320, U320);
|
||||
mul_impls!(I256, I512);
|
||||
div_impls!(I256, U256);
|
||||
smodinv_impls!(I256, I320);
|
||||
scale_impls!(I256, I320);
|
||||
conversion_impls!(I256, U256, I320, U320);
|
||||
conversion_impls!(I256, U256, I512, U512);
|
||||
conversion_impls!(I256, U256, I576, U576);
|
||||
@@ -31,6 +33,7 @@ shift_impls!(I320, U320);
|
||||
subtraction_impls!(I320, I384, U384);
|
||||
mul_impls!(I320, I640);
|
||||
div_impls!(I320, U320);
|
||||
scale_impls!(I320, I384);
|
||||
conversion_impls!(I320, U320, I384, U384);
|
||||
conversion_impls!(I320, U320, I640, U640);
|
||||
conversion_impls!(I320, U320, I704, U704);
|
||||
@@ -40,6 +43,7 @@ subtraction_impls!(I384, I448, U448);
|
||||
mul_impls!(I384, I768);
|
||||
div_impls!(I384, U384);
|
||||
smodinv_impls!(I384, I448);
|
||||
scale_impls!(I384, I448);
|
||||
conversion_impls!(I384, U384, I448, U448);
|
||||
conversion_impls!(I384, U384, I768, U768);
|
||||
conversion_impls!(I384, U384, I896, U896);
|
||||
@@ -52,6 +56,7 @@ shift_impls!(I448, U448);
|
||||
subtraction_impls!(I448, I512, U512);
|
||||
mul_impls!(I448, I896);
|
||||
div_impls!(I448, U448);
|
||||
scale_impls!(I448, I512);
|
||||
conversion_impls!(I448, U448, I512, U512);
|
||||
conversion_impls!(I448, U448, I896, U896);
|
||||
conversion_impls!(I448, U448, I960, U960);
|
||||
@@ -59,6 +64,7 @@ signed_impls!(I512, U512);
|
||||
subtraction_impls!(I512, I576, U576);
|
||||
mul_impls!(I512, I1024);
|
||||
div_impls!(I512, U512);
|
||||
scale_impls!(I512, I576);
|
||||
conversion_impls!(I512, U512, I576, U576);
|
||||
conversion_impls!(I512, U512, I1024, U1024);
|
||||
egcd_impls!(I576, U512, I512, I1152);
|
||||
@@ -72,6 +78,7 @@ subtraction_impls!(I576, I640, U640);
|
||||
mul_impls!(I576, I1152);
|
||||
div_impls!(I576, U576);
|
||||
smodinv_impls!(I576, I640);
|
||||
scale_impls!(I576, I640);
|
||||
conversion_impls!(I576, U576, I640, U640);
|
||||
conversion_impls!(I576, U576, I1152, U1152);
|
||||
conversion_impls!(I576, U576, I1216, U1216);
|
||||
@@ -85,6 +92,7 @@ shift_impls!(I640, U640);
|
||||
subtraction_impls!(I640, I704, U704);
|
||||
mul_impls!(I640, I1280);
|
||||
div_impls!(I640, U640);
|
||||
scale_impls!(I640, I704);
|
||||
conversion_impls!(I640, U640, I704, U704);
|
||||
conversion_impls!(I640, U640, I1280, U1280);
|
||||
conversion_impls!(I640, U640, I1344, U1344);
|
||||
@@ -95,6 +103,7 @@ signed_impls!(I896, U896);
|
||||
subtraction_impls!(I896, I960, U960);
|
||||
mul_impls!(I896, I1792);
|
||||
div_impls!(I896, U896);
|
||||
scale_impls!(I896, I960);
|
||||
conversion_impls!(I896, U896, I960, U960);
|
||||
conversion_impls!(I896, U896, I1792, U1792);
|
||||
signed_impls!(I960, U960);
|
||||
@@ -109,6 +118,7 @@ shift_impls!(I1088, U1088);
|
||||
subtraction_impls!(I1088, I1152, U1152);
|
||||
mul_impls!(I1088, I2176);
|
||||
div_impls!(I1088, U1088);
|
||||
scale_impls!(I1088, I1152);
|
||||
conversion_impls!(I1088, U1088, I1152, U1152);
|
||||
conversion_impls!(I1088, U1088, I2176, U2176);
|
||||
conversion_impls!(I1088, U1088, I2240, U2240);
|
||||
@@ -121,6 +131,7 @@ signed_impls!(I1280, U1280);
|
||||
subtraction_impls!(I1280, I1344, U1344);
|
||||
mul_impls!(I1280, I2560);
|
||||
div_impls!(I1280, U1280);
|
||||
scale_impls!(I1280, I1344);
|
||||
conversion_impls!(I1280, U1280, I1344, U1344);
|
||||
conversion_impls!(I1280, U1280, I2560, U2560);
|
||||
signed_impls!(I1344, U1344);
|
||||
@@ -134,6 +145,7 @@ shift_impls!(I1600, U1600);
|
||||
subtraction_impls!(I1600, I1664, U1664);
|
||||
mul_impls!(I1600, I3200);
|
||||
div_impls!(I1600, U1600);
|
||||
scale_impls!(I1600, I1664);
|
||||
conversion_impls!(I1600, U1600, I1664, U1664);
|
||||
conversion_impls!(I1600, U1600, I3200, U3200);
|
||||
conversion_impls!(I1600, U1600, I3264, U3264);
|
||||
@@ -150,6 +162,7 @@ shift_impls!(I2112, U2112);
|
||||
subtraction_impls!(I2112, I2176, U2176);
|
||||
mul_impls!(I2112, I4224);
|
||||
div_impls!(I2112, U2112);
|
||||
scale_impls!(I2112, I2176);
|
||||
conversion_impls!(I2112, U2112, I2176, U2176);
|
||||
conversion_impls!(I2112, U2112, I4224, U4224);
|
||||
conversion_impls!(I2112, U2112, I4288, U4288);
|
||||
@@ -169,6 +182,7 @@ shift_impls!(I3136, U3136);
|
||||
subtraction_impls!(I3136, I3200, U3200);
|
||||
mul_impls!(I3136, I6272);
|
||||
div_impls!(I3136, U3136);
|
||||
scale_impls!(I3136, I3200);
|
||||
conversion_impls!(I3136, U3136, I3200, U3200);
|
||||
conversion_impls!(I3136, U3136, I6272, U6272);
|
||||
conversion_impls!(I3136, U3136, I6336, U6336);
|
||||
@@ -187,6 +201,7 @@ shift_impls!(I4160, U4160);
|
||||
subtraction_impls!(I4160, I4224, U4224);
|
||||
mul_impls!(I4160, I8320);
|
||||
div_impls!(I4160, U4160);
|
||||
scale_impls!(I4160, I4224);
|
||||
conversion_impls!(I4160, U4160, I4224, U4224);
|
||||
conversion_impls!(I4160, U4160, I8320, U8320);
|
||||
conversion_impls!(I4160, U4160, I8384, U8384);
|
||||
@@ -208,6 +223,7 @@ shift_impls!(I7744, U7744);
|
||||
subtraction_impls!(I7744, I7808, U7808);
|
||||
mul_impls!(I7744, I15488);
|
||||
div_impls!(I7744, U7744);
|
||||
scale_impls!(I7744, I7808);
|
||||
conversion_impls!(I7744, U7744, I7808, U7808);
|
||||
conversion_impls!(I7744, U7744, I15488, U15488);
|
||||
conversion_impls!(I7744, U7744, I15552, U15552);
|
||||
@@ -223,6 +239,7 @@ shift_impls!(I8256, U8256);
|
||||
subtraction_impls!(I8256, I8320, U8320);
|
||||
mul_impls!(I8256, I16512);
|
||||
div_impls!(I8256, U8256);
|
||||
scale_impls!(I8256, I8320);
|
||||
conversion_impls!(I8256, U8256, I8320, U8320);
|
||||
conversion_impls!(I8256, U8256, I16512, U16512);
|
||||
conversion_impls!(I8256, U8256, I16576, U16576);
|
||||
@@ -241,6 +258,7 @@ shift_impls!(I15424, U15424);
|
||||
subtraction_impls!(I15424, I15488, U15488);
|
||||
mul_impls!(I15424, I30848);
|
||||
div_impls!(I15424, U15424);
|
||||
scale_impls!(I15424, I15488);
|
||||
conversion_impls!(I15424, U15424, I15488, U15488);
|
||||
conversion_impls!(I15424, U15424, I30848, U30848);
|
||||
conversion_impls!(I15424, U15424, I30912, U30912);
|
||||
@@ -523,6 +541,29 @@ mod tests {
|
||||
generate_sigshiftr_tests!(I8256, U8256, i8256);
|
||||
generate_sigshiftr_tests!(I15424, U15424, i15424);
|
||||
}
|
||||
mod sigscale {
|
||||
use super::super::*;
|
||||
use testing::{build_test_path,run_test};
|
||||
|
||||
generate_sigscale_tests!(I192, U192, i192, I256, U256);
|
||||
generate_sigscale_tests!(I256, U256, i256, I320, U320);
|
||||
generate_sigscale_tests!(I320, U320, i320, I384, U384);
|
||||
generate_sigscale_tests!(I384, U384, i384, I448, U448);
|
||||
generate_sigscale_tests!(I448, U448, i448, I512, U512);
|
||||
generate_sigscale_tests!(I512, U512, i512, I576, U576);
|
||||
generate_sigscale_tests!(I576, U576, i576, I640, U640);
|
||||
generate_sigscale_tests!(I640, U640, i640, I704, U704);
|
||||
generate_sigscale_tests!(I896, U896, i896, I960, U960);
|
||||
generate_sigscale_tests!(I1088, U1088, i1088, I1152, U1152);
|
||||
generate_sigscale_tests!(I1280, U1280, i1280, I1344, U1344);
|
||||
generate_sigscale_tests!(I1600, U1600, i1600, I1664, U1664);
|
||||
generate_sigscale_tests!(I2112, U2112, i2112, I2176, U2176);
|
||||
generate_sigscale_tests!(I3136, U3136, i3136, I3200, U3200);
|
||||
generate_sigscale_tests!(I4160, U4160, i4160, I4224, U4224);
|
||||
generate_sigscale_tests!(I7744, U7744, i7744, I7808, U7808);
|
||||
generate_sigscale_tests!(I8256, U8256, i8256, I8320, U8320);
|
||||
generate_sigscale_tests!(I15424, U15424, i15424, I15488, U15488);
|
||||
}
|
||||
mod egcd {
|
||||
use super::super::*;
|
||||
use testing::{build_test_path,run_test};
|
||||
|
||||
@@ -28,6 +28,8 @@ mod modinv;
|
||||
#[macro_use]
|
||||
mod mul;
|
||||
#[macro_use]
|
||||
mod scale;
|
||||
#[macro_use]
|
||||
mod shift;
|
||||
#[macro_use]
|
||||
mod subtraction;
|
||||
|
||||
121
src/signed/scale.rs
Normal file
121
src/signed/scale.rs
Normal file
@@ -0,0 +1,121 @@
|
||||
macro_rules! scale_impls
|
||||
{
|
||||
($base: ident, $big: ident) => {
|
||||
scale_impls!($base, $big, u8);
|
||||
scale_impls!($base, $big, u16);
|
||||
scale_impls!($base, $big, u32);
|
||||
scale_impls!($base, $big, u64);
|
||||
scale_impls!($base, $big, usize);
|
||||
|
||||
scale_impls!($base, $big, scaled i8);
|
||||
scale_impls!($base, $big, scaled i16);
|
||||
scale_impls!($base, $big, scaled i32);
|
||||
scale_impls!($base, $big, scaled i64);
|
||||
scale_impls!($base, $big, scaled isize);
|
||||
};
|
||||
($base: ident, $big: ident, $prim: ident) => {
|
||||
impl Mul<$prim> for $base {
|
||||
type Output = $big;
|
||||
|
||||
fn mul(self, factor: $prim) -> $big {
|
||||
&self * factor
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Mul<$prim> for &'a $base {
|
||||
type Output = $big;
|
||||
|
||||
fn mul(self, factor: $prim) -> $big {
|
||||
let mut res = $big::zero();
|
||||
scale(&mut res.value.value, &self.value.value, factor as u64);
|
||||
res.negative = self.negative && !res.value.is_zero();
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<$base> for $prim {
|
||||
type Output = $big;
|
||||
|
||||
fn mul(self, rhs: $base) -> $big {
|
||||
rhs.mul(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Mul<&'a $base> for $prim {
|
||||
type Output = $big;
|
||||
|
||||
fn mul(self, rhs: &$base) -> $big {
|
||||
rhs.mul(self)
|
||||
}
|
||||
}
|
||||
};
|
||||
($base: ident, $big: ident, scaled $prim: ident) => {
|
||||
impl Mul<$prim> for $base {
|
||||
type Output = $big;
|
||||
|
||||
fn mul(self, factor: $prim) -> $big {
|
||||
&self * factor
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Mul<$prim> for &'a $base {
|
||||
type Output = $big;
|
||||
|
||||
fn mul(self, factor: $prim) -> $big {
|
||||
let mut res = $big::zero();
|
||||
scale(&mut res.value.value, &self.value.value, factor.abs() as u64);
|
||||
res.negative = (self.negative ^ (factor < 0)) && !res.value.is_zero();
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<$base> for $prim {
|
||||
type Output = $big;
|
||||
|
||||
fn mul(self, rhs: $base) -> $big {
|
||||
rhs.mul(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Mul<&'a $base> for $prim {
|
||||
type Output = $big;
|
||||
|
||||
fn mul(self, rhs: &$base) -> $big {
|
||||
rhs.mul(self)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
macro_rules! generate_sigscale_tests
|
||||
{
|
||||
($name: ident, $uname: ident, $lname: ident, $big: ident, $ubig: ident) => {
|
||||
#[test]
|
||||
fn $lname() {
|
||||
generate_sigscale_tests!(body $name, $uname, $lname, $big, $ubig);
|
||||
}
|
||||
};
|
||||
(ignore $name: ident, $uname:ident, $lname: ident, $big: ident, $ubig: ident) => {
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn $lname() {
|
||||
generate_sigscale_tests!(body $name, $uname, $lname, $big, $ubig);
|
||||
}
|
||||
};
|
||||
(body $name: ident, $uname: ident, $lname: ident, $big: ident, $ubig: ident) => {
|
||||
let fname = build_test_path("sigscale", stringify!($name));
|
||||
run_test(fname.to_string(), 3, |case| {
|
||||
let (nega, abytes) = case.get("a").unwrap();
|
||||
let (negb, bbytes) = case.get("b").unwrap();
|
||||
let (negc, cbytes) = case.get("c").unwrap();
|
||||
|
||||
let a = $name::new(*nega, $uname::from_bytes(abytes));
|
||||
let bbig = $name::new(*negb, $uname::from_bytes(bbytes));
|
||||
let c = $big::new(*negc, $ubig::from_bytes(cbytes));
|
||||
let b = i64::from(&bbig);
|
||||
let res = &a * b;
|
||||
assert_eq!(c, res);
|
||||
});
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user