#
source:
trunk/third/gmp/mpz/clrbit.c
@
18191

Revision 18191, 2.9 KB checked in by ghudson, 22 years ago (diff) |
---|

Line | |
---|---|

1 | /* mpz_clrbit -- clear a specified bit. |

2 | |

3 | Copyright 1991, 1993, 1994, 1995, 2001, 2002 Free Software Foundation, Inc. |

4 | |

5 | This file is part of the GNU MP Library. |

6 | |

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 2.1 of the License, or (at your |

10 | option) any later version. |

11 | |

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. |

16 | |

17 | You should have received a copy of the GNU Lesser General Public License |

18 | along with the GNU MP Library; see the file COPYING.LIB. If not, write to |

19 | the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, |

20 | MA 02111-1307, USA. */ |

21 | |

22 | #include "gmp.h" |

23 | #include "gmp-impl.h" |

24 | |

25 | void |

26 | mpz_clrbit (mpz_ptr d, unsigned long int bit_index) |

27 | { |

28 | mp_size_t dsize = d->_mp_size; |

29 | mp_ptr dp = d->_mp_d; |

30 | mp_size_t limb_index; |

31 | |

32 | limb_index = bit_index / GMP_NUMB_BITS; |

33 | if (dsize >= 0) |

34 | { |

35 | if (limb_index < dsize) |

36 | { |

37 | dp[limb_index] &= ~((mp_limb_t) 1 << (bit_index % GMP_NUMB_BITS)); |

38 | MPN_NORMALIZE (dp, dsize); |

39 | d->_mp_size = dsize; |

40 | } |

41 | else |

42 | ; |

43 | } |

44 | else |

45 | { |

46 | mp_size_t zero_bound; |

47 | |

48 | /* Simulate two's complement arithmetic, i.e. simulate |

49 | 1. Set OP = ~(OP - 1) [with infinitely many leading ones]. |

50 | 2. clear the bit. |

51 | 3. Set OP = ~OP + 1. */ |

52 | |

53 | dsize = -dsize; |

54 | |

55 | /* No upper bound on this loop, we're sure there's a non-zero limb |

56 | sooner ot later. */ |

57 | for (zero_bound = 0; ; zero_bound++) |

58 | if (dp[zero_bound] != 0) |

59 | break; |

60 | |

61 | if (limb_index > zero_bound) |

62 | { |

63 | if (limb_index < dsize) |

64 | dp[limb_index] |= (mp_limb_t) 1 << (bit_index % GMP_NUMB_BITS); |

65 | else |

66 | { |

67 | /* Ugh. The bit should be cleared outside of the end of the |

68 | number. We have to increase the size of the number. */ |

69 | if (d->_mp_alloc < limb_index + 1) |

70 | { |

71 | _mpz_realloc (d, limb_index + 1); |

72 | dp = d->_mp_d; |

73 | } |

74 | MPN_ZERO (dp + dsize, limb_index - dsize); |

75 | dp[limb_index] = (mp_limb_t) 1 << (bit_index % GMP_NUMB_BITS); |

76 | d->_mp_size = -(limb_index + 1); |

77 | } |

78 | } |

79 | else if (limb_index == zero_bound) |

80 | { |

81 | dp[limb_index] = ((((dp[limb_index] - 1) |

82 | | ((mp_limb_t) 1 << (bit_index % GMP_NUMB_BITS))) + 1) |

83 | & GMP_NUMB_MASK); |

84 | if (dp[limb_index] == 0) |

85 | { |

86 | mp_size_t i; |

87 | for (i = limb_index + 1; i < dsize; i++) |

88 | { |

89 | dp[i] = (dp[i] + 1) & GMP_NUMB_MASK; |

90 | if (dp[i] != 0) |

91 | goto fin; |

92 | } |

93 | /* We got carry all way out beyond the end of D. Increase |

94 | its size (and allocation if necessary). */ |

95 | dsize++; |

96 | if (d->_mp_alloc < dsize) |

97 | { |

98 | _mpz_realloc (d, dsize); |

99 | dp = d->_mp_d; |

100 | } |

101 | dp[i] = 1; |

102 | d->_mp_size = -dsize; |

103 | fin:; |

104 | } |

105 | } |

106 | else |

107 | ; |

108 | } |

109 | } |

**Note:**See TracBrowser for help on using the repository browser.