Coverage Report

Created: 2024-11-21 06:47

/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
7.47k
#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
17.5k
{
52
17.5k
  mp_srcptr up, vp;
53
17.5k
  mp_ptr wp;
54
17.5k
  mp_size_t usize, vsize, wsize;
55
17.5k
  mp_size_t abs_usize;
56
17.5k
  mp_size_t abs_vsize;
57
58
17.5k
  usize = SIZ(u);
59
17.5k
  vsize = VARIATION SIZ(v);
60
17.5k
  abs_usize = ABS (usize);
61
17.5k
  abs_vsize = ABS (vsize);
62
63
17.5k
  if (abs_usize < abs_vsize)
64
7.97k
    {
65
      /* Swap U and V. */
66
7.97k
      MPZ_SRCPTR_SWAP (u, v);
67
7.97k
      MP_SIZE_T_SWAP (usize, vsize);
68
7.97k
      MP_SIZE_T_SWAP (abs_usize, abs_vsize);
69
7.97k
    }
70
71
  /* True: ABS_USIZE >= ABS_VSIZE.  */
72
73
  /* If not space for w (and possible carry), increase space.  */
74
17.5k
  wsize = abs_usize + 1;
75
17.5k
  wp = MPZ_REALLOC (w, wsize);
76
77
  /* These must be after realloc (u or v may be the same as w).  */
78
17.5k
  up = PTR(u);
79
17.5k
  vp = PTR(v);
80
81
17.5k
  if ((usize ^ vsize) < 0)
82
9.97k
    {
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
9.97k
      if (abs_usize != abs_vsize)
88
7.07k
  {
89
7.07k
    mpn_sub (wp, up, abs_usize, vp, abs_vsize);
90
7.07k
    wsize = abs_usize;
91
7.07k
    MPN_NORMALIZE_NOT_ZERO (wp, wsize);
92
7.07k
    if (usize < 0)
93
3.39k
      wsize = -wsize;
94
7.07k
  }
95
2.89k
      else
96
2.89k
  {
97
2.89k
    int cmp = mpn_cmp (up, vp, abs_usize);
98
2.89k
    if (cmp < 0)
99
2.21k
      {
100
2.21k
        mpn_sub_n (wp, vp, up, abs_usize);
101
2.21k
        wsize = abs_usize;
102
2.21k
        MPN_NORMALIZE_NOT_ZERO (wp, wsize);
103
2.21k
        if (usize >= 0)
104
601
    wsize = -wsize;
105
2.21k
      }
106
678
    else if (cmp > 0)
107
644
      {
108
644
        mpn_sub_n (wp, up, vp, abs_usize);
109
644
        wsize = abs_usize;
110
644
        MPN_NORMALIZE_NOT_ZERO (wp, wsize);
111
644
        if (usize < 0)
112
51
    wsize = -wsize;
113
644
      }
114
34
    else
115
34
      wsize = 0;
116
2.89k
  }
117
9.97k
    }
118
7.53k
  else
119
7.53k
    {
120
      /* U and V have same sign.  Add them.  */
121
7.53k
      mp_limb_t cy_limb = mpn_add (wp, up, abs_usize, vp, abs_vsize);
122
7.53k
      wp[abs_usize] = cy_limb;
123
7.53k
      wsize = abs_usize + cy_limb;
124
7.53k
      if (usize < 0)
125
501
  wsize = -wsize;
126
7.53k
    }
127
128
17.5k
  SIZ(w) = wsize;
129
17.5k
}
__gmpz_sub
Line
Count
Source
51
7.47k
{
52
7.47k
  mp_srcptr up, vp;
53
7.47k
  mp_ptr wp;
54
7.47k
  mp_size_t usize, vsize, wsize;
55
7.47k
  mp_size_t abs_usize;
56
7.47k
  mp_size_t abs_vsize;
57
58
7.47k
  usize = SIZ(u);
59
7.47k
  vsize = VARIATION SIZ(v);
60
7.47k
  abs_usize = ABS (usize);
61
7.47k
  abs_vsize = ABS (vsize);
62
63
7.47k
  if (abs_usize < abs_vsize)
64
3.50k
    {
65
      /* Swap U and V. */
66
3.50k
      MPZ_SRCPTR_SWAP (u, v);
67
3.50k
      MP_SIZE_T_SWAP (usize, vsize);
68
3.50k
      MP_SIZE_T_SWAP (abs_usize, abs_vsize);
69
3.50k
    }
70
71
  /* True: ABS_USIZE >= ABS_VSIZE.  */
72
73
  /* If not space for w (and possible carry), increase space.  */
74
7.47k
  wsize = abs_usize + 1;
75
7.47k
  wp = MPZ_REALLOC (w, wsize);
76
77
  /* These must be after realloc (u or v may be the same as w).  */
78
7.47k
  up = PTR(u);
79
7.47k
  vp = PTR(v);
80
81
7.47k
  if ((usize ^ vsize) < 0)
82
6.72k
    {
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
6.72k
      if (abs_usize != abs_vsize)
88
5.52k
  {
89
5.52k
    mpn_sub (wp, up, abs_usize, vp, abs_vsize);
90
5.52k
    wsize = abs_usize;
91
5.52k
    MPN_NORMALIZE_NOT_ZERO (wp, wsize);
92
5.52k
    if (usize < 0)
93
3.22k
      wsize = -wsize;
94
5.52k
  }
95
1.20k
      else
96
1.20k
  {
97
1.20k
    int cmp = mpn_cmp (up, vp, abs_usize);
98
1.20k
    if (cmp < 0)
99
602
      {
100
602
        mpn_sub_n (wp, vp, up, abs_usize);
101
602
        wsize = abs_usize;
102
602
        MPN_NORMALIZE_NOT_ZERO (wp, wsize);
103
602
        if (usize >= 0)
104
591
    wsize = -wsize;
105
602
      }
106
604
    else if (cmp > 0)
107
575
      {
108
575
        mpn_sub_n (wp, up, vp, abs_usize);
109
575
        wsize = abs_usize;
110
575
        MPN_NORMALIZE_NOT_ZERO (wp, wsize);
111
575
        if (usize < 0)
112
5
    wsize = -wsize;
113
575
      }
114
29
    else
115
29
      wsize = 0;
116
1.20k
  }
117
6.72k
    }
118
741
  else
119
741
    {
120
      /* U and V have same sign.  Add them.  */
121
741
      mp_limb_t cy_limb = mpn_add (wp, up, abs_usize, vp, abs_vsize);
122
741
      wp[abs_usize] = cy_limb;
123
741
      wsize = abs_usize + cy_limb;
124
741
      if (usize < 0)
125
473
  wsize = -wsize;
126
741
    }
127
128
7.47k
  SIZ(w) = wsize;
129
7.47k
}
__gmpz_add
Line
Count
Source
51
10.0k
{
52
10.0k
  mp_srcptr up, vp;
53
10.0k
  mp_ptr wp;
54
10.0k
  mp_size_t usize, vsize, wsize;
55
10.0k
  mp_size_t abs_usize;
56
10.0k
  mp_size_t abs_vsize;
57
58
10.0k
  usize = SIZ(u);
59
10.0k
  vsize = VARIATION SIZ(v);
60
10.0k
  abs_usize = ABS (usize);
61
10.0k
  abs_vsize = ABS (vsize);
62
63
10.0k
  if (abs_usize < abs_vsize)
64
4.47k
    {
65
      /* Swap U and V. */
66
4.47k
      MPZ_SRCPTR_SWAP (u, v);
67
4.47k
      MP_SIZE_T_SWAP (usize, vsize);
68
4.47k
      MP_SIZE_T_SWAP (abs_usize, abs_vsize);
69
4.47k
    }
70
71
  /* True: ABS_USIZE >= ABS_VSIZE.  */
72
73
  /* If not space for w (and possible carry), increase space.  */
74
10.0k
  wsize = abs_usize + 1;
75
10.0k
  wp = MPZ_REALLOC (w, wsize);
76
77
  /* These must be after realloc (u or v may be the same as w).  */
78
10.0k
  up = PTR(u);
79
10.0k
  vp = PTR(v);
80
81
10.0k
  if ((usize ^ vsize) < 0)
82
3.24k
    {
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
3.24k
      if (abs_usize != abs_vsize)
88
1.55k
  {
89
1.55k
    mpn_sub (wp, up, abs_usize, vp, abs_vsize);
90
1.55k
    wsize = abs_usize;
91
1.55k
    MPN_NORMALIZE_NOT_ZERO (wp, wsize);
92
1.55k
    if (usize < 0)
93
170
      wsize = -wsize;
94
1.55k
  }
95
1.68k
      else
96
1.68k
  {
97
1.68k
    int cmp = mpn_cmp (up, vp, abs_usize);
98
1.68k
    if (cmp < 0)
99
1.61k
      {
100
1.61k
        mpn_sub_n (wp, vp, up, abs_usize);
101
1.61k
        wsize = abs_usize;
102
1.61k
        MPN_NORMALIZE_NOT_ZERO (wp, wsize);
103
1.61k
        if (usize >= 0)
104
10
    wsize = -wsize;
105
1.61k
      }
106
74
    else if (cmp > 0)
107
69
      {
108
69
        mpn_sub_n (wp, up, vp, abs_usize);
109
69
        wsize = abs_usize;
110
69
        MPN_NORMALIZE_NOT_ZERO (wp, wsize);
111
69
        if (usize < 0)
112
46
    wsize = -wsize;
113
69
      }
114
5
    else
115
5
      wsize = 0;
116
1.68k
  }
117
3.24k
    }
118
6.79k
  else
119
6.79k
    {
120
      /* U and V have same sign.  Add them.  */
121
6.79k
      mp_limb_t cy_limb = mpn_add (wp, up, abs_usize, vp, abs_vsize);
122
6.79k
      wp[abs_usize] = cy_limb;
123
6.79k
      wsize = abs_usize + cy_limb;
124
6.79k
      if (usize < 0)
125
28
  wsize = -wsize;
126
6.79k
    }
127
128
10.0k
  SIZ(w) = wsize;
129
10.0k
}