diff --git a/src/int/big.rs b/src/int/big.rs index f11a2fb2..95f7b135 100644 --- a/src/int/big.rs +++ b/src/int/big.rs @@ -1,3 +1,5 @@ +//! Integers used for wide operations, larger than `u128`. + #![allow(unused)] use crate::int::{DInt, HInt, Int, MinInt}; @@ -208,93 +210,93 @@ impl MinInt for i256 { // } // } -// macro_rules! impl_common { -// ($ty:ty) => { -// impl ops::Add for $ty { -// type Output = Self; - -// fn add(self, rhs: Self) -> Self::Output { -// let (val, wrapped) = self.overflowing_add(rhs); -// debug_assert!(!wrapped, "attempted to add with overflow"); -// val -// } -// } - -// impl ops::AddAssign for $ty { -// fn add_assign(&mut self, rhs: Self) { -// *self = *self + rhs -// } -// } - -// impl ops::BitAnd for $ty { -// type Output = Self; - -// fn bitand(self, rhs: Self) -> Self::Output { -// Self([ -// self.0[0] & rhs.0[0], -// self.0[1] & rhs.0[1], -// self.0[2] & rhs.0[2], -// self.0[3] & rhs.0[3], -// ]) -// } -// } - -// impl ops::BitAndAssign for $ty { -// fn bitand_assign(&mut self, rhs: Self) { -// *self = *self & rhs -// } -// } - -// impl ops::BitOr for $ty { -// type Output = Self; - -// fn bitor(self, rhs: Self) -> Self::Output { -// Self([ -// self.0[0] | rhs.0[0], -// self.0[1] | rhs.0[1], -// self.0[2] | rhs.0[2], -// self.0[3] | rhs.0[3], -// ]) -// } -// } - -// impl ops::BitOrAssign for $ty { -// fn bitor_assign(&mut self, rhs: Self) { -// *self = *self | rhs -// } -// } - -// impl ops::BitXor for $ty { -// type Output = Self; - -// fn bitxor(self, rhs: Self) -> Self::Output { -// Self([ -// self.0[0] ^ rhs.0[0], -// self.0[1] ^ rhs.0[1], -// self.0[2] ^ rhs.0[2], -// self.0[3] ^ rhs.0[3], -// ]) -// } -// } - -// impl ops::BitXorAssign for $ty { -// fn bitxor_assign(&mut self, rhs: Self) { -// *self = *self ^ rhs -// } -// } - -// impl ops::Not for $ty { -// type Output = Self; - -// fn not(self) -> Self::Output { -// Self([!self.0[0], !self.0[1], !self.0[2], !self.0[3]]) -// } -// } -// }; -// } +macro_rules! impl_common { + ($ty:ty) => { + // impl ops::Add for $ty { + // type Output = Self; + + // fn add(self, rhs: Self) -> Self::Output { + // let (val, wrapped) = self.overflowing_add(rhs); + // debug_assert!(!wrapped, "attempted to add with overflow"); + // val + // } + // } + + // impl ops::AddAssign for $ty { + // fn add_assign(&mut self, rhs: Self) { + // *self = *self + rhs + // } + // } + + // impl ops::BitAnd for $ty { + // type Output = Self; + + // fn bitand(self, rhs: Self) -> Self::Output { + // Self([ + // self.0[0] & rhs.0[0], + // self.0[1] & rhs.0[1], + // self.0[2] & rhs.0[2], + // self.0[3] & rhs.0[3], + // ]) + // } + // } + + // impl ops::BitAndAssign for $ty { + // fn bitand_assign(&mut self, rhs: Self) { + // *self = *self & rhs + // } + // } + + // impl ops::BitOr for $ty { + // type Output = Self; + + // fn bitor(self, rhs: Self) -> Self::Output { + // Self([ + // self.0[0] | rhs.0[0], + // self.0[1] | rhs.0[1], + // self.0[2] | rhs.0[2], + // self.0[3] | rhs.0[3], + // ]) + // } + // } + + // impl ops::BitOrAssign for $ty { + // fn bitor_assign(&mut self, rhs: Self) { + // *self = *self | rhs + // } + // } + + // impl ops::BitXor for $ty { + // type Output = Self; + + // fn bitxor(self, rhs: Self) -> Self::Output { + // Self([ + // self.0[0] ^ rhs.0[0], + // self.0[1] ^ rhs.0[1], + // self.0[2] ^ rhs.0[2], + // self.0[3] ^ rhs.0[3], + // ]) + // } + // } + + // impl ops::BitXorAssign for $ty { + // fn bitxor_assign(&mut self, rhs: Self) { + // *self = *self ^ rhs + // } + // } + + impl ops::Not for $ty { + type Output = Self; + + fn not(self) -> Self::Output { + Self([!self.0[0], !self.0[1], !self.0[2], !self.0[3]]) + } + } + }; +} -// impl_common!(i256); -// impl_common!(u256); +impl_common!(i256); +impl_common!(u256); // impl ops::Sub for u256 { // type Output = Self; diff --git a/src/int/mod.rs b/src/int/mod.rs index 6af12dee..1a296608 100644 --- a/src/int/mod.rs +++ b/src/int/mod.rs @@ -14,7 +14,10 @@ pub use self::leading_zeros::__clzsi2; public_test_dep! { /// Minimal integer implementations needed on wide integers` -pub(crate) trait MinInt: Copy + core::fmt::Debug { +pub(crate) trait MinInt: Copy + + core::fmt::Debug + + ops::Not +{ /// Type with the same width but other signedness type OtherSign: MinInt; @@ -54,7 +57,6 @@ pub(crate) trait Int: MinInt + ops::BitOr + ops::BitXor + ops::BitAnd - + ops::Not { /// LUT used for maximizing the space covered and minimizing the computational cost of fuzzing /// in `testcrate`. For example, Self = u128 produces [0,1,2,7,8,15,16,31,32,63,64,95,96,111, diff --git a/testcrate/src/lib.rs b/testcrate/src/lib.rs index 9bd155f6..38d1835c 100644 --- a/testcrate/src/lib.rs +++ b/testcrate/src/lib.rs @@ -14,8 +14,10 @@ //! correct rounding. #![no_std] +use core::ops; + use compiler_builtins::float::Float; -use compiler_builtins::int::Int; +use compiler_builtins::int::{Int, MinInt}; use rand_xoshiro::rand_core::{RngCore, SeedableRng}; use rand_xoshiro::Xoshiro128StarStar; @@ -101,7 +103,10 @@ macro_rules! edge_cases { /// Feeds a series of fuzzing inputs to `f`. The fuzzer first uses an algorithm designed to find /// edge cases, followed by a more random fuzzer that runs `n` times. -pub fn fuzz(n: u32, mut f: F) { +pub fn fuzz(n: u32, mut f: F) +where + ::UnsignedInt: Int, +{ // edge case tester. Calls `f` 210 times for u128. // zero gets skipped by the loop f(I::ZERO); @@ -111,7 +116,7 @@ pub fn fuzz(n: u32, mut f: F) { // random fuzzer let mut rng = Xoshiro128StarStar::seed_from_u64(0); - let mut x: I = Int::ZERO; + let mut x: I = MinInt::ZERO; for _ in 0..n { fuzz_step(&mut rng, &mut x); f(x) @@ -119,7 +124,10 @@ pub fn fuzz(n: u32, mut f: F) { } /// The same as `fuzz`, except `f` has two inputs. -pub fn fuzz_2(n: u32, f: F) { +pub fn fuzz_2(n: u32, f: F) +where + ::UnsignedInt: Int, +{ // Check cases where the first and second inputs are zero. Both call `f` 210 times for `u128`. edge_cases!(I, case, { f(I::ZERO, case); @@ -150,10 +158,10 @@ pub fn fuzz_shift(f: F) { // Shift functions are very simple and do not need anything other than shifting a small // set of random patterns for every fuzz length. let mut rng = Xoshiro128StarStar::seed_from_u64(0); - let mut x: I = Int::ZERO; + let mut x: I = MinInt::ZERO; for i in 0..I::FUZZ_NUM { fuzz_step(&mut rng, &mut x); - f(x, Int::ZERO); + f(x, MinInt::ZERO); f(x, I::FUZZ_LENGTHS[i] as u32); } }