1 | /* mpz_fdiv_ui -- Division rounding the quotient towards -infinity. |
---|

2 | The remainder gets the same sign as the denominator. |
---|

3 | |
---|

4 | Copyright 1994, 1995, 1996, 2001, 2002 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 | unsigned long int |
---|

27 | mpz_fdiv_ui (mpz_srcptr dividend, unsigned long int divisor) |
---|

28 | { |
---|

29 | mp_size_t ns, nn; |
---|

30 | mp_ptr np; |
---|

31 | mp_limb_t rl; |
---|

32 | |
---|

33 | if (divisor == 0) |
---|

34 | DIVIDE_BY_ZERO; |
---|

35 | |
---|

36 | ns = SIZ(dividend); |
---|

37 | if (ns == 0) |
---|

38 | { |
---|

39 | return 0; |
---|

40 | } |
---|

41 | |
---|

42 | nn = ABS(ns); |
---|

43 | np = PTR(dividend); |
---|

44 | #if GMP_NAIL_BITS != 0 |
---|

45 | if (divisor > GMP_NUMB_MAX) |
---|

46 | { |
---|

47 | mp_limb_t dp[2], rp[2]; |
---|

48 | mp_ptr qp; |
---|

49 | mp_size_t rn; |
---|

50 | TMP_DECL (mark); |
---|

51 | |
---|

52 | if (nn == 1) /* tdiv_qr requirements; tested above for 0 */ |
---|

53 | { |
---|

54 | rl = np[0]; |
---|

55 | rp[0] = rl; |
---|

56 | } |
---|

57 | else |
---|

58 | { |
---|

59 | TMP_MARK (mark); |
---|

60 | dp[0] = divisor & GMP_NUMB_MASK; |
---|

61 | dp[1] = divisor >> GMP_NUMB_BITS; |
---|

62 | qp = TMP_ALLOC_LIMBS (nn - 2 + 1); |
---|

63 | mpn_tdiv_qr (qp, rp, (mp_size_t) 0, np, nn, dp, (mp_size_t) 2); |
---|

64 | TMP_FREE (mark); |
---|

65 | rl = rp[0] + (rp[1] << GMP_NUMB_BITS); |
---|

66 | } |
---|

67 | |
---|

68 | if (rl != 0 && ns < 0) |
---|

69 | { |
---|

70 | rl = divisor - rl; |
---|

71 | rp[0] = rl & GMP_NUMB_MASK; |
---|

72 | rp[1] = rl >> GMP_NUMB_BITS; |
---|

73 | } |
---|

74 | |
---|

75 | rn = 1 + (rl > GMP_NUMB_MAX); rn -= (rp[rn - 1] == 0); |
---|

76 | } |
---|

77 | else |
---|

78 | #endif |
---|

79 | { |
---|

80 | rl = mpn_mod_1 (np, nn, (mp_limb_t) divisor); |
---|

81 | if (rl == 0) |
---|

82 | ; |
---|

83 | else |
---|

84 | { |
---|

85 | if (ns < 0) |
---|

86 | rl = divisor - rl; |
---|

87 | } |
---|

88 | } |
---|

89 | |
---|

90 | return rl; |
---|

91 | } |
---|