Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  biguint.rs

  Sprache: Rust
 

use num_bigint::Sign::Plus;
use num_bigint::{BigInt, ToBigInt};
use num_bigint::{BigUint, ToBigUint};
use num_integer::Integer;

use std::cmp::Ordering::{Equal, Greater, Less};
use std::collections::hash_map::RandomState;
use std::hash::{BuildHasher, Hash, Hasher};
use std::iter::repeat;
use std::str::FromStr;
use std::{f32, f64};

use num_traits::{
    pow, CheckedAdd, CheckedDiv, CheckedMul, CheckedSub, Euclid, FromBytes, FromPrimitive, Num,
    One, Pow, ToBytes, ToPrimitive, Zero,
};

mod consts;
use crate::consts::*;

#[macro_use]
mod macros;

#[test]
fn test_from_bytes_be() {
    fn check(s: &str, result: &str) {
        let b = BigUint::parse_bytes(result.as_bytes(), 10).unwrap();
        assert_eq!(BigUint::from_bytes_be(s.as_bytes()), b);
        assert_eq!(<BigUint as FromBytes>::from_be_bytes(s.as_bytes()), b);
    }
    check("A""65");
    check("AA""16705");
    check("AB""16706");
    check("Hello world!""22405534230753963835153736737");
    assert_eq!(BigUint::from_bytes_be(&[]), BigUint::zero());
}

#[test]
fn test_to_bytes_be() {
    fn check(s: &str, result: &str) {
        let b = BigUint::parse_bytes(result.as_bytes(), 10).unwrap();
        assert_eq!(b.to_bytes_be(), s.as_bytes());
        assert_eq!(<BigUint as ToBytes>::to_be_bytes(&b), s.as_bytes());
    }
    check("A""65");
    check("AA""16705");
    check("AB""16706");
    check("Hello world!""22405534230753963835153736737");
    let b: BigUint = Zero::zero();
    assert_eq!(b.to_bytes_be(), [0]);

    // Test with leading/trailing zero bytes and a full BigDigit of value 0
    let b = BigUint::from_str_radix("00010000000000000200"16).unwrap();
    assert_eq!(b.to_bytes_be(), [100000020]);
}

#[test]
fn test_from_bytes_le() {
    fn check(s: &str, result: &str) {
        let b = BigUint::parse_bytes(result.as_bytes(), 10).unwrap();
        assert_eq!(BigUint::from_bytes_le(s.as_bytes()), b);
        assert_eq!(<BigUint as FromBytes>::from_le_bytes(s.as_bytes()), b);
    }
    check("A""65");
    check("AA""16705");
    check("BA""16706");
    check("!dlrow olleH""22405534230753963835153736737");
    assert_eq!(BigUint::from_bytes_le(&[]), BigUint::zero());
}

#[test]
fn test_to_bytes_le() {
    fn check(s: &str, result: &str) {
        let b = BigUint::parse_bytes(result.as_bytes(), 10).unwrap();
        assert_eq!(b.to_bytes_le(), s.as_bytes());
        assert_eq!(<BigUint as ToBytes>::to_le_bytes(&b), s.as_bytes());
    }
    check("A""65");
    check("AA""16705");
    check("BA""16706");
    check("!dlrow olleH""22405534230753963835153736737");
    let b: BigUint = Zero::zero();
    assert_eq!(b.to_bytes_le(), [0]);

    // Test with leading/trailing zero bytes and a full BigDigit of value 0
    let b = BigUint::from_str_radix("00010000000000000200"16).unwrap();
    assert_eq!(b.to_bytes_le(), [020000001]);
}

#[test]
fn test_cmp() {
    let data: [&[_]; 7] = [&[], &[1], &[2], &[! style='color: green'>0], &[01], &[>21], &[111]];
    let data: Vec<BigUint> = data.iter().map(|v| BigUint::from_slice(*v)).collect();
    for (i, ni) in data.iter().enumerate() {
        for (j0, nj) in data[i..].iter().enumerate() {
            let j = j0 + i;
            if i == j {
                assert_eq!(ni.cmp(nj), Equal);
                assert_eq!(nj.cmp(ni), Equal);
                assert_eq!(ni, nj);
                assert!(!(ni != nj));
                assert!(ni <= nj);
                assert!(ni >= nj);
                assert!(!(ni < nj));
                assert!(!(ni > nj));
            } else {
                assert_eq!(ni.cmp(nj), Less);
                assert_eq!(nj.cmp(ni), Greater);

                assert!(!(ni == nj));
                assert!(ni != nj);

                assert!(ni <= nj);
                assert!(!(ni >= nj));
                assert!(ni < nj);
                assert!(!(ni > nj));

                assert!(!(nj <= ni));
                assert!(nj >= ni);
                assert!(!(nj < ni));
                assert!(nj > ni);
            }
        }
    }
}

fn hash<T: Hash>(x: &T) -> u64 {
    let mut hasher = <RandomState as BuildHasher>::Hasher::new();
    x.hash(&mut hasher);
    hasher.finish()
}

#[test]
fn test_hash() {
    use crate::hash;

    let a = BigUint::new(vec![]);
    let b = BigUint::new(vec![0]);
    let c = BigUint::new(vec![1]);
    let d = BigUint::new(vec![100000]);
    let e = BigUint::new(vec![000001]);
    assert!(hash(&a) == hash(&b));
    assert!(hash(&b) != hash(&c));
    assert!(hash(&c) == hash(&d));
    assert!(hash(&d) != hash(&e));
}

// LEFT, RIGHT, AND, OR, XOR
const BIT_TESTS: &[(&[u32], &[u32], &[u32], &[u32], &[u32])] = &[
    (&[], &[], &[], &[], &[]),
    (&[101], &[11], &[1], &[111], &[011]),
    (&[101], &[011], &[001], &[111], &[11]),
    (
        &[26848217],
        &[96454],
        &[26034],
        &[97250217],
        &[71246817],
    ),
];

#[test]
fn test_bitand() {
    for elm in BIT_TESTS {
        let (a_vec, b_vec, c_vec, _, _) = *elm;
        let a = BigUint::from_slice(a_vec);
        let b = BigUint::from_slice(b_vec);
        let c = BigUint::from_slice(c_vec);

        assert_op!(a & b == c);
        assert_op!(b & a == c);
        assert_assign_op!(a &= b == c);
        assert_assign_op!(b &= a == c);
    }
}

#[test]
fn test_bitor() {
    for elm in BIT_TESTS {
        let (a_vec, b_vec, _, c_vec, _) = *elm;
        let a = BigUint::from_slice(a_vec);
        let b = BigUint::from_slice(b_vec);
        let c = BigUint::from_slice(c_vec);

        assert_op!(a | b == c);
        assert_op!(b | a == c);
        assert_assign_op!(a |= b == c);
        assert_assign_op!(b |= a == c);
    }
}

#[test]
fn test_bitxor() {
    for elm in BIT_TESTS {
        let (a_vec, b_vec, _, _, c_vec) = *elm;
        let a = BigUint::from_slice(a_vec);
        let b = BigUint::from_slice(b_vec);
        let c = BigUint::from_slice(c_vec);

        assert_op!(a ^ b == c);
        assert_op!(b ^ a == c);
        assert_op!(a ^ c == b);
        assert_op!(c ^ a == b);
        assert_op!(b ^ c == a);
        assert_op!(c ^ b == a);
        assert_assign_op!(a ^= b == c);
        assert_assign_op!(b ^= a == c);
        assert_assign_op!(a ^= c == b);
        assert_assign_op!(c ^= a == b);
        assert_assign_op!(b ^= c == a);
        assert_assign_op!(c ^= b == a);
    }
}

#[test]
fn test_shl() {
    fn check(s: &str, shift: usize, ans: &str) {
        let opt_biguint = BigUint::from_str_radix(s, 16).ok();
        let mut bu_assign = opt_biguint.unwrap();
        let bu = (bu_assign.clone() << shift).to_str_radix(16);
        assert_eq!(bu, ans);
        bu_assign <<= shift;
        assert_eq!(bu_assign.to_str_radix(16), ans);
    }

    check("0"3"0");
    check("1"3"8");

    check(
        "1\
         0000\
         0000\
         0000\
         0001\
         0000\
         0000\
         0000\
         0001",
        3,
        "8\
         0000\
         0000\
         0000\
         0008\
         0000\
         0000\
         0000\
         0008",
    );
    check(
        "1\
         0000\
         0001\
         0000\
         0001",
        2,
        "4\
         0000\
         0004\
         0000\
         0004",
    );
    check(
        "1\
         0001\
         0001",
        1,
        "2\
         0002\
         0002",
    );

    check(
        "\
         4000\
         0000\
         0000\
         0000",
        3,
        "2\
         0000\
         0000\
         0000\
         0000",
    );
    check(
        "4000\
         0000",
        2,
        "1\
         0000\
         0000",
    );
    check(
        "4000",
        2,
        "1\
         0000",
    );

    check(
        "4000\
         0000\
         0000\
         0000",
        67,
        "2\
         0000\
         0000\
         0000\
         0000\
         0000\
         0000\
         0000\
         0000",
    );
    check(
        "4000\
         0000",
        35,
        "2\
         0000\
         0000\
         0000\
         0000",
    );
    check(
        "4000",
        19,
        "2\
         0000\
         0000",
    );

    check(
        "fedc\
         ba98\
         7654\
         3210\
         fedc\
         ba98\
         7654\
         3210",
        4,
        "f\
         edcb\
         a987\
         6543\
         210f\
         edcb\
         a987\
         6543\
         2100",
    );
    check(
        "88887777666655554444333322221111",
        16,
        "888877776666555544443333222211110000",
    );
}

