static char rcsid[] = "$Id: H:/drh/idioms/book/RCS/mp.doc,v 1.11 1996/06/26 23:02:01 drh Exp $";
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include "assert.h"
#include "fmt.h"
#include "mem.h"
#include "xp.h"
#include "mp.h"
#define T MP_T
#define sign(x) ((x)[nbytes-1]>>shift)
#define ones(n) (~(~0UL<<(((n)-1)%8+1)))
#define iszero(x) (XP_length(nbytes,(x))==1 && (x)[0]==0)
#define BASE (1<<8)
#define bitop(op) \
int i; assert(z); assert(x); assert(y); \
for (i = 0; i < nbytes; i++) z[i] = x[i] op y[i]; \
return z
#define bitopi(op) assert(z); assert(x); \
applyu(op, z, x, y); \
return z
#define shft(fill, op) \
assert(x); assert(z); assert(s >= 0); \
if (s >= nbits) memset(z, fill, nbytes); \
else op(nbytes, z, nbytes, x, s, fill); \
z[nbytes-1] &= msb; \
return z
const Except_T MP_Dividebyzero = { "Division by zero" };
const Except_T MP_Overflow = { "Overflow" };
static int nbits = 32;
static int nbytes = (32-1)/8 + 1;
static int shift = (32-1)%8;
static unsigned char msb = 0xFF;
static unsigned char temp[16 + 16 + 16 + 2*16+2];
static T tmp[] = {temp, temp+1*16, temp+2*16, temp+3*16};
static int applyu(T op(T, T, T), T z, T x,
unsigned long u) {
unsigned long carry;
{ T z = tmp[2]; carry = XP_fromint(nbytes, z, u);
carry |= z[nbytes-1]&~msb;
z[nbytes-1] &= msb; }
op(z, x, tmp[2]);
return carry != 0;
}
static int apply(T op(T, T, T), T z, T x, long v) {
{ T z = tmp[2]; if (v == LONG_MIN) {
XP_fromint(nbytes, z, LONG_MAX + 1UL);
XP_neg(nbytes, z, z, 1);
} else if (v < 0) {
XP_fromint(nbytes, z, -v);
XP_neg(nbytes, z, z, 1);
} else
XP_fromint(nbytes, z, v);
z[nbytes-1] &= msb; }
op(z, x, tmp[2]);
return (nbits < 8*(int)sizeof (v) &&
(v < -(1L<<(nbits-1)) || v >= (1L<<(nbits-1))));
}
int MP_set(int n) {
int prev = nbits;
assert(n > 1);
nbits = n;
nbytes = (n-1)/8 + 1;
shift = (n-1)%8;
msb = ones(n);
if (tmp[0] != temp)
FREE(tmp[0]);
if (nbytes <= 16)
tmp[0] = temp;
else
tmp[0] = ALLOC(3*nbytes + 2*nbytes + 2);
tmp[1] = tmp[0] + 1*nbytes;
tmp[2] = tmp[0] + 2*nbytes;
tmp[3] = tmp[0] + 3*nbytes;
return prev;
}
T MP_new(unsigned long u) {
return MP_fromintu(ALLOC(nbytes), u);
}
T MP_fromintu(T z, unsigned long u) {
unsigned long carry;
assert(z);
carry = XP_fromint(nbytes, z, u);
carry |= z[nbytes-1]&~msb;
z[nbytes-1] &= msb;
if (carry)
RAISE(MP_Overflow);
return z;
}
T MP_fromint(T z, long v) {
assert(z);
if (v == LONG_MIN) {
XP_fromint(nbytes, z, LONG_MAX + 1UL);
XP_neg(nbytes, z, z, 1);
} else if (v < 0) {
XP_fromint(nbytes, z, -v);
XP_neg(nbytes, z, z, 1);
} else
XP_fromint(nbytes, z, v);
z[nbytes-1] &= msb;
if ((nbits < 8*(int)sizeof (v) &&
(v < -(1L<<(nbits-1)) || v >= (1L<<(nbits-1)))))
RAISE(MP_Overflow);
return z;
}
long MP_toint(T x) {
unsigned char d[sizeof (unsigned long)];
assert(x);
MP_cvt(8*sizeof d, d, x);
return XP_toint(sizeof d, d);
}
T MP_cvt(int m, T z, T x) {
int fill, i, mbytes = (m - 1)/8 + 1;
assert(m > 1);
assert(x); assert(z);
fill = sign(x) ? 0xFF : 0;
if (m < nbits) {
int carry = (x[mbytes-1]^fill)&~ones(m);
for (i = mbytes; i < nbytes; i++)
carry |= x[i]^fill;
memcpy(z, x, mbytes);
z[mbytes-1] &= ones(m);
if (carry)
RAISE(MP_Overflow);
} else {
memcpy(z, x, nbytes);
z[nbytes-1] |= fill&~msb;
for (i = nbytes; i < mbytes; i++)
z[i] = fill;
z[mbytes-1] &= ones(m);
}
return z;
}
unsigned long MP_tointu(T x) {
unsigned char d[sizeof (unsigned long)];
assert(x);
MP_cvtu(8*sizeof d, d, x);
return XP_toint(sizeof d, d);
}
T MP_cvtu(int m, T z, T x) {
int i, mbytes = (m - 1)/8 + 1;
assert(m > 1);
assert(x); assert(z);
if (m < nbits) {
int carry = x[mbytes-1]&~ones(m);
for (i = mbytes; i < nbytes; i++)
carry |= x[i];
memcpy(z, x, mbytes);
z[mbytes-1] &= ones(m);
if (carry)
RAISE(MP_Overflow);
} else {
memcpy(z, x, nbytes);
for (i = nbytes; i < mbytes; i++)
z[i] = 0;
}
return z;
}
T MP_addu(T z, T x, T y) {
int carry;
assert(x); assert(y); assert(z);
carry = XP_add(nbytes, z, x, y, 0);
carry |= z[nbytes-1]&~msb;
z[nbytes-1] &= msb;
if (carry)
RAISE(MP_Overflow);
return z;
}
T MP_subu(T z, T x, T y) {
int borrow;
assert(x); assert(y); assert(z);
borrow = XP_sub(nbytes, z, x, y, 0);
borrow |= z[nbytes-1]&~msb;
z[nbytes-1] &= msb;
if (borrow)
RAISE(MP_Overflow);
return z;
}
T MP_mul2u(T z, T x, T y) {
assert(x); assert(y); assert(z);
memset(tmp[3], '\0', 2*nbytes);
XP_mul(tmp[3], nbytes, x, nbytes, y);
memcpy(z, tmp[3], (2*nbits - 1)/8 + 1);
return z;
}
T MP_mulu(T z, T x, T y) {
assert(x); assert(y); assert(z);
memset(tmp[3], '\0', 2*nbytes);
XP_mul(tmp[3], nbytes, x, nbytes, y);
memcpy(z, tmp[3], nbytes);
z[nbytes-1] &= msb;
{
int i;
if (tmp[3][nbytes-1]&~msb)
RAISE(MP_Overflow);
for (i = 0; i < nbytes; i++)
if (tmp[3][i+nbytes] != 0)
RAISE(MP_Overflow);
}
return z;
}
T MP_divu(T z, T x, T y) {
assert(x); assert(y); assert(z);
{
memcpy(tmp[1], y, nbytes);
y = tmp[1];
}
if (!XP_div(nbytes, z, x, nbytes, y, tmp[2], tmp[3]))
RAISE(MP_Dividebyzero);
return z;
}
T MP_modu(T z, T x, T y) {
assert(x); assert(y); assert(z);
{
memcpy(tmp[1], y, nbytes);
y = tmp[1];
}
if (!XP_div(nbytes, tmp[2], x, nbytes, y, z, tmp[3]))
RAISE(MP_Dividebyzero);
return z;
}
T MP_add(T z, T x, T y) {
int sx, sy;
assert(x); assert(y); assert(z);
sx = sign(x);
sy = sign(y);
XP_add(nbytes, z, x, y, 0);
z[nbytes-1] &= msb;
if (sx == sy && sy != sign(z))
RAISE(MP_Overflow);
return z;
}
T MP_sub(T z, T x, T y) {
int sx, sy;
assert(x); assert(y); assert(z);
sx = sign(x);
sy = sign(y);
XP_sub(nbytes, z, x, y, 0);
z[nbytes-1] &= msb;
if (sx != sy && sy == sign(z))
RAISE(MP_Overflow);
return z;
}
T MP_neg(T z, T x) {
int sx;
assert(x); assert(z);
sx = sign(x);
XP_neg(nbytes, z, x, 1);
z[nbytes-1] &= msb;
if (sx && sx == sign(z))
RAISE(MP_Overflow);
return z;
}
T MP_mul2(T z, T x, T y) {
int sx, sy;
assert(x); assert(y); assert(z);
sx = sign(x);
sy = sign(y);
if (sx) {
XP_neg(nbytes, tmp[0], x, 1);
x = tmp[0];
x[nbytes-1] &= msb;
}
if (sy) {
XP_neg(nbytes, tmp[1], y, 1);
y = tmp[1];
y[nbytes-1] &= msb;
}
memset(tmp[3], '\0', 2*nbytes);
XP_mul(tmp[3], nbytes, x, nbytes, y);
if (sx != sy)
XP_neg((2*nbits - 1)/8 + 1, z, tmp[3], 1);
else
memcpy(z, tmp[3], (2*nbits - 1)/8 + 1);
return z;
}
T MP_mul(T z, T x, T y) {
int sx, sy;
assert(x); assert(y); assert(z);
sx = sign(x);
sy = sign(y);
if (sx) {
XP_neg(nbytes, tmp[0], x, 1);
x = tmp[0];
x[nbytes-1] &= msb;
}
if (sy) {
XP_neg(nbytes, tmp[1], y, 1);
y = tmp[1];
y[nbytes-1] &= msb;
}
memset(tmp[3], '\0', 2*nbytes);
XP_mul(tmp[3], nbytes, x, nbytes, y);
if (sx != sy)
XP_neg(nbytes, z, tmp[3], 1);
else
memcpy(z, tmp[3], nbytes);
z[nbytes-1] &= msb;
{
int i;
if (tmp[3][nbytes-1]&~msb)
RAISE(MP_Overflow);
for (i = 0; i < nbytes; i++)
if (tmp[3][i+nbytes] != 0)
RAISE(MP_Overflow);
}
if (sx == sy && sign(z))
RAISE(MP_Overflow);
return z;
}
T MP_div(T z, T x, T y) {
int sx, sy;
assert(x); assert(y); assert(z);
sx = sign(x);
sy = sign(y);
if (sx) {
XP_neg(nbytes, tmp[0], x, 1);
x = tmp[0];
x[nbytes-1] &= msb;
}
if (sy) {
XP_neg(nbytes, tmp[1], y, 1);
y = tmp[1];
y[nbytes-1] &= msb;
} else {
memcpy(tmp[1], y, nbytes);
y = tmp[1];
}
if (!XP_div(nbytes, z, x, nbytes, y, tmp[2], tmp[3]))
RAISE(MP_Dividebyzero);
if (sx != sy) {
XP_neg(nbytes, z, z, 1);
if (!iszero(tmp[2]))
XP_diff(nbytes, z, z, 1);
z[nbytes-1] &= msb;
} else if
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
cii11.zip (81个子文件)
history.html 13KB
custom.mk 8B
install.html 15KB
examples
getword.h 191B
ids.c 599B
words.c 1018B
getword.c 725B
basename.c 720B
integer.c 881B
integer.h 399B
iref.c 4KB
wf.c 2KB
mpcalc.c 5KB
idents.c 909B
sieve.c 2KB
cref.c 3KB
kref.c 3KB
xref.c 3KB
spin.c 1KB
double.c 1KB
sort.c 2KB
calc.c 3KB
include
sem.h 486B
except.h 2KB
atom.h 335B
arith.h 312B
mp.h 2KB
table.h 704B
assert.h 265B
arrayrep.h 302B
thread.h 583B
ring.h 691B
arena.h 565B
mem.h 910B
text.h 2KB
stack.h 368B
bit.h 827B
ap.h 1KB
array.h 531B
seq.h 534B
chan.h 335B
str.h 2KB
list.h 685B
set.h 769B
fmt.h 1KB
xp.h 1KB
makefile 7KB
src
memmove.c 473B
ap.c 9KB
fmt.c 9KB
set.c 7KB
mem.c 1KB
strncmp.c 393B
ring.c 4KB
assert.c 219B
seq.c 3KB
swtch.s 4KB
text.c 10KB
table.c 3KB
atom.c 5KB
bit.c 4KB
arith.c 636B
chan.c 937B
xp.c 6KB
str.c 6KB
list.c 2KB
except.c 837B
thread-nt.c 7KB
libcii.def 3KB
array.c 2KB
mp.c 16KB
stack.c 954B
arena.c 2KB
strerror.c 405B
thread.c 7KB
memcmp.c 378B
memchk.c 3KB
makefile.nt 8KB
README 548B
packing.lst 1KB
CPYRIGHT 881B
共 81 条
- 1
资源评论
- ynkmr2012-07-02在WINDOWS下编译不了,thread.c引用了LINUX下的头文件,但其它的都可以.
- lcrpkking2012-07-31终于看到全面的代码了 MEN和ASSERT很有用啊!
- hero9c12014-11-29里面的代码很好,给C语言的开发提供了很多素材
- Grey05022012-12-03很好,在linux下测试过,有启发
- dongAxis2013-03-20这个对于C的研究又进了一步, 很好的.....
szq2k08
- 粉丝: 5
- 资源: 33
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功