1 /* mpz_combit -- complement a specified bit.
3 Copyright 2002, 2003 Free Software Foundation, Inc.
5 This file is part of the GNU MP Library.
7 The GNU MP Library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
12 The GNU MP Library is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
24 mpz_combit (mpz_ptr d
, mp_bitcnt_t bit_index
)
26 mp_size_t dsize
= ABSIZ(d
);
29 mp_size_t limb_index
= bit_index
/ GMP_NUMB_BITS
;
30 mp_limb_t bit
= ((mp_limb_t
) 1 << (bit_index
% GMP_NUMB_BITS
));
32 if (limb_index
>= dsize
)
34 MPZ_REALLOC(d
, limb_index
+ 1);
37 MPN_ZERO(dp
+ dsize
, limb_index
+ 1 - dsize
);
38 dsize
= limb_index
+ 1;
43 dp
[limb_index
] ^= bit
;
44 MPN_NORMALIZE (dp
, dsize
);
49 mp_limb_t x
= -dp
[limb_index
];
52 /* non-zero limb below us means ones-complement */
53 for (i
= limb_index
-1; i
>= 0; i
--)
56 x
--; /* change twos comp to ones comp */
64 /* Clearing the bit increases the magitude. We might need a carry. */
65 MPZ_REALLOC(d
, dsize
+ 1);
68 __GMPN_ADD_1 (c
, dp
+limb_index
, dp
+limb_index
,
69 dsize
- limb_index
, bit
);
74 /* Setting the bit decreases the magnitude */
75 mpn_sub_1(dp
+limb_index
, dp
+limb_index
, dsize
+ limb_index
, bit
);
77 MPN_NORMALIZE (dp
, dsize
);