initial commit

This commit is contained in:
xiaoh105
2025-05-21 16:56:46 +08:00
commit 940b85ac80
12 changed files with 1023 additions and 0 deletions

275
projects/task1/mini-gmp.c Executable file
View File

@ -0,0 +1,275 @@
#include "mini-gmp.h"
mp_size_t gmp_abs(mp_size_t x) {
return x >= 0 ? x : -x;
}
mp_size_t gmp_max(mp_size_t a, mp_size_t b) {
return a > b ? a : b;
}
int gmp_cmp(mp_size_t a, mp_size_t b) {
return (a > b) - (a < b);
}
/* MPN interface */
/* 从 低地址向高地址 顺序复制 */
void
mpn_copyi (mp_ptr d, mp_srcptr s, mp_size_t n)
{
mp_size_t i;
for (i = 0; i < n; i++)
d[i] = s[i];
}
/* 大于返回1小于返回-1等于返回0 */
int
mpn_cmp (mp_srcptr ap, mp_srcptr bp, mp_size_t n)
{
while (--n >= 0)
{
if (ap[n] != bp[n])
return ap[n] > bp[n] ? 1 : -1;
}
return 0;
}
/*处理位数不同的情况*/
static int
mpn_cmp4 (mp_srcptr ap, mp_size_t an, mp_srcptr bp, mp_size_t bn)
{
if (an != bn)
return an < bn ? -1 : 1;
else
return mpn_cmp (ap, bp, an);
}
/*返回非0的位数*/
static mp_size_t
mpn_normalized_size (mp_srcptr xp, mp_size_t n)
{
while (n > 0 && xp[n-1] == 0)
--n;
return n;
}
/* 多精度数ap 加上单精度数b返回最后产生的进位 */
mp_limb_t
mpn_add_1 (mp_ptr rp, mp_srcptr ap, mp_size_t n, mp_limb_t b)
{
mp_size_t i;
//assert (n > 0);
i = 0;
do
{
mp_limb_t r = ap[i] + b;
/* Carry out */
b = (r < b);
rp[i] = r;
}
while (++i < n);
return b;
}
/* 位数相同的多精度数ap 加上多精度数bp返回最后产生的进位 */
mp_limb_t
mpn_add_n (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t n)
{
mp_size_t i;
mp_limb_t cy;
for (i = 0, cy = 0; i < n; i++)
{
mp_limb_t a, b, r;
a = ap[i]; b = bp[i];
r = a + cy;
cy = (r < cy);
r += b;
cy += (r < b);
rp[i] = r;
}
return cy;
}
/*不同位数的多精度数相加,返回最后的进位*/
mp_limb_t
mpn_add (mp_ptr rp, mp_srcptr ap, mp_size_t an, mp_srcptr bp, mp_size_t bn)
{
mp_limb_t cy;
//assert (an >= bn);
cy = mpn_add_n (rp, ap, bp, bn);
if (an > bn)
cy = mpn_add_1 (rp + bn, ap + bn, an - bn, cy);
return cy;
}
mp_limb_t
mpn_sub_1 (mp_ptr rp, mp_srcptr ap, mp_size_t n, mp_limb_t b)
{
mp_size_t i;
//assert (n > 0);
i = 0;
do
{
mp_limb_t a = ap[i];
/* Carry out */
mp_limb_t cy = a < b;
rp[i] = a - b;
b = cy;
}
while (++i < n);
return b;
}
mp_limb_t
mpn_sub_n (mp_ptr rp, mp_srcptr ap, mp_srcptr bp, mp_size_t n)
{
mp_size_t i;
mp_limb_t cy;
for (i = 0, cy = 0; i < n; i++)
{
mp_limb_t a, b;
a = ap[i]; b = bp[i];
b += cy;
cy = (b < cy);
cy += (a < b);
rp[i] = a - b;
}
return cy;
}
mp_limb_t
mpn_sub (mp_ptr rp, mp_srcptr ap, mp_size_t an, mp_srcptr bp, mp_size_t bn)
{
mp_limb_t cy;
//assert (an >= bn);
cy = mpn_sub_n (rp, ap, bp, bn);
if (an > bn)
cy = mpn_sub_1 (rp + bn, ap + bn, an - bn, cy);
return cy;
}
/* MPZ interface */
void
mpz_clear (mpz_t r)
{
if (r->_mp_alloc)
gmp_free_limbs (r->_mp_d, r->_mp_alloc);
}
static mp_ptr
mpz_realloc (mpz_t r, mp_size_t size)
{
size = gmp_max (size, 1);
if (r->_mp_alloc)
r->_mp_d = gmp_realloc_limbs (r->_mp_d, r->_mp_alloc, size);
else
r->_mp_d = gmp_alloc_limbs (size);
r->_mp_alloc = size;
if (gmp_abs (r->_mp_size) > size)
r->_mp_size = 0;
return r->_mp_d;
}
/* Realloc for an mpz_t WHAT if it has less than NEEDED limbs. */
mp_ptr mrz_realloc_if(mpz_t z,mp_size_t n) {
return n > z->_mp_alloc ? mpz_realloc(z, n) : z->_mp_d;
}
/* MPZ comparisons and the like. */
int
mpz_sgn (const mpz_t u)
{
return gmp_cmp (u->_mp_size, 0);
}
void
mpz_swap (mpz_t u, mpz_t v)
{
mp_size_t_swap (u->_mp_alloc, v->_mp_alloc);
mp_ptr_swap(u->_mp_d, v->_mp_d);
mp_size_t_swap (u->_mp_size, v->_mp_size);
}
/* MPZ addition and subtraction */
static mp_size_t
mpz_abs_add (mpz_t r, const mpz_t a, const mpz_t b)
{
mp_size_t an = gmp_abs (a->_mp_size);
mp_size_t bn = gmp_abs (b->_mp_size);
mp_ptr rp;
mp_limb_t cy;
if (an < bn)
{
mpz_srcptr_swap (a, b);
mp_size_t_swap (an, bn);
}
rp = mrz_realloc_if (r, an + 1);
cy = mpn_add (rp, a->_mp_d, an, b->_mp_d, bn);
rp[an] = cy;
return an + cy;
}
static mp_size_t
mpz_abs_sub (mpz_t r, const mpz_t a, const mpz_t b)
{
mp_size_t an = gmp_abs (a->_mp_size);
mp_size_t bn = gmp_abs (b->_mp_size);
int cmp;
mp_ptr rp;
cmp = mpn_cmp4 (a->_mp_d, an, b->_mp_d, bn);
if (cmp > 0)
{
rp = mrz_realloc_if (r, an);
mpn_sub (rp, a->_mp_d, an, b->_mp_d, bn);
return mpn_normalized_size (rp, an);
}
else if (cmp < 0)
{
rp = mrz_realloc_if (r, bn);
mpn_sub (rp, b->_mp_d, bn, a->_mp_d, an);
return -mpn_normalized_size (rp, bn);
}
else
return 0;
}
void
mpz_add (mpz_t r, const mpz_t a, const mpz_t b)
{
mp_size_t rn;
if ( (a->_mp_size ^ b->_mp_size) >= 0)
rn = mpz_abs_add (r, a, b);
else
rn = mpz_abs_sub (r, a, b);
r->_mp_size = a->_mp_size >= 0 ? rn : - rn;
}
void
mpz_sub (mpz_t r, const mpz_t a, const mpz_t b)
{
mp_size_t rn;
if ( (a->_mp_size ^ b->_mp_size) >= 0)
rn = mpz_abs_sub (r, a, b);
else
rn = mpz_abs_add (r, a, b);
r->_mp_size = a->_mp_size >= 0 ? rn : - rn;
}

