Commit 091047f3 authored by Ken Thompson's avatar Ken Thompson

adding and deleting files

R=r
DELTA=1685  (920 added, 765 deleted, 0 changed)
OCL=14030
CL=14030
parent 272ae659
...@@ -4,14 +4,16 @@ ...@@ -4,14 +4,16 @@
#include "go.h" #include "go.h"
/// uses arihmetic
int int
mpcmpfixfix(Mpint *a, Mpint *b) mpcmpfixfix(Mpint *a, Mpint *b)
{ {
if(a->val > b->val) Mpint c;
return +1;
if(a->val < b->val) mpmovefixfix(&c, a);
return -1; mpsubfixfix(&c, b);
return 0; return mptestfix(&c);
} }
int int
...@@ -26,206 +28,124 @@ mpcmpfixc(Mpint *b, vlong c) ...@@ -26,206 +28,124 @@ mpcmpfixc(Mpint *b, vlong c)
int int
mpcmpfltflt(Mpflt *a, Mpflt *b) mpcmpfltflt(Mpflt *a, Mpflt *b)
{ {
if(a->val > b->val) Mpflt c;
return +1;
if(a->val < b->val) mpmovefltflt(&c, a);
return -1; mpsubfltflt(&c, b);
return 0; return mptestflt(&c);
} }
int int
mpcmpfltc(Mpint *b, double c) mpcmpfltc(Mpflt *b, double c)
{ {
Mpint a; Mpflt a;
mpmovecflt(&a, c); mpmovecflt(&a, c);
return mpcmpfltflt(&a, b); return mpcmpfltflt(&a, b);
} }
void
mpaddfixfix(Mpint *a, Mpint *b)
{
a->val += b->val;
}
void void
mpsubfixfix(Mpint *a, Mpint *b) mpsubfixfix(Mpint *a, Mpint *b)
{ {
a->val -= b->val; mpnegfix(b);
mpaddfixfix(a, b);
mpnegfix(b);
} }
void void
mpmulfixfix(Mpint *a, Mpint *b) mpsubfltflt(Mpflt *a, Mpflt *b)
{ {
a->val *= b->val; mpnegflt(b);
mpaddfltflt(a, b);
mpnegflt(b);
} }
void void
mpdivfixfix(Mpint *a, Mpint *b) mpaddcfix(Mpint *a, vlong c)
{ {
a->val /= b->val; Mpint b;
}
void mpmovecfix(&b, c);
mpmodfixfix(Mpint *a, Mpint *b) mpaddfixfix(a, &b);
{
a->val %= b->val;
} }
void void
mporfixfix(Mpint *a, Mpint *b) mpaddcflt(Mpflt *a, double c)
{ {
a->val |= b->val; Mpflt b;
}
void mpmovecflt(&b, c);
mpandfixfix(Mpint *a, Mpint *b) mpaddfltflt(a, &b);
{
a->val &= b->val;
} }
void void
mpxorfixfix(Mpint *a, Mpint *b) mpmulcfix(Mpint *a, vlong c)
{ {
a->val ^= b->val; Mpint b;
}
void mpmovecfix(&b, c);
mplshfixfix(Mpint *a, Mpint *b) mpmulfixfix(a, &b);
{
a->val <<= b->val;
} }
void void
mprshfixfix(Mpint *a, Mpint *b) mpmulcflt(Mpflt *a, double c)
{ {
a->val >>= b->val; Mpflt b;
}
void mpmovecflt(&b, c);
mpnegfix(Mpint *a) mpmulfltflt(a, &b);
{
a->val = -a->val;
} }
void void
mpcomfix(Mpint *a) mpdivfixfix(Mpint *a, Mpint *b)
{ {
a->val = ~a->val; Mpint q, r;
}
void mpdivmodfixfix(&q, &r, a, b);
mpaddfltflt(Mpflt *a, Mpflt *b) mpmovefixfix(a, &q);
{
a->val += b->val;
} }
void void
mpsubfltflt(Mpflt *a, Mpflt *b) mpmodfixfix(Mpint *a, Mpint *b)
{ {
a->val -= b->val; Mpint q, r;
}
void mpdivmodfixfix(&q, &r, a, b);
mpmulfltflt(Mpflt *a, Mpflt *b) mpmovefixfix(a, &r);
{
a->val *= b->val;
} }
void void
mpdivfltflt(Mpflt *a, Mpflt *b) mpcomfix(Mpint *a)
{
a->val /= b->val;
}
vlong
mpgetfix(Mpint *a)
{
return a->val;
}
double
mpgetflt(Mpflt *a)
{
return a->val;
}
void
mpmovefixfix(Mpint *a, Mpint *b)
{ {
*a = *b; Mpint b;
}
void mpmovecfix(&b, 1);
mpmovefltflt(Mpflt *a, Mpflt *b) mpnegfix(a);
{ mpsubfixfix(a, &b);
*a = *b;
} }
void void
mpmovefixflt(Mpflt *a, Mpint *b) mpmovefixflt(Mpflt *a, Mpint *b)
{ {
a->val = b->val; mpmovecflt(a, mpgetfix(b));
}
void
mpmovecfix(Mpint *a, vlong c)
{
a->val = c;
}
void
mpmovecflt(Mpflt *a, double c)
{
a->val = c;
} }
void void
mpmovefltfix(Mpint *a, Mpflt *b) mpmovefltfix(Mpint *a, Mpflt *b)
{ {
a->val = b->val; mpmovecfix(a, mpgetflt(b));
}
void
mpnegflt(Mpflt *a)
{
a->val = -a->val;
} }
void void
mpaddcflt(Mpflt *a, double c) mpmovefixfix(Mpint *a, Mpint *b)
{
Mpflt b;
mpmovecflt(&b, c);
mpaddfltflt(a, &b);
}
void
mpmulcflt(Mpflt *a, double c)
{
Mpflt b;
mpmovecflt(&b, c);
mpmulfltflt(a, &b);
}
void
mpaddcfix(Mpint *a, vlong c)
{ {
Mpint b; *a = *b;
mpmovecfix(&b, c);
mpaddfixfix(a, &b);
} }
void void
mpmulcfix(Mpint *a, vlong c) mpmovefltflt(Mpflt *a, Mpflt *b)
{ {
Mpint b; *a = *b;
mpmovecfix(&b, c);
mpmulfixfix(a, &b);
} }
// //
...@@ -265,7 +185,7 @@ mpatoflt(Mpflt *a, char *as) ...@@ -265,7 +185,7 @@ mpatoflt(Mpflt *a, char *as)
ex = 0; /* exponent */ ex = 0; /* exponent */
zer = 1; /* zero */ zer = 1; /* zero */
mpmovecflt(a, 0); mpmovecflt(a, 0.0);
for(;;) { for(;;) {
switch(c = *s++) { switch(c = *s++) {
default: default:
...@@ -348,7 +268,6 @@ bad: ...@@ -348,7 +268,6 @@ bad:
void void
mpatofix(Mpint *a, char *as) mpatofix(Mpint *a, char *as)
{ {
int c, f; int c, f;
char *s; char *s;
......
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "go.h"
//
// return the significant
// words of the argument
//
static int
mplen(Mpint *a)
{
int i, n;
long *a1;
n = -1;
a1 = &a->a[0];
for(i=0; i<Mpprec; i++) {
if(*a1++ != 0)
n = i;
}
return n+1;
}
//
// left shift mpint by one
// ignores sign and overflow
//
static void
mplsh(Mpint *a)
{
long *a1, x;
int i, c;
c = 0;
a1 = &a->a[0];
for(i=0; i<Mpprec; i++) {
x = (*a1 << 1) + c;
c = 0;
if(x >= Mpbase) {
x -= Mpbase;
c = 1;
}
*a1++ = x;
}
}
//
// left shift mpint by Mpscale
// ignores sign and overflow
//
static void
mplshw(Mpint *a)
{
long *a1;
int i;
a1 = &a->a[Mpprec-1];
for(i=1; i<Mpprec; i++) {
a1[0] = a1[-1];
*a1--;
}
a1[0] = 0;
}
//
// right shift mpint by one
// ignores sign and overflow
//
static void
mprsh(Mpint *a)
{
long *a1, x;
int i, c;
c = 0;
a1 = &a->a[Mpprec];
for(i=0; i<Mpprec; i++) {
x = *--a1;
*a1 = (x + c) >> 1;
c = 0;
if(x & 1)
c = Mpbase;
}
}
//
// right shift mpint by Mpscale
// ignores sign and overflow
//
static void
mprshw(Mpint *a)
{
long *a1;
int i;
a1 = &a->a[0];
for(i=1; i<Mpprec; i++) {
a1[0] = a1[1];
*a1++;
}
a1[0] = 0;
}
//
// return the sign of (abs(a)-abs(b))
//
static int
mpcmp(Mpint *a, Mpint *b)
{
long x, *a1, *b1;
int i;
if(a->ovf || b->ovf) {
warn("ovf in cmp");
return 0;
}
a1 = &a->a[0] + Mpprec;
b1 = &b->a[0] + Mpprec;
for(i=0; i<Mpprec; i++) {
x = *--a1 - *--b1;
if(x > 0)
return +1;
if(x < 0)
return -1;
}
return 0;
}
//
// negate a
// ignore sign and ovf
//
static void
mpneg(Mpint *a)
{
long x, *a1;
int i, c;
a1 = &a->a[0];
c = 0;
for(i=0; i<Mpprec; i++) {
x = c - *a1;
*a1++ = x;
c = 0;
if(x < 0)
c = 1;
}
}
/// implements fix arihmetic
void
mpaddfixfix(Mpint *a, Mpint *b)
{
int i, c;
long x, *a1, *b1;
if(a->ovf || b->ovf) {
warn("ovf in mpaddxx");
a->ovf = 1;
return;
}
c = 0;
a1 = &a->a[0];
b1 = &b->a[0];
if(a->neg != b->neg)
goto sub;
// perform a+b
for(i=0; i<Mpprec; i++) {
x = *a1 + *b1++ + c;
c = 0;
if(x >= Mpbase) {
x -= Mpbase;
c = 1;
}
*a1++ = x;
}
a->ovf = c;
if(a->ovf)
warn("set ovf in mpaddxx");
return;
sub:
// perform a-b
switch(mpcmp(a, b)) {
case 0:
mpmovecfix(a, 0);
break;
case 1:
for(i=0; i<Mpprec; i++) {
x = *a1 - *b1++ - c;
c = 0;
if(x < 0) {
x += Mpbase;
c = 1;
}
*a1++ = x;
}
break;
case -1:
a->neg ^= 1;
for(i=0; i<Mpprec; i++) {
x = *b1++ - *a1 - c;
c = 0;
if(x < 0) {
x += Mpbase;
c = 1;
}
*a1++ = x;
}
break;
}
}
void
mpmulfixfix(Mpint *a, Mpint *b)
{
int i, j, na, nb;
long *a1, x;
Mpint s, q;
if(a->ovf || b->ovf) {
warn("ovf in mpmulfixfix");
a->ovf = 1;
return;
}
// pick the smaller
// to test for bits
na = mplen(a);
nb = mplen(b);
if(na > nb) {
mpmovefixfix(&s, a);
a1 = &b->a[0];
na = nb;
} else {
mpmovefixfix(&s, b);
a1 = &a->a[0];
}
s.neg = 0;
mpmovecfix(&q, 0);
for(i=0; i<na; i++) {
x = *a1++;
for(j=0; j<Mpscale; j++) {
if(x & 1)
mpaddfixfix(&q, &s);
mplsh(&s);
x >>= 1;
}
}
q.neg = a->neg ^ b->neg;
mpmovefixfix(a, &q);
if(a->ovf)
warn("set ovf in mpmulfixfix");
}
void
mporfixfix(Mpint *a, Mpint *b)
{
int i;
long x, *a1, *b1;
if(a->ovf || b->ovf) {
warn("ovf in mporfixfix");
mpmovecfix(a, 0);
a->ovf = 1;
return;
}
if(a->neg) {
a->neg = 0;
mpneg(a);
}
if(b->neg)
mpneg(b);
a1 = &a->a[0];
b1 = &b->a[0];
for(i=0; i<Mpprec; i++) {
x = *a1;
*a1++ = x | *b1++;
}
if(b->neg)
mpneg(b);
if(x & Mpsign) {
a->neg = 1;
mpneg(a);
}
}
void
mpandfixfix(Mpint *a, Mpint *b)
{
int i;
long x, *a1, *b1;
if(a->ovf || b->ovf) {
warn("ovf in mpandfixfix");
mpmovecfix(a, 0);
a->ovf = 1;
return;
}
if(a->neg) {
a->neg = 0;
mpneg(a);
}
if(b->neg)
mpneg(b);
a1 = &a->a[0];
b1 = &b->a[0];
for(i=0; i<Mpprec; i++) {
x = *a1;
*a1++ = x & *b1++;
}
if(b->neg)
mpneg(b);
if(x & Mpsign) {
a->neg = 1;
mpneg(a);
}
}
void
mpxorfixfix(Mpint *a, Mpint *b)
{
int i;
long x, *a1, *b1;
if(a->ovf || b->ovf) {
warn("ovf in mporfixfix");
mpmovecfix(a, 0);
a->ovf = 1;
return;
}
if(a->neg) {
a->neg = 0;
mpneg(a);
}
if(b->neg)
mpneg(b);
a1 = &a->a[0];
b1 = &b->a[0];
for(i=0; i<Mpprec; i++) {
x = *a1;
*a1++ = x ^ *b1++;
}
if(b->neg)
mpneg(b);
if(x & Mpsign) {
a->neg = 1;
mpneg(a);
}
}
void
mplshfixfix(Mpint *a, Mpint *b)
{
vlong s;
if(a->ovf || b->ovf) {
warn("ovf in mporfixfix");
mpmovecfix(a, 0);
a->ovf = 1;
return;
}
s = mpgetfix(b);
if(s < 0 || s >= Mpprec*Mpscale) {
warn("stupid shift: %lld", s);
mpmovecfix(a, 0);
return;
}
while(s >= Mpscale) {
mplshw(a);
s -= Mpscale;
}
while(s > 0) {
mplsh(a);
s--;
}
}
void
mprshfixfix(Mpint *a, Mpint *b)
{
vlong s;
if(a->ovf || b->ovf) {
warn("ovf in mprshfixfix");
mpmovecfix(a, 0);
a->ovf = 1;
return;
}
s = mpgetfix(b);
if(s < 0 || s >= Mpprec*Mpscale) {
warn("stupid shift: %lld", s);
mpmovecfix(a, 0);
return;
}
while(s >= Mpscale) {
mprshw(a);
s -= Mpscale;
}
while(s > 0) {
mprsh(a);
s--;
}
}
void
mpnegfix(Mpint *a)
{
a->neg ^= 1;
}
vlong
mpgetfix(Mpint *a)
{
vlong v;
if(a->ovf) {
warn("ovf in mpgetfix");
return 0;
}
v = (vlong)a->a[0];
v |= (vlong)a->a[1] << Mpscale;
v |= (vlong)a->a[2] << (Mpscale+Mpscale);
if(a->neg)
v = -v;
return v;
}
void
mpmovecfix(Mpint *a, vlong c)
{
int i;
long *a1;
vlong x;
a->neg = 0;
a->ovf = 0;
x = c;
if(x < 0) {
a->neg = 1;
x = -x;
}
a1 = &a->a[0];
for(i=0; i<Mpprec; i++) {
*a1++ = x&Mpmask;
x >>= Mpscale;
}
}
void
mpdivmodfixfix(Mpint *q, Mpint *r, Mpint *n, Mpint *d)
{
int i, nn, dn;
mpmovefixfix(r, n);
mpmovecfix(q, 0);
// shift denominator until it
// is larger than numerator
for(i=0; i<Mpprec*Mpscale; i++) {
if(mpcmp(d, r) > 0)
break;
mplsh(d);
}
// if it never happens
// denominator is probably zero
if(i >= Mpprec*Mpscale) {
q->ovf = 1;
r->ovf = 1;
warn("set ovf in mpdivmodfixfix");
return;
}
// shift denominator back creating
// quotient a bit at a time
// when done the remaining numerator
// will be the remainder
for(; i>0; i--) {
mplsh(q);
mprsh(d);
if(mpcmp(d, r) <= 0) {
mpaddcfix(q, 1);
mpsubfixfix(r, d);
}
}
}
int
mptestfix(Mpint *a)
{
Mpint b;
int r;
mpmovecfix(&b, 0);
r = mpcmp(a, &b);
if(a->neg) {
if(r > 0)
return -1;
if(r < 0)
return +1;
}
return r;
}
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "go.h"
/// implements float arihmetic
void
mpaddfltflt(Mpflt *a, Mpflt *b)
{
a->val += b->val;
}
void
mpmulfltflt(Mpflt *a, Mpflt *b)
{
a->val *= b->val;
}
void
mpdivfltflt(Mpflt *a, Mpflt *b)
{
a->val /= b->val;
}
double
mpgetflt(Mpflt *a)
{
return a->val;
}
void
mpmovecflt(Mpflt *a, double c)
{
a->val = c;
}
void
mpnegflt(Mpflt *a)
{
a->val = -a->val;
}
int
mptestflt(Mpflt *a)
{
if(a->val < 0)
return -1;
if(a->val > 0)
return +1;
return 0;
}
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include <u.h>
#include <libc.h>
int mpatof(char*, double*);
int mpatov(char *s, vlong *v);
enum
{
Mpscale = 29, /* safely smaller than bits in a int32 */
Mpprec = 36, /* Mpscale*Mpprec sb > largest fp exp */
Mpbase = 1L<<Mpscale,
};
typedef
struct
{
int32 a[Mpprec];
char ovf;
} Mp;
static void mpint(Mp*, int);
static void mppow(Mp*, int, int);
static void mpmul(Mp*, int);
static void mpadd(Mp*, Mp*);
static int mptof(Mp*, double*);
/*
* convert a string, s, to floating in *d
* return conversion overflow.
* required syntax is [+-]d*[.]d*[e[+-]d*]
*/
int
mpatof(char *s, double *d)
{
Mp a, b;
int dp, c, f, ef, ex, zer;
double d1, d2;
dp = 0; /* digits after decimal point */
f = 0; /* sign */
ex = 0; /* exponent */
zer = 1; /* zero */
memset(&a, 0, sizeof(a));
for(;;) {
switch(c = *s++) {
default:
goto bad;
case '-':
f = 1;
case ' ':
case '\t':
case '+':
continue;
case '.':
dp = 1;
continue;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
zer = 0;
case '0':
mpint(&b, c-'0');
mpmul(&a, 10);
mpadd(&a, &b);
if(dp)
dp++;
continue;
case 'E':
case 'e':
ex = 0;
ef = 0;
for(;;) {
c = *s++;
if(c == '+' || c == ' ' || c == '\t')
continue;
if(c == '-') {
ef = 1;
continue;
}
if(c >= '0' && c <= '9') {
ex = ex*10 + (c-'0');
continue;
}
break;
}
if(ef)
ex = -ex;
case 0:
break;
}
break;
}
if(a.ovf)
goto bad;
if(zer) {
*d = 0;
return 0;
}
if(dp)
dp--;
dp -= ex;
if(dp > 0) {
/*
* must divide by 10**dp
*/
if(mptof(&a, &d1))
goto bad;
/*
* trial exponent of 8**dp
* 8 (being between 5 and 10)
* should pick up all underflows
* in the division of 5**dp.
*/
d2 = frexp(d1, &ex);
d2 = ldexp(d2, ex-3*dp);
if(d2 == 0)
goto bad;
/*
* decompose each 10 into 5*2.
* create 5**dp in fixed point
* and then play with the exponent
* for the remaining 2**dp.
* note that 5**dp will overflow
* with as few as 134 input digits.
*/
mpint(&a, 1);
mppow(&a, 5, dp);
if(mptof(&a, &d2))
goto bad;
d1 = frexp(d1/d2, &ex);
d1 = ldexp(d1, ex-dp);
if(d1 == 0)
goto bad;
} else {
/*
* must multiply by 10**|dp| --
* just do it in fixed point.
*/
mppow(&a, 10, -dp);
if(mptof(&a, &d1))
goto bad;
}
if(f)
d1 = -d1;
*d = d1;
return 0;
bad:
return 1;
}
/*
* convert a to floating in *d
* return conversion overflow
*/
static int
mptof(Mp *a, double *d)
{
double f, g;
int32 x, *a1;
int i;
if(a->ovf)
return 1;
a1 = a->a;
f = ldexp(*a1++, 0);
for(i=Mpscale; i<Mpprec*Mpscale; i+=Mpscale)
if(x = *a1++) {
g = ldexp(x, i);
/*
* NOTE: the test (g==0) is plan9
* specific. ansi compliant overflow
* is signaled by HUGE and errno==ERANGE.
* change this for your particular ldexp.
*/
if(g == 0)
return 1;
f += g; /* this could bomb! */
}
*d = f;
return 0;
}
/*
* return a += b
*/
static void
mpadd(Mp *a, Mp *b)
{
int i, c;
int32 x, *a1, *b1;
if(b->ovf)
a->ovf = 1;
if(a->ovf)
return;
c = 0;
a1 = a->a;
b1 = b->a;
for(i=0; i<Mpprec; i++) {
x = *a1 + *b1++ + c;
c = 0;
if(x >= Mpbase) {
x -= Mpbase;
c = 1;
}
*a1++ = x;
}
a->ovf = c;
}
/*
* return a = c
*/
static void
mpint(Mp *a, int c)
{
memset(a, 0, sizeof(*a));
a->a[0] = c;
}
/*
* return a *= c
*/
static void
mpmul(Mp *a, int c)
{
Mp p;
int b;
memmove(&p, a, sizeof(p));
if(!(c & 1))
memset(a, 0, sizeof(*a));
c &= ~1;
for(b=2; c; b<<=1) {
mpadd(&p, &p);
if(c & b) {
mpadd(a, &p);
c &= ~b;
}
}
}
/*
* return a *= b**e
*/
static void
mppow(Mp *a, int b, int e)
{
int b1;
b1 = b*b;
b1 = b1*b1;
while(e >= 4) {
mpmul(a, b1);
e -= 4;
if(a->ovf)
return;
}
while(e > 0) {
mpmul(a, b);
e--;
}
}
/*
* convert a string, s, to vlong in *v
* return conversion overflow.
* required syntax is [0[x]]d*
*/
int
mpatov(char *s, vlong *v)
{
vlong n, nn;
int c;
n = 0;
c = *s;
if(c == '0')
goto oct;
while(c = *s++) {
if(c >= '0' && c <= '9')
nn = n*10 + c-'0';
else
goto bad;
if(n < 0 && nn >= 0)
goto bad;
n = nn;
}
goto out;
oct:
s++;
c = *s;
if(c == 'x' || c == 'X')
goto hex;
while(c = *s++) {
if(c >= '0' || c <= '7')
nn = n*8 + c-'0';
else
goto bad;
if(n < 0 && nn >= 0)
goto bad;
n = nn;
}
goto out;
hex:
s++;
while(c = *s++) {
if(c >= '0' && c <= '9')
c += 0-'0';
else
if(c >= 'a' && c <= 'f')
c += 10-'a';
else
if(c >= 'A' && c <= 'F')
c += 10-'A';
else
goto bad;
nn = n*16 + c;
if(n < 0 && nn >= 0)
goto bad;
n = nn;
}
out:
*v = n;
return 0;
bad:
*v = ~0;
return 1;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment