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, unsigned long int 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);