66
projects/task1/mini-gmp.h Executable file
View File

@ -0,0 +1,66 @@
typedef unsigned long mp_limb_t;
typedef long mp_size_t;
typedef unsigned long mp_bitcnt_t;
typedef mp_limb_t *mp_ptr;
typedef const mp_limb_t *mp_srcptr;
typedef struct
{
int _mp_alloc; /* Number of *limbs* allocated and pointed
to by the _mp_d field. */
int _mp_size; /* abs(_mp_size) is the number of limbs the
last field points to. If _mp_size is
negative this is a negative number. */
mp_limb_t *_mp_d; /* Pointer to the limbs. */
} __mpz_struct;
/* mpz_t is an array type that contains a single element of __mpz_struct, acting as a reference. */
typedef __mpz_struct mpz_t[1];
typedef __mpz_struct *mpz_ptr;
typedef const __mpz_struct *mpz_srcptr;
/* BEGIN Given Functions */
/* Swap functions. */
void mp_size_t_swap(mp_size_t x, mp_size_t y);
void mp_ptr_swap(mp_ptr x, mp_ptr y);
void mpz_srcptr_swap(mpz_srcptr x, mpz_srcptr y);
/* Memory allocation functions. */
static mp_ptr
gmp_alloc_limbs (mp_size_t size);
static mp_ptr
gmp_realloc_limbs (mp_ptr old, mp_size_t old_size, mp_size_t size);
static void
gmp_free_limbs (mp_ptr old, mp_size_t size);
/* END Given Functions */
void mpn_copyi (mp_ptr, mp_srcptr, mp_size_t);
int mpn_cmp (mp_srcptr, mp_srcptr, mp_size_t);
mp_limb_t mpn_add_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
mp_limb_t mpn_add_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
mp_limb_t mpn_add (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
mp_limb_t mpn_sub_1 (mp_ptr, mp_srcptr, mp_size_t, mp_limb_t);
mp_limb_t mpn_sub_n (mp_ptr, mp_srcptr, mp_srcptr, mp_size_t);
mp_limb_t mpn_sub (mp_ptr, mp_srcptr, mp_size_t, mp_srcptr, mp_size_t);
void mpz_clear (mpz_t);
int mpz_sgn (const mpz_t);
void mpz_neg (mpz_t, const mpz_t);
void mpz_swap (mpz_t, mpz_t);
void mpz_add (mpz_t, const mpz_t, const mpz_t);
void mpz_sub (mpz_t, const mpz_t, const mpz_t);
void mpz_set (mpz_t, const mpz_t);