#[test]
fn test_shr() {
    fn check(s: &str, shift: usize, ans: &str) {
        let opt_biguint = BigUint::from_str_radix(s, 16).ok();
        let mut bu_assign = opt_biguint.unwrap();
        let bu = (bu_assign.clone() >> shift).to_str_radix(16);
        assert_eq!(bu, ans);
        bu_assign >>= shift;
        assert_eq!(bu_assign.to_str_radix(16), ans);
    }

    check("0"3"0");
    check("f"3"1");

    check(
        "1\
         0000\
         0000\
         0000\
         0001\
         0000\
         0000\
         0000\
         0001",
        3,
        "2000\
         0000\
         0000\
         0000\
         2000\
         0000\
         0000\
         0000",
    );
    check(
        "1\
         0000\
         0001\
         0000\
         0001",
        2,
        "4000\
         0000\
         4000\
         0000",
    );
    check(
        "1\
         0001\
         0001",
        1,
        "8000\
         8000",
    );

    check(
        "2\
         0000\
         0000\
         0000\
         0001\
         0000\
         0000\
         0000\
         0001",
        67,
        "4000\
         0000\
         0000\
         0000",
    );
    check(
        "2\
         0000\
         0001\
         0000\
         0001",
        35,
        "4000\
         0000",
    );
    check(
        "2\
         0001\
         0001",
        19,
        "4000",
    );

    check(
        "1\
         0000\
         0000\
         0000\
         0000",
        1,
        "8000\
         0000\
         0000\
         0000",
    );
    check(
        "1\
         0000\
         0000",
        1,
        "8000\
         0000",
    );
    check(
        "1\
         0000",
        1,
        "8000",
    );
    check(
        "f\
         edcb\
         a987\
         6543\
         210f\
         edcb\
         a987\
         6543\
         2100",
        4,
        "fedc\
         ba98\
         7654\
         3210\
         fedc\
         ba98\
         7654\
         3210",
    );

    check(
        "888877776666555544443333222211110000",
        16,
        "88887777666655554444333322221111",
    );
}

// `DoubleBigDigit` size dependent
#[test]
fn test_convert_i64() {
    fn check(b1: BigUint, i: i64) {
        let b2: BigUint = FromPrimitive::from_i64(i).unwrap();
        assert_eq!(b1, b2);
        assert_eq!(b1.to_i64().unwrap(), i);
    }

    check(Zero::zero(), 0);
    check(One::one(), 1);
    check(i64::MAX.to_biguint().unwrap(), i64::MAX);

    check(BigUint::new(vec![]), 0);
    check(BigUint::new(vec![1]), 1);
    check(BigUint::new(vec![N1]), (1 << 32) - 1);
    check(BigUint::new(vec![01]), 1 << 32);
    check(BigUint::new(vec![N1, N1 >> 1]), i64::MAX);

    assert_eq!(i64::MIN.to_biguint(), None);
    assert_eq!(BigUint::new(vec![N1, N1]).to_i64(), None);
    assert_eq!(BigUint::new(vec![001]).to_i64(), None);
    assert_eq!(BigUint::new(vec![N1, N1, N1]).to_i64(), None);
}

#[test]
fn test_convert_i128() {
    fn check(b1: BigUint, i: i128) {
        let b2: BigUint = FromPrimitive::from_i128(i).unwrap();
        assert_eq!(b1, b2);
        assert_eq!(b1.to_i128().unwrap(), i);
    }

    check(Zero::zero(), 0);
    check(One::one(), 1);
    check(i128::MAX.to_biguint().unwrap(), i128::MAX);

    check(BigUint::new(vec![]), 0);
    check(BigUint::new(vec![1]), 1);
    check(BigUint::new(vec![N1]), (1 << 32) - 1);
    check(BigUint::new(vec![01]), 1 << 32);
    check(BigUint::new(vec![N1, N1, N1, N1 >> 1]), i128::MAX);

    assert_eq!(i128::MIN.to_biguint(), None);
    assert_eq!(BigUint::new(vec![N1, N1, N1, N1]).to_i128(), None);
    assert_eq!(BigUint::new(vec![00001]).to_i128(), None);
    assert_eq!(BigUint::new(vec![N1, N1, N1, N1, N1]).to_i128(), None);
}

// `DoubleBigDigit` size dependent
#[test]
fn test_convert_u64() {
    fn check(b1: BigUint, u: u64) {
        let b2: BigUint = FromPrimitive::from_u64(u).unwrap();
        assert_eq!(b1, b2);
        assert_eq!(b1.to_u64().unwrap(), u);
    }

    check(Zero::zero(), 0);
    check(One::one(), 1);
    check(u64::MIN.to_biguint().unwrap(), u64::MIN);
    check(u64::MAX.to_biguint().unwrap(), u64::MAX);

    check(BigUint::new(vec![]), 0);
    check(BigUint::new(vec![1]), 1);
    check(BigUint::new(vec![N1]), (1 << 32) - 1);
    check(BigUint::new(vec![01]), 1 << 32);
    check(BigUint::new(vec![N1, N1]), u64::MAX);

    assert_eq!(BigUint::new(vec![001]).to_u64(), None);
    assert_eq!(BigUint::new(vec![N1, N1, N1]).to_u64(), None);
}

#[test]
fn test_convert_u128() {
    fn check(b1: BigUint, u: u128) {
        let b2: BigUint = FromPrimitive::from_u128(u).unwrap();
        assert_eq!(b1, b2);
        assert_eq!(b1.to_u128().unwrap(), u);
    }

    check(Zero::zero(), 0);
    check(One::one(), 1);
    check(u128::MIN.to_biguint().unwrap(), u128::MIN);
    check(u128::MAX.to_biguint().unwrap(), u128::MAX);

    check(BigUint::new(vec![]), 0);
    check(BigUint::new(vec![1]), 1);
    check(BigUint::new(vec![N1]), (1 << 32) - 1);
    check(BigUint::new(vec![01]), 1 << 32);
    check(BigUint::new(vec![N1, N1, N1, N1]), u128::MAX);

    assert_eq!(BigUint::new(vec![00001]).to_u128(), None);
    assert_eq!(BigUint::new(vec![N1, N1, N1, N1, N1]).to_u128(), None);
}

