1 /*
2 Copyright (C) 2009 William Hart
3
4 This file is part of FLINT.
5
6 FLINT is free software: you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License (LGPL) as published
8 by the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version. See <http://www.gnu.org/licenses/>.
10 */
11
12 #include <gmp.h>
13 #include "flint.h"
14 #include "ulong_extras.h"
15 #include "fmpz.h"
16
17 void
fmpz_sub(fmpz_t f,const fmpz_t g,const fmpz_t h)18 fmpz_sub(fmpz_t f, const fmpz_t g, const fmpz_t h)
19 {
20 fmpz c1 = *g;
21 fmpz c2 = *h;
22
23 if (!COEFF_IS_MPZ(c1)) /* g is small */
24 {
25 if (!COEFF_IS_MPZ(c2)) /* both inputs are small */
26 {
27 fmpz_set_si(f, c1 - c2);
28 }
29 else /* g is small, h is large */
30 {
31 __mpz_struct *mpz3 = _fmpz_promote(f); /* g is saved and h is large */
32 __mpz_struct *mpz2 = COEFF_TO_PTR(c2);
33 if (c1 < WORD(0))
34 {
35 flint_mpz_add_ui(mpz3, mpz2, -c1);
36 mpz_neg(mpz3, mpz3);
37 }
38 else
39 flint_mpz_ui_sub(mpz3, c1, mpz2);
40 _fmpz_demote_val(f); /* may have cancelled */
41 }
42 }
43 else
44 {
45 if (!COEFF_IS_MPZ(c2)) /* g is large, h is small */
46 {
47 __mpz_struct *mpz3 = _fmpz_promote(f); /* h is saved and g is large */
48 __mpz_struct *mpz1 = COEFF_TO_PTR(c1);
49 if (c2 < WORD(0))
50 flint_mpz_add_ui(mpz3, mpz1, -c2);
51 else
52 flint_mpz_sub_ui(mpz3, mpz1, c2);
53 _fmpz_demote_val(f); /* may have cancelled */
54 }
55 else /* g and h are large */
56 {
57 __mpz_struct *mpz3 = _fmpz_promote(f); /* aliasing means f is already large */
58 __mpz_struct *mpz1 = COEFF_TO_PTR(c1);
59 __mpz_struct *mpz2 = COEFF_TO_PTR(c2);
60 mpz_sub(mpz3, mpz1, mpz2);
61 _fmpz_demote_val(f); /* may have cancelled */
62 }
63 }
64 }
65