1 /* mpz_setbit -- set a specified bit.
3 Copyright 1991, 1993, 1994, 1995, 1997, 1999, 2001, 2002 Free Software
6 This file is part of the GNU MP Library.
8 The GNU MP Library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
13 The GNU MP Library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
25 mpz_setbit (mpz_ptr d
, mp_bitcnt_t bit_index
)
27 mp_size_t dsize
= d
->_mp_size
;
31 limb_index
= bit_index
/ GMP_NUMB_BITS
;
34 if (limb_index
< dsize
)
36 dp
[limb_index
] |= (mp_limb_t
) 1 << (bit_index
% GMP_NUMB_BITS
);
41 /* Ugh. The bit should be set outside of the end of the
42 number. We have to increase the size of the number. */
43 if (UNLIKELY (d
->_mp_alloc
< limb_index
+ 1))
44 dp
= _mpz_realloc (d
, limb_index
+ 1);
45 MPN_ZERO (dp
+ dsize
, limb_index
- dsize
);
46 dp
[limb_index
] = (mp_limb_t
) 1 << (bit_index
% GMP_NUMB_BITS
);
47 d
->_mp_size
= limb_index
+ 1;
54 /* Simulate two's complement arithmetic, i.e. simulate
55 1. Set OP = ~(OP - 1) [with infinitely many leading ones].
57 3. Set OP = ~OP + 1. */
61 /* No upper bound on this loop, we're sure there's a non-zero limb
63 for (zero_bound
= 0; ; zero_bound
++)
64 if (dp
[zero_bound
] != 0)
67 if (limb_index
> zero_bound
)
69 if (limb_index
< dsize
)
72 dlimb
= dp
[limb_index
];
73 dlimb
&= ~((mp_limb_t
) 1 << (bit_index
% GMP_NUMB_BITS
));
74 dp
[limb_index
] = dlimb
;
76 if (UNLIKELY (dlimb
== 0 && limb_index
== dsize
-1))
78 /* high limb became zero, must normalize */
81 } while (dsize
> 0 && dp
[dsize
-1] == 0);
86 else if (limb_index
== zero_bound
)
88 dp
[limb_index
] = ((dp
[limb_index
] - 1)
89 & ~((mp_limb_t
) 1 << (bit_index
% GMP_NUMB_BITS
))) + 1;
90 if (dp
[limb_index
] == 0)
93 for (i
= limb_index
+ 1; i
< dsize
; i
++)
99 /* We got carry all way out beyond the end of D. Increase
100 its size (and allocation if necessary). */
102 if (UNLIKELY (d
->_mp_alloc
< dsize
))
103 dp
= _mpz_realloc (d
, dsize
);
105 d
->_mp_size
= -dsize
;
111 mpn_decr_u (dp
+ limb_index
,
112 (mp_limb_t
) 1 << (bit_index
% GMP_NUMB_BITS
));
113 dsize
-= dp
[dsize
- 1] == 0;
114 d
->_mp_size
= -dsize
;