mirror of https://github.com/golang/go.git
adding and deleting files
R=r DELTA=1685 (920 added, 765 deleted, 0 changed) OCL=14030 CL=14030
This commit is contained in:
parent
272ae659db
commit
091047f36c
|
|
@ -1,17 +1,19 @@
|
|||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// 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"
|
||||
|
||||
/// uses arihmetic
|
||||
|
||||
int
|
||||
mpcmpfixfix(Mpint *a, Mpint *b)
|
||||
{
|
||||
if(a->val > b->val)
|
||||
return +1;
|
||||
if(a->val < b->val)
|
||||
return -1;
|
||||
return 0;
|
||||
Mpint c;
|
||||
|
||||
mpmovefixfix(&c, a);
|
||||
mpsubfixfix(&c, b);
|
||||
return mptestfix(&c);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -26,188 +28,36 @@ mpcmpfixc(Mpint *b, vlong c)
|
|||
int
|
||||
mpcmpfltflt(Mpflt *a, Mpflt *b)
|
||||
{
|
||||
if(a->val > b->val)
|
||||
return +1;
|
||||
if(a->val < b->val)
|
||||
return -1;
|
||||
return 0;
|
||||
Mpflt c;
|
||||
|
||||
mpmovefltflt(&c, a);
|
||||
mpsubfltflt(&c, b);
|
||||
return mptestflt(&c);
|
||||
}
|
||||
|
||||
int
|
||||
mpcmpfltc(Mpint *b, double c)
|
||||
mpcmpfltc(Mpflt *b, double c)
|
||||
{
|
||||
Mpint a;
|
||||
Mpflt a;
|
||||
|
||||
mpmovecflt(&a, c);
|
||||
return mpcmpfltflt(&a, b);
|
||||
}
|
||||
|
||||
void
|
||||
mpaddfixfix(Mpint *a, Mpint *b)
|
||||
{
|
||||
a->val += b->val;
|
||||
}
|
||||
|
||||
void
|
||||
mpsubfixfix(Mpint *a, Mpint *b)
|
||||
{
|
||||
a->val -= b->val;
|
||||
}
|
||||
|
||||
void
|
||||
mpmulfixfix(Mpint *a, Mpint *b)
|
||||
{
|
||||
a->val *= b->val;
|
||||
}
|
||||
|
||||
void
|
||||
mpdivfixfix(Mpint *a, Mpint *b)
|
||||
{
|
||||
a->val /= b->val;
|
||||
}
|
||||
|
||||
void
|
||||
mpmodfixfix(Mpint *a, Mpint *b)
|
||||
{
|
||||
a->val %= b->val;
|
||||
}
|
||||
|
||||
void
|
||||
mporfixfix(Mpint *a, Mpint *b)
|
||||
{
|
||||
a->val |= b->val;
|
||||
}
|
||||
|
||||
void
|
||||
mpandfixfix(Mpint *a, Mpint *b)
|
||||
{
|
||||
a->val &= b->val;
|
||||
}
|
||||
|
||||
void
|
||||
mpxorfixfix(Mpint *a, Mpint *b)
|
||||
{
|
||||
a->val ^= b->val;
|
||||
}
|
||||
|
||||
void
|
||||
mplshfixfix(Mpint *a, Mpint *b)
|
||||
{
|
||||
a->val <<= b->val;
|
||||
}
|
||||
|
||||
void
|
||||
mprshfixfix(Mpint *a, Mpint *b)
|
||||
{
|
||||
a->val >>= b->val;
|
||||
}
|
||||
|
||||
void
|
||||
mpnegfix(Mpint *a)
|
||||
{
|
||||
a->val = -a->val;
|
||||
}
|
||||
|
||||
void
|
||||
mpcomfix(Mpint *a)
|
||||
{
|
||||
a->val = ~a->val;
|
||||
}
|
||||
|
||||
void
|
||||
mpaddfltflt(Mpflt *a, Mpflt *b)
|
||||
{
|
||||
a->val += b->val;
|
||||
mpnegfix(b);
|
||||
mpaddfixfix(a, b);
|
||||
mpnegfix(b);
|
||||
}
|
||||
|
||||
void
|
||||
mpsubfltflt(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;
|
||||
}
|
||||
|
||||
vlong
|
||||
mpgetfix(Mpint *a)
|
||||
{
|
||||
return a->val;
|
||||
}
|
||||
|
||||
double
|
||||
mpgetflt(Mpflt *a)
|
||||
{
|
||||
return a->val;
|
||||
}
|
||||
|
||||
void
|
||||
mpmovefixfix(Mpint *a, Mpint *b)
|
||||
{
|
||||
*a = *b;
|
||||
}
|
||||
|
||||
void
|
||||
mpmovefltflt(Mpflt *a, Mpflt *b)
|
||||
{
|
||||
*a = *b;
|
||||
}
|
||||
|
||||
void
|
||||
mpmovefixflt(Mpflt *a, Mpint *b)
|
||||
{
|
||||
a->val = b->val;
|
||||
}
|
||||
|
||||
void
|
||||
mpmovecfix(Mpint *a, vlong c)
|
||||
{
|
||||
a->val = c;
|
||||
}
|
||||
|
||||
void
|
||||
mpmovecflt(Mpflt *a, double c)
|
||||
{
|
||||
a->val = c;
|
||||
}
|
||||
|
||||
void
|
||||
mpmovefltfix(Mpint *a, Mpflt *b)
|
||||
{
|
||||
a->val = b->val;
|
||||
}
|
||||
|
||||
void
|
||||
mpnegflt(Mpflt *a)
|
||||
{
|
||||
a->val = -a->val;
|
||||
}
|
||||
|
||||
void
|
||||
mpaddcflt(Mpflt *a, double c)
|
||||
{
|
||||
Mpflt b;
|
||||
|
||||
mpmovecflt(&b, c);
|
||||
mpaddfltflt(a, &b);
|
||||
}
|
||||
|
||||
void
|
||||
mpmulcflt(Mpflt *a, double c)
|
||||
{
|
||||
Mpflt b;
|
||||
|
||||
mpmovecflt(&b, c);
|
||||
mpmulfltflt(a, &b);
|
||||
mpnegflt(b);
|
||||
mpaddfltflt(a, b);
|
||||
mpnegflt(b);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -219,6 +69,15 @@ mpaddcfix(Mpint *a, vlong c)
|
|||
mpaddfixfix(a, &b);
|
||||
}
|
||||
|
||||
void
|
||||
mpaddcflt(Mpflt *a, double c)
|
||||
{
|
||||
Mpflt b;
|
||||
|
||||
mpmovecflt(&b, c);
|
||||
mpaddfltflt(a, &b);
|
||||
}
|
||||
|
||||
void
|
||||
mpmulcfix(Mpint *a, vlong c)
|
||||
{
|
||||
|
|
@ -228,6 +87,67 @@ mpmulcfix(Mpint *a, vlong c)
|
|||
mpmulfixfix(a, &b);
|
||||
}
|
||||
|
||||
void
|
||||
mpmulcflt(Mpflt *a, double c)
|
||||
{
|
||||
Mpflt b;
|
||||
|
||||
mpmovecflt(&b, c);
|
||||
mpmulfltflt(a, &b);
|
||||
}
|
||||
|
||||
void
|
||||
mpdivfixfix(Mpint *a, Mpint *b)
|
||||
{
|
||||
Mpint q, r;
|
||||
|
||||
mpdivmodfixfix(&q, &r, a, b);
|
||||
mpmovefixfix(a, &q);
|
||||
}
|
||||
|
||||
void
|
||||
mpmodfixfix(Mpint *a, Mpint *b)
|
||||
{
|
||||
Mpint q, r;
|
||||
|
||||
mpdivmodfixfix(&q, &r, a, b);
|
||||
mpmovefixfix(a, &r);
|
||||
}
|
||||
|
||||
void
|
||||
mpcomfix(Mpint *a)
|
||||
{
|
||||
Mpint b;
|
||||
|
||||
mpmovecfix(&b, 1);
|
||||
mpnegfix(a);
|
||||
mpsubfixfix(a, &b);
|
||||
}
|
||||
|
||||
void
|
||||
mpmovefixflt(Mpflt *a, Mpint *b)
|
||||
{
|
||||
mpmovecflt(a, mpgetfix(b));
|
||||
}
|
||||
|
||||
void
|
||||
mpmovefltfix(Mpint *a, Mpflt *b)
|
||||
{
|
||||
mpmovecfix(a, mpgetflt(b));
|
||||
}
|
||||
|
||||
void
|
||||
mpmovefixfix(Mpint *a, Mpint *b)
|
||||
{
|
||||
*a = *b;
|
||||
}
|
||||
|
||||
void
|
||||
mpmovefltflt(Mpflt *a, Mpflt *b)
|
||||
{
|
||||
*a = *b;
|
||||
}
|
||||
|
||||
//
|
||||
// power of ten
|
||||
//
|
||||
|
|
@ -265,7 +185,7 @@ mpatoflt(Mpflt *a, char *as)
|
|||
ex = 0; /* exponent */
|
||||
zer = 1; /* zero */
|
||||
|
||||
mpmovecflt(a, 0);
|
||||
mpmovecflt(a, 0.0);
|
||||
for(;;) {
|
||||
switch(c = *s++) {
|
||||
default:
|
||||
|
|
@ -348,7 +268,6 @@ bad:
|
|||
void
|
||||
mpatofix(Mpint *a, char *as)
|
||||
{
|
||||
|
||||
int c, f;
|
||||
char *s;
|
||||
|
||||
|
|
@ -0,0 +1,529 @@
|
|||
// 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;
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
// 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;
|
||||
}
|
||||
|
|
@ -1,342 +0,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;
|
||||
}
|
||||
Loading…
Reference in New Issue