Back to index

glibc  2.9
rshift.c
Go to the documentation of this file.
00001 /* mpn_rshift -- Shift right a low-level natural-number integer.
00002 
00003 Copyright (C) 1991, 1993, 1994, 1996 Free Software Foundation, Inc.
00004 
00005 This file is part of the GNU MP Library.
00006 
00007 The GNU MP Library is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU Lesser General Public License as published by
00009 the Free Software Foundation; either version 2.1 of the License, or (at your
00010 option) any later version.
00011 
00012 The GNU MP Library is distributed in the hope that it will be useful, but
00013 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00014 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00015 License for more details.
00016 
00017 You should have received a copy of the GNU Lesser General Public License
00018 along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
00019 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00020 MA 02111-1307, USA. */
00021 
00022 #include <gmp.h>
00023 #include "gmp-impl.h"
00024 
00025 /* Shift U (pointed to by UP and USIZE limbs long) CNT bits to the right
00026    and store the USIZE least significant limbs of the result at WP.
00027    The bits shifted out to the right are returned.
00028 
00029    Argument constraints:
00030    1. 0 < CNT < BITS_PER_MP_LIMB
00031    2. If the result is to be written over the input, WP must be <= UP.
00032 */
00033 
00034 mp_limb_t
00035 #if __STDC__
00036 mpn_rshift (register mp_ptr wp,
00037            register mp_srcptr up, mp_size_t usize,
00038            register unsigned int cnt)
00039 #else
00040 mpn_rshift (wp, up, usize, cnt)
00041      register mp_ptr wp;
00042      register mp_srcptr up;
00043      mp_size_t usize;
00044      register unsigned int cnt;
00045 #endif
00046 {
00047   register mp_limb_t high_limb, low_limb;
00048   register unsigned sh_1, sh_2;
00049   register mp_size_t i;
00050   mp_limb_t retval;
00051 
00052 #ifdef DEBUG
00053   if (usize == 0 || cnt == 0)
00054     abort ();
00055 #endif
00056 
00057   sh_1 = cnt;
00058 
00059 #if 0
00060   if (sh_1 == 0)
00061     {
00062       if (wp != up)
00063        {
00064          /* Copy from low end to high end, to allow specified input/output
00065             overlapping.  */
00066          for (i = 0; i < usize; i++)
00067            wp[i] = up[i];
00068        }
00069       return usize;
00070     }
00071 #endif
00072 
00073   wp -= 1;
00074   sh_2 = BITS_PER_MP_LIMB - sh_1;
00075   high_limb = up[0];
00076   retval = high_limb << sh_2;
00077   low_limb = high_limb;
00078 
00079   for (i = 1; i < usize; i++)
00080     {
00081       high_limb = up[i];
00082       wp[i] = (low_limb >> sh_1) | (high_limb << sh_2);
00083       low_limb = high_limb;
00084     }
00085   wp[i] = low_limb >> sh_1;
00086 
00087   return retval;
00088 }