Anonymous avatar Anonymous committed a291207

Support bignums with MPIR. Add documentation on the bignum, ratio,
and bigfloat implementations. See xemacs-patches message with ID
<CAHCOHQkytZao7Uk9ggeo1HKKJtN1bqO054X2mPsGYyQFjbHrZA@mail.gmail.com>;
and following messages.

Comments (0)

Files changed (15)

+2013-06-17  Jerry James  <james@xemacs.org>
+
+	* configure.ac: Support bignums with MPIR.
+
 2013-06-17  Jerry James  <james@xemacs.org>
 
 	* configure.ac: Add check for mp_set_memory_functions.
                           loaded libraries (Dynamic Shared Objects).
   --with-bignum=TYPE      Compile in support for bignums, ratios, or bigfloats
                           using library support. TYPE must be one of "gmp"
-                          (for GNU MP), "mp" (for BSD MP), or "no" (disabled).
+                          (for GNU MP), "mpir" (for MPIR), "mp" (for BSD MP),
+                          or "no" (disabled).
 
 Platform Specific options
 -------------------------
   enableval="$with_bignum"
   withval="$with_bignum"
   _bignum_bogus=yes
- for x in no gmp mp ; do
+ for x in no gmp mpir mp ; do
    if test $x = $with_bignum ; then
 	_bignum_bogus=no
    fi
  done
  if test "$_bignum_bogus" = "yes" ; then
 	(echo "$progname: Usage error:"
-echo " " "The --with-bignum option must have one of these values: \`no',\`gmp',\`mp'."
+echo " " "The --with-bignum option must have one of these values: \`no',\`gmp',\`mpir',\`mp'."
 echo "  Use \`$progname --help' to show usage.") >&2 && exit 1
  fi
 unset _bignum_bogus
   else
     { echo "Error:" "Required GMP numeric support cannot be provided." >&2; exit 1; }
   fi
