1
0
mirror of git://git.sv.gnu.org/coreutils.git synced 2026-06-01 23:36:29 +02:00

maint: use Gnulib libgmp module

This lets use assume multiple-precision arithmetic on all
platforms, simplifying the code.
* bootstrap.conf (gnulib_modules): Add libgmp.
* configure.ac: Don’t call cu_GMP, as this is now done by Gnulib.
* m4/gmp.m4: Remove.
* src/expr.c, src/factor.c: Use gmp.h unconditionally.
* src/factor.c: Use the simpler ‘#ifndef mpz_inits’ to
determine whether there is an mpz_inits macro.
This commit is contained in:
Paul Eggert
2020-07-07 10:39:10 -07:00
parent 4c8495cf11
commit 1304644488
5 changed files with 9 additions and 195 deletions
+1
View File
@@ -144,6 +144,7 @@ gnulib_modules="
lchown
ldtoastr
lib-ignore
libgmp
linebuffer
link
link-follow
-2
View File
@@ -474,8 +474,6 @@ AC_CHECK_DECLS([strsignal, sys_siglist, _sys_siglist, __sys_siglist], , ,
[AC_INCLUDES_DEFAULT
#include <signal.h>])
cu_GMP
# Build df only if there's a point to it.
if test $gl_cv_list_mounted_fs = yes && test $gl_cv_fs_space = yes; then
gl_ADD_PROG([optional_bin_progs], [df])
-48
View File
@@ -1,48 +0,0 @@
# Tests for GNU GMP (or any compatible replacement).
dnl Copyright (C) 2008-2020 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl Written by James Youngman.
dnl Check for libgmp. We avoid use of AC_CHECK_LIBS because we don't want to
dnl add this to $LIBS for all targets.
AC_DEFUN([cu_GMP],
[
LIB_GMP=
AC_SUBST([LIB_GMP])
AC_ARG_WITH([gmp],
AS_HELP_STRING([--without-gmp],
[do not use the GNU MP library for arbitrary precision
calculation (default: use it if available)]),
[cu_use_gmp=$withval],
[cu_use_gmp=auto])
if test $cu_use_gmp != no; then
dnl It was noticed on one MacOS X 10.5.8 system at least
dnl that the libs were available but the header wasn't
HAVE_GMP=0
AC_CHECK_HEADERS_ONCE([gmp.h])
if test $ac_cv_header_gmp_h = yes; then
cu_saved_libs=$LIBS
AC_SEARCH_LIBS([__gmpz_init], [gmp],
[test "$ac_cv_search___gmpz_init" = "none required" ||
LIB_GMP=$ac_cv_search___gmpz_init
AC_DEFINE([HAVE_GMP], [1],
[Define if you have GNU libgmp (or replacement)])
HAVE_GMP=1
# This only available in GMP >= 5
AC_CHECK_DECLS([mpz_inits], [], [], [[#include <gmp.h>]])
])
LIBS=$cu_saved_libs
fi
if test $HAVE_GMP != 1; then
AC_MSG_WARN([libgmp development library was not found or not usable.])
AC_MSG_WARN([AC_PACKAGE_NAME will be built without GMP support.])
fi
fi
])
+2 -109
View File
@@ -33,6 +33,7 @@
#include <sys/types.h>
#include "system.h"
#include <gmp.h>
#include <regex.h>
#include "die.h"
#include "error.h"
@@ -45,105 +46,6 @@
int, the widest unsigned type that GMP supports. */
verify (SIZE_MAX <= ULONG_MAX);
#ifndef HAVE_GMP
# define HAVE_GMP 0
#endif
#if HAVE_GMP
# include <gmp.h>
#else
static void integer_overflow (char) ATTRIBUTE_NORETURN;
/* Approximate gmp.h well enough for expr.c's purposes. */
typedef intmax_t mpz_t[1];
static void mpz_clear (mpz_t z) { (void) z; }
static void mpz_init_set_ui (mpz_t z, unsigned long int i) { z[0] = i; }
static int
mpz_init_set_str (mpz_t z, char *s, int base)
{
return xstrtoimax (s, NULL, base, z, "") == LONGINT_OK ? 0 : -1;
}
static void
mpz_add (mpz_t r, mpz_t a0, mpz_t b0)
{
intmax_t a = a0[0];
intmax_t b = b0[0];
intmax_t val = a + b;
if ((val < a) != (b < 0))
integer_overflow ('+');
r[0] = val;
}
static void
mpz_sub (mpz_t r, mpz_t a0, mpz_t b0)
{
intmax_t a = a0[0];
intmax_t b = b0[0];
intmax_t val = a - b;
if ((a < val) != (b < 0))
integer_overflow ('-');
r[0] = val;
}
static void
mpz_mul (mpz_t r, mpz_t a0, mpz_t b0)
{
intmax_t a = a0[0];
intmax_t b = b0[0];
intmax_t val = a * b;
if (! (a == 0 || b == 0
|| ((val < 0) == ((a < 0) ^ (b < 0)) && val / a == b)))
integer_overflow ('*');
r[0] = val;
}
static void
mpz_tdiv_q (mpz_t r, mpz_t a0, mpz_t b0)
{
intmax_t a = a0[0];
intmax_t b = b0[0];
/* Some x86-style hosts raise an exception for INT_MIN / -1. */
if (a < - INTMAX_MAX && b == -1)
integer_overflow ('/');
r[0] = a / b;
}
static void
mpz_tdiv_r (mpz_t r, mpz_t a0, mpz_t b0)
{
intmax_t a = a0[0];
intmax_t b = b0[0];
/* Some x86-style hosts raise an exception for INT_MIN % -1. */
r[0] = a < - INTMAX_MAX && b == -1 ? 0 : a % b;
}
static char * _GL_ATTRIBUTE_MALLOC
mpz_get_str (char const *str, int base, mpz_t z)
{
(void) str; (void) base;
char buf[INT_BUFSIZE_BOUND (intmax_t)];
return xstrdup (imaxtostr (z[0], buf));
}
static int
mpz_sgn (mpz_t z)
{
return z[0] < 0 ? -1 : 0 < z[0];
}
static int
mpz_fits_ulong_p (mpz_t z)
{
return 0 <= z[0] && z[0] <= ULONG_MAX;
}
static unsigned long int
mpz_get_ui (mpz_t z)
{
return z[0];
}
static int
mpz_out_str (FILE *stream, int base, mpz_t z)
{
(void) base;
char buf[INT_BUFSIZE_BOUND (intmax_t)];
return fputs (imaxtostr (z[0], buf), stream) != EOF;
}
#endif
/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "expr"
@@ -414,15 +316,6 @@ or 0, 2 if EXPRESSION is syntactically invalid, and 3 if an error occurred.\n\
}
#if ! HAVE_GMP
/* Report an integer overflow for operation OP and exit. */
static void
integer_overflow (char op)
{
die (EXPR_FAILURE, ERANGE, "%c", op);
}
#endif
int
main (int argc, char **argv)
{
@@ -603,7 +496,7 @@ toarith (VALUE *v)
if (! looks_like_integer (s))
return false;
if (mpz_init_set_str (v->u.i, s, 10) != 0 && !HAVE_GMP)
if (mpz_init_set_str (v->u.i, s, 10) != 0)
die (EXPR_FAILURE, ERANGE, "%s", (s));
free (s);
v->type = integer;
+6 -36
View File
@@ -35,12 +35,6 @@
The factoring code for two words will fall into the code for one word when
progress allows that.
Using GMP is optional. Define HAVE_GMP to make this code include GMP
factoring code. The GMP factoring code is based on GMP's demos/factorize.c
(last synced 2012-09-07). The GMP-based factoring code will stay in GMP
factoring code even if numbers get small enough for using the two-word
code.
Algorithm:
(1) Perform trial division using a small primes table, but without hardware
@@ -104,13 +98,7 @@
#include <config.h>
#include <getopt.h>
#include <stdio.h>
#if HAVE_GMP
# include <gmp.h>
# if !HAVE_DECL_MPZ_INITS
# include <stdarg.h>
# endif
#endif
#include <gmp.h>
#include <assert.h>
#include "system.h"
@@ -246,14 +234,12 @@ struct factors
unsigned char nfactors;
};
#if HAVE_GMP
struct mp_factors
{
mpz_t *p;
unsigned long int *e;
unsigned long int nfactors;
};
#endif
static void factor (uintmax_t, uintmax_t, struct factors *);
@@ -570,12 +556,12 @@ factor_insert_large (struct factors *factors,
factor_insert (factors, p0);
}
#if HAVE_GMP
#ifndef mpz_inits
# if !HAVE_DECL_MPZ_INITS
# include <stdarg.h>
# define mpz_inits(...) mpz_va_init (mpz_init, __VA_ARGS__)
# define mpz_clears(...) mpz_va_init (mpz_clear, __VA_ARGS__)
# define mpz_inits(...) mpz_va_init (mpz_init, __VA_ARGS__)
# define mpz_clears(...) mpz_va_init (mpz_clear, __VA_ARGS__)
static void
mpz_va_init (void (*mpz_single_init)(mpz_t), ...)
@@ -590,7 +576,7 @@ mpz_va_init (void (*mpz_single_init)(mpz_t), ...)
va_end (ap);
}
# endif
#endif
static void mp_factor (mpz_t, struct mp_factors *);
@@ -660,7 +646,6 @@ mp_factor_insert_ui (struct mp_factors *factors, unsigned long int prime)
mp_factor_insert (factors, pz);
mpz_clear (pz);
}
#endif /* HAVE_GMP */
/* Number of bits in an uintmax_t. */
@@ -835,7 +820,6 @@ factor_using_division (uintmax_t *t1p, uintmax_t t1, uintmax_t t0,
return t0;
}
#if HAVE_GMP
static void
mp_factor_using_division (mpz_t t, struct mp_factors *factors)
{
@@ -872,7 +856,6 @@ mp_factor_using_division (mpz_t t, struct mp_factors *factors)
mpz_clear (q);
}
#endif
/* Entry i contains (2i+1)^(-1) mod 2^8. */
static const unsigned char binvert_table[128] =
@@ -1171,7 +1154,6 @@ millerrabin2 (const uintmax_t *np, uintmax_t ni, const uintmax_t *bp,
return false;
}
#if HAVE_GMP
static bool
mp_millerrabin (mpz_srcptr n, mpz_srcptr nm1, mpz_ptr x, mpz_ptr y,
mpz_srcptr q, unsigned long int k)
@@ -1191,7 +1173,6 @@ mp_millerrabin (mpz_srcptr n, mpz_srcptr nm1, mpz_ptr x, mpz_ptr y,
}
return false;
}
#endif
/* Lucas' prime test. The number of iterations vary greatly, up to a few dozen
have been observed. The average seem to be about 2. */
@@ -1377,7 +1358,6 @@ prime2_p (uintmax_t n1, uintmax_t n0)
abort ();
}
#if HAVE_GMP
static bool
mp_prime_p (mpz_t n)
{
@@ -1460,7 +1440,6 @@ mp_prime_p (mpz_t n)
return is_prime;
}
#endif
static void
factor_using_pollard_rho (uintmax_t n, unsigned long int a,
@@ -1669,7 +1648,6 @@ factor_using_pollard_rho2 (uintmax_t n1, uintmax_t n0, unsigned long int a,
}
}
#if HAVE_GMP
static void
mp_factor_using_pollard_rho (mpz_t n, unsigned long int a,
struct mp_factors *factors)
@@ -1761,7 +1739,6 @@ mp_factor_using_pollard_rho (mpz_t n, unsigned long int a,
mpz_clears (P, t2, t, z, x, y, NULL);
}
#endif
#if USE_SQUFOF
/* FIXME: Maybe better to use an iteration converging to 1/sqrt(n)? If
@@ -2251,7 +2228,6 @@ factor (uintmax_t t1, uintmax_t t0, struct factors *factors)
}
}
#if HAVE_GMP
/* Use Pollard-rho to compute the prime factors of
arbitrary-precision T, and put the results in FACTORS. */
static void
@@ -2273,7 +2249,6 @@ mp_factor (mpz_t t, struct mp_factors *factors)
}
}
}
#endif
static strtol_error
strto2uintmax (uintmax_t *hip, uintmax_t *lop, const char *s)
@@ -2526,7 +2501,6 @@ print_factors (const char *input)
return false;
}
#if HAVE_GMP
devmsg ("[using arbitrary-precision arithmetic] ");
mpz_t t;
struct mp_factors factors;
@@ -2545,10 +2519,6 @@ print_factors (const char *input)
putchar ('\n');
fflush (stdout);
return true;
#else
error (0, 0, _("%s is too large"), quote (input));
return false;
#endif
}
void