root/src/bignum.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. mpz_to_intmax
  2. ARG_NONNULL
  3. ARG_NONNULL
  4. bignum_val
  5. xbignum_val
  6. bignum_integer
  7. mpz_set_integer

     1 /* Big numbers for Emacs.
     2 
     3 Copyright 2018-2023 Free Software Foundation, Inc.
     4 
     5 This file is part of GNU Emacs.
     6 
     7 GNU Emacs is free software: you can redistribute it and/or modify
     8 it under the terms of the GNU General Public License as published by
     9 the Free Software Foundation, either version 3 of the License, or (at
    10 your option) any later version.
    11 
    12 GNU Emacs is distributed in the hope that it will be useful,
    13 but WITHOUT ANY WARRANTY; without even the implied warranty of
    14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    15 GNU General Public License for more details.
    16 
    17 You should have received a copy of the GNU General Public License
    18 along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
    19 
    20 /* Include this header only if access to bignum internals is needed.  */
    21 
    22 #ifndef BIGNUM_H
    23 #define BIGNUM_H
    24 
    25 #include <gmp.h>
    26 #include "lisp.h"
    27 
    28 /* Number of data bits in a limb.  */
    29 #ifndef GMP_NUMB_BITS
    30 enum { GMP_NUMB_BITS = TYPE_WIDTH (mp_limb_t) };
    31 #endif
    32 
    33 struct Lisp_Bignum
    34 {
    35   union vectorlike_header header;
    36   mpz_t value;
    37 } GCALIGNED_STRUCT;
    38 
    39 extern mpz_t mpz[5];
    40 
    41 extern void init_bignum (void);
    42 extern Lisp_Object make_integer_mpz (void);
    43 extern bool mpz_to_intmax (mpz_t const, intmax_t *) ARG_NONNULL ((1, 2));
    44 extern bool mpz_to_uintmax (mpz_t const, uintmax_t *) ARG_NONNULL ((1, 2));
    45 extern void mpz_set_intmax_slow (mpz_t, intmax_t) ARG_NONNULL ((1));
    46 extern void mpz_set_uintmax_slow (mpz_t, uintmax_t) ARG_NONNULL ((1));
    47 extern void emacs_mpz_mul (mpz_t, mpz_t const, mpz_t const)
    48   ARG_NONNULL ((1, 2, 3));
    49 extern void emacs_mpz_mul_2exp (mpz_t, mpz_t const, EMACS_INT)
    50   ARG_NONNULL ((1, 2));
    51 extern void emacs_mpz_pow_ui (mpz_t, mpz_t const, unsigned long)
    52   ARG_NONNULL ((1, 2));
    53 extern double mpz_get_d_rounded (mpz_t const) ATTRIBUTE_CONST;
    54 extern Lisp_Object get_random_bignum (struct Lisp_Bignum const *);
    55 
    56 INLINE_HEADER_BEGIN
    57 
    58 INLINE struct Lisp_Bignum *
    59 XBIGNUM (Lisp_Object a)
    60 {
    61   eassert (BIGNUMP (a));
    62   return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Bignum);
    63 }
    64 
    65 INLINE void ARG_NONNULL ((1))
    66 mpz_set_intmax (mpz_t result, intmax_t v)
    67 {
    68   /* mpz_set_si works in terms of long, but Emacs may use a wider
    69      integer type, and so sometimes will have to construct the mpz_t
    70      by hand.  */
    71   if (LONG_MIN <= v && v <= LONG_MAX)
    72     mpz_set_si (result, v);
    73   else
    74     mpz_set_intmax_slow (result, v);
    75 }
    76 INLINE void ARG_NONNULL ((1))
    77 mpz_set_uintmax (mpz_t result, uintmax_t v)
    78 {
    79   if (v <= ULONG_MAX)
    80     mpz_set_ui (result, v);
    81   else
    82     mpz_set_uintmax_slow (result, v);
    83 }
    84 
    85 /* Return a pointer to the mpz_t value represented by the bignum I.
    86    It is const because the value should not change.  */
    87 INLINE mpz_t const *
    88 bignum_val (struct Lisp_Bignum const *i)
    89 {
    90   return &i->value;
    91 }
    92 INLINE mpz_t const *
    93 xbignum_val (Lisp_Object i)
    94 {
    95   return bignum_val (XBIGNUM (i));
    96 }
    97 
    98 /* Return a pointer to an mpz_t that is equal to the Lisp integer I.
    99    If I is a bignum this returns a pointer to I's representation;
   100    otherwise this sets *TMP to I's value and returns TMP.  */
   101 INLINE mpz_t const *
   102 bignum_integer (mpz_t *tmp, Lisp_Object i)
   103 {
   104   if (FIXNUMP (i))
   105     {
   106       mpz_set_intmax (*tmp, XFIXNUM (i));
   107       /* The unnecessary cast pacifies a buggy GCC 4.8.5.  */
   108       return (mpz_t const *) tmp;
   109     }
   110   return xbignum_val (i);
   111 }
   112 
   113 /* Set RESULT to the value stored in the Lisp integer I.  If I is a
   114    big integer, copy it to RESULT.  RESULT must already be
   115    initialized.  */
   116 INLINE void
   117 mpz_set_integer (mpz_t result, Lisp_Object i)
   118 {
   119   if (FIXNUMP (i))
   120     mpz_set_intmax (result, XFIXNUM (i));
   121   else
   122     mpz_set (result, *xbignum_val (i));
   123 }
   124 
   125 INLINE_HEADER_END
   126 
   127 #endif /* BIGNUM_H */

/* [<][>][^][v][top][bottom][index][help] */