qfall_math/integer/z/arithmetic/neg.rs
1// Copyright 2026 Joshua Limbrey
2//
3// This file is part of qFALL-math
4//
5// qFALL-math is free software: you can redistribute it and/or modify it under
6// the terms of the Mozilla Public License Version 2.0 as published by the
7// Mozilla Foundation. See <https://mozilla.org/en-US/MPL/2.0/>.
8
9//! Implementation of the [`Neg`] trait for [`Z`] values.
10
11use super::super::Z;
12use flint3_sys::fmpz_neg;
13use std::ops::Neg;
14
15impl Neg for Z {
16 type Output = Z;
17
18 /// Implements the [`Neg`] trait for [`Z`] values.
19 /// [`Neg`] is implemented for both borrowed and owned [`Z`].
20 ///
21 /// When called on owned [`Z`] it will reuse the memory of `self`.
22 ///
23 /// Returns the additive inverse of `self` as a [`Z`].
24 ///
25 /// # Examples
26 /// ```
27 /// use qfall_math::integer::Z;
28 ///
29 /// let a: Z = Z::from(42);
30 ///
31 /// let b: Z = -&a;
32 /// let c: Z = -a;
33 /// ```
34 fn neg(mut self) -> Self::Output {
35 unsafe { fmpz_neg(&mut self.value, &self.value) };
36 self
37 }
38}
39
40impl Neg for &Z {
41 type Output = Z;
42
43 /// Documentation at [`Z::neg`].
44 fn neg(self) -> Self::Output {
45 let mut out = Z::default();
46 unsafe { fmpz_neg(&mut out.value, &self.value) };
47 out
48 }
49}
50
51#[cfg(test)]
52mod test_neg {
53 use super::Z;
54
55 /// Ensure that `neg` works for small numbers.
56 #[test]
57 fn correct_small() {
58 let a: Z = Z::ONE;
59 let b: Z = Z::MINUS_ONE;
60 let c: Z = Z::ZERO;
61
62 assert_eq!(a, -(-&a));
63 assert_eq!(a, -&b);
64 assert_eq!(b, -&a);
65 assert_eq!(a, -b.clone());
66 assert_eq!(b, -a);
67 assert_eq!(c, -&c);
68 assert_eq!(c.clone(), -c);
69 }
70
71 /// Ensure that `neg` works for large numbers.
72 #[test]
73 fn correct_large() {
74 let a: Z = Z::from(u64::MAX);
75 let b: Z = Z::from(i64::MAX);
76
77 assert_eq!(a, -(-&a));
78 assert_eq!(b, -(-&b));
79 }
80}