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

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

Line | |
---|---|

1 | /* mpz_com(mpz_ptr dst, mpz_ptr src) -- Assign the bit-complemented value of |

2 | SRC to DST. |

3 | |

4 | Copyright 1991, 1993, 1994, 1996, 2001 Free 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 the GNU Lesser General Public License as published by |

10 | the Free Software Foundation; either version 2.1 of the License, or (at your |

11 | option) any later version. |

12 | |

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

17 | |

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

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

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

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

22 | |

23 | #include "gmp.h" |

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

25 | |

26 | void |

27 | mpz_com (mpz_ptr dst, mpz_srcptr src) |

28 | { |

29 | mp_size_t size = src->_mp_size; |

30 | mp_srcptr src_ptr; |

31 | mp_ptr dst_ptr; |

32 | |

33 | if (size >= 0) |

34 | { |

35 | /* As with infinite precision: one's complement, two's complement. |

36 | But this can be simplified using the identity -x = ~x + 1. |

37 | So we're going to compute (~~x) + 1 = x + 1! */ |

38 | |

39 | if (dst->_mp_alloc < size + 1) |

40 | _mpz_realloc (dst, size + 1); |

41 | |

42 | src_ptr = src->_mp_d; |

43 | dst_ptr = dst->_mp_d; |

44 | |

45 | if (size == 0) |

46 | { |

47 | /* Special case, as mpn_add wants the first arg's size >= the |

48 | second arg's size. */ |

49 | dst_ptr[0] = 1; |

50 | dst->_mp_size = -1; |

51 | return; |

52 | } |

53 | |

54 | { |

55 | mp_limb_t cy; |

56 | |

57 | cy = mpn_add_1 (dst_ptr, src_ptr, size, (mp_limb_t) 1); |

58 | if (cy) |

59 | { |

60 | dst_ptr[size] = cy; |

61 | size++; |

62 | } |

63 | } |

64 | |

65 | /* Store a negative size, to indicate ones-extension. */ |

66 | dst->_mp_size = -size; |

67 | } |

68 | else |

69 | { |

70 | /* As with infinite precision: two's complement, then one's complement. |

71 | But that can be simplified using the identity -x = ~(x - 1). |

72 | So we're going to compute ~~(x - 1) = x - 1! */ |

73 | size = -size; |

74 | |

75 | if (dst->_mp_alloc < size) |

76 | _mpz_realloc (dst, size); |

77 | |

78 | src_ptr = src->_mp_d; |

79 | dst_ptr = dst->_mp_d; |

80 | |

81 | mpn_sub_1 (dst_ptr, src_ptr, size, (mp_limb_t) 1); |

82 | size -= dst_ptr[size - 1] == 0; |

83 | |

84 | /* Store a positive size, to indicate zero-extension. */ |

85 | dst->_mp_size = size; |

86 | } |

87 | } |

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