+elif test "$with_bignum" = "mpir"; then
+  ac_fn_c_check_header_mongrel "$LINENO" "mpir.h" "ac_cv_header_mpir_h" "$ac_includes_default"
+if test "x$ac_cv_header_mpir_h" = xyes; then :
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __gmpz_init in -lmpir" >&5
+$as_echo_n "checking for __gmpz_init in -lmpir... " >&6; }
+if ${ac_cv_lib_mpir___gmpz_init+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lmpir  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char __gmpz_init ();
+int
+main ()
+{
+return __gmpz_init ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_mpir___gmpz_init=yes
+else
+  ac_cv_lib_mpir___gmpz_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mpir___gmpz_init" >&5
+$as_echo "$ac_cv_lib_mpir___gmpz_init" >&6; }
+if test "x$ac_cv_lib_mpir___gmpz_init" = xyes; then :
+  have_mpz_init=yes
+fi
+
+fi
+
+
+  if test "$have_mpz_init" = "yes"; then
+    $as_echo "#define WITH_NUMBER_TYPES 1" >>confdefs.h
+
+    $as_echo "#define WITH_MPIR 1" >>confdefs.h
+
+    LIBS="-lmpir $LIBS" &&  if test "$verbose" = "yes"; then echo "    Prepending \"-lmpir\" to \$LIBS"; fi
+  else
+    { echo "Error:" "Required MPIR numeric support cannot be provided." >&2; exit 1; }
+  fi
 elif test "$with_bignum" = "mp"; then
   for library in "" "-lcrypto"; do
     ac_fn_c_check_header_mongrel "$LINENO" "mp.h" "ac_cv_header_mp_h" "$ac_includes_default"
 test "$with_dnet" = yes && echo "  Compiling in support for DNET."
 test "$with_modules" = "yes" && echo "  Compiling in support for dynamic shared object modules."
 test "$with_bignum" = "gmp" && echo "  Compiling in support for more number types using the GNU MP library."
+test "$with_bignum" = "mpir" && echo "  Compiling in support for more number types using the MPIR library."
 test "$with_bignum" = "mp" && echo "  Compiling in support for more number types using the BSD MP library."
 if test "$with_union_type" = yes ; then
   echo "  Using the union type for Lisp_Objects."
 XE_KEYWORD_ARG([bignum],
 	AS_HELP_STRING([--with-bignum=TYPE],[Compile in support for bignums, ratios, or bigfloats
                         using library support.  TYPE must be one of "gmp"
-                        (for GNU MP), "mp" (for BSD MP), or "no" (disabled).]),
-	[], [with_bignum="no"],[no,gmp,mp])
+                        (for GNU MP), "mpir" (for MPIR), "mp" (for BSD MP),
+                        or "no" (disabled).]),
+	[], [with_bignum="no"],[no,gmp,mpir,mp])
 dnl
 XE_HELP_SUBSECTION([Platform Specific options])
 XE_MERGED_ARG([workshop],
   else
     XE_DIE("Required GMP numeric support cannot be provided.")
   fi
+elif test "$with_bignum" = "mpir"; then
+  AC_CHECK_HEADER(mpir.h, [
+    AC_CHECK_LIB(mpir, __gmpz_init, have_mpz_init=yes)])
+  if test "$have_mpz_init" = "yes"; then
+    AC_DEFINE(WITH_NUMBER_TYPES)
+    AC_DEFINE(WITH_MPIR)
+    XE_PREPEND(-lmpir, LIBS)
+  else
+    XE_DIE("Required MPIR numeric support cannot be provided.")
+  fi
 elif test "$with_bignum" = "mp"; then
   for library in "" "-lcrypto"; do
     AC_CHECK_HEADER(mp.h, [
 test "$with_dnet" = yes && echo "  Compiling in support for DNET."
 test "$with_modules" = "yes" && echo "  Compiling in support for dynamic shared object modules."
 test "$with_bignum" = "gmp" && echo "  Compiling in support for more number types using the GNU MP library."
+test "$with_bignum" = "mpir" && echo "  Compiling in support for more number types using the MPIR library."
 test "$with_bignum" = "mp" && echo "  Compiling in support for more number types using the BSD MP library."
 if test "$with_union_type" = yes ; then
   echo "  Using the union type for Lisp_Objects."
+2013-06-17  Jerry James  <james@xemacs.org>
+
+	* internals/internals.texi (Numeric Types): New chapter describing
+	the implementation of bignums, ratios, and bigfloats.
+	* lispref/numbers.texi (The Bignum Extension): Update description
+	to include MPIR, fix broken URLs, and note that BSD MP support is
+	now more complete.
+	(Bignum Basics): Note MPIR support.
+	(Ratio Basics): Add a missing comma.
+	(Bigfloat Basics): Fix an incomplete sentence and add examples.
+	* xemacs-faq.texi (Q7.2.1): Update description to include MPIR,
+	note that BSD MP support is now more complete, and remove the
+	paragraph where I promise to write internals documentation.
+	(Q7.2.3): Update ancient section that mentions the Pentium III.
+
 2013-01-22  Jerry James  <james@xemacs.org>
 
 	* lispref/glyphs.texi (Image Instantiators): Add :visible to the

man/internals/internals.texi

-        \input texinfo  @c -*-texinfo-*-
+\input texinfo  @c -*-texinfo-*-
 @c %**start of header
 @setfilename ../../info/internals.info
 @settitle XEmacs Internals Manual
 @author Matthias Neubauer
 @author Olivier Galibert
 @author Andy Piper
+@author Jerry James
 
 
 @page
 * CVS Techniques::              
 * XEmacs from the Inside::      
 * Basic Types::                 
+* Numeric Types::               
 * Low-Level Allocation::        
 * The XEmacs Object System (Abstractly Speaking)::  
 * How Lisp Objects Are Represented in C::  
 @item @file{nt.c} @tab
 @item @file{ntheap.c} @tab
 @item @file{ntplay.c} @tab
-@item @file{number-gmp.c} @tab
-@item @file{number-gmp.h} @tab
-@item @file{number-mp.c} @tab
-@item @file{number-mp.h} @tab
-@item @file{number.c} @tab
-@item @file{number.h} @tab
+@item @file{number-gmp.c} @tab @ref{GMP and MPIR driver}
+@item @file{number-gmp.h} @tab @ref{GMP and MPIR driver}
+@item @file{number-mp.c} @tab @ref{BSD MP driver}
+@item @file{number-mp.h} @tab @ref{BSD MP driver}
+@item @file{number-mpir.c} @tab @ref{GMP and MPIR driver}
+@item @file{number-mpir.h} @tab @ref{GMP and MPIR driver}
+@item @file{number.c} @tab @ref{Abstract Numeric Interface}
+@item @file{number.h} @tab @ref{Abstract Numeric Interface}
 @item @file{fontcolor-gtk-impl.h} @tab
 @item @file{fontcolor-gtk.c} @tab
 @item @file{fontcolor-gtk.h} @tab
 of obscure and unwanted interactions occurring than if they were to
 change the C code.
 
-@node Basic Types, Low-Level Allocation, XEmacs from the Inside, Top
+@node Basic Types, Numeric Types, XEmacs from the Inside, Top
 @chapter Basic Types
 @cindex basic types
 @cindex types, basic
 
 Not yet documented.
 
-@node Low-Level Allocation, The XEmacs Object System (Abstractly Speaking), Basic Types, Top
+@node Numeric Types, Low-Level Allocation, Basic Types, Top
+@chapter Numeric Types
+@cindex numeric types
+@cindex types, numeric
+
+@menu
+* Abstract Numeric Interface::  
+* GMP and MPIR driver::         
+* BSD MP driver::               
+* Numeric driver interface::    
+@end menu
+
+@node Abstract Numeric Interface, GMP and MPIR driver, Numeric Types, Numeric Types
+@section Abstract Interface
+@cindex abstract numeric interface
+
+The following types are always defined in the same manner:
+@itemize
+@item fixnum
+Whatever fits in the @code{Lisp_Object} type.
+@item integer
+The union of the @code{fixnum} and @code{bignum} types.
+@item rational
+The union of the @code{integer} and @code{ratio} types.
+@item float
+The equivalent of a C @code{double}.
+@item floating
+The union of the @code{float} and @code{bigfloat} types.
+@item real
+The union of the @code{rational} and @code{floating} types.
+@item number
+The union of the @code{real} and @code{complex} types.  Since there is
+no @code{complex} type, this is currently equivalent to the @code{real}
+type.
+@end itemize
+
+The remaining types (@code{bignum}, @code{ratio}, and @code{bigfloat})
+are defined by library-specific drivers, as detailed in the remaining
+sections of this chapter.  A given driver may define one or more of
+these types to be empty.  In fact, the default configuration makes all
+three types empty, so that @code{integer} and @code{rational} are the
+same types as @code{fixnum}, etc.  The configure script sets zero or
+more of the symbols @code{HAVE_BIGNUM}, @code{HAVE_RATIO}, and
+@code{HAVE_BIGFLOAT} to indicate which types are nonempty.  These are
+the consequences of an empty type:
+@itemize
+@item bignum
+Then @code{bignump(x)} is false for all x.  Any attempt to create a
+bignum causes an error to be raised.
+@item ratio
+Then @code{ratiop(x)} is false for all x.  Any attempt to create a ratio
+causes an error to be raised.
+@item bigfloat
+Then @code{bigfloat(x)} is false for all x.  Any attempt to create a
+bigfloat causes an error to be raised.
+@end itemize
+
+We @code{(provide)} the following symbols, so that Lisp code can
+determine when the various numeric types are available for use:
+@itemize @bullet
+@item
+@code{(provide 'bignum)} if @code{HAVE_BIGNUM} is set
+@item
+@code{(provde 'ratio)} if @code{HAVE_RATIO} is set
+@item
+@code{(provide 'bigfloat)} if @code{HAVE_BIGFLOAT} is set
+@end itemize
+
+C code should use one of the following macros to create a Lisp integer,
+depending on the type of the C integer to be converted.
+@itemize @bullet
+@item
+@code{make_fixnum(x)} if x is guaranteed to fit into a Lisp fixnum.
+@item
+@code{make_integer(x)} if x is a signed C integer of any type.
+@item
+@code{make_unsigned_integer(x)} if x is an unsigned C integer of any type.
+@end itemize
+
+The @code{make_integer(x)} and @code{make_unsigned_integer(x)} macros
+both create a fixnum if possible, and a bignum otherwise.  The value
+@code{x} can be a C integer of any size up to and including the size
+of a C @code{long long int}.  The @code{make_fixnum(x)} macro is
+intended to signal the programmer's intent that only fixnum-sized
+integers will be used.  In some cases, if the compiler cannot prove
+that the parameter is always in the fixnum range, this macro is also a
+code optimization.
+
+@node GMP and MPIR driver, BSD MP driver, Abstract Numeric Interface, Numeric Types
+@section GMP driver
+@cindex gmp
+@cindex mpir
+
+The GNU Multiple Precision library (@uref{http://gmplib.org/}) and its
+fork, the Multiple Precision Integers and Rationals library
+(@uref{http://www.mpir.org/}), provide large integers, ratios, and
+floating point numbers.  The same driver supports both GMP and MPIR, and
+provides all 3 of the optional types: bignums, ratios, and bigfloats,
+implemented with the types @code{mpz_t}, @code{mpq_t}, and @code{mpf_t},
+respectively.  Most of the abstract numeric interface is defined in
+terms of macros that expand directly into GMP or MPIR API calls, since
+GMP and MPIR provide a rich interface.
+
+@node BSD MP driver, Numeric driver interface, GMP and MPIR driver, Numeric Types
+@section BSD MP driver
+@cindex BSD mp
+
+The BSD MP interface is less rich than its GMP and MPIR counterparts.
+It provides only large integers, implemented as type @code{MINT *};
+ratios and bigfloats are not available.  BSD MP libraries are supplied
+by multiple vendors, with some small variations.  This driver is
+intended to work with any variation.
+
+Some BSD MP libraries use function names that are likely cause name
+collisions, such as @code{gcd}, @code{mult}, and @code{pow}.  Others
+follow the Single Unix Specification recommendation (see
+@uref{http://www.unix.com/man-page/all/3mp/mp_mcmp/}) and prefix all of
+the function names with ``mp_'': @code{mp_gcd}, @code{mp_mult},
+@code{mp_pow}, etc.  The XEmacs configure script detects which of the
+two interfaces is in use, and defines @code{MP_PREFIX} for the latter
+case.  We use macros (@code{MP_MULT}, etc.) to hide this difference.
+
+Another variation is that some, but not all, BSD MP libraries supply a
+function named @code{move} or @code{mp_move} that copies its first
+argument into its second argument.  We define the move operation as
+setting the destination number to the source number plus zero for those
+libraries that do not supply this function.
+
+The BSD MP interface does not directly support many of the operations
+that we need, so the implementations sometimes consist of complex
+functions.  See the implementation of @code{bignum_random}, for
+example.
+
+@node Numeric driver interface,  , BSD MP driver, Numeric Types
+@section Numeric driver interface
+@cindex numeric driver interface
+
+@menu
+* Bignum interface::              
+* Ratio interface::               
+* Bigfloat interface::            
+@end menu
+
+@node Bignum interface, Ratio interface, Numeric driver interface, Numeric driver interface
+@subsection Bignum interface
+@cindex bignum interface
+
+Each bignum implementation defines @code{HAVE_BIGNUM} and an appropriate
+bignum type.  For example, the GMP driver uses this definition:
+
+@example
+typedef mpz_t bignum;
+@end example
+
+The following names are defined for each driver, either as real C
+functions or as C preprocessor macros.
+@itemize
+@item void bignum_init(bignum b)
+Does any necessary initialization before the bignum @code{b} can be
+used.  This function typically allocates memory for the bignum.
+@item void bignum_fini(bignum b)
+Cleans up any resources held by the bignum @code{b}, typically
+deallocating the memory dedicated to that bignum.  The object referred
+to by @code{b} must not be accessed after this call returns.
+@item unsigned int bignum_hashcode(bignum b)
+Returns a hash code for the bignum, suitable for use in XEmacs hash
+tables.
+@item int bignum_sign(bignum b)
+Returns a positive value, zero, or a negative value to indicate that
+@code{b} is positive, zero, or negative, respectively.
+@item int bignum_evenp(bignum b)
+Returns a nonzero value if @code{b} is an even number, zero if it is odd.
+@item int bignum_oddp(bignum b)
+Returns a nonzero value if @code{b} is an odd number, zero if it is even.
+@item int bignum_fits_int_p(bignum b)
+Returns a nonzero value if @code{b} can be represented in a C
+@code{int}, zero otherwise.
+@item int bignum_fits_uint_p(bignum b)
+Returns a nonzero value if @code{b} can be represented in a C
+@code{unsigned int}, zero otherwise.
+@item int bignum_fits_long_p(bignum b)
+Returns a nonzero value if @code{b} can be represented in a C
+@code{long int}, zero otherwise.
+@item int bignum_fits_ulong_p(bignum b)
+Returns a nonzero value if @code{b} can be represented in a C
+@code{unsigned long int}, zero otherwise.
+@item int bignum_fits_llong_p(bignum b)
+Returns a nonzero value if @code{b} can be represented in a C
+@code{long long int}, zero otherwise.
+@item int bignum_fits_ullong_p(bignum b)
+Returns a nonzero value if @code{b} can be represented in a C
+@code{unsigned long long int}, zero otherwise.
+@item void bignum_to_string(bignum b, int base)
+Converts @code{b} into a string representation using the given base,
+which is an integer between 2 and 36, inclusive.
+@item int bignum_to_int(bignum b)
+Converts @code{b} into a C @code{int}.  If @code{b} does not fit into a
+C @code{int}, the results are undefined.
+@item unsigned int bignum_to_uint(bignum b)
+Converts @code{b} into a C @code{unsigned int}.  If @code{b} does not
+fit into a C @code{unsigned int}, the results are undefined.
+@item long bignum_to_long(bignum b)
+Converts @code{b} into a C @code{long int}.  If @code{b} does not fit
+into a C @code{long int}, the results are undefined.
+@item unsigned long bignum_to_ulong(bignum b)
+Converts @code{b} into a C @code{unsigned long int}.  If @code{b} does
+not fit into a C @code{unsigned long int}, the results are undefined.
+@item long long bignum_to_llong(bignum b)
+Converts @code{b} into a C @code{long long int}.  If @code{b} does not
+fit into a C @code{long long int}, the results are undefined.
+@item unsigned long long bignum_to_ullong(bignum b)
+Converts @code{b} into a C @code{unsigned long long int}.  If @code{b}
+does not fit into a C @code{unsigned long long int}, the results are
+undefined.
+@item double bignum_to_double(bignum b)
+Converts @code{b} into a C @code{double}.  If @code{b} is too large to
+represent as a C @code{double}, the results are implementation-specific.
+Typically, the result is positive or negative infinity, for
+implementations that can represent infinity.
+@item void bignum_set(bignum b1, bignum b2)
+Assigns the value of @code{b2} to the bignum @code{b1} by copying.
+@item void bignum_set_string(bignum b, const char *s, int base)
+Assigns @code{b} the value of the integer contained in string @code{s},
+which is a number in base @code{base}.
+@item void bignum_set_long(bignum b, long l)
+Assigns @code{b} the value of the long integer @code{l}.
+@item void bignum_set_ulong(bignum b, unsigned long l)
+Assigns @code{b} the value of the unsigned long integer @code{l}.
+@item void bignum_set_llong(bignum b, long long l)
+Assigns @code{b} the value of the long long integer @code{l}.
+@item void bignum_set_ullong(bignum b, unsigned long long l)
+Assigns @code{b} the value of the unsigned long long integer @code{l}.
+@item void bignum_set_double(bignum b, double d)
+Assigns @code{b} to the truncated value of @code{d}; i.e, the fractional
+part of @code{d} is dropped.
+@item void bignum_set_ratio(bignum b, ratio r)
+Assigns @code{b} to the truncated value of @code{r}; i.e., the
+non-integer part of @code{r} is dropped.  This function exists only if
+the driver supports ratios.
+@item void bignum_set_bigfloat(bignum b, bigfloat f)
+Assigns @code{b} to the truncated value of @code{f}; i.e., the
+fractional part of @code{f} is dropped.  This function exists only if
+the driver supports bigfloats.
+@item int bignum_cmp(bignum b1, bignum b2)
+Returns a positive value, zero, or a negative value as @code{b1} is
+greater than, equal to, or less than @code{b2}, respectively.
+@item int bignum_lt(bignum b1, bignum b2)
+Returns nonzero if @code{b1} is less than @code{b2}, zero otherwise.
+@item int bignum_le(bignum b1, bignum b2)
+Returns nonzero if @code{b1} is less than or equal to @code{b2}, zero
+otherwise.
+@item int bignum_eql(bignum b1, bignum b2)
+Returns nonzero if @code{b1} is equal to @code{b2}, zero otherwise.
+@item int bignum_ge(bignum b1, bignum b2)
+Returns nonzero if @code{b1} is greater than or equal to @code{b2}, zero
+otherwise.
+@item int bignum_gt(bignum b1, bignum b2)
+Returns nonzero if @code{b1} is greater than @code{b2}, zero otherwise.
+@item void bignum_neg(bignum b, bignum b2)
+Sets @code{b} to the negation of @code{b2}.
+@item void bignum_abs(bignum b, bignum b2)
+Sets @code{b} to the absolute value of @code{b2}.
+@item void bignum_add(bignum b, bignum b1, bignum b2)
+Sets @code{b} to the sum of @code{b1} and @code{b2}.
+@item void bignum_sub(bignum b, bignum b1, bignum b2)
+Sets @code{b} to the value of @code{b1} minus @code{b2}.
+@item void bignum_mul(bignum b, bignum b1, bignum b2)
+Sets @code{b} to the product of @code{b1} and @code{b2}.
+@item int bignum_divisible_p(bignum b1, bignum b2)
+Returns nonzero if @code{b1} is evenly divisible by @code{b2}.
+@item void bignum_div(bignum b, bignum b1, bignum b2)
+Sets @code{b} to the truncated value of @code{b1} divided by @code{b2}.
+That is, this function rounds toward zero.
+@item void bignum_ceil(bignum b, bignum b1, bignum b2)
+Sets @code{b} to the ceiling of @code{b1} divided by @code{b2}.  That
+is, ths function rounds toward positive infinity.
+@item void bignum_floor(bignum b, bignum b1, bignum b2)
+Sets @code{b} to the floor of @code{b1} divided by @code{b2}.  That is,
+ths function rounds toward negative infinity.
+@item void bignum_mod(bignum b, bignum b1, bignum b2)
+Sets @code{b} to @code{b1} mod @code{b2}; i.e., the remainder after
+dividing @code{b1} by @code{b2}.  The sign is ignored; @code{b} is
+always nonnegative after this operation.
+@item void bignum_pow(bignum res, bignum b, unsigned int pow)
+Sets @code{res} to @code{b} to the @code{pow}th power.
+@item void bignum_gcd(bignum res, bignum b1, bignum b2)
+Sets @code{res} to the greatest common divisor of @code{b1} and
+@code{b2}.
+@item void bignum_lcm(bignum res, bignum b1, bignum b2)
+Sets @code{res} to the least common multiple of @code{b1} and @code{b2}.
+@item void bignum_and(bignum res, bignum b1, bignum b2)
+Sets @code{res} to the bitwise AND of @code{b1} and @code{b2}.
+@item void bignum_ior(bignum res, bignum b1, bignum b2)
+Sets @code{res} to the bitwise inclusive OR of @code{b1} and @code{b2}.
+@item void bignum_xor(bignum res, bignum b1, bignum b2)
+Sets @code{res} to the bitwise exclusive OR of @code{b1} and @code{b2}.
+@item void bignum_not(bignum res, bignum b)
+Sets @code{res} to the bitwise NOT of @code{b}.
+@item void bignum_setbit(bignum b, unsigned int bit)
+Sets the @code{bit}th bit of @code{b} to one, where the zeroth bit is
+the least significant.
+@item void bignum_clrbit(bignum b, unsigned int bit)
+Clears the @code{bit}th bit of @code{b} (i.e., sets it to zero), where
+the zeroth bit is the least significant.
+@item int bignum_testbit(bignum b, unsigned int bit)
+Returns the @code{bit}th bit of @code{b}, where the zeroth bit is the
+least significant.
+@item void bignum_lshift(bignum res, bignum b, unsigned int bits)
+Sets @code{res} to the value of @code{b} shifted left by @code{bits}
+bits.
+@item void bignum_rshift(bignum res, bignum b, unsigned int bits)
+Sets @code{res} to the value of @code{b} shifted right by @code{bits}
+bits.
+@item void bignum_random_seed(unsigned int seed)
+If the implementing library has its own pseudorandom number generator,
+then this function seeds the generator.  If there is no generator, this
+function is a no-op.
+@item void bignum_random(bignum res, bignum limit)
+Sets @code{res} to a random number between zero (inclusive) and
+@code{limit} (exclusive).
+@end itemize
+
+@node Ratio interface, Bigfloat interface, Bignum interface, Numeric driver interface
+@subsection Ratio interface
+@cindex ratio interface
+
+Each ratio implementation defines @code{HAVE_RATIO} and an appropriate
+ratio type.  For example, the GMP driver uses this definition:
+
+@example
+typedef mpq_t ratio;
+@end example
+
+The following names are defined for each driver, either as real C
+functions or as C preprocessor macros.
+@itemize
+@item void ratio_init(ratio r)
+Does any necessary initialization before the ratio @code{r} can be
+used.  This function typically allocates memory for the ratio.
+@item void ratio_fini(ratio r)
+Cleans up any resources held by the ratio @code{r}, typically
+deallocating the memory dedicated to that ratio.  The object referred
+to by @code{r} must not be accessed after this call returns.
+@item unsigned int ratio_hashcode(ratio r)
+Returns a hash code for the ratio, suitable for use in XEmacs hash
+tables.
+@item int ratio_sign(ratio r)
+Returns a positive value, zero, or a negative value to indicate that
+@code{r} is positive, zero, or negative, respectively.
+@item bignum ratio_numerator(ratio r)
+Returns the numerator of @code{r}.
+@item bignum ratio_denominator(ratio r)
+Returns the denominator of @code{r}.
+@item void ratio_canonicalize(ratio r)
+Removes any common factors from the numerator and denominator of
+@code{r}.
+@item void ratio_to_string(ratio r, int base)
+Converts @code{r} into a string representation using the given base,
+which is an integer between 2 and 36, inclusive.
+@item int ratio_to_int(ratio r)
+Converts @code{r} into a C @code{int} by truncating the ratio.  If the
+truncation of @code{r} does not fit into a C @code{int}, the results are
+undefined.
+@item unsigned int ratio_to_uint(ratio r)
+Converts @code{r} into a C @code{unsigned int} by truncating the ratio.
+If the truncation of @code{r} does not fit into a C @code{unsigned int},
+the results are undefined.
+@item long ratio_to_long(ratio r)
+Converts @code{r} into a C @code{long int} by truncating the ratio.  If
+the truncation of @code{r} does not fit into a C @code{long int}, the
+results are undefined.
+@item unsigned long ratio_to_ulong(ratio r)
+Converts @code{r} into a C @code{unsigned long int} by truncating the
+ratio.  If @code{r} does not fit into a C @code{unsigned long int}, the
+results are undefined.
+@item double ratio_to_double(ratio r)
+Converts @code{r} into a C @code{double}.  If @code{r} is too large to
+represent as a C @code{double}, the results are implementation-specific.
+Typically, the result is positive or negative infinity, for
+implementations that can represent infinity.
+@item void ratio_set(ratio r1, ratio r2)
+Assigns the value of @code{r2} to the ratio @code{r1} by copying.
+@item void ratio_set_string(ratio r, const char *s, int base)
+Assigns @code{r} the value of the ratio contained in string @code{s},
+which is a pair of numbers in base @code{base} separated by a forward
+slash.
+@item void ratio_set_long(ratio r, long l)
+Assigns @code{r} the value of the long integer @code{l}.
+@item void ratio_set_ulong(ratio r, unsigned long l)
+Assigns @code{r} the value of the unsigned long integer @code{l}.
+@item void ratio_set_double(ratio r, double d)
+Assigns @code{r} to the exact value of @code{d}.  There is no rounding.
+@item void ratio_set_bignum(ratio r, bignum b)
+Assigns @code{r} to the value of @code{b}; i.e., the denominator is set
+to one.
+@item void ratio_set_bigfloat(ratio b, bigfloat f)
+Assigns @code{b} to the exact value of @code{f}.  There is no rounding.
+This function exists only if the driver supports bigfloats.
+@item void ratio_set_long_ulong(ratio r, long num, unsigned long den)
+Assigns @code{r} the canonicalized ratio resulting from the division of
+@code{num} by @code{den}.
+@item void ratio_set_ulong_ulong(ratio r, unsigned long num, unsigned long den)
+Assigns @code{r} the canonicalized ratio resulting from the division of
+@code{num} by @code{den}.
+@item void ratio_set_bignum_bignum(ratio r, bignum num, bignum den)
+Assigns @code{r} the canonicalized ratio resulting from the division of
+@code{num} by @code{den}.
+@item int ratio_cmp(ratio r1, ratio r2)
+Returns a positive value, zero, or a negative value as @code{r1} is
+greater than, equal to, or less than @code{r2}, respectively.
+@item int ratio_lt(ratio r1, ratio r2)
+Returns nonzero if @code{r1} is less than @code{r2}, zero otherwise.
+@item int ratio_le(ratio r1, ratio r2)
+Returns nonzero if @code{r1} is less than or equal to @code{r2}, zero
+otherwise.
+@item int ratio_eql(ratio r1, ratio r2)
+Returns nonzero if @code{r1} is equal to @code{r2}, zero otherwise.
+@item int ratio_ge(ratio r1, ratio r2)
+Returns nonzero if @code{r1} is greater than or equal to @code{r2}, zero
+otherwise.
+@item int ratio_gt(ratio r1, ratio r2)
+Returns nonzero if @code{r1} is greater than @code{r2}, zero otherwise.
+@item void ratio_neg(ratio q, ratio q2)
+Sets @code{q} to the negation of @code{q2}.
+@item void ratio_abs(ratio q, ratio q2)
+Sets @code{q} to the absolute value of @code{q2}.
+@item void ratio_inv(ratio q, ratio q2)
+Sets @code{q} to the inverse of @code{q2}.
+@item void ratio_add(ratio res, ratio q1, ratio q2)
+Sets @code{res} to the sum of @code{q1} and @code{q2}.
+@item void ratio_sub(ratio res, ratio q1, ratio q2)
+Sets @code{res} to the value of @code{q1} minus @code{q2}.
+@item void ratio_mul(ratio res, ratio q1, ratio q2)
+Sets @code{res} to the product of @code{q1} and @code{q2}.
+@item void ratio_div(ratio res, ratio q1, ratio q2)
+Sets @code{res} to the value of @code{q1} divided by @code{q2}.
+@end itemize
+
+@node Bigfloat interface,  , Ratio interface, Numeric driver interface
+@subsection Bigfloat interface
+@cindex bigfloat interface
+
+Each bigfloat implementation defines @code{HAVE_BIGFLOAT} and an
+appropriate bigfloat type.  For example, the GMP driver uses this
+definition:
+
+@example
+typedef mpf_t bigfloat;
+@end example
+
+The following names are defined for each driver, either as real C
+functions or as C preprocessor macros.
+@itemize
+@item void bigfloat_init(bigfloat f)
+Does any necessary initialization before the bigfloat @code{f} can be
+used.  This function typically allocates memory for the bigfloat.
+@item void bigfloat_init_prec(bigfloat f, unsigned int prec)
+Like @code{bigfloat_init}, but also sets the precision of @code{f} to
+@emph{at least} @code{prec} bits.
+@item void bigfloat_fini(bigfloat f)
+Cleans up any resources held by the bigfloat @code{f}, typically
+deallocating the memory dedicated to that bigfloat.  The object referred
+to by @code{f} must not be accessed after this call returns.
+@item unsigned int bigfloat_hashcode(bigfloat f)
+Returns a hash code for the bigfloat, suitable for use in XEmacs hash
+tables.
+@item int bigfloat_sign(bigfloat f)
+Returns a positive value, zero, or a negative value to indicate that
+@code{f} is positive, zero, or negative, respectively.
+@item unsigned int bigfloat_get_prec(bigfloat f)
+Returns the precision of @code{f} in bits.
+@item void bigfloat_set_prec(bigfloat f, unsigned int prec)
+Sets the precision of @code{f} to @emph{at least} @code{prec} bits.
+@item void bigfloat_set_default_prec(unsigned int prec)
+Sets the default precision of newly created bigfloats.
+@item unsigned int bigfloat_get_default_prec(void)
+Gets the default precision of newly created bigfloats.
+@item void bigfloat_to_string(bigfloat f, int base)
+Converts @code{f} into a string representation using the given base,
+which is an integer between 2 and 36, inclusive.
+@item int bigfloat_to_int(bigfloat f)
+Converts @code{f} into a C @code{int} by truncating the bigfloat.  If the
+truncation of @code{f} does not fit into a C @code{int}, the results are
+undefined.
+@item unsigned int bigfloat_to_uint(bigfloat f)
+Converts @code{f} into a C @code{unsigned int} by truncating the bigfloat.
+If the truncation of @code{f} does not fit into a C @code{unsigned int},
+the results are undefined.
+@item long bigfloat_to_long(bigfloat f)
+Converts @code{f} into a C @code{long int} by truncating the bigfloat.  If
+the truncation of @code{f} does not fit into a C @code{long int}, the
+results are undefined.
+@item unsigned long bigfloat_to_ulong(bigfloat f)
+Converts @code{f} into a C @code{unsigned long int} by truncating the
+bigfloat.  If @code{f} does not fit into a C @code{unsigned long int}, the
+results are undefined.
+@item double bigfloat_to_double(bigfloat f)
+Converts @code{f} into a C @code{double}.  If @code{f} is too large to
+represent as a C @code{double}, the results are implementation-specific.
+Typically, the result is positive or negative infinity, for
+implementations that can represent infinity.
+@item void bigfloat_set(bigfloat f1, bigfloat f2)
+Assigns the value of @code{f2} to the bigfloat @code{f1} by copying.
+@item void bigfloat_set_string(bigfloat f, const char *s, int base)
+Assigns @code{f} the value of the bigfloat contained in string @code{s}.
+@item void bigfloat_set_long(bigfloat f, long l)
+Assigns @code{f} the value of the long integer @code{l}.
+@item void bigfloat_set_ulong(bigfloat f, unsigned long l)
+Assigns @code{f} the value of the unsigned long integer @code{l}.
+@item void bigfloat_set_double(bigfloat f, double d)
+Assigns @code{f} the value of @code{d}.
+@item void bigfloat_set_bignum(bigfloat f, bignum b)
+Assigns @code{f} to the value of @code{b}.
+@item void bigfloat_set_ratio(bigfloat b, ratio r)
+Assigns @code{b} to the result of dividing the numerator of @code{r} by
+its denominator.
+@item int bigfloat_cmp(bigfloat f1, bigfloat f2)
+Returns a positive value, zero, or a negative value as @code{f1} is
+greater than, equal to, or less than @code{f2}, respectively.
+@item int bigfloat_lt(bigfloat f1, bigfloat f2)
+Returns nonzero if @code{f1} is less than @code{f2}, zero otherwise.
+@item int bigfloat_le(bigfloat f1, bigfloat f2)
+Returns nonzero if @code{f1} is less than or equal to @code{f2}, zero
+otherwise.
+@item int bigfloat_eql(bigfloat f1, bigfloat f2)
+Returns nonzero if @code{f1} is equal to @code{f2}, zero otherwise.
+@item int bigfloat_ge(bigfloat f1, bigfloat f2)
+Returns nonzero if @code{f1} is greater than or equal to @code{f2}, zero
+otherwise.
+@item int bigfloat_gt(bigfloat f1, bigfloat f2)
+Returns nonzero if @code{f1} is greater than @code{f2}, zero otherwise.
+@item void bigfloat_neg(bigfloat f, bigfloat f2)
+Sets @code{f} to the negation of @code{f2}.
+@item void bigfloat_abs(bigfloat f, bigfloat f2)
+Sets @code{f} to the absolute value of @code{f2}.
+@item void bigfloat_add(bigfloat res, bigfloat f1, bigfloat f2)
+Sets @code{res} to the sum of @code{f1} and @code{f2}.
+@item void bigfloat_sub(bigfloat res, bigfloat f1, bigfloat f2)
+Sets @code{res} to the value of @code{f1} minus @code{f2}.
+@item void bigfloat_mul(bigfloat res, bigfloat f1, bigfloat f2)
+Sets @code{res} to the product of @code{f1} and @code{f2}.
+@item void bigfloat_div(bigfloat res, bigfloat f1, bigfloat f2)
+Sets @code{res} to the value of @code{f1} divided by @code{f2}.
+@item void bigfloat_ceil(bigfloat res, bigfloat f)
+Sets @code{res} to the ceiling of @code{f}.
+@item void bigfloat_floor(bigfloat res, bigfloat f)
+Sets @code{res} to the floor of @code{f}.
+@item void bigfloat_trunc(bigfloat res, bigfloat f)
+Sets @code{res} to the truncation of @code{f}.
+@item void bigfloat_sqrt(bigfloat res, bigfloat f)
+Sets @code{res} to the square root of @code{f}.
+@item void bigfloat_pow(bigfloat res, bigfloat f, unsigned int exp)
+Sets @code{res} to the value of @code{f} raised to the @code{exp}th power.
+@end itemize
+
+@node Low-Level Allocation, The XEmacs Object System (Abstractly Speaking), Numeric Types, Top
 @chapter Low-Level Allocation
 @cindex low-level allocation
 @cindex allocation, low-level
 
 
 @node Ben's separate stderr notes,  , Subprocesses, Subprocesses
-@subsection Ben's separate stderr notes (probably obsolete)
+@section Ben's separate stderr notes (probably obsolete)
 
 This node contains some notes that Ben kept on his separate subprocess
 workspace.  These notes probably describe changes and features that have

man/lispref/numbers.texi

 numbers is limited only by the amount of virtual memory (and time) you
 can throw at them.
 
-  As of 09 April 2004, support for the GNU Multiple Precision
-arithmetic library (GMP) is nearly complete, and support for the BSD
-Multiple Precision arithmetic library (MP) is being debugged.  To enable
-bignum support using GMP (respectively MP), invoke configure with your
-usual options, and add @samp{--use-number-lib=gmp} (respectively
-@samp{--use-number-lib=mp}).  The default is to disable bignum support,
-but if you are using a script to automate the build process, it may be
-convenient to explicitly disable support by @emph{appending}
-@samp{--use-number-lib=no} to your invocation of configure.  GMP has an
-MP compatibility mode, but it is not recommended, as there remain poorly
-understood bugs (even more so than for other vendors' versions of MP).
+  XEmacs supports the GNU Multiple Precision arithmetic library (GMP),
+the Multiple Precision Integers and Rationals library (MPIR), and the
+BSD Multiple Precision arithmetic library (MP).  To enable bignum
+support using GMP, MPIR, or MP, invoke configure with your usual options
+and add @samp{--use-number-lib=gmp}, @samp{--use-number-lib=mpir}, or
+@samp{--use-number-lib=mp}, respectively.  The default is to disable
+bignum support, but if you are using a script to automate the build
+process, it may be convenient to explicitly disable support by
+@emph{appending} @samp{--use-number-lib=no} to your invocation of
+configure.  GMP has an MP compatibility mode, but it is not recommended,
+as there remain poorly understood bugs (even more so than for other
+vendors' versions of MP).
 
-  With GMP, exact arithmetic with integers and ratios of arbitrary
-precision and approximate (``floating point'') arithmetic of arbitrary
-precision are implemented efficiently in the library.  (Note that
-numerical implementations are quite delicate and sensitive to
+  With GMP and MPIR, exact arithmetic with integers and ratios of
+arbitrary precision and approximate (``floating point'') arithmetic of
+arbitrary precision are implemented efficiently in the library.  (Note
+that numerical implementations are quite delicate and sensitive to
 optimization.  If the library was poorly optimized for your hardware, as
 is often the case with Linux distributions for 80x86, you may achieve
 gains of @emph{several orders of magnitude} by rebuilding the MP
-library.  See @uref{http://www.swox.com/gmp/gmp-speed.html}.)  The MP
-implementation provides arbitrary precision integers.  Ratios and arbitrary
-precision floats are not available with MP.
+library.  See @uref{http://gmplib.org/gmpbench.html}.)  The MP
+implementation provides arbitrary precision integers.  Ratios and
+arbitrary precision floats are not available with MP.
 
   If your code needs to run correctly whether or not the feature is
 provided, you may test for the features @code{bignum}, @code{ratio}, and
 are bigfloat, and bigfloats are only coerced to other numerical types by
 explicit calls to the function @code{coerce}.
 
-  Bignum support is incomplete.  If you would like to help with bignum
-support, especially on BSD MP, please subscribe to the
-@uref{http://www.xemacs.org/Lists/#xemacs-beta, XEmacs Beta mailing
-list}, and book up on @file{number-gmp.h} and @file{number-mp.h}.  Jerry
-has promised to write internals documentation eventually, but if your
-skills run more to analysis and documentation than to writing new code,
-feel free to fill in the gap!
-
 @menu
 * Bignum Basics::             Representation and range of integers.
 * Ratio Basics::              Representation and range of rational numbers.
 
 In most cases, bignum support should be transparent to users and Lisp
 programmers.  A bignum-enabled XEmacs will automatically convert from
-fixnums to bignums and back in pure integer arithmetic, and for GNU MP,
-from floats to bigfloats.  (Bigfloats must be explicitly coerced to
-other types, even if they are exactly representable by less precise
+fixnums to bignums and back in pure integer arithmetic, and for GMP and
+MPIR, from floats to bigfloats.  (Bigfloats must be explicitly coerced
+to other types, even if they are exactly representable by less precise
 types.)  The Lisp reader and printer have been enhanced to handle
 bignums, as have the mathematical functions.  Rationals (fixnums,
 bignums, and ratios) are printed using the @samp{%d}, @samp{%o},
 @node Ratio Basics
 @subsection Ratio Basics
 
-Ratios, when available have the read syntax and print representation
+Ratios, when available, have the read syntax and print representation
 @samp{3/5}.  Like other rationals (fixnums and bignums), they are
 printed using the @samp{%d}, @samp{%o}, @samp{%x}, and @samp{%u} format
 conversions.
 setting @code{default-float-precision} to a non-zero value.  Precision
 is given in bits, with a maximum precision of
 @code{bigfloat-maximum-precision}.
-@c #### is this true?
-Bigfloats are created automatically when a number with yes
 
+@example
+(let* ((float1 (string-to-number "9999999999999999.99999999999999999999"))
+       (default-float-precision 256)
+       (float2 (string-to-number "9999999999999999.99999999999999999999")))
+  (+ (if (bigfloatp float1) 1 0)
+     (if (bigfloatp float2) 2 0)))
+    @result{} 2
+@end example
 
+@example
+(let* ((float1 (float 999999999999999999999999999999999999999999999999999999))
+       (default-float-precision 256)
+       (float2 (float 999999999999999999999999999999999999999999999999999999)))
+  (princ float1)
+  (terpri)
+  (princ float2)
+  (terpri))
+    @result{} 9.999999999999999e+53
+9.99999999999999999999999999999999999999999999999999999E53
+t
+@end example
+
+Explicit type coercion is also available, although then the precision of
+the bigfloat is no greater than the source type.
+
+@example
+(coerce 999999999999999 'bigfloat)
+    @result{} 9.99999999999999E14
+@end example
 
 @node Canonicalization and Contagion
 @subsection Canonicalization and Contagion

man/xemacs-faq.texi

 
 Thanks to @email{james@@xemacs.org, Jerry James}, XEmacs 21.5.18 and
 later can use the capabilities of multiple-precision libraries that may
-be available for your platform.  The GNU Multiple Precision (GMP) and
-BSD Multiple Precision (MP) libraries are partially supported.  GMP
-gives you @dfn{bignums} (arbitrary precision integers), @dfn{ratios}
-(arbitrary precision fractions), and @dfn{bigfloats} (arbitrary
-precision floating point numbers).  GNU MP is better-supported by XEmacs
-at the time of writing (2004-04-06).  BSD MP support does not include
-ratios or bigfloats, and it throws errors that aren't understood.
+be available for your platform.  The GNU Multiple Precision (GMP),
+Multiple Precision Integers and Rationals (MPIR), and BSD Multiple
+Precision (MP) libraries are supported.  GMP and MPIR give you
+@dfn{bignums} (arbitrary precision integers), @dfn{ratios} (arbitrary
+precision fractions), and @dfn{bigfloats} (arbitrary precision floating
+point numbers).  GMP and MPIR are better-supported by XEmacs.  BSD MP
+support does not include ratios or bigfloats.
 
 In most cases, bignum support should be transparent to users and Lisp
 programmers.  A bignum-enabled XEmacs will automatically convert from
-fixnums to bignums and back in pure integer arithmetic, and for GNU MP,
-from floats to bigfloats.  (Bigfloats must be explicitly coerced to
-other types, even if they are exactly representable by less precise
+fixnums to bignums and back in pure integer arithmetic, and for GMP and
+MPIR, from floats to bigfloats.  (Bigfloats must be explicitly coerced
+to other types, even if they are exactly representable by less precise
 types.)  The Lisp reader and printer have been enhanced to handle
 bignums, as have the mathematical functions.  Rationals (fixnums,
 bignums, and ratios) are printed using the @samp{%d}, @samp{%o},
 arbitrarily decide to hand you an unpleasant surprise rather than a
 bignum @ref{Q7.2.2, XEmacs segfaults when I use very big numbers!}.
 
-To configure with GNU MP, add @samp{--use-number-lib=gmp}
-(@samp{--enable-bignum=gmp} in 21.5 or later) to your invocation of
-@file{configure}.  For BSD MP, use @samp{--use-number-lib=mp}
-(@samp{--enable-bignum=mp} for 21.5).
-
-If you would like to help with bignum support, especially on BSD MP,
-please subscribe to the @uref{http://www.xemacs.org/Lists/#xemacs-beta,
-XEmacs Beta mailing list}, and book up on @file{number-gmp.h} and
-@file{number-mp.h}.  Jerry has promised to write internals documentation
-eventually, but if your skills run more to analysis and documentation
-than to writing new code, feel free to fill in the gap!
+To configure with GMP, add @samp{--enable-bignum=gmp} to your invocation
+of @file{configure}.  For MPIR, use @samp{--enable-bignum=mpir}.  For
+BSD MP, use @samp{--enable-bignum=mp}.
 
 
 @node Q7.2.2, Q7.2.3, Q7.2.1, Advanced
 @node Q7.2.3, Q7.2.4, Q7.2.2, Advanced
 @unnumberedsubsec Q7.2.3: Bignums are really slow!
 
-Many Linux distributions compile all their packages for the i386, and
-this is costly.  An optimized version can give you two or three orders
-of magnitude better performance for a Pentium III or IV.  (Yes, really.
-See @uref{http://www.swox.com/gmp/gmp-speed.html}.)
+Many Unix and Linux distributions compile all packages for a generic
+version of the supported CPU, and this is costly.  An optimized version
+can improve responiveness dramatically; see
+@uref{http://gmplib.org/gmpbench.html}.)
 
 
 @node Q7.2.4,  , Q7.2.3, Advanced
+2013-06-17  Jerry James  <james@xemacs.org>
+
+	* Makefile.in.in: Support bignums with MPIR.
+	* config.h.in (WITH_MPIR): New macro.
+	* number.c: Add MPIR support.
+	* number.h: Ditto.
+	* number-gmp.h: Ditto.
+	(ratio_set_long_ulong): Canonicalize the ratio.
+	(ratio_set_ulong_ulong): Ditto.
+	* number-gmp.c (init_number_gmp): Add void param to silence GCC.
+	* number-mp.c (init_number_mp): Ditto.
+
 2013-06-17  Jerry James  <james@xemacs.org>
 
 	* alloc.c (make_bignum_un): New function.

src/Makefile.in.in

 mule_wnn_objs=mule-wnnfns.o
 #endif
 
-#ifdef WITH_GMP
+#if defined(WITH_GMP) || defined(WITH_MPIR)
 number_objs=number-gmp.o number.o
 #endif
 #ifdef WITH_MP
 /* Enhanced numeric support */
 #undef WITH_NUMBER_TYPES
 #undef WITH_GMP
+#undef WITH_MPIR
 #undef WITH_MP
 #undef MP_PREFIX
 #undef HAVE_MP_MOVE
-/* Numeric types for XEmacs using the GNU MP library.
-   Copyright (C) 2004 Jerry James.
+/* Numeric types for XEmacs using the GMP or MPIR library.
+   Copyright (C) 2004,2013 Jerry James.
 
 This file is part of XEmacs.
 
 }
 
 void
-init_number_gmp ()
+init_number_gmp (void)
 {
   mp_set_memory_functions ((void *(*) (size_t)) xmalloc, gmp_realloc,
 			   gmp_free);
-/* Definitions of numeric types for XEmacs using the GNU MP library.
-   Copyright (C) 2004 Jerry James.
+/* Definitions of numeric types for XEmacs using the GMP or MPIR library.
+   Copyright (C) 2004,2013 Jerry James.
 
 This file is part of XEmacs.
 
    Occurs on line 1596 of gmp.h in version 4.1.4. */
 #pragma warning ( disable : 4146 )
 #endif
+#ifdef WITH_GMP
 #include <gmp.h>
+#endif
+#ifdef WITH_MPIR
+#include <mpir.h>
+#endif
 #ifdef _MSC_VER
 #pragma warning ( default : 4146 )
 #endif
 #define ratio_set_double(r,f)           mpq_set_d (r, f)
 #define ratio_set_bignum(r,b)           mpq_set_z (r, b)
 #define ratio_set_bigfloat(r,f)         mpq_set_f (r, f)
-#define ratio_set_long_ulong(r,num,den)    mpq_set_si (r, num, den)
-#define ratio_set_ulong_ulong(r,num,den)   mpq_set_ui (r, num, den)
-/* FIXME: Why does this canonicalize, but the previous 2 don't? */
+#define ratio_set_long_ulong(r,num,den) do {	\
+    mpq_set_si (r, num, den);			\
+    mpq_canonicalize (r);			\
+  } while (0)
+#define ratio_set_ulong_ulong(r,num,den) do {	\
+    mpq_set_ui (r, num, den);			\
+    mpq_canonicalize (r);			\
+  } while (0)
 #define ratio_set_bignum_bignum(r,num,den) do {	\
     mpz_set (mpq_numref (r), num);		\
     mpz_set (mpq_denref (r), den);		\
 #endif
 
 void
-init_number_mp ()
+init_number_mp (void)
 {
 #ifdef HAVE_MP_SET_MEMORY_FUNCTIONS
   mp_set_memory_functions ((void *(*) (size_t)) xmalloc, mp_realloc, mp_free);
     {
       number_initialized = 1;
 
-#ifdef WITH_GMP
+#if defined(WITH_GMP) || defined(WITH_MPIR)
       init_number_gmp ();
 #endif
 #ifdef WITH_MP
 */
 
 /* Load the library definitions */
-#ifdef WITH_GMP
+#if defined(WITH_GMP) || defined(WITH_MPIR)
 #include "number-gmp.h"
 #endif
 #ifdef WITH_MP
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.