Coverage Report

Created: 2024-11-21 07:03

/src/libgmp/mpz/aors.h
Line
Count
Source
1
/* mpz_add, mpz_sub -- add or subtract integers.
2
3
Copyright 1991, 1993, 1994, 1996, 2000, 2001, 2011, 2012, 2020 Free
4
Software Foundation, Inc.
5
6
This file is part of the GNU MP Library.
7
8
The GNU MP Library is free software; you can redistribute it and/or modify
9
it under the terms of either:
10
11
  * the GNU Lesser General Public License as published by the Free
12
    Software Foundation; either version 3 of the License, or (at your
13
    option) any later version.
14
15
or
16
17
  * the GNU General Public License as published by the Free Software
18
    Foundation; either version 2 of the License, or (at your option) any
19
    later version.
20
21
or both in parallel, as here.
22
23
The GNU MP Library is distributed in the hope that it will be useful, but
24
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
25
or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
26
for more details.
27
28
You should have received copies of the GNU General Public License and the
29
GNU Lesser General Public License along with the GNU MP Library.  If not,
30
see https://www.gnu.org/licenses/.  */
31
32
#include "gmp-impl.h"
33
34
35
#ifdef OPERATION_add
36
#define FUNCTION     mpz_add
37
#define VARIATION
38
#endif
39
#ifdef OPERATION_sub
40
#define FUNCTION     mpz_sub
41
707k
#define VARIATION    -
42
#endif
43
44
#ifndef FUNCTION
45
Error, need OPERATION_add or OPERATION_sub
46
#endif
47
48
49
void
50
FUNCTION (mpz_ptr w, mpz_srcptr u, mpz_srcptr v)
51
709k
{
52
709k
  mp_srcptr up, vp;
53
709k
  mp_ptr wp;
54
709k
  mp_size_t usize, vsize, wsize;
55
709k
  mp_size_t abs_usize;
56
709k
  mp_size_t abs_vsize;
57
58
709k
  usize = SIZ(u);
59
709k
  vsize = VARIATION SIZ(v);
60
709k
  abs_usize = ABS (usize);
61
709k
  abs_vsize = ABS (vsize);
62
63
709k
  if (abs_usize < abs_vsize)
64
47.7k
    {
65
      /* Swap U and V. */
66
47.7k
      MPZ_SRCPTR_SWAP (u, v);
67
47.7k
      MP_SIZE_T_SWAP (usize, vsize);
68
47.7k
      MP_SIZE_T_SWAP (abs_usize, abs_vsize);
69
47.7k
    }
70
71
  /* True: ABS_USIZE >= ABS_VSIZE.  */
72
73
  /* If not space for w (and possible carry), increase space.  */
74
709k
  wsize = abs_usize + 1;
75
709k
  wp = MPZ_REALLOC (w, wsize);
76
77
  /* These must be after realloc (u or v may be the same as w).  */
78
709k
  up = PTR(u);
79
709k
  vp = PTR(v);
80
81
709k
  if ((usize ^ vsize) < 0)
82
533k
    {
83
      /* U and V have different sign.  Need to compare them to determine
84
   which operand to subtract from which.  */
85
86
      /* This test is right since ABS_USIZE >= ABS_VSIZE.  */
87
533k
      if (abs_usize != abs_vsize)
88
64.2k
  {
89
64.2k
    mpn_sub (wp, up, abs_usize, vp, abs_vsize);
90
64.2k
    wsize = abs_usize;
91
64.2k
    MPN_NORMALIZE_NOT_ZERO (wp, wsize);
92
64.2k
    if (usize < 0)
93
35.2k
      wsize = -wsize;
94
64.2k
  }
95
468k
      else
96
468k
  {
97
468k
    int cmp = mpn_cmp (up, vp, abs_usize);
98
468k
    if (cmp < 0)
99
268k
      {
100
268k
        mpn_sub_n (wp, vp, up, abs_usize);
101
268k
        wsize = abs_usize;
102
268k
        MPN_NORMALIZE_NOT_ZERO (wp, wsize);
103
268k
        if (usize >= 0)
104
193k
    wsize = -wsize;
105
268k
      }
106
200k
    else if (cmp > 0)
107
199k
      {
108
199k
        mpn_sub_n (wp, up, vp, abs_usize);
109
199k
        wsize = abs_usize;
110
199k
        MPN_NORMALIZE_NOT_ZERO (wp, wsize);
111
199k
        if (usize < 0)
112
61.3k
    wsize = -wsize;
113
199k
      }
114
1.12k
    else
115
1.12k
      wsize = 0;
116
468k
  }
117
533k
    }
118
176k
  else
119
176k
    {
120
      /* U and V have same sign.  Add them.  */
121
176k
      mp_limb_t cy_limb = mpn_add (wp, up, abs_usize, vp, abs_vsize);
122
176k
      wp[abs_usize] = cy_limb;
123
176k
      wsize = abs_usize + cy_limb;
124
176k
      if (usize < 0)
125
94.0k
  wsize = -wsize;
126
176k
    }
127
128
709k
  SIZ(w) = wsize;
129
709k
}
__gmpz_add
Line
Count
Source
51
1.47k
{
52
1.47k
  mp_srcptr up, vp;
53
1.47k
  mp_ptr wp;
54
1.47k
  mp_size_t usize, vsize, wsize;
55
1.47k
  mp_size_t abs_usize;
56
1.47k
  mp_size_t abs_vsize;
57
58
1.47k
  usize = SIZ(u);
59
1.47k
  vsize = VARIATION SIZ(v);
60
1.47k
  abs_usize = ABS (usize);
61
1.47k
  abs_vsize = ABS (vsize);
62
63
1.47k
  if (abs_usize < abs_vsize)
64
282
    {
65
      /* Swap U and V. */
66
282
      MPZ_SRCPTR_SWAP (u, v);
67
282
      MP_SIZE_T_SWAP (usize, vsize);
68
282
      MP_SIZE_T_SWAP (abs_usize, abs_vsize);
69
282
    }
70
71
  /* True: ABS_USIZE >= ABS_VSIZE.  */
72
73
  /* If not space for w (and possible carry), increase space.  */
74
1.47k
  wsize = abs_usize + 1;
75
1.47k
  wp = MPZ_REALLOC (w, wsize);
76
77
  /* These must be after realloc (u or v may be the same as w).  */
78
1.47k
  up = PTR(u);
79
1.47k
  vp = PTR(v);
80
81
1.47k
  if ((usize ^ vsize) < 0)
82
1.00k
    {
83
      /* U and V have different sign.  Need to compare them to determine
84
   which operand to subtract from which.  */
85
86
      /* This test is right since ABS_USIZE >= ABS_VSIZE.  */
87
1.00k
      if (abs_usize != abs_vsize)
88
172
  {
89
172
    mpn_sub (wp, up, abs_usize, vp, abs_vsize);
90
172
    wsize = abs_usize;
91
172
    MPN_NORMALIZE_NOT_ZERO (wp, wsize);
92
172
    if (usize < 0)
93
56
      wsize = -wsize;
94
172
  }
95
832
      else
96
832
  {
97
832
    int cmp = mpn_cmp (up, vp, abs_usize);
98
832
    if (cmp < 0)
99
776
      {
100
776
        mpn_sub_n (wp, vp, up, abs_usize);
101
776
        wsize = abs_usize;
102
776
        MPN_NORMALIZE_NOT_ZERO (wp, wsize);
103
776
        if (usize >= 0)
104
121
    wsize = -wsize;
105
776
      }
106
56
    else if (cmp > 0)
107
26
      {
108
26
        mpn_sub_n (wp, up, vp, abs_usize);
109
26
        wsize = abs_usize;
110
26
        MPN_NORMALIZE_NOT_ZERO (wp, wsize);
111
26
        if (usize < 0)
112
18
    wsize = -wsize;
113
26
      }
114
30
    else
115
30
      wsize = 0;
116
832
  }
117
1.00k
    }
118
469
  else
119
469
    {
120
      /* U and V have same sign.  Add them.  */
121
469
      mp_limb_t cy_limb = mpn_add (wp, up, abs_usize, vp, abs_vsize);
122
469
      wp[abs_usize] = cy_limb;
123
469
      wsize = abs_usize + cy_limb;
124
469
      if (usize < 0)
125
168
  wsize = -wsize;
126
469
    }
127
128
1.47k
  SIZ(w) = wsize;
129
1.47k
}
__gmpz_sub
Line
Count
Source
51
707k
{
52
707k
  mp_srcptr up, vp;
53
707k
  mp_ptr wp;
54
707k
  mp_size_t usize, vsize, wsize;
55
707k
  mp_size_t abs_usize;
56
707k
  mp_size_t abs_vsize;
57
58
707k
  usize = SIZ(u);
59
707k
  vsize = VARIATION SIZ(v);
60
707k
  abs_usize = ABS (usize);
61
707k
  abs_vsize = ABS (vsize);
62
63
707k
  if (abs_usize < abs_vsize)
64
47.4k
    {
65
      /* Swap U and V. */
66
47.4k
      MPZ_SRCPTR_SWAP (u, v);
67
47.4k
      MP_SIZE_T_SWAP (usize, vsize);
68
47.4k
      MP_SIZE_T_SWAP (abs_usize, abs_vsize);
69
47.4k
    }
70
71
  /* True: ABS_USIZE >= ABS_VSIZE.  */
72
73
  /* If not space for w (and possible carry), increase space.  */
74
707k
  wsize = abs_usize + 1;
75
707k
  wp = MPZ_REALLOC (w, wsize);
76
77
  /* These must be after realloc (u or v may be the same as w).  */
78
707k
  up = PTR(u);
79
707k
  vp = PTR(v);
80
81
707k
  if ((usize ^ vsize) < 0)
82
532k
    {
83
      /* U and V have different sign.  Need to compare them to determine
84
   which operand to subtract from which.  */
85
86
      /* This test is right since ABS_USIZE >= ABS_VSIZE.  */
87
532k
      if (abs_usize != abs_vsize)
88
64.1k
  {
89
64.1k
    mpn_sub (wp, up, abs_usize, vp, abs_vsize);
90
64.1k
    wsize = abs_usize;
91
64.1k
    MPN_NORMALIZE_NOT_ZERO (wp, wsize);
92
64.1k
    if (usize < 0)
93
35.2k
      wsize = -wsize;
94
64.1k
  }
95
467k
      else
96
467k
  {
97
467k
    int cmp = mpn_cmp (up, vp, abs_usize);
98
467k
    if (cmp < 0)
99
267k
      {
100
267k
        mpn_sub_n (wp, vp, up, abs_usize);
101
267k
        wsize = abs_usize;
102
267k
        MPN_NORMALIZE_NOT_ZERO (wp, wsize);
103
267k
        if (usize >= 0)
104
193k
    wsize = -wsize;
105
267k
      }
106
200k
    else if (cmp > 0)
107
199k
      {
108
199k
        mpn_sub_n (wp, up, vp, abs_usize);
109
199k
        wsize = abs_usize;
110
199k
        MPN_NORMALIZE_NOT_ZERO (wp, wsize);
111
199k
        if (usize < 0)
112
61.3k
    wsize = -wsize;
113
199k
      }
114
1.09k
    else
115
1.09k
      wsize = 0;
116
467k
  }
117
532k
    }
118
175k
  else
119
175k
    {
120
      /* U and V have same sign.  Add them.  */
121
175k
      mp_limb_t cy_limb = mpn_add (wp, up, abs_usize, vp, abs_vsize);
122
175k
      wp[abs_usize] = cy_limb;
123
175k
      wsize = abs_usize + cy_limb;
124
175k
      if (usize < 0)
125
93.8k
  wsize = -wsize;
126
175k
    }
127
128
707k
  SIZ(w) = wsize;
129
707k
}