qfall_math/integer_mod_q/z_q/arithmetic/
neg.rs1use super::super::Zq;
12use crate::integer::Z;
13use flint3_sys::fmpz_mod_neg;
14use std::ops::Neg;
15
16impl Neg for Zq {
17 type Output = Zq;
18
19 fn neg(mut self) -> Self::Output {
36 unsafe {
37 fmpz_mod_neg(
38 &mut self.value.value,
39 &self.value.value,
40 self.modulus.get_fmpz_mod_ctx_struct(),
41 )
42 };
43 self
44 }
45}
46
47impl Neg for &Zq {
48 type Output = Zq;
49
50 fn neg(self) -> Self::Output {
52 let mut out = Z::ZERO;
53 unsafe {
54 fmpz_mod_neg(
55 &mut out.value,
56 &self.value.value,
57 self.modulus.get_fmpz_mod_ctx_struct(),
58 )
59 };
60 Zq {
61 value: out,
62 modulus: self.modulus.clone(),
63 }
64 }
65}
66
67#[cfg(test)]
68mod test_neg {
69 use super::Zq;
70 use crate::integer::Z;
71
72 #[test]
74 fn correct_small() {
75 let a = Zq::from((1, 17));
76 let b = Zq::from((-1, 17));
77 let c = Zq::from((0, 17));
78
79 assert_eq!(a, -(-&a));
80 assert_eq!(a, -&b);
81 assert_eq!(b, -&a);
82 assert_eq!(a, -b.clone());
83 assert_eq!(b, -a);
84 assert_eq!(c, -&c);
85 assert_eq!(c.clone(), -c);
86 }
87
88 #[test]
90 fn correct_large() {
91 let a = Zq::from((i64::MAX, u64::MAX));
92 let b = Zq::from((u64::MAX - i64::MAX as u64, u64::MAX));
93
94 assert_eq!(a, -(-&a));
95 assert_eq!(b, -&a);
96 assert_eq!(b, -a);
97 }
98
99 #[test]
102 fn reduced() {
103 let a = Zq::from((3, 17));
104 let c = Zq::from((0, 17));
105
106 let neg_a = -&a;
107 let neg_c = -c;
108
109 assert_eq!(
110 Z::from(14),
111 neg_a.get_representative_least_nonnegative_residue()
112 );
113 assert_eq!(
114 Z::from(14),
115 (-a).get_representative_least_nonnegative_residue()
116 );
117 assert_eq!(
118 Z::ZERO,
119 neg_c.get_representative_least_nonnegative_residue()
120 );
121 assert_eq!(Z::from(17), neg_a.get_mod());
122 }
123}