Skip to main content

qfall_math/rational/q/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 [`Q`] values.
10
11use super::super::Q;
12use flint3_sys::fmpq_neg;
13use std::ops::Neg;
14
15impl Neg for Q {
16    type Output = Q;
17
18    /// Implements the [`Neg`] trait for [`Q`] values.
19    /// [`Neg`] is implements for both borrowed and owned [`Q`].
20    ///
21    /// When called on owned [`Q`] it will reuse the memory of `self`.
22    ///
23    /// Returns the additive inverse of `self` as a [`Q`].
24    ///
25    /// # Examples
26    /// ```
27    /// use qfall_math::rational::Q;
28    ///
29    /// let a: Q = Q::from((1, 42));
30    ///
31    /// let b: Q = -&a;
32    /// let c: Q = -a;
33    /// ```
34    fn neg(mut self) -> Self::Output {
35        unsafe { fmpq_neg(&mut self.value, &self.value) };
36        self
37    }
38}
39
40impl Neg for &Q {
41    type Output = Q;
42
43    /// Documentation at [`Q::neg`].
44    fn neg(self) -> Self::Output {
45        let mut out = Q::default();
46        unsafe { fmpq_neg(&mut out.value, &self.value) };
47        out
48    }
49}
50
51#[cfg(test)]
52mod test_neg {
53    use super::Q;
54
55    /// Ensure that `neg` works for small numbers.
56    #[test]
57    fn correct_small() {
58        let a: Q = Q::ONE;
59        let b: Q = Q::MINUS_ONE;
60        let c: Q = Q::ZERO;
61
62        let d: Q = Q::from((1, 42));
63
64        assert_eq!(a, -(-&a));
65        assert_eq!(a, -&b);
66        assert_eq!(b, -&a);
67        assert_eq!(a, -b.clone());
68        assert_eq!(b, -a);
69        assert_eq!(c, -&c);
70        assert_eq!(c.clone(), -c);
71        assert_eq!(d, -(-&d));
72        assert_eq!(d.clone(), -(-d));
73    }
74
75    /// Ensure that `neg` works for large numbers.
76    #[test]
77    fn correct_large() {
78        let a: Q = Q::from(u64::MAX);
79        let b: Q = Q::from(i64::MAX);
80
81        assert_eq!(a, -(-&a));
82        assert_eq!(b, -(-&b));
83    }
84}