xref: /dflybsd-src/contrib/gmp/mpf/get_si.c (revision d365564473a20a528d07c59cad8ee2f4bea5546f)
14b6a78b7SSimon Schubert /* mpf_get_si -- mpf to long conversion
24b6a78b7SSimon Schubert 
34b6a78b7SSimon Schubert Copyright 2001, 2002, 2004 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 /* Any fraction bits are truncated, meaning simply discarded.
254b6a78b7SSimon Schubert 
264b6a78b7SSimon Schubert    For values bigger than a long, the low bits are returned, like
274b6a78b7SSimon Schubert    mpz_get_si, but this isn't documented.
284b6a78b7SSimon Schubert 
294b6a78b7SSimon Schubert    Notice this is equivalent to mpz_set_f + mpz_get_si.
304b6a78b7SSimon Schubert 
314b6a78b7SSimon Schubert 
324b6a78b7SSimon Schubert    Implementation:
334b6a78b7SSimon Schubert 
344b6a78b7SSimon Schubert    fl is established in basically the same way as for mpf_get_ui, see that
354b6a78b7SSimon Schubert    code for explanations of the conditions.
364b6a78b7SSimon Schubert 
374b6a78b7SSimon Schubert    However unlike mpf_get_ui we need an explicit return 0 for exp<=0.  When
384b6a78b7SSimon Schubert    f is a negative fraction (ie. size<0 and exp<=0) we can't let fl==0 go
394b6a78b7SSimon Schubert    through to the zany final "~ ((fl - 1) & LONG_MAX)", that would give
404b6a78b7SSimon Schubert    -0x80000000 instead of the desired 0.  */
414b6a78b7SSimon Schubert 
424b6a78b7SSimon Schubert long
mpf_get_si(mpf_srcptr f)43*d2d4b659SJohn Marino mpf_get_si (mpf_srcptr f) __GMP_NOTHROW
444b6a78b7SSimon Schubert {
454b6a78b7SSimon Schubert   mp_exp_t exp;
464b6a78b7SSimon Schubert   mp_size_t size, abs_size;
474b6a78b7SSimon Schubert   mp_srcptr fp;
484b6a78b7SSimon Schubert   mp_limb_t fl;
494b6a78b7SSimon Schubert 
504b6a78b7SSimon Schubert   exp = EXP (f);
514b6a78b7SSimon Schubert   size = SIZ (f);
524b6a78b7SSimon Schubert   fp = PTR (f);
534b6a78b7SSimon Schubert 
544b6a78b7SSimon Schubert   /* fraction alone truncates to zero
554b6a78b7SSimon Schubert      this also covers zero, since we have exp==0 for zero */
564b6a78b7SSimon Schubert   if (exp <= 0)
574b6a78b7SSimon Schubert     return 0L;
584b6a78b7SSimon Schubert 
594b6a78b7SSimon Schubert   /* there are some limbs above the radix point */
604b6a78b7SSimon Schubert 
614b6a78b7SSimon Schubert   fl = 0;
624b6a78b7SSimon Schubert   abs_size = ABS (size);
634b6a78b7SSimon Schubert   if (abs_size >= exp)
644b6a78b7SSimon Schubert     fl = fp[abs_size-exp];
654b6a78b7SSimon Schubert 
664b6a78b7SSimon Schubert #if BITS_PER_ULONG > GMP_NUMB_BITS
674b6a78b7SSimon Schubert   if (exp > 1 && abs_size+1 >= exp)
684b6a78b7SSimon Schubert     fl |= fp[abs_size - exp + 1] << GMP_NUMB_BITS;
694b6a78b7SSimon Schubert #endif
704b6a78b7SSimon Schubert 
714b6a78b7SSimon Schubert   if (size > 0)
724b6a78b7SSimon Schubert     return fl & LONG_MAX;
734b6a78b7SSimon Schubert   else
744b6a78b7SSimon Schubert     /* this form necessary to correctly handle -0x80..00 */
75*d2d4b659SJohn Marino     return -1 - (long) ((fl - 1) & LONG_MAX);
764b6a78b7SSimon Schubert }
77