use decimal_scaled::{D38, D38s12};
#[test]
fn bitand_clears_bits() {
let a = D38s12::from_bits(0xF0);
let b = D38s12::from_bits(0x0F);
assert_eq!(a & b, D38s12::from_bits(0x00));
}
#[test]
fn bitand_assign_in_place() {
let mut a = D38s12::from_bits(0xFF);
a &= D38s12::from_bits(0x0F);
assert_eq!(a, D38s12::from_bits(0x0F));
}
#[test]
fn bitor_sets_bits() {
let zero = D38s12::ZERO;
let one_lsb = D38s12::from_bits(1);
assert_eq!(zero | one_lsb, one_lsb);
}
#[test]
fn bitor_assign_in_place() {
let mut a = D38s12::from_bits(0xF0);
a |= D38s12::from_bits(0x0F);
assert_eq!(a, D38s12::from_bits(0xFF));
}
#[test]
fn bitxor_toggles_bits() {
let a = D38s12::from_bits(0b1100);
let b = D38s12::from_bits(0b1010);
assert_eq!(a ^ b, D38s12::from_bits(0b0110));
}
#[test]
fn bitxor_assign_in_place() {
let mut a = D38s12::from_bits(0xFF);
a ^= D38s12::from_bits(0x0F);
assert_eq!(a, D38s12::from_bits(0xF0));
}
#[test]
fn bitxor_self_is_zero() {
let a = D38s12::from_bits(0xDEAD_BEEF_i128);
assert_eq!(a ^ a, D38s12::ZERO);
}
#[test]
fn shl_doubles_lsb() {
assert_eq!(D38s12::from_bits(1) << 1u32, D38s12::from_bits(2));
}
#[test]
fn shr_halves_lsb() {
assert_eq!(D38s12::from_bits(2) >> 1u32, D38s12::from_bits(1));
}
#[test]
fn shr_is_sign_extending() {
assert_eq!(D38s12::from_bits(-1) >> 1u32, D38s12::from_bits(-1));
}
#[test]
fn shr_negative_stays_negative() {
assert_eq!(D38s12::from_bits(-8) >> 1u32, D38s12::from_bits(-4));
}
#[test]
fn shl_assign_in_place() {
let mut a = D38s12::from_bits(1);
a <<= 4u32;
assert_eq!(a, D38s12::from_bits(16));
}
#[test]
fn shr_assign_in_place() {
let mut a = D38s12::from_bits(16);
a >>= 2u32;
assert_eq!(a, D38s12::from_bits(4));
}
#[test]
fn not_zero_is_neg_one() {
assert_eq!(!D38s12::ZERO, D38s12::from_bits(-1));
}
#[test]
fn not_neg_one_is_zero() {
assert_eq!(!D38s12::from_bits(-1), D38s12::ZERO);
}
#[test]
fn not_is_self_inverse() {
let a = D38s12::from_bits(0xCAFE);
assert_eq!(!!a, a);
}
#[test]
fn unsigned_shr_zero_fills_negative() {
assert_eq!(
D38s12::from_bits(-1).unsigned_shr(1),
D38s12::from_bits(i128::MAX)
);
}
#[test]
fn unsigned_shr_positive_matches_arithmetic_shr() {
let a = D38s12::from_bits(0xFF);
assert_eq!(a.unsigned_shr(4), a >> 4u32);
assert_eq!(a.unsigned_shr(4), D38s12::from_bits(0x0F));
}
#[test]
fn unsigned_shr_zero_amount_identity() {
let a = D38s12::from_bits(-42);
assert_eq!(a.unsigned_shr(0), a);
}
#[test]
fn rotate_left_low_bits() {
assert_eq!(
D38s12::from_bits(0b111).rotate_left(1),
D38s12::from_bits(0b1110)
);
}
#[test]
fn rotate_right_low_bit_wraps_to_top() {
assert_eq!(
D38s12::from_bits(1).rotate_right(1),
D38s12::from_bits(i128::MIN)
);
}
#[test]
fn rotate_left_full_width_is_identity() {
let a = D38s12::from_bits(0xDEAD_BEEF_i128);
assert_eq!(a.rotate_left(128), a);
}
#[test]
fn rotate_right_round_trip() {
let a = D38s12::from_bits(0xCAFE_F00D_i128);
assert_eq!(a.rotate_left(13).rotate_right(13), a);
}
#[test]
fn leading_zeros_lsb_is_127() {
assert_eq!(D38s12::from_bits(1).leading_zeros(), 127);
}
#[test]
fn leading_zeros_zero_is_128() {
assert_eq!(D38s12::ZERO.leading_zeros(), 128);
}
#[test]
fn leading_zeros_neg_one_is_zero() {
assert_eq!(D38s12::from_bits(-1).leading_zeros(), 0);
}
#[test]
fn trailing_zeros_eight_is_three() {
assert_eq!(D38s12::from_bits(8).trailing_zeros(), 3);
}
#[test]
fn trailing_zeros_zero_is_128() {
assert_eq!(D38s12::ZERO.trailing_zeros(), 128);
}
#[test]
fn trailing_zeros_one_is_zero() {
assert_eq!(D38s12::from_bits(1).trailing_zeros(), 0);
}
#[test]
fn count_ones_pattern() {
assert_eq!(D38s12::from_bits(0b101).count_ones(), 2);
}
#[test]
fn count_zeros_pattern() {
assert_eq!(D38s12::from_bits(0b101).count_zeros(), 126);
}
#[test]
fn count_ones_zero_is_zero() {
assert_eq!(D38s12::ZERO.count_ones(), 0);
}
#[test]
fn count_ones_neg_one_is_128() {
assert_eq!(D38s12::from_bits(-1).count_ones(), 128);
}
#[test]
fn count_zeros_complement_relation() {
let a = D38s12::from_bits(0xDEAD_BEEF_CAFE_i128);
assert_eq!(a.count_ones() + a.count_zeros(), 128);
}
#[test]
fn is_power_of_two_true_for_eight() {
assert!(D38s12::from_bits(8).is_power_of_two());
}
#[test]
fn is_power_of_two_false_for_seven() {
assert!(!D38s12::from_bits(7).is_power_of_two());
}
#[test]
fn is_power_of_two_false_for_zero() {
assert!(!D38s12::ZERO.is_power_of_two());
}
#[test]
fn is_power_of_two_false_for_negative() {
assert!(!D38s12::from_bits(-1).is_power_of_two());
}
#[test]
fn is_power_of_two_storage_not_value_semantic() {
assert!(!D38s12::ONE.is_power_of_two());
}
#[test]
fn next_power_of_two_seven_is_eight() {
assert_eq!(
D38s12::from_bits(7).next_power_of_two(),
D38s12::from_bits(8)
);
}
#[test]
fn next_power_of_two_eight_is_eight() {
assert_eq!(
D38s12::from_bits(8).next_power_of_two(),
D38s12::from_bits(8)
);
}
#[test]
fn next_power_of_two_one_is_one() {
assert_eq!(
D38s12::from_bits(1).next_power_of_two(),
D38s12::from_bits(1)
);
}
#[test]
fn ops_work_at_scale_six() {
type D6 = D38<6>;
let a = D6::from_bits(0b1100);
let b = D6::from_bits(0b1010);
assert_eq!(a & b, D6::from_bits(0b1000));
assert_eq!(a | b, D6::from_bits(0b1110));
assert_eq!(a ^ b, D6::from_bits(0b0110));
assert_eq!(D6::from_bits(1) << 3u32, D6::from_bits(8));
assert_eq!(D6::from_bits(8) >> 3u32, D6::from_bits(1));
assert_eq!(!D6::ZERO, D6::from_bits(-1));
assert_eq!(D6::from_bits(8).count_ones(), 1);
assert!(D6::from_bits(8).is_power_of_two());
}