Skip to content

Commit

Permalink
More MinInt work
Browse files Browse the repository at this point in the history
  • Loading branch information
tgross35 committed Apr 12, 2024
1 parent 85a83d1 commit e5e93e8
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 94 deletions.
174 changes: 88 additions & 86 deletions src/int/big.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Integers used for wide operations, larger than `u128`.

#![allow(unused)]

use crate::int::{DInt, HInt, Int, MinInt};
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 4 additions & 2 deletions src/int/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Output = Self>
{

/// Type with the same width but other signedness
type OtherSign: MinInt;
Expand Down Expand Up @@ -54,7 +57,6 @@ pub(crate) trait Int: MinInt
+ ops::BitOr<Output = Self>
+ ops::BitXor<Output = Self>
+ ops::BitAnd<Output = Self>
+ ops::Not<Output = Self>
{
/// 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,
Expand Down
20 changes: 14 additions & 6 deletions testcrate/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<I: Int, F: FnMut(I)>(n: u32, mut f: F) {
pub fn fuzz<I: Int, F: FnMut(I)>(n: u32, mut f: F)
where
<I as MinInt>::UnsignedInt: Int,
{
// edge case tester. Calls `f` 210 times for u128.
// zero gets skipped by the loop
f(I::ZERO);
Expand All @@ -111,15 +116,18 @@ pub fn fuzz<I: Int, F: FnMut(I)>(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)
}
}

/// The same as `fuzz`, except `f` has two inputs.
pub fn fuzz_2<I: Int, F: Fn(I, I)>(n: u32, f: F) {
pub fn fuzz_2<I: Int, F: Fn(I, I)>(n: u32, f: F)
where
<I as MinInt>::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);
Expand Down Expand Up @@ -150,10 +158,10 @@ pub fn fuzz_shift<I: Int, F: Fn(I, u32)>(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);
}
}
Expand Down

0 comments on commit e5e93e8

Please sign in to comment.