#
source:
trunk/third/gmp/mpz/tdiv_r_2exp.c
@
15294

Revision 15294, 2.2 KB checked in by ghudson, 24 years ago (diff) |
---|

Line | |
---|---|

1 | /* mpz_tdiv_r_2exp -- Divide a integer by 2**CNT and produce a remainder. |

2 | |

3 | Copyright (C) 1991, 1993, 1994, 1995 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 | #if __STDC__ |

27 | mpz_tdiv_r_2exp (mpz_ptr res, mpz_srcptr in, unsigned long int cnt) |

28 | #else |

29 | mpz_tdiv_r_2exp (res, in, cnt) |

30 | mpz_ptr res; |

31 | mpz_srcptr in; |

32 | unsigned long int cnt; |

33 | #endif |

34 | { |

35 | mp_size_t in_size = ABS (in->_mp_size); |

36 | mp_size_t res_size; |

37 | mp_size_t limb_cnt = cnt / BITS_PER_MP_LIMB; |

38 | mp_srcptr in_ptr = in->_mp_d; |

39 | |

40 | if (in_size > limb_cnt) |

41 | { |

42 | /* The input operand is (probably) greater than 2**CNT. */ |

43 | mp_limb_t x; |

44 | |

45 | x = in_ptr[limb_cnt] & (((mp_limb_t) 1 << cnt % BITS_PER_MP_LIMB) - 1); |

46 | if (x != 0) |

47 | { |

48 | res_size = limb_cnt + 1; |

49 | if (res->_mp_alloc < res_size) |

50 | _mpz_realloc (res, res_size); |

51 | |

52 | res->_mp_d[limb_cnt] = x; |

53 | } |

54 | else |

55 | { |

56 | res_size = limb_cnt; |

57 | MPN_NORMALIZE (in_ptr, res_size); |

58 | |

59 | if (res->_mp_alloc < res_size) |

60 | _mpz_realloc (res, res_size); |

61 | |

62 | limb_cnt = res_size; |

63 | } |

64 | } |

65 | else |

66 | { |

67 | /* The input operand is smaller than 2**CNT. We perform a no-op, |

68 | apart from that we might need to copy IN to RES. */ |

69 | res_size = in_size; |

70 | if (res->_mp_alloc < res_size) |

71 | _mpz_realloc (res, res_size); |

72 | |

73 | limb_cnt = res_size; |

74 | } |

75 | |

76 | if (res != in) |

77 | MPN_COPY (res->_mp_d, in->_mp_d, limb_cnt); |

78 | res->_mp_size = in->_mp_size >= 0 ? res_size : -res_size; |

79 | } |

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