#[test]
#[allow(clippy::float_cmp)]
fn test_convert_f32() {
    fn check(b1: &BigUint, f: f32) {
        let b2 = BigUint::from_f32(f).unwrap();
        assert_eq!(b1, &b2);
        assert_eq!(b1.to_f32().unwrap(), f);
    }

    check(&BigUint::zero(), 0.0);
    check(&BigUint::one(), 1.0);
    check(&BigUint::from(u16::MAX), pow(2.0_f32, 16) - 1.0);
    check(&BigUint::from(1u64 << 32), pow(2.0_f32, 32));
    check(&BigUint::from_slice(&[001]), pow(2.0_f32, 64));
    check(
        &((BigUint::one() << 100) + (BigUint::one() << 123)),
        pow(2.0_f32, 100) + pow(2.0_f32, 123),
    );
    check(&(BigUint::one() << 127), pow(2.0_f32, 127));
    check(&(BigUint::from((1u64 << 24) - 1) << (128 - 24)), f32::MAX);

    // keeping all 24 digits with the bits at different offsets to the BigDigits
    let x: u32 = 0b00000000101111011111011011011101;
    let mut f = x as f32;
    let mut b = BigUint::from(x);
    for _ in 0..64 {
        check(&b, f);
        f *= 2.0;
        b <<= 1;
    }

    // this number when rounded to f64 then f32 isn't the same as when rounded straight to f32
    let n: u64 = 0b0000000000111111111111111111111111011111111111111111111111111111;
    assert!((n as f64) as f32 != n as f32);
    assert_eq!(BigUint::from(n).to_f32(), Some(n as f32));

    // test rounding up with the bits at different offsets to the BigDigits
    let mut f = ((1u64 << 25) - 1as f32;
    let mut b = BigUint::from(1u64 << 25);
    for _ in 0..64 {
        assert_eq!(b.to_f32(), Some(f));
        f *= 2.0;
        b <<= 1;
    }

    // test correct ties-to-even rounding
    let weird: i128 = (1i128 << 100) + (1i128 << (100 - f32::MANTISSA_DIGITS));
    assert_ne!(weird as f32, (weird + 1as f32);

    assert_eq!(BigInt::from(weird).to_f32(), Some(weird as f32));
    assert_eq!(BigInt::from(weird + 1).to_f32(), Some((weird + 1as f32));

    // rounding
    assert_eq!(BigUint::from_f32(-1.0), None);
    assert_eq!(BigUint::from_f32(-0.99999), Some(BigUint::zero()));
    assert_eq!(BigUint::from_f32(-0.5), Some(BigUint::zero()));
    assert_eq!(BigUint::from_f32(-0.0), Some(BigUint::zero()));
    assert_eq!(
        BigUint::from_f32(f32::MIN_POSITIVE / 2.0),
        Some(BigUint::zero())
    );
    assert_eq!(BigUint::from_f32(f32::MIN_POSITIVE), Some(BigUint::zero()));
    assert_eq!(BigUint::from_f32(0.5), Some(BigUint::zero()));
    assert_eq!(BigUint::from_f32(0.99999), Some(BigUint::zero()));
    assert_eq!(BigUint::from_f32(f32::consts::E), Some(BigUint::from(2u32)));
    assert_eq!(
        BigUint::from_f32(f32::consts::PI),
        Some(BigUint::from(3u32))
    );

    // special float values
    assert_eq!(BigUint::from_f32(f32::NAN), None);
    assert_eq!(BigUint::from_f32(f32::INFINITY), None);
    assert_eq!(BigUint::from_f32(f32::NEG_INFINITY), None);
    assert_eq!(BigUint::from_f32(f32::MIN), None);

    // largest BigUint that will round to a finite f32 value
    let big_num = (BigUint::one() << 128u8) - 1u8 - (BigUint::one() << (128u8 - 25));
    assert_eq!(big_num.to_f32(), Some(f32::MAX));
    assert_eq!((big_num + 1u8).to_f32(), Some(f32::INFINITY));

    assert_eq!(
        ((BigUint::one() << 128u8) - 1u8).to_f32(),
        Some(f32::INFINITY)
    );
    assert_eq!((BigUint::one() << 128u8).to_f32(), Some(f32::INFINITY));
}

#[test]
#[allow(clippy::float_cmp)]
fn test_convert_f64() {
    fn check(b1: &BigUint, f: f64) {
        let b2 = BigUint::from_f64(f).unwrap();
        assert_eq!(b1, &b2);
        assert_eq!(b1.to_f64().unwrap(), f);
    }

    check(&BigUint::zero(), 0.0);
    check(&BigUint::one(), 1.0);
    check(&BigUint::from(u32::MAX), pow(2.0_f64, 32) - 1.0);
    check(&BigUint::from(1u64 << 32), pow(2.0_f64, 32));
    check(&BigUint::from_slice(&[001]), pow(2.0_f64, 64));
    check(
        &((BigUint::one() << 100) + (BigUint::one() << 152)),
        pow(2.0_f64, 100) + pow(2.0_f64, 152),
    );
    check(&(BigUint::one() << 1023), pow(2.0_f64, 1023));
    check(&(BigUint::from((1u64 << 53) - 1) << (1024 - 53)), f64::MAX);

    // keeping all 53 digits with the bits at different offsets to the BigDigits
    let x: u64 = 0b0000000000011110111110110111111101110111101111011111011011011101;
    let mut f = x as f64;
    let mut b = BigUint::from(x);
    for _ in 0..128 {
        check(&b, f);
        f *= 2.0;
        b <<= 1;
    }

    // test rounding up with the bits at different offsets to the BigDigits
    let mut f = ((1u64 << 54) - 1as f64;
    let mut b = BigUint::from(1u64 << 54);
    for _ in 0..128 {
        assert_eq!(b.to_f64(), Some(f));
        f *= 2.0;
        b <<= 1;
    }

    // test correct ties-to-even rounding
    let weird: i128 = (1i128 << 100) + (1i128 << (100 - f64::MANTISSA_DIGITS));
    assert_ne!(weird as f64, (weird + 1as f64);

    assert_eq!(BigInt::from(weird).to_f64(), Some(weird as f64));
    assert_eq!(BigInt::from(weird + 1).to_f64(), Some((weird + 1as f64));

    // rounding
    assert_eq!(BigUint::from_f64(-1.0), None);
    assert_eq!(BigUint::from_f64(-0.99999), Some(BigUint::zero()));
    assert_eq!(BigUint::from_f64(-0.5), Some(BigUint::zero()));
    assert_eq!(BigUint::from_f64(-0.0), Some(BigUint::zero()));
    assert_eq!(
        BigUint::from_f64(f64::MIN_POSITIVE / 2.0),
        Some(BigUint::zero())
    );
    assert_eq!(BigUint::from_f64(f64::MIN_POSITIVE), Some(BigUint::zero()));
    assert_eq!(BigUint::from_f64(0.5), Some(BigUint::zero()));
    assert_eq!(BigUint::from_f64(0.99999), Some(BigUint::zero()));
    assert_eq!(BigUint::from_f64(f64::consts::E), Some(BigUint::from(2u32)));
    assert_eq!(
        BigUint::from_f64(f64::consts::PI),
        Some(BigUint::from(3u32))
    );

    // special float values
    assert_eq!(BigUint::from_f64(f64::NAN), None);
    assert_eq!(BigUint::from_f64(f64::INFINITY), None);
    assert_eq!(BigUint::from_f64(f64::NEG_INFINITY), None);
    assert_eq!(BigUint::from_f64(f64::MIN), None);

    // largest BigUint that will round to a finite f64 value
    let big_num = (BigUint::one() << 1024u16) - 1u8 - (BigUint::one() << (1024u16 - 54));
    assert_eq!(big_num.to_f64(), Some(f64::MAX));
    assert_eq!((big_num + 1u8).to_f64(), Some(f64::INFINITY));

    assert_eq!(
        ((BigUint::one() << 1024u16) - 1u8).to_f64(),
        Some(f64::INFINITY)
    );
    assert_eq!((BigUint::one() << 1024u16).to_f64(), Some(f64::INFINITY));
}

#[test]
fn test_convert_to_bigint() {
    fn check(n: BigUint, ans: BigInt) {
        assert_eq!(n.to_bigint().unwrap(), ans);
        assert_eq!(n.to_bigint().unwrap().to_biguint().unwrap(), n);
    }
    check(Zero::zero(), Zero::zero());
    check(
        BigUint::new(vec![123]),
        BigInt::from_biguint(Plus, BigUint::new(vec![123])),
    );
}

#[test]
fn test_convert_from_uint() {
    macro_rules! check {
        ($ty:ident, $max:expr) => {
            assert_eq!(BigUint::from($ty::zero()), BigUint::zero());
            assert_eq!(BigUint::from($ty::one()), BigUint::one());
            assert_eq!(BigUint::from($ty::MAX - $ty::one()), $max - BigUint::one());
            assert_eq!(BigUint::from($ty::MAX), $max);
        };
    }

    check!(u8, BigUint::from_slice(&[u8::MAX as u32]));
    check!(u16, BigUint::from_slice(&[u16::MAX as u32]));
    check!(u32, BigUint::from_slice(&[u32::MAX]));
    check!(u64, BigUint::from_slice(&[u32::MAX, u32::MAX]));
    check!(
        u128,
        BigUint::from_slice(&[u32::MAX, u32::MAX, u32::MAX, u32::MAX])
    );
    check!(usize, BigUint::from(usize::MAX as u64));
}

#[test]
fn test_add() {
    for elm in SUM_TRIPLES.iter() {
        let (a_vec, b_vec, c_vec) = *elm;
        let a = BigUint::from_slice(a_vec);
        let b = BigUint::from_slice(b_vec);
        let c = BigUint::from_slice(c_vec);

        assert_op!(a + b == c);
        assert_op!(b + a == c);
        assert_assign_op!(a += b == c);
        assert_assign_op!(b += a == c);
    }
}

#[test]
fn test_sub() {
    for elm in SUM_TRIPLES.iter() {
        let (a_vec, b_vec, c_vec) = *elm;
        let a = BigUint::from_slice(a_vec);
        let b = BigUint::from_slice(b_vec);
        let c = BigUint::from_slice(c_vec);

        assert_op!(c - a == b);
        assert_op!(c - b == a);
        assert_assign_op!(c -= a == b);
        assert_assign_op!(c -= b == a);
    }
}

#[test]
#[should_panic]
fn test_sub_fail_on_underflow() {
    let (a, b): (BigUint, BigUint) = (Zero::zero(), One::one());
    let _ = a - b;
}

#[test]
fn test_mul() {
    for elm in MUL_TRIPLES.iter() {
        let (a_vec, b_vec, c_vec) = *elm;
        let a = BigUint::from_slice(a_vec);
        let b = BigUint::from_slice(b_vec);
        let c = BigUint::from_slice(c_vec);

        assert_op!(a * b == c);
        assert_op!(b * a == c);
        assert_assign_op!(a *= b == c);
        assert_assign_op!(b *= a == c);
    }

    for elm in DIV_REM_QUADRUPLES.iter() {
        let (a_vec, b_vec, c_vec, d_vec) = *elm;
        let a = BigUint::from_slice(a_vec);
        let b = BigUint::from_slice(b_vec);
        let c = BigUint::from_slice(c_vec);
        let d = BigUint::from_slice(d_vec);

        assert!(a == &b * &c + &d);
        assert!(a == &c * &b + &d);
    }
}

#[test]
fn test_div_rem() {
    for elm in MUL_TRIPLES.iter() {
        let (a_vec, b_vec, c_vec) = *elm;
        let a = BigUint::from_slice(a_vec);
        let b = BigUint::from_slice(b_vec);
        let c = BigUint::from_slice(c_vec);

        if !a.is_zero() {
            assert_op!(c / a == b);
            assert_op!(c % a == BigUint::zero());
            assert_assign_op!(c /= a == b);
            assert_assign_op!(c %= a == BigUint::zero());
            assert_eq!(c.div_rem(&a), (b.clone(), BigUint::zero()));
        }
        if !b.is_zero() {
            assert_op!(c / b == a);
            assert_op!(c % b == BigUint::zero());
            assert_assign_op!(c /= b == a);
            assert_assign_op!(c %= b == BigUint::zero());
            assert_eq!(c.div_rem(&b), (a.clone(), BigUint::zero()));
        }
    }

    for elm in DIV_REM_QUADRUPLES.iter() {
        let (a_vec, b_vec, c_vec, d_vec) = *elm;
        let a = BigUint::from_slice(a_vec);
        let b = BigUint::from_slice(b_vec);
        let c = BigUint::from_slice(c_vec);
        let d = BigUint::from_slice(d_vec);

        if !b.is_zero() {
            assert_op!(a / b == c);
            assert_op!(a % b == d);
            assert_assign_op!(a /= b == c);
            assert_assign_op!(a %= b == d);
            assert!(a.div_rem(&b) == (c, d));
        }
    }
}

#[test]
fn test_div_rem_big_multiple() {
    let a = BigUint::from(3u32).pow(100u32);
    let a2 = &a * &a;

    let (div, rem) = a2.div_rem(&a);
    assert_eq!(div, a);
    assert!(rem.is_zero());

    let (div, rem) = (&a2 - 1u32).div_rem(&a);
    assert_eq!(div, &a - 1u32);
    assert_eq!(rem, &a - 1u32);
}

#[test]
fn test_div_ceil() {
    fn check(a: &BigUint, b: &BigUint, d: &BigUint, m: &BigUint) {
        if m.is_zero() {
            assert_eq!(a.div_ceil(b), *d);
        } else {
            assert_eq!(a.div_ceil(b), d + 1u32);
        }
    }

    for elm in MUL_TRIPLES.iter() {
        let (a_vec, b_vec, c_vec) = *elm;
        let a = BigUint::from_slice(a_vec);
        let b = BigUint::from_slice(b_vec);
        let c = BigUint::from_slice(c_vec);

        if !a.is_zero() {
            check(&c, &a, &b, &Zero::zero());
        }
        if !b.is_zero() {
            check(&c, &b, &a, &Zero::zero());
        }
    }

    for elm in DIV_REM_QUADRUPLES.iter() {
        let (a_vec, b_vec, c_vec, d_vec) = *elm;
        let a = BigUint::from_slice(a_vec);
        let b = BigUint::from_slice(b_vec);
        let c = BigUint::from_slice(c_vec);
        let d = BigUint::from_slice(d_vec);

        if !b.is_zero() {
            check(&a, &b, &c, &d);
        }
    }
}

#[test]
fn test_div_rem_euclid() {
    fn check(a: &BigUint, b: &BigUint, d: &BigUint, m: &BigUint) {
        assert_eq!(a.div_euclid(b), *d);
        assert_eq!(a.rem_euclid(b), *m);
    }

    for elm in MUL_TRIPLES.iter() {
        let (a_vec, b_vec, c_vec) = *elm;
        let a = BigUint::from_slice(a_vec);
        let b = BigUint::from_slice(b_vec);
        let c = BigUint::from_slice(c_vec);

        if !a.is_zero() {
            check(&c, &a, &b, &Zero::zero());
        }
        if !b.is_zero() {
            check(&c, &b, &a, &Zero::zero());
        }
    }

    for elm in DIV_REM_QUADRUPLES.iter() {
        let (a_vec, b_vec, c_vec, d_vec) = *elm;
        let a = BigUint::from_slice(a_vec);
        let b = BigUint::from_slice(b_vec);
        let c = BigUint::from_slice(c_vec);
        let d = BigUint::from_slice(d_vec);

        if !b.is_zero() {
            check(&a, &b, &c, &d);
        }
    }
}

#[test]
fn test_checked_add() {
    for elm in SUM_TRIPLES.iter() {
        let (a_vec, b_vec, c_vec) = *elm;
        let a = BigUint::from_slice(a_vec);
        let b = BigUint::from_slice(b_vec);
        let c = BigUint::from_slice(c_vec);

        assert!(a.checked_add(&b).unwrap() == c);
        assert!(b.checked_add(&a).unwrap() == c);
    }
}

#[test]
fn test_checked_sub() {
    for elm in SUM_TRIPLES.iter() {
        let (a_vec, b_vec, c_vec) = *elm;
        let a = BigUint::from_slice(a_vec);
        let b = BigUint::from_slice(b_vec);
        let c = BigUint::from_slice(c_vec);

        assert!(c.checked_sub(&a).unwrap() == b);
        assert!(c.checked_sub(&b).unwrap() == a);

        if a > c {
            assert!(a.checked_sub(&c).is_none());
        }
        if b > c {
            assert!(b.checked_sub(&c).is_none());
        }
    }
}

#[test]
fn test_checked_mul() {
    for elm in MUL_TRIPLES.iter() {
        let (a_vec, b_vec, c_vec) = *elm;
        let a = BigUint::from_slice(a_vec);
        let b = BigUint::from_slice(b_vec);
        let c = BigUint::from_slice(c_vec);

        assert!(a.checked_mul(&b).unwrap() == c);
        assert!(b.checked_mul(&a).unwrap() == c);
    }

    for elm in DIV_REM_QUADRUPLES.iter() {
        let (a_vec, b_vec, c_vec, d_vec) = *elm;
        let a = BigUint::from_slice(a_vec);
        let b = BigUint::from_slice(b_vec);
        let c = BigUint::from_slice(c_vec);
        let d = BigUint::from_slice(d_vec);

        assert!(a == b.checked_mul(&c).unwrap() + &d);
        assert!(a == c.checked_mul(&b).unwrap() + &d);
    }
}

#[test]
fn test_mul_overflow() {
    // Test for issue #187 - overflow due to mac3 incorrectly sizing temporary
    let s = "5311379928167670986895882065524686273295931177270319231994441382\
             0040355986085224273916250223263671004753755210595137000079652876\
             0829212940754539968588340162273730474622005920097370111";
    let a: BigUint = s.parse().unwrap();
    let b = a.clone();
    let _ = a.checked_mul(&b);
}

#[test]
fn test_mul_overflow_2() {
    // Try a bunch of sizes that are right on the edge of multiplication length
    // overflow, where (x * x).data.len() == 2 * x.data.len() + 1.
    for i in 1u8..20 {
        let bits = 1u32 << i;
        let x = (BigUint::one() << bits) - 1u32;
        let x2 = (BigUint::one() << (2 * bits)) - &x - &x - 1u32;
        assert_eq!(&x * &x, x2);
    }
}

#[test]
fn test_checked_div() {
    for elm in MUL_TRIPLES.iter() {
        let (a_vec, b_vec, c_vec) = *elm;
        let a = BigUint::from_slice(a_vec);
        let b = BigUint::from_slice(b_vec);
        let c = BigUint::from_slice(c_vec);

        if !a.is_zero() {
            assert!(c.checked_div(&a).unwrap() == b);
        }
        if !b.is_zero() {
            assert!(c.checked_div(&b).unwrap() == a);
        }

        assert!(c.checked_div(&Zero::zero()).is_none());
    }
}

#[test]
fn test_gcd() {
    fn check(a: usize, b: usize, c: usize) {
        let big_a: BigUint = FromPrimitive::from_usize(a).unwrap();
        let big_b: BigUint = FromPrimitive::from_usize(b).unwrap();
        let big_c: BigUint = FromPrimitive::from_usize(c).unwrap();

        assert_eq!(big_a.gcd(&big_b), big_c);
        assert_eq!(big_a.gcd_lcm(&big_b).0, big_c);
    }

    check(1022);
    check(1031);
    check(033);
    check(333);
    check(564214);
}

#[test]
fn test_lcm() {
    fn check(a: usize, b: usize, c: usize) {
        let big_a: BigUint = FromPrimitive::from_usize(a).unwrap();
        let big_b: BigUint = FromPrimitive::from_usize(b).unwrap();
        let big_c: BigUint = FromPrimitive::from_usize(c).unwrap();

        assert_eq!(big_a.lcm(&big_b), big_c);
        assert_eq!(big_a.gcd_lcm(&big_b).1, big_c);
    }

    check(000);
    check(100);
    check(010);
    check(111);
    check(8972);
    check(11555);
    check(99171683);
}

#[test]
fn test_is_multiple_of() {
    assert!(BigUint::from(0u32).is_multiple_of(&BigUint::from(0u32)));
    assert!(BigUint::from(6u32).is_multiple_of(&BigUint::from(6u32)));
    assert!(BigUint::from(6u32).is_multiple_of(&BigUint::from(3u32)));
    assert!(BigUint::from(6u32).is_multiple_of(&BigUint::from(1u32)));

    assert!(!BigUint::from(42u32).is_multiple_of(&BigUint::from(5u32)));
    assert!(!BigUint::from(5u32).is_multiple_of(&BigUint::from(3u32)));
    assert!(!BigUint::from(42u32).is_multiple_of(&BigUint::from(0u32)));
}

#[test]
fn test_next_multiple_of() {
    assert_eq!(
        BigUint::from(16u32).next_multiple_of(&BigUint::from(8u32)),
        BigUint::from(16u32)
    );
    assert_eq!(
        BigUint::from(23u32).next_multiple_of(&BigUint::from(8u32)),
        BigUint::from(24u32)
    );
}

#[test]
fn test_prev_multiple_of() {
    assert_eq!(
        BigUint::from(16u32).prev_multiple_of(&BigUint::from(8u32)),
        BigUint::from(16u32)
    );
    assert_eq!(
        BigUint::from(23u32).prev_multiple_of(&BigUint::from(8u32)),
        BigUint::from(16u32)
    );
}

#[test]
fn test_is_even() {
    let one: BigUint = FromStr::from_str("1").unwrap();
    let two: BigUint = FromStr::from_str("2").unwrap();
    let thousand: BigUint = FromStr::from_str("1000").unwrap();
    let big: BigUint = FromStr::from_str("1000000000000000000000").unwrap();
    let bigger: BigUint = FromStr::from_str("1000000000000000000001").unwrap();
    assert!(one.is_odd());
    assert!(two.is_even());
    assert!(thousand.is_even());
    assert!(big.is_even());
    assert!(bigger.is_odd());
    assert!((&one << 64u8).is_even());
    assert!(((&one << 64u8) + one).is_odd());
}

fn to_str_pairs() -> Vec<(BigUint, Vec<(u32, String)>)> {
    let bits = 32;
    vec![
        (
            Zero::zero(),
            vec![(2"0".to_string()), (3"0".to_string())],
        ),
        (
            BigUint::from_slice(&[0xff]),
            vec![
                (2"11111111".to_string()),
                (3"100110".to_string()),
                (4"3333".to_string()),
                (5"2010".to_string()),
                (6"1103".to_string()),
                (7"513".to_string()),
                (8"377".to_string()),
                (9"313".to_string()),
                (10"255".to_string()),
                (11"212".to_string()),
                (12"193".to_string()),
                (13"168".to_string()),
                (14"143".to_string()),
                (15"120".to_string()),
                (16"ff".to_string()),
            ],
        ),
        (
            BigUint::from_slice(&[0xfff]),
            vec![
                (2"111111111111".to_string()),
                (4"333333".to_string()),
                (16"fff".to_string()),
            ],
        ),
        (
            BigUint::from_slice(&[12]),
            vec![
                (
                    2,
                    format!("10{}1", repeat("0").take(bits - 1).collect::<String>()),
                ),
                (
                    4,
                    format!("2{}1", repeat("0").take(bits / 2 - 1).collect::<String>()),
                ),
                (
                    10,
                    match bits {
                        64 => "36893488147419103233".to_string(),
                        32 => "8589934593".to_string(),
                        16 => "131073".to_string(),
                        _ => panic!(),
                    },
                ),
                (
                    16,
                    format!("2{}1", repeat("0").take(bits / 4 - 1).collect::<String>()),
                ),
            ],
        ),
        (
            BigUint::from_slice(&[123]),
            vec![
                (
                    2,
                    format!(
                        "11{}10{}1",
                        repeat("0").take(bits - 2).collect::<String>(),
                        repeat("0").take(bits - 1).collect::<String>()
                    ),
                ),
                (
                    4,
                    format!(
                        "3{}2{}1",
                        repeat("0").take(bits / 2 - 1).collect::<String>(),
                        repeat("0").take(bits / 2 - 1).collect::<String>()
                    ),
                ),
                (
                    8,
                    match bits {
                        64 => "14000000000000000000004000000000000000000001".to_string(),
                        32 => "6000000000100000000001".to_string(),
                        16 => "140000400001".to_string(),
                        _ => panic!(),
                    },
                ),
                (
                    10,
                    match bits {
                        64 => "1020847100762815390427017310442723737601".to_string(),
                        32 => "55340232229718589441".to_string(),
                        16 => "12885032961".to_string(),
                        _ => panic!(),
                    },
                ),
                (
                    16,
                    format!(
                        "3{}2{}1",
                        repeat("0").take(bits / 4 - 1).collect::<String>(),
                        repeat("0").take(bits / 4 - 1).collect::<String>()
                    ),
                ),
            ],
        ),
    ]
}

#[test]
fn test_to_str_radix() {
    let r = to_str_pairs();
    for num_pair in r.iter() {
        let &(ref n, ref rs) = num_pair;
        for str_pair in rs.iter() {
            let &(ref radix, ref str) = str_pair;
            assert_eq!(n.to_str_radix(*radix), *str);
        }
    }
}

#[test]
fn test_from_and_to_radix() {
    const GROUND_TRUTH: &[(&[u8], u32, &[u8])] = &[
        (b"0"42, &[0]),
        (
            b"ffffeeffbb",
            2,
            &[
                1101110111111111011101111111,
                111111111111,
            ],
        ),
        (
            b"ffffeeffbb",
            3,
            &[
                22112112000001200001002201,
            ],
        ),
        (
            b"ffffeeffbb",
            4,
            &[32323333232333333333],
        ),
        (
            b"ffffeeffbb",
            5,
            &[043314241442300121],
        ),
        (
            b"ffffeeffbb",
            6,
            &[5545500125301022],
        ),
        (
            b"ffffeeffbb",
            7,
            &[423601616203241],
        ),
        (
            b"ffffeeffbb",
            8,
            &[37677537777771],
        ),
        (b"ffffeeffbb"9, &[8457003203083]),
        (b"ffffeeffbb"10, &[5953150159901]),
        (b"ffffeeffbb"11, &[1076520333493]),
        (b"ffffeeffbb"12, &[118510110311951]),
        (b"ffffeeffbb"13, &[0574656118127]),
        (b"ffffeeffbb"14, &[11441184603113]),
        (b"ffffeeffbb"15, &[511132110209131]),
        (b"ffffeeffbb"16, &[11111515141415151515]),
        (b"ffffeeffbb"17, &[02141221481049]),
        (b"ffffeeffbb"18, &[17155131016161395]),
        (b"ffffeeffbb"19, &[1413289011473]),
        (b"ffffeeffbb"20, &[1519314017191822]),
        (b"ffffeeffbb"21, &[1154135189181]),
        (b"ffffeeffbb"22, &[213721151217020]),
        (b"ffffeeffbb"23, &[21216910721014]),
        (b"ffffeeffbb"24, &[11101914221117239]),
        (b"ffffeeffbb"25, &[201821222114357]),
        (b"ffffeeffbb"26, &[131524111762365]),
        (b"ffffeeffbb"27, &[1716702103243]),
        (b"ffffeeffbb"28, &[11161115141813252]),
        (b"ffffeeffbb"29, &[6871914132152]),
        (b"ffffeeffbb"30, &[51318111078201]),
        (b"ffffeeffbb"31, &[222615198272981]),
        (b"ffffeeffbb"32, &[2729312930313131]),
        (b"ffffeeffbb"33, &[322027121122625]),
        (b"ffffeeffbb"34, &[179163313253120]),
        (b"ffffeeffbb"35, &[2532225114317]),
        (b"ffffeeffbb"36, &[353456323114]),
        (b"ffffeeffbb"37, &[162118433192111]),
        (b"ffffeeffbb"38, &[33251929206239]),
        (b"ffffeeffbb"39, &[26272923161808]),
        (b"ffffeeffbb"40, &[353930111617286]),
        (b"ffffeeffbb"41, &[36309181219265]),
        (b"ffffeeffbb"42, &[11343727113324]),
        (b"ffffeeffbb"43, &[324112104014]),
        (b"ffffeeffbb"44, &[43124032323193]),
        (b"ffffeeffbb"45, &[353844182218422]),
        (b"ffffeeffbb"46, &[21451841172242]),
        (b"ffffeeffbb"47, &[373711126082]),
        (b"ffffeeffbb"48, &[11414043543411]),
        (b"ffffeeffbb"49, &[18457132021301]),
        (b"ffffeeffbb"50, &[45215342118201]),
        (b"ffffeeffbb"51, &[17626223824111]),
        (b"ffffeeffbb"52, &[39333830463131]),
        (b"ffffeeffbb"53, &[317442393249]),
        (b"ffffeeffbb"54, &[1735837311844]),
        (b"ffffeeffbb"55, &[1052948363939]),
        (b"ffffeeffbb"56, &[11505122253635]),
        (b"ffffeeffbb"57, &[1455124320332]),
        (b"ffffeeffbb"58, &[3518455695128]),
        (b"ffffeeffbb"59, &[5128202655326]),
        (b"ffffeeffbb"60, &[3562746583323]),
        (b"ffffeeffbb"61, &[587654492021]),
        (b"ffffeeffbb"62, &[5359314102219]),
        (b"ffffeeffbb"63, &[5350234563617]),
        (b"ffffeeffbb"64, &[59624759636315]),
        (b"ffffeeffbb"65, &[053394403714]),
        (b"ffffeeffbb"66, &[6559391641913]),
        (b"ffffeeffbb"67, &[35141916251012]),
        (b"ffffeeffbb"68, &[5138635015811]),
        (b"ffffeeffbb"69, &[44451858681210]),
        (b"ffffeeffbb"70, &[255106013249]),
        (b"ffffeeffbb"71, &[543096528418]),
        (b"ffffeeffbb"72, &[3535555417647]),
        (b"ffffeeffbb"73, &[344484027197]),
        (b"ffffeeffbb"74, &[534745636516]),
        (b"ffffeeffbb"75, &[2056107224136]),
        (b"ffffeeffbb"76, &[7131526048535]),
        (b"ffffeeffbb"77, &[3273146315215]),
        (b"ffffeeffbb"78, &[6513173264684]),
        (b"ffffeeffbb"79, &[375625625414]),
        (b"ffffeeffbb"80, &[7559374143154]),
        (b"ffffeeffbb"81, &[446802127723]),
        (b"ffffeeffbb"82, &[773527446503]),
        (b"ffffeeffbb"83, &[5251197610303]),
        (b"ffffeeffbb"84, &[1180191976103]),
        (b"ffffeeffbb"85, &[082201468772]),
        (b"ffffeeffbb"86, &[312783762612]),
        (b"ffffeeffbb"87, &[351220852462]),
        (b"ffffeeffbb"88, &[436544230322]),
        (b"ffffeeffbb"89, &[4952852180182]),
        (b"ffffeeffbb"90, &[356478241862]),
        (b"ffffeeffbb"91, &[3917836317851]),
        (b"ffffeeffbb"92, &[6722857975741]),
        (b"ffffeeffbb"93, &[536039294651]),
        (b"ffffeeffbb"94, &[378927276551]),
        (b"ffffeeffbb"95, &[90748999471]),
        (b"ffffeeffbb"96, &[5920463581381]),
        (b"ffffeeffbb"97, &[948760713311]),
        (b"ffffeeffbb"98, &[6722635062231]),
        (b"ffffeeffbb"99, &[986691261161]),
        (b"ffffeeffbb"100, &[953551109591]),
        (b"ffffeeffbb"101, &[8727786231]),
        (b"ffffeeffbb"102, &[17332795999]),
        (b"ffffeeffbb"103, &[30229008794]),
        (b"ffffeeffbb"104, &[916887683890]),
        (b"ffffeeffbb"105, &[958054731586]),
        (b"ffffeeffbb"106, &[313024161782]),
        (b"ffffeeffbb"107, &[515010124278]),
        (b"ffffeeffbb"108, &[717196788974]),
        (b"ffffeeffbb"109, &[331893225071]),
        (b"ffffeeffbb"110, &[655357882968]),
        (b"ffffeeffbb"111, &[539367902765]),
        (b"ffffeeffbb"112, &[1110996654362]),
        (b"ffffeeffbb"113, &[2723106567659]),
        (b"ffffeeffbb"114, &[7184311121157]),
        (b"ffffeeffbb"115, &[90221567654]),
        (b"ffffeeffbb"116, &[353898574052]),
        (b"ffffeeffbb"117, &[26113115621750]),
        (b"ffffeeffbb"118, &[5114518748]),
        (b"ffffeeffbb"119, &[10231110108846]),
        (b"ffffeeffbb"120, &[359396502244]),
        (b"ffffeeffbb"121, &[87612364742]),
        (b"ffffeeffbb"122, &[119641228340]),
        (b"ffffeeffbb"123, &[771193290639]),
        (b"ffffeeffbb"124, &[11512231796237]),
        (b"ffffeeffbb"125, &[951084774336]),
        (b"ffffeeffbb"126, &[5325116397834]),
        (b"ffffeeffbb"127, &[2223125673533]),
        (b"ffffeeffbb"128, &[591275912712731]),
        (b"ffffeeffbb"129, &[893615910030]),
        (b"ffffeeffbb"130, &[6591123897929]),
        (b"ffffeeffbb"131, &[587239636528]),
        (b"ffffeeffbb"132, &[1316292825727]),
        (b"ffffeeffbb"133, &[10931511235526]),
        (b"ffffeeffbb"134, &[357421276025]),
        (b"ffffeeffbb"135, &[12513249377024]),
        (b"ffffeeffbb"136, &[511211171338523]),
        (b"ffffeeffbb"137, &[113601352210722]),
        (b"ffffeeffbb"138, &[11391739313321]),
        (b"ffffeeffbb"139, &[11475102512621]),
        (b"ffffeeffbb"140, &[952535166220]),
        (b"ffffeeffbb"141, &[1311371611010219]),
        (b"ffffeeffbb"142, &[12512110834619]),
        (b"ffffeeffbb"143, &[6578138555518]),
        (b"ffffeeffbb"144, &[1071251211510917]),
        (b"ffffeeffbb"145, &[3513122422217]),
        (b"ffffeeffbb"146, &[107381031238316]),
        (b"ffffeeffbb"147, &[116967198216]),
        (b"ffffeeffbb"148, &[1272375997115]),
        (b"ffffeeffbb"149, &[1361105311414414]),
        (b"ffffeeffbb"150, &[951401331307114]),
        (b"ffffeeffbb"151, &[155029137014]),
        (b"ffffeeffbb"152, &[14715891218313]),
        (b"ffffeeffbb"153, &[178793721713]),
        (b"ffffeeffbb"154, &[109113313310612]),
        (b"ffffeeffbb"155, &[1151411201394412]),
        (b"ffffeeffbb"156, &[1434548214011]),
        (b"ffffeeffbb"157, &[14992151068211]),
        (b"ffffeeffbb"158, &[3710779462611]),
        (b"ffffeeffbb"159, &[137371465113010]),
        (b"ffffeeffbb"160, &[15569291157710]),
        (b"ffffeeffbb"161, &[679846682610]),
        (b"ffffeeffbb"162, &[12515560631389]),
        (b"ffffeeffbb"163, &[964311893909]),
        (b"ffffeeffbb"164, &[15999123152439]),
        (b"ffffeeffbb"165, &[65171691638]),
        (b"ffffeeffbb"166, &[135108251651198]),
        (b"ffffeeffbb"167, &[165116164103778]),
        (b"ffffeeffbb"168, &[111666744368]),
        (b"ffffeeffbb"169, &[6559711491647]),
        (b"ffffeeffbb"170, &[858326761267]),
        (b"ffffeeffbb"171, &[71132140157887]),
        (b"ffffeeffbb"172, &[3612747527]),
        (b"ffffeeffbb"173, &[122665383167]),
        (b"ffffeeffbb"174, &[3565881556]),
        (b"ffffeeffbb"175, &[952084561226]),
        (b"ffffeeffbb"176, &[439157159896]),
        (b"ffffeeffbb"177, &[1101275440586]),
        (b"ffffeeffbb"178, &[491154347276]),
        (b"ffffeeffbb"179, &[1309141781755]),
        (b"ffffeeffbb"180, &[35122109701475]),
        (b"ffffeeffbb"181, &[94944791195]),
        (b"ffffeeffbb"182, &[39546619925]),
        (b"ffffeeffbb"183, &[119214369655]),
        (b"ffffeeffbb"184, &[67579044395]),
        (b"ffffeeffbb"185, &[9063141123135]),
        (b"ffffeeffbb"186, &[531231721191744]),
        (b"ffffeeffbb"187, &[1532168281514]),
        (b"ffffeeffbb"188, &[13113894321284]),
        (b"ffffeeffbb"189, &[1791211561301054]),
        (b"ffffeeffbb"190, &[185179164131834]),
        (b"ffffeeffbb"191, &[1181233731624]),
        (b"ffffeeffbb"192, &[591068316414]),
        (b"ffffeeffbb"193, &[57374786204]),
        (b"ffffeeffbb"194, &[191140634504]),
        (b"ffffeeffbb"195, &[6516983841753]),
        (b"ffffeeffbb"196, &[671586461573]),
        (b"ffffeeffbb"197, &[1212616731393]),
        (b"ffffeeffbb"198, &[197151165751213]),
        (b"ffffeeffbb"199, &[5517536221043]),
        (b"ffffeeffbb"200, &[19516716238873]),
        (b"ffffeeffbb"201, &[3527136124703]),
        (b"ffffeeffbb"202, &[876415376543]),
        (b"ffffeeffbb"203, &[1511911494383]),
        (b"ffffeeffbb"204, &[119103135175223]),
        (b"ffffeeffbb"205, &[2007912311573]),
        (b"ffffeeffbb"206, &[1331652021151982]),
        (b"ffffeeffbb"207, &[441531931751842]),
        (b"ffffeeffbb"208, &[91190125861712]),
        (b"ffffeeffbb"209, &[10915134531582]),
        (b"ffffeeffbb"210, &[9540171741452]),
        (b"ffffeeffbb"211, &[841951621501322]),
        (b"ffffeeffbb"212, &[311559681202]),
        (b"ffffeeffbb"213, &[12557127361082]),
        (b"ffffeeffbb"214, &[51132255962]),
        (b"ffffeeffbb"215, &[175133177122842]),
        (b"ffffeeffbb"216, &[179357823732]),
        (b"ffffeeffbb"217, &[53101208186612]),
        (b"ffffeeffbb"218, &[339214179502]),
        (b"ffffeeffbb"219, &[107147175217392]),
        (b"ffffeeffbb"220, &[1758117979292]),
        (b"ffffeeffbb"221, &[07695204182]),
        (b"ffffeeffbb"222, &[532131615082]),
        (b"ffffeeffbb"223, &[158161421362211]),
        (b"ffffeeffbb"224, &[12354521622121]),
        (b"ffffeeffbb"225, &[1704315122041]),
        (b"ffffeeffbb"226, &[27682241051951]),
        (b"ffffeeffbb"227, &[4569157201871]),
        (b"ffffeeffbb"228, &[71213641991781]),
        (b"ffffeeffbb"229, &[129203661861701]),
        (b"ffffeeffbb"230, &[205183572081621]),
        (b"ffffeeffbb"231, &[3250164331551]),
        (b"ffffeeffbb"232, &[35135531231471]),
        (b"ffffeeffbb"233, &[2094789131401]),
        (b"ffffeeffbb"234, &[143561751681321]),
        (b"ffffeeffbb"235, &[2251572161211251]),
        (b"ffffeeffbb"236, &[51661191051181]),
        (b"ffffeeffbb"237, &[116150261191111]),
        (b"ffffeeffbb"238, &[22115871621041]),
        (b"ffffeeffbb"239, &[234155214234971]),
        (b"ffffeeffbb"240, &[155468496911]),
        (b"ffffeeffbb"241, &[1874890225841]),
        (b"ffffeeffbb"242, &[87212151140781]),
        (b"ffffeeffbb"243, &[2062218981721]),
        (b"ffffeeffbb"244, &[1199312248661]),
        (b"ffffeeffbb"245, &[16522411740601]),
        (b"ffffeeffbb"246, &[7712110057541]),
        (b"ffffeeffbb"247, &[5212824298481]),
        (b"ffffeeffbb"248, &[115247224164421]),
        (b"ffffeeffbb"249, &[2181272235371]),
        (b"ffffeeffbb"250, &[9554168118311]),
        (b"ffffeeffbb"251, &[1212042403261]),
        (b"ffffeeffbb"252, &[179138123162201]),
        (b"ffffeeffbb"253, &[2150191151]),
        (b"ffffeeffbb"254, &[149116340101]),
        (b"ffffeeffbb"255, &[170225247951]),
        (b"ffffeeffbb"256, &[187255238255255]),
    ];

    for &(bigint, radix, inbaseradix_le) in GROUND_TRUTH.iter() {
        let bigint = BigUint::parse_bytes(bigint, 16).unwrap();
        // to_radix_le
        assert_eq!(bigint.to_radix_le(radix), inbaseradix_le);
        // to_radix_be
        let mut inbase_be = bigint.to_radix_be(radix);
        inbase_be.reverse(); // now le
        assert_eq!(inbase_be, inbaseradix_le);
        // from_radix_le
        assert_eq!(
            BigUint::from_radix_le(inbaseradix_le, radix).unwrap(),
            bigint
        );
        // from_radix_be
        let mut inbaseradix_be = Vec::from(inbaseradix_le);
        inbaseradix_be.reverse();
        assert_eq!(
            BigUint::from_radix_be(&inbaseradix_be, radix).unwrap(),
            bigint
        );
    }

    assert!(BigUint::from_radix_le(&[1010010], 50).is_none());
    assert_eq!(BigUint::from_radix_le(&[], 2), Some(BigUint::zero()));
    assert_eq!(BigUint::from_radix_be(&[], 2), Some(BigUint::zero()));
}

#[test]
fn test_from_str_radix() {
    let r = to_str_pairs();
    for num_pair in r.iter() {
        let &(ref n, ref rs) = num_pair;
        for str_pair in rs.iter() {
            let &(ref radix, ref str) = str_pair;
            assert_eq!(n, &BigUint::from_str_radix(str, *radix).unwrap());
        }
    }

    let zed = BigUint::from_str_radix("Z"10).ok();
    assert_eq!(zed, None);
    let blank = BigUint::from_str_radix("_"2).ok();
    assert_eq!(blank, None);
    let blank_one = BigUint::from_str_radix("_1"2).ok();
    assert_eq!(blank_one, None);
    let plus_one = BigUint::from_str_radix("+1"10).ok();
    assert_eq!(plus_one, Some(BigUint::from_slice(&[1])));
    let plus_plus_one = BigUint::from_str_radix("++1"10).ok();
    assert_eq!(plus_plus_one, None);
    let minus_one = BigUint::from_str_radix("-1"10).ok();
    assert_eq!(minus_one, None);
    let zero_plus_two = BigUint::from_str_radix("0+2"10).ok();
    assert_eq!(zero_plus_two, None);
    let three = BigUint::from_str_radix("1_1"2).ok();
    assert_eq!(three, Some(BigUint::from_slice(&[3])));
    let ff = BigUint::from_str_radix("1111_1111"2).ok();
    assert_eq!(ff, Some(BigUint::from_slice(&[0xff])));
}

#[test]
fn test_all_str_radix() {
    let n = BigUint::new((0..10).collect());
    for radix in 2..37 {
        let s = n.to_str_radix(radix);
        let x = BigUint::from_str_radix(&s, radix);
        assert_eq!(x.unwrap(), n);

        let s = s.to_ascii_uppercase();
        let x = BigUint::from_str_radix(&s, radix);
        assert_eq!(x.unwrap(), n);
    }
}

#[test]
fn test_big_str() {
    for n in 2..=20_u32 {
        let x: BigUint = BigUint::from(n).pow(10_000_u32);
        let s = x.to_string();
        let y: BigUint = s.parse().unwrap();
        assert_eq!(x, y);
    }
}

#[test]
fn test_lower_hex() {
    let a = BigUint::parse_bytes(b"A"16).unwrap();
    let hello = BigUint::parse_bytes(b"22405534230753963835153736737"10).unwrap();

    assert_eq!(format!("{:x}", a), "a");
    assert_eq!(format!("{:x}", hello), "48656c6c6f20776f726c6421");
    assert_eq!(format!("{:♥>+#8x}", a), "♥♥♥♥+0xa");
}

#[test]
fn test_upper_hex() {
    let a = BigUint::parse_bytes(b"A"16).unwrap();
    let hello = BigUint::parse_bytes(b"22405534230753963835153736737"10).unwrap();

    assert_eq!(format!("{:X}", a), "A");
    assert_eq!(format!("{:X}", hello), "48656C6C6F20776F726C6421");
    assert_eq!(format!("{:♥>+#8X}", a), "♥♥♥♥+0xA");
}

#[test]
fn test_binary() {
    let a = BigUint::parse_bytes(b"A"16).unwrap();
    let hello = BigUint::parse_bytes(b"224055342307539"10).unwrap();

    assert_eq!(format!("{:b}", a), "1010");
    assert_eq!(
        format!("{:b}", hello),
        "110010111100011011110011000101101001100011010011"
    );
    assert_eq!(format!("{:♥>+#8b}", a), "♥+0b1010");
}

#[test]
fn test_octal() {
    let a = BigUint::parse_bytes(b"A"16).unwrap();
    let hello = BigUint::parse_bytes(b"22405534230753963835153736737"10).unwrap();

    assert_eq!(format!("{:o}", a), "12");
    assert_eq!(format!("{:o}", hello), "22062554330674403566756233062041");
    assert_eq!(format!("{:♥>+#8o}", a), "♥♥♥+0o12");
}

#[test]
fn test_display() {
    let a = BigUint::parse_bytes(b"A"16).unwrap();
    let hello = BigUint::parse_bytes(b"22405534230753963835153736737"10).unwrap();

    assert_eq!(format!("{}", a), "10");
    assert_eq!(format!("{}", hello), "22405534230753963835153736737");
    assert_eq!(format!("{:♥>+#8}", a), "♥♥♥♥♥+10");
}

#[test]
fn test_factor() {
    fn factor(n: usize) -> BigUint {
        let mut f: BigUint = One::one();
        for i in 2..=n {
            // FIXME(#5992): assignment operator overloads
            // f *= FromPrimitive::from_usize(i);
            let bu: BigUint = FromPrimitive::from_usize(i).unwrap();
            f *= bu;
        }
        f
    }

    fn check(n: usize, s: &str) {
        let n = factor(n);
        let ans = BigUint::from_str_radix(s, 10).unwrap();
        assert_eq!(n, ans);
    }

    check(3"6");
    check(10"3628800");
    check(20"2432902008176640000");
    check(30"265252859812191058636308480000000");
}

#[test]
fn test_bits() {
    assert_eq!(BigUint::new(vec![0000]).bits(), 0);
    let n: BigUint = FromPrimitive::from_usize(0).unwrap();
    assert_eq!(n.bits(), 0);
    let n: BigUint = FromPrimitive::from_usize(1).unwrap();
    assert_eq!(n.bits(), 1);
    let n: BigUint = FromPrimitive::from_usize(3).unwrap();
    assert_eq!(n.bits(), 2);
    let n: BigUint = BigUint::from_str_radix("4000000000"16).unwrap();
    assert_eq!(n.bits(), 39);
    let one: BigUint = One::one();
    assert_eq!((one << 426u16).bits(), 427);
}

#[test]
fn test_iter_sum() {
    let result: BigUint = FromPrimitive::from_isize(1234567).unwrap();
    let data: Vec<BigUint> = vec![
        FromPrimitive::from_u32(1000000).unwrap(),
        FromPrimitive::from_u32(200000).unwrap(),
        FromPrimitive::from_u32(30000).unwrap(),
        FromPrimitive::from_u32(4000).unwrap(),
        FromPrimitive::from_u32(500).unwrap(),
        FromPrimitive::from_u32(60).unwrap(),
        FromPrimitive::from_u32(7).unwrap(),
    ];

    assert_eq!(result, data.iter().sum::<BigUint>());
    assert_eq!(result, data.into_iter().sum::<BigUint>());
}

#[test]
fn test_iter_product() {
    let data: Vec<BigUint> = vec![
        FromPrimitive::from_u32(1001).unwrap(),
        FromPrimitive::from_u32(1002).unwrap(),
        FromPrimitive::from_u32(1003).unwrap(),
        FromPrimitive::from_u32(1004).unwrap(),
        FromPrimitive::from_u32(1005).unwrap(),
    ];
    let result = data.get(0).unwrap()
        * data.get(1).unwrap()
        * data.get(2).unwrap()
        * data.get(3).unwrap()
        * data.get(4).unwrap();

    assert_eq!(result, data.iter().product::<BigUint>());
    assert_eq!(result, data.into_iter().product::<BigUint>());
}

#[test]
fn test_iter_sum_generic() {
    let result: BigUint = FromPrimitive::from_isize(1234567).unwrap();
    let data = vec![1000000_u32, 200000300004000500607];

    assert_eq!(result, data.iter().sum::<BigUint>());
    assert_eq!(result, data.into_iter().sum::<BigUint>());
}

#[test]
fn test_iter_product_generic() {
    let data = vec![1001_u32, 1002100310041005];
    let result = data[0].to_biguint().unwrap()
        * data[1].to_biguint().unwrap()
        * data[2].to_biguint().unwrap()
        * data[3].to_biguint().unwrap()
        * data[4].to_biguint().unwrap();

    assert_eq!(result, data.iter().product::<BigUint>());
    assert_eq!(result, data.into_iter().product::<BigUint>());
}

#[test]
fn test_pow() {
    let one = BigUint::from(1u32);
    let two = BigUint::from(2u32);
    let four = BigUint::from(4u32);
    let eight = BigUint::from(8u32);
    let tentwentyfour = BigUint::from(1024u32);
    let twentyfourtyeight = BigUint::from(2048u32);
    macro_rules! check {
        ($t:ty) => {
            assert_eq!(Pow::pow(&two, 0 as $t), one);
            assert_eq!(Pow::pow(&two, 1 as $t), two);
            assert_eq!(Pow::pow(&two, 2 as $t), four);
            assert_eq!(Pow::pow(&two, 3 as $t), eight);
            assert_eq!(Pow::pow(&two, 10 as $t), tentwentyfour);
            assert_eq!(Pow::pow(&two, 11 as $t), twentyfourtyeight);
            assert_eq!(Pow::pow(&two, &(11 as $t)), twentyfourtyeight);
        };
    }
    check!(u8);
    check!(u16);
    check!(u32);
    check!(u64);
    check!(u128);
    check!(usize);

    let pow_1e10000 = BigUint::from(10u32).pow(10_000_u32);
    let manual_1e10000 = repeat(10u32).take(10_000).product::<BigUint>();
    assert!(manual_1e10000 == pow_1e10000);
}

#[test]
fn test_trailing_zeros() {
    assert!(BigUint::from(0u8).trailing_zeros().is_none());
    assert_eq!(BigUint::from(1u8).trailing_zeros().unwrap(), 0);
    assert_eq!(BigUint::from(2u8).trailing_zeros().unwrap(), 1);
    let x: BigUint = BigUint::one() << 128;
    assert_eq!(x.trailing_zeros().unwrap(), 128);
}

#[test]
fn test_trailing_ones() {
    assert_eq!(BigUint::from(0u8).trailing_ones(), 0);
    assert_eq!(BigUint::from(1u8).trailing_ones(), 1);
    assert_eq!(BigUint::from(2u8).trailing_ones(), 0);
    assert_eq!(BigUint::from(3u8).trailing_ones(), 2);
    let x: BigUint = (BigUint::from(3u8) << 128) | BigUint::from(3u8);
    assert_eq!(x.trailing_ones(), 2);
    let x: BigUint = (BigUint::one() << 128) - BigUint::one();
    assert_eq!(x.trailing_ones(), 128);
}

#[test]
fn test_count_ones() {
    assert_eq!(BigUint::from(0u8).count_ones(), 0);
    assert_eq!(BigUint::from(1u8).count_ones(), 1);
    assert_eq!(BigUint::from(2u8).count_ones(), 1);
    assert_eq!(BigUint::from(3u8).count_ones(), 2);
    let x: BigUint = (BigUint::from(3u8) << 128) | BigUint::from(3u8);
    assert_eq!(x.count_ones(), 4);
}

#[test]
fn test_bit() {
    assert!(!BigUint::from(0u8).bit(0));
    assert!(!BigUint::from(0u8).bit(100));
    assert!(!BigUint::from(42u8).bit(4));
    assert!(BigUint::from(42u8).bit(5));
    let x: BigUint = (BigUint::from(3u8) << 128) | BigUint::from(3u8);
    assert!(x.bit(129));
    assert!(!x.bit(130));
}

#[test]
fn test_set_bit() {
    let mut x = BigUint::from(3u8);
    x.set_bit(128true);
    x.set_bit(129true);
    assert_eq!(x, (BigUint::from(3u8) << 128) | BigUint::from(3u8));
    x.set_bit(0false);
    x.set_bit(128false);
    x.set_bit(130false);
    assert_eq!(x, (BigUint::from(2u8) << 128) | BigUint::from(2u8));
    x.set_bit(129false);
    x.set_bit(1false);
    assert_eq!(x, BigUint::zero());
}

Messung V0.5 in Prozent
C=88 H=96 G=91

¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.33Angebot  ¤

*Eine klare Vorstellung vom Zielzustand






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=277311
#Domains=752002