xref: /dflybsd-src/contrib/gmp/mpz/tstbit.c (revision d365564473a20a528d07c59cad8ee2f4bea5546f)
14b6a78b7SSimon Schubert /* mpz_tstbit -- test a specified bit.
24b6a78b7SSimon Schubert 
34b6a78b7SSimon Schubert Copyright 2000, 2002 Free Software Foundation, Inc.
44b6a78b7SSimon Schubert 
54b6a78b7SSimon Schubert This file is part of the GNU MP Library.
64b6a78b7SSimon Schubert 
74b6a78b7SSimon Schubert The GNU MP Library is free software; you can redistribute it and/or modify
84b6a78b7SSimon Schubert it under the terms of the GNU Lesser General Public License as published by
94b6a78b7SSimon Schubert the Free Software Foundation; either version 3 of the License, or (at your
104b6a78b7SSimon Schubert option) any later version.
114b6a78b7SSimon Schubert 
124b6a78b7SSimon Schubert The GNU MP Library is distributed in the hope that it will be useful, but
134b6a78b7SSimon Schubert WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
144b6a78b7SSimon Schubert or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
154b6a78b7SSimon Schubert License for more details.
164b6a78b7SSimon Schubert 
174b6a78b7SSimon Schubert You should have received a copy of the GNU Lesser General Public License
184b6a78b7SSimon Schubert along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
194b6a78b7SSimon Schubert 
204b6a78b7SSimon Schubert #include "gmp.h"
214b6a78b7SSimon Schubert #include "gmp-impl.h"
224b6a78b7SSimon Schubert 
234b6a78b7SSimon Schubert 
244b6a78b7SSimon Schubert /* For negatives the effective twos complement is achieved by negating the
254b6a78b7SSimon Schubert    limb tested, either with a ones or twos complement.  Twos complement
264b6a78b7SSimon Schubert    ("-") is used if there's only zero limbs below the one being tested.
274b6a78b7SSimon Schubert    Ones complement ("~") is used if there's a non-zero below.  Note that "-"
284b6a78b7SSimon Schubert    is correct even if the limb examined is 0 (and the true beginning of twos
294b6a78b7SSimon Schubert    complement is further up).
304b6a78b7SSimon Schubert 
314b6a78b7SSimon Schubert    Testing the limbs below p is unavoidable on negatives, but will usually
324b6a78b7SSimon Schubert    need to examine only *(p-1).  The search is done from *(p-1) down to
334b6a78b7SSimon Schubert    *u_ptr, since that might give better cache locality, and because a
344b6a78b7SSimon Schubert    non-zero limb is perhaps a touch more likely in the middle of a number
354b6a78b7SSimon Schubert    than at the low end.
364b6a78b7SSimon Schubert 
374b6a78b7SSimon Schubert    Bits past the end of available data simply follow sign of u.  Notice that
384b6a78b7SSimon Schubert    the limb_index >= abs_size test covers u=0 too.  */
394b6a78b7SSimon Schubert 
404b6a78b7SSimon Schubert int
mpz_tstbit(mpz_srcptr u,mp_bitcnt_t bit_index)41*d2d4b659SJohn Marino mpz_tstbit (mpz_srcptr u, mp_bitcnt_t bit_index) __GMP_NOTHROW
424b6a78b7SSimon Schubert {
434b6a78b7SSimon Schubert   mp_srcptr      u_ptr      = PTR(u);
444b6a78b7SSimon Schubert   mp_size_t      size       = SIZ(u);
454b6a78b7SSimon Schubert   unsigned       abs_size   = ABS(size);
4654028e53SJohn Marino   mp_size_t      limb_index = bit_index / GMP_NUMB_BITS;
474b6a78b7SSimon Schubert   mp_srcptr      p          = u_ptr + limb_index;
484b6a78b7SSimon Schubert   mp_limb_t      limb;
494b6a78b7SSimon Schubert 
504b6a78b7SSimon Schubert   if (limb_index >= abs_size)
514b6a78b7SSimon Schubert     return (size < 0);
524b6a78b7SSimon Schubert 
534b6a78b7SSimon Schubert   limb = *p;
544b6a78b7SSimon Schubert   if (size < 0)
554b6a78b7SSimon Schubert     {
564b6a78b7SSimon Schubert       limb = -limb;     /* twos complement */
574b6a78b7SSimon Schubert 
584b6a78b7SSimon Schubert       while (p != u_ptr)
594b6a78b7SSimon Schubert         {
604b6a78b7SSimon Schubert           p--;
614b6a78b7SSimon Schubert           if (*p != 0)
624b6a78b7SSimon Schubert             {
634b6a78b7SSimon Schubert               limb--;   /* make it a ones complement instead */
644b6a78b7SSimon Schubert               break;
654b6a78b7SSimon Schubert             }
664b6a78b7SSimon Schubert         }
674b6a78b7SSimon Schubert     }
684b6a78b7SSimon Schubert 
694b6a78b7SSimon Schubert   return (limb >> (bit_index % GMP_NUMB_BITS)) & 1;
704b6a78b7SSimon Schubert }
71