#
source:
trunk/third/gmp/mpf/div_2exp.c
@
18191

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

Line | |
---|---|

1 | /* mpf_div_2exp -- Divide a float by 2^n. |

2 | |

3 | Copyright 1993, 1994, 1996, 2000, 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 | mpf_div_2exp (mpf_ptr r, mpf_srcptr u, unsigned long int exp) |

27 | { |

28 | mp_srcptr up; |

29 | mp_ptr rp = r->_mp_d; |

30 | mp_size_t usize; |

31 | mp_size_t abs_usize; |

32 | mp_size_t prec = r->_mp_prec; |

33 | mp_exp_t uexp = u->_mp_exp; |

34 | |

35 | usize = u->_mp_size; |

36 | |

37 | if (usize == 0) |

38 | { |

39 | r->_mp_size = 0; |

40 | r->_mp_exp = 0; |

41 | return; |

42 | } |

43 | |

44 | abs_usize = ABS (usize); |

45 | up = u->_mp_d; |

46 | |

47 | if (exp % GMP_NUMB_BITS == 0) |

48 | { |

49 | prec++; /* retain more precision here as we don't need |

50 | to account for carry-out here */ |

51 | if (abs_usize > prec) |

52 | { |

53 | up += abs_usize - prec; |

54 | abs_usize = prec; |

55 | } |

56 | if (rp != up) |

57 | MPN_COPY_INCR (rp, up, abs_usize); |

58 | r->_mp_exp = uexp - exp / GMP_NUMB_BITS; |

59 | } |

60 | else |

61 | { |

62 | mp_limb_t cy_limb; |

63 | mp_size_t adj; |

64 | if (abs_usize > prec) |

65 | { |

66 | up += abs_usize - prec; |

67 | abs_usize = prec; |

68 | /* Use mpn_rshift since mpn_lshift operates downwards, and we |

69 | therefore would clobber part of U before using that part, in case |

70 | R is the same variable as U. */ |

71 | cy_limb = mpn_rshift (rp + 1, up, abs_usize, exp % GMP_NUMB_BITS); |

72 | rp[0] = cy_limb; |

73 | adj = rp[abs_usize] != 0; |

74 | } |

75 | else |

76 | { |

77 | cy_limb = mpn_lshift (rp, up, abs_usize, |

78 | GMP_NUMB_BITS - exp % GMP_NUMB_BITS); |

79 | rp[abs_usize] = cy_limb; |

80 | adj = cy_limb != 0; |

81 | } |

82 | |

83 | abs_usize += adj; |

84 | r->_mp_exp = uexp - exp / GMP_NUMB_BITS - 1 + adj; |

85 | } |

86 | r->_mp_size = usize >= 0 ? abs_usize : -abs_usize; |

87 | } |

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