use super::super::Zq;
use crate::integer::Z;
use flint3_sys::fmpz_mod_neg;
use std::ops::Neg;
impl Neg for Zq {
type Output = Zq;
fn neg(mut self) -> Self::Output {
unsafe {
fmpz_mod_neg(
&mut self.value.value,
&self.value.value,
self.modulus.get_fmpz_mod_ctx_struct(),
)
};
self
}
}
impl Neg for &Zq {
type Output = Zq;
fn neg(self) -> Self::Output {
let mut out = Z::ZERO;
unsafe {
fmpz_mod_neg(
&mut out.value,
&self.value.value,
self.modulus.get_fmpz_mod_ctx_struct(),
)
};
Zq {
value: out,
modulus: self.modulus.clone(),
}
}
}
#[cfg(test)]
mod test_neg {
use super::Zq;
use crate::integer::Z;
#[test]
fn correct_small() {
let a = Zq::from((1, 17));
let b = Zq::from((-1, 17));
let c = Zq::from((0, 17));
assert_eq!(a, -(-&a));
assert_eq!(a, -&b);
assert_eq!(b, -&a);
assert_eq!(a, -b.clone());
assert_eq!(b, -a);
assert_eq!(c, -&c);
assert_eq!(c.clone(), -c);
}
#[test]
fn correct_large() {
let a = Zq::from((i64::MAX, u64::MAX));
let b = Zq::from((u64::MAX - i64::MAX as u64, u64::MAX));
assert_eq!(a, -(-&a));
assert_eq!(b, -&a);
assert_eq!(b, -a);
}
#[test]
fn reduced() {
let a = Zq::from((3, 17));
let c = Zq::from((0, 17));
let neg_a = -&a;
let neg_c = -c;
assert_eq!(
Z::from(14),
neg_a.get_representative_least_nonnegative_residue()
);
assert_eq!(
Z::from(14),
(-a).get_representative_least_nonnegative_residue()
);
assert_eq!(
Z::ZERO,
neg_c.get_representative_least_nonnegative_residue()
);
assert_eq!(Z::from(17), neg_a.get_mod());
}
}