1
0
mirror of https://github.com/golang/go synced 2024-10-01 16:18:32 -06:00

cmd/internal/gc: use big.Int to represent Mpint bits

- renamed (existing) Mpint -> Mpfix
- defined (new) Mpint using big.Int
- modified funcs mpxxx operating on new Mpint
- renamed funcs mpxxx -> _mpxxx if still needed with Mpfix
- left old (possibly unused) code in place for comparison

Passes all.bash.

Change-Id: I1fc7bba7dc4b6386f2f0950d745cec17c1e67615

cmd/internal/gc: renamed Mpint -> Mpfix

Change-Id: Ia06aeae1081ef29d5ad9b711fb57e4c5579ce29b
Reviewed-on: https://go-review.googlesource.com/7830
Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
Robert Griesemer 2015-03-18 14:10:22 -07:00
parent 653426f08f
commit 888767fcc4
5 changed files with 476 additions and 130 deletions

View File

@ -7,6 +7,7 @@ package gc
import ( import (
"bytes" "bytes"
"cmd/internal/obj" "cmd/internal/obj"
"math/big"
) )
// avoid <ctype.h> // avoid <ctype.h>
@ -65,14 +66,22 @@ const (
Mpdebug = 0 Mpdebug = 0
) )
// Mpint represents an integer constant.
type Mpint struct { type Mpint struct {
Val big.Int
Ovf bool // set if Val overflowed compiler limit (sticky)
}
// Mpfix is the original (old) representation of an integer constant.
// Still needed for Mpflt.
type Mpfix struct {
A [Mpprec]int A [Mpprec]int
Neg uint8 Neg uint8
Ovf uint8 Ovf uint8
} }
type Mpflt struct { type Mpflt struct {
Val Mpint Val Mpfix
Exp int16 Exp int16
} }

View File

@ -1401,7 +1401,7 @@ ncu:
str = lexbuf.String() str = lexbuf.String()
yylval.val.U.Xval = new(Mpint) yylval.val.U.Xval = new(Mpint)
mpatofix(yylval.val.U.Xval, str) mpatofix(yylval.val.U.Xval, str)
if yylval.val.U.Xval.Ovf != 0 { if yylval.val.U.Xval.Ovf {
Yyerror("overflow in constant") Yyerror("overflow in constant")
Mpmovecfix(yylval.val.U.Xval, 0) Mpmovecfix(yylval.val.U.Xval, 0)
} }

View File

@ -8,39 +8,48 @@ import (
"cmd/internal/obj" "cmd/internal/obj"
"fmt" "fmt"
"math" "math"
"math/big"
) )
/// uses arithmetic /// uses arithmetic
func mpcmpfixflt(a *Mpint, b *Mpflt) int { func mpcmpfixflt(a *Mpfix, b *Mpflt) int {
var c Mpflt var c Mpflt
buf := Bconv(a, 0) buf := _Bconv(a, 0)
mpatoflt(&c, buf) mpatoflt(&c, buf)
return mpcmpfltflt(&c, b) return mpcmpfltflt(&c, b)
} }
func mpcmpfltfix(a *Mpflt, b *Mpint) int { func mpcmpfltfix(a *Mpflt, b *Mpfix) int {
var c Mpflt var c Mpflt
buf := Bconv(b, 0) buf := _Bconv(b, 0)
mpatoflt(&c, buf) mpatoflt(&c, buf)
return mpcmpfltflt(a, &c) return mpcmpfltflt(a, &c)
} }
func Mpcmpfixfix(a *Mpint, b *Mpint) int { func Mpcmpfixfix(a, b *Mpint) int {
var c Mpint return a.Val.Cmp(&b.Val)
}
mpmovefixfix(&c, a) func _Mpcmpfixfix(a *Mpfix, b *Mpfix) int {
mpsubfixfix(&c, b) var c Mpfix
_mpmovefixfix(&c, a)
_mpsubfixfix(&c, b)
return mptestfix(&c) return mptestfix(&c)
} }
func mpcmpfixc(b *Mpint, c int64) int { func mpcmpfixc(b *Mpint, c int64) int {
var c1 Mpint return b.Val.Cmp(big.NewInt(c))
}
Mpmovecfix(&c1, c) func _mpcmpfixc(b *Mpfix, c int64) int {
return Mpcmpfixfix(b, &c1) var c1 Mpfix
_Mpmovecfix(&c1, c)
return _Mpcmpfixfix(b, &c1)
} }
func mpcmpfltflt(a *Mpflt, b *Mpflt) int { func mpcmpfltflt(a *Mpflt, b *Mpflt) int {
@ -58,10 +67,14 @@ func mpcmpfltc(b *Mpflt, c float64) int {
return mpcmpfltflt(b, &a) return mpcmpfltflt(b, &a)
} }
func mpsubfixfix(a *Mpint, b *Mpint) { func mpsubfixfix(a, b *Mpint) {
mpnegfix(a) a.Val.Sub(&a.Val, &b.Val)
mpaddfixfix(a, b, 0) }
mpnegfix(a)
func _mpsubfixfix(a *Mpfix, b *Mpfix) {
_mpnegfix(a)
_mpaddfixfix(a, b, 0)
_mpnegfix(a)
} }
func mpsubfltflt(a *Mpflt, b *Mpflt) { func mpsubfltflt(a *Mpflt, b *Mpflt) {
@ -70,11 +83,11 @@ func mpsubfltflt(a *Mpflt, b *Mpflt) {
mpnegflt(a) mpnegflt(a)
} }
func mpaddcfix(a *Mpint, c int64) { func mpaddcfix(a *Mpfix, c int64) {
var b Mpint var b Mpfix
Mpmovecfix(&b, c) _Mpmovecfix(&b, c)
mpaddfixfix(a, &b, 0) _mpaddfixfix(a, &b, 0)
} }
func mpaddcflt(a *Mpflt, c float64) { func mpaddcflt(a *Mpflt, c float64) {
@ -84,11 +97,11 @@ func mpaddcflt(a *Mpflt, c float64) {
mpaddfltflt(a, &b) mpaddfltflt(a, &b)
} }
func mpmulcfix(a *Mpint, c int64) { func mpmulcfix(a *Mpfix, c int64) {
var b Mpint var b Mpfix
Mpmovecfix(&b, c) _Mpmovecfix(&b, c)
mpmulfixfix(a, &b) _mpmulfixfix(a, &b)
} }
func mpmulcflt(a *Mpflt, c float64) { func mpmulcflt(a *Mpflt, c float64) {
@ -98,41 +111,136 @@ func mpmulcflt(a *Mpflt, c float64) {
mpmulfltflt(a, &b) mpmulfltflt(a, &b)
} }
func mpdivfixfix(a *Mpint, b *Mpint) { func mpdivfixfix(a, b *Mpint) {
var q Mpint a.Val.Quo(&a.Val, &b.Val)
var r Mpint
mpdivmodfixfix(&q, &r, a, b)
mpmovefixfix(a, &q)
} }
func mpmodfixfix(a *Mpint, b *Mpint) { func _mpdivfixfix(a *Mpfix, b *Mpfix) {
var q Mpint var q Mpfix
var r Mpint var r Mpfix
mpdivmodfixfix(&q, &r, a, b) mpdivmodfixfix(&q, &r, a, b)
mpmovefixfix(a, &r) _mpmovefixfix(a, &q)
} }
func mpcomfix(a *Mpint) { func mpmodfixfix(a, b *Mpint) {
var b Mpint a.Val.Rem(&a.Val, &b.Val)
}
Mpmovecfix(&b, 1) func _mpmodfixfix(a *Mpfix, b *Mpfix) {
mpnegfix(a) var q Mpfix
mpsubfixfix(a, &b) var r Mpfix
mpdivmodfixfix(&q, &r, a, b)
_mpmovefixfix(a, &r)
}
func mpcomfix(a *Mpfix) {
var b Mpfix
_Mpmovecfix(&b, 1)
_mpnegfix(a)
_mpsubfixfix(a, &b)
}
// *a = Mpfix(*b)
func mpmoveintfix(a *Mpfix, b *Mpint) {
if b.Ovf {
_Mpmovecfix(a, 0)
a.Ovf = 1
return
}
var bb big.Int
bb.Abs(&b.Val)
i := 0
for ; i < Mpprec && bb.Sign() != 0; i++ {
// depends on (unspecified) behavior of Int.Uint64
a.A[i] = int(bb.Uint64() & Mpmask)
bb.Rsh(&bb, Mpscale)
}
if bb.Sign() != 0 {
// MPint overflows
_Mpmovecfix(a, 0)
a.Ovf = 1
return
}
for ; i < Mpprec; i++ {
a.A[i] = 0
}
a.Neg = 0
if b.Val.Sign() < 0 {
a.Neg = 1
}
a.Ovf = 0
// leave for debugging
// println("mpmoveintfix:", b.Val.String(), "->", _Bconv(a, 0))
}
// *a = big.Int(*b)
func mpmovefixint(a *Mpint, b *Mpfix) {
if b.Ovf != 0 {
mpsetovf(a)
return
}
i := Mpprec - 1
for ; i >= 0 && b.A[i] == 0; i-- {
}
a.Val.SetUint64(0)
var x big.Int
for ; i >= 0; i-- {
a.Val.Lsh(&a.Val, Mpscale)
a.Val.Or(&a.Val, x.SetUint64(uint64(b.A[i]&Mpmask)))
}
if b.Neg != 0 {
a.Val.Neg(&a.Val)
}
a.Ovf = false
// leave for debugging
// println("mpmovefixint:", _Bconv(b, 0), "->", a.Val.String())
} }
func Mpmovefixflt(a *Mpflt, b *Mpint) { func Mpmovefixflt(a *Mpflt, b *Mpint) {
mpmoveintfix(&a.Val, b) // a.Val = *b
a.Exp = 0
mpnorm(a)
}
func _Mpmovefixflt(a *Mpflt, b *Mpfix) {
a.Val = *b a.Val = *b
a.Exp = 0 a.Exp = 0
mpnorm(a) mpnorm(a)
} }
func mpexactfltfix(a *Mpint, b *Mpflt) int {
mpmovefixint(a, &b.Val) // *a = b.Val
Mpshiftfix(a, int(b.Exp))
if b.Exp < 0 {
var f Mpflt
mpmoveintfix(&f.Val, a) // f.Val = *a
f.Exp = 0
mpnorm(&f)
if mpcmpfltflt(b, &f) != 0 {
return -1
}
}
return 0
}
// convert (truncate) b to a. // convert (truncate) b to a.
// return -1 (but still convert) if b was non-integer. // return -1 (but still convert) if b was non-integer.
func mpexactfltfix(a *Mpint, b *Mpflt) int { func _mpexactfltfix(a *Mpfix, b *Mpflt) int {
*a = b.Val *a = b.Val
Mpshiftfix(a, int(b.Exp)) _Mpshiftfix(a, int(b.Exp))
if b.Exp < 0 { if b.Exp < 0 {
var f Mpflt var f Mpflt
f.Val = *a f.Val = *a
@ -176,7 +284,41 @@ func mpmovefltfix(a *Mpint, b *Mpflt) int {
return -1 return -1
} }
func mpmovefixfix(a *Mpint, b *Mpint) { func _mpmovefltfix(a *Mpfix, b *Mpflt) int {
if _mpexactfltfix(a, b) == 0 {
return 0
}
// try rounding down a little
f := *b
f.Val.A[0] = 0
if _mpexactfltfix(a, &f) == 0 {
return 0
}
// try rounding up a little
for i := 1; i < Mpprec; i++ {
f.Val.A[i]++
if f.Val.A[i] != Mpbase {
break
}
f.Val.A[i] = 0
}
mpnorm(&f)
if _mpexactfltfix(a, &f) == 0 {
return 0
}
return -1
}
func mpmovefixfix(a, b *Mpint) {
a.Val.Set(&b.Val)
}
func _mpmovefixfix(a *Mpfix, b *Mpfix) {
*a = *b *a = *b
} }
@ -202,7 +344,7 @@ func mppow10flt(a *Mpflt, p int) {
} }
} }
func mphextofix(a *Mpint, s string) { func mphextofix(a *Mpfix, s string) {
for s != "" && s[0] == '0' { for s != "" && s[0] == '0' {
s = s[1:] s = s[1:]
} }
@ -445,16 +587,35 @@ bad:
Mpmovecflt(a, 0.0) Mpmovecflt(a, 0.0)
} }
func mpatofix(a *Mpint, as string) {
_, ok := a.Val.SetString(as, 0)
if !ok {
// required syntax is [+-][0[x]]d*
// At the moment we lose precise error cause;
// the old code distinguished between:
// - malformed hex constant
// - malformed octal constant
// - malformed decimal constant
// TODO(gri) use different conversion function
Yyerror("malformed integer constant: %s", as)
a.Val.SetUint64(0)
return
}
if mptestovf(a, 0) {
Yyerror("constant too large: %s", as)
}
}
// //
// fixed point input // fixed point input
// required syntax is [+-][0[x]]d* // required syntax is [+-][0[x]]d*
// //
func mpatofix(a *Mpint, as string) { func _mpatofix(a *Mpfix, as string) {
var c int var c int
s := as s := as
f := 0 f := 0
Mpmovecfix(a, 0) _Mpmovecfix(a, 0)
c, s = intstarstringplusplus(s) c, s = intstarstringplusplus(s)
switch c { switch c {
@ -525,36 +686,43 @@ func mpatofix(a *Mpint, as string) {
out: out:
if f != 0 { if f != 0 {
mpnegfix(a) _mpnegfix(a)
} }
return return
bad: bad:
Mpmovecfix(a, 0) _Mpmovecfix(a, 0)
} }
func Bconv(xval *Mpint, flag int) string { func Bconv(xval *Mpint, flag int) string {
var q Mpint if flag&obj.FmtSharp != 0 {
return fmt.Sprintf("%#x", &xval.Val)
}
return xval.Val.String()
}
mpmovefixfix(&q, xval) func _Bconv(xval *Mpfix, flag int) string {
var q Mpfix
_mpmovefixfix(&q, xval)
f := 0 f := 0
if mptestfix(&q) < 0 { if mptestfix(&q) < 0 {
f = 1 f = 1
mpnegfix(&q) _mpnegfix(&q)
} }
var buf [500]byte var buf [500]byte
p := len(buf) p := len(buf)
var r Mpint var r Mpfix
if flag&obj.FmtSharp != 0 /*untyped*/ { if flag&obj.FmtSharp != 0 /*untyped*/ {
// Hexadecimal // Hexadecimal
var sixteen Mpint var sixteen Mpfix
Mpmovecfix(&sixteen, 16) _Mpmovecfix(&sixteen, 16)
var digit int var digit int
for { for {
mpdivmodfixfix(&q, &r, &q, &sixteen) mpdivmodfixfix(&q, &r, &q, &sixteen)
digit = int(Mpgetfix(&r)) digit = int(_Mpgetfix(&r))
if digit < 10 { if digit < 10 {
p-- p--
buf[p] = byte(digit + '0') buf[p] = byte(digit + '0')
@ -573,13 +741,13 @@ func Bconv(xval *Mpint, flag int) string {
buf[p] = '0' buf[p] = '0'
} else { } else {
// Decimal // Decimal
var ten Mpint var ten Mpfix
Mpmovecfix(&ten, 10) _Mpmovecfix(&ten, 10)
for { for {
mpdivmodfixfix(&q, &r, &q, &ten) mpdivmodfixfix(&q, &r, &q, &ten)
p-- p--
buf[p] = byte(Mpgetfix(&r) + '0') buf[p] = byte(_Mpgetfix(&r) + '0')
if mptestfix(&q) <= 0 { if mptestfix(&q) <= 0 {
break break
} }
@ -646,21 +814,21 @@ func Fconv(fvp *Mpflt, flag int) string {
fv = *fvp fv = *fvp
for fv.Val.A[0] == 0 { for fv.Val.A[0] == 0 {
Mpshiftfix(&fv.Val, -Mpscale) _Mpshiftfix(&fv.Val, -Mpscale)
fv.Exp += Mpscale fv.Exp += Mpscale
} }
for fv.Val.A[0]&1 == 0 { for fv.Val.A[0]&1 == 0 {
Mpshiftfix(&fv.Val, -1) _Mpshiftfix(&fv.Val, -1)
fv.Exp += 1 fv.Exp += 1
} }
if fv.Exp >= 0 { if fv.Exp >= 0 {
buf = fmt.Sprintf("%vp+%d", Bconv(&fv.Val, obj.FmtSharp), fv.Exp) buf = fmt.Sprintf("%vp+%d", _Bconv(&fv.Val, obj.FmtSharp), fv.Exp)
goto out goto out
} }
buf = fmt.Sprintf("%vp-%d", Bconv(&fv.Val, obj.FmtSharp), -fv.Exp) buf = fmt.Sprintf("%vp-%d", _Bconv(&fv.Val, obj.FmtSharp), -fv.Exp)
out: out:
var fp string var fp string

View File

@ -8,7 +8,7 @@ package gc
// return the significant // return the significant
// words of the argument // words of the argument
// //
func mplen(a *Mpint) int { func mplen(a *Mpfix) int {
n := -1 n := -1
for i := 0; i < Mpprec; i++ { for i := 0; i < Mpprec; i++ {
if a.A[i] != 0 { if a.A[i] != 0 {
@ -23,7 +23,7 @@ func mplen(a *Mpint) int {
// left shift mpint by one // left shift mpint by one
// ignores sign // ignores sign
// //
func mplsh(a *Mpint, quiet int) { func mplsh(a *Mpfix, quiet int) {
var x int var x int
c := 0 c := 0
@ -48,7 +48,7 @@ func mplsh(a *Mpint, quiet int) {
// left shift mpint by Mpscale // left shift mpint by Mpscale
// ignores sign // ignores sign
// //
func mplshw(a *Mpint, quiet int) { func mplshw(a *Mpfix, quiet int) {
i := Mpprec - 1 i := Mpprec - 1
if a.A[i] != 0 { if a.A[i] != 0 {
a.Ovf = 1 a.Ovf = 1
@ -67,7 +67,7 @@ func mplshw(a *Mpint, quiet int) {
// right shift mpint by one // right shift mpint by one
// ignores sign and overflow // ignores sign and overflow
// //
func mprsh(a *Mpint) { func mprsh(a *Mpfix) {
var x int var x int
c := 0 c := 0
@ -90,7 +90,7 @@ func mprsh(a *Mpint) {
// right shift mpint by Mpscale // right shift mpint by Mpscale
// ignores sign and overflow // ignores sign and overflow
// //
func mprshw(a *Mpint) { func mprshw(a *Mpfix) {
var i int var i int
lo := a.A[0] lo := a.A[0]
@ -107,7 +107,7 @@ func mprshw(a *Mpint) {
// //
// return the sign of (abs(a)-abs(b)) // return the sign of (abs(a)-abs(b))
// //
func mpcmp(a *Mpint, b *Mpint) int { func mpcmp(a *Mpfix, b *Mpfix) int {
if a.Ovf != 0 || b.Ovf != 0 { if a.Ovf != 0 || b.Ovf != 0 {
if nsavederrors+nerrors == 0 { if nsavederrors+nerrors == 0 {
Yyerror("ovf in cmp") Yyerror("ovf in cmp")
@ -133,7 +133,7 @@ func mpcmp(a *Mpint, b *Mpint) int {
// negate a // negate a
// ignore sign and ovf // ignore sign and ovf
// //
func mpneg(a *Mpint) { func mpneg(a *Mpfix) {
var x int var x int
c := 0 c := 0
@ -149,8 +149,21 @@ func mpneg(a *Mpint) {
} }
} }
// shift left by s (or right by -s)
func Mpshiftfix(a *Mpint, s int) { func Mpshiftfix(a *Mpint, s int) {
switch {
case s > 0:
if mptestovf(a, s) {
Yyerror("constant shift overflow")
return
}
a.Val.Lsh(&a.Val, uint(s))
case s < 0:
a.Val.Rsh(&a.Val, uint(-s))
}
}
// shift left by s (or right by -s)
func _Mpshiftfix(a *Mpfix, s int) {
if s >= 0 { if s >= 0 {
for s >= Mpscale { for s >= Mpscale {
mplshw(a, 0) mplshw(a, 0)
@ -175,9 +188,40 @@ func Mpshiftfix(a *Mpint, s int) {
} }
} }
/// implements fix arihmetic /// implements fix arithmetic
func mpaddfixfix(a *Mpint, b *Mpint, quiet int) { func mpsetovf(a *Mpint) {
a.Val.SetUint64(0)
a.Ovf = true
}
func mptestovf(a *Mpint, extra int) bool {
// We don't need to be precise here, any reasonable upper limit would do.
// For now, use existing limit so we pass all the tests unchanged.
const limit = Mpscale * Mpprec
if a.Val.BitLen()+extra > limit {
mpsetovf(a)
}
return a.Ovf
}
func mpaddfixfix(a, b *Mpint, quiet int) {
if a.Ovf || b.Ovf {
if nsavederrors+nerrors == 0 {
Yyerror("ovf in mpaddxx")
}
mpsetovf(a)
return
}
a.Val.Add(&a.Val, &b.Val)
if mptestovf(a, 0) && quiet == 0 {
Yyerror("constant addition overflow")
}
}
func _mpaddfixfix(a *Mpfix, b *Mpfix, quiet int) {
if a.Ovf != 0 || b.Ovf != 0 { if a.Ovf != 0 || b.Ovf != 0 {
if nsavederrors+nerrors == 0 { if nsavederrors+nerrors == 0 {
Yyerror("ovf in mpaddxx") Yyerror("ovf in mpaddxx")
@ -191,7 +235,7 @@ func mpaddfixfix(a *Mpint, b *Mpint, quiet int) {
// perform a-b // perform a-b
switch mpcmp(a, b) { switch mpcmp(a, b) {
case 0: case 0:
Mpmovecfix(a, 0) _Mpmovecfix(a, 0)
case 1: case 1:
var x int var x int
@ -244,7 +288,23 @@ func mpaddfixfix(a *Mpint, b *Mpint, quiet int) {
return return
} }
func mpmulfixfix(a *Mpint, b *Mpint) { func mpmulfixfix(a, b *Mpint) {
if a.Ovf || b.Ovf {
if nsavederrors+nerrors == 0 {
Yyerror("ovf in mpmulfixfix")
}
mpsetovf(a)
return
}
a.Val.Mul(&a.Val, &b.Val)
if mptestovf(a, 0) {
Yyerror("constant multiplication overflow")
}
}
func _mpmulfixfix(a *Mpfix, b *Mpfix) {
if a.Ovf != 0 || b.Ovf != 0 { if a.Ovf != 0 || b.Ovf != 0 {
if nsavederrors+nerrors == 0 { if nsavederrors+nerrors == 0 {
Yyerror("ovf in mpmulfixfix") Yyerror("ovf in mpmulfixfix")
@ -258,21 +318,21 @@ func mpmulfixfix(a *Mpint, b *Mpint) {
na := mplen(a) na := mplen(a)
nb := mplen(b) nb := mplen(b)
var s Mpint var s Mpfix
var c *Mpint var c *Mpfix
if na > nb { if na > nb {
mpmovefixfix(&s, a) _mpmovefixfix(&s, a)
c = b c = b
na = nb na = nb
} else { } else {
mpmovefixfix(&s, b) _mpmovefixfix(&s, b)
c = a c = a
} }
s.Neg = 0 s.Neg = 0
var q Mpint var q Mpfix
Mpmovecfix(&q, 0) _Mpmovecfix(&q, 0)
var j int var j int
var x int var x int
for i := 0; i < na; i++ { for i := 0; i < na; i++ {
@ -284,7 +344,7 @@ func mpmulfixfix(a *Mpint, b *Mpint) {
goto out goto out
} }
mpaddfixfix(&q, &s, 1) _mpaddfixfix(&q, &s, 1)
if q.Ovf != 0 { if q.Ovf != 0 {
goto out goto out
} }
@ -297,13 +357,13 @@ func mpmulfixfix(a *Mpint, b *Mpint) {
out: out:
q.Neg = a.Neg ^ b.Neg q.Neg = a.Neg ^ b.Neg
mpmovefixfix(a, &q) _mpmovefixfix(a, &q)
if a.Ovf != 0 { if a.Ovf != 0 {
Yyerror("constant multiplication overflow") Yyerror("constant multiplication overflow")
} }
} }
func mpmulfract(a *Mpint, b *Mpint) { func mpmulfract(a *Mpfix, b *Mpfix) {
if a.Ovf != 0 || b.Ovf != 0 { if a.Ovf != 0 || b.Ovf != 0 {
if nsavederrors+nerrors == 0 { if nsavederrors+nerrors == 0 {
Yyerror("ovf in mpmulflt") Yyerror("ovf in mpmulflt")
@ -312,11 +372,11 @@ func mpmulfract(a *Mpint, b *Mpint) {
return return
} }
var s Mpint var s Mpfix
mpmovefixfix(&s, b) _mpmovefixfix(&s, b)
s.Neg = 0 s.Neg = 0
var q Mpint var q Mpfix
Mpmovecfix(&q, 0) _Mpmovecfix(&q, 0)
i := Mpprec - 1 i := Mpprec - 1
x := a.A[i] x := a.A[i]
@ -335,26 +395,38 @@ func mpmulfract(a *Mpint, b *Mpint) {
for j = 0; j < Mpscale; j++ { for j = 0; j < Mpscale; j++ {
x <<= 1 x <<= 1
if x&Mpbase != 0 { if x&Mpbase != 0 {
mpaddfixfix(&q, &s, 1) _mpaddfixfix(&q, &s, 1)
} }
mprsh(&s) mprsh(&s)
} }
} }
q.Neg = a.Neg ^ b.Neg q.Neg = a.Neg ^ b.Neg
mpmovefixfix(a, &q) _mpmovefixfix(a, &q)
if a.Ovf != 0 { if a.Ovf != 0 {
Yyerror("constant multiplication overflow") Yyerror("constant multiplication overflow")
} }
} }
func mporfixfix(a *Mpint, b *Mpint) { func mporfixfix(a, b *Mpint) {
if a.Ovf || b.Ovf {
if nsavederrors+nerrors == 0 {
Yyerror("ovf in mporfixfix")
}
mpsetovf(a)
return
}
a.Val.Or(&a.Val, &b.Val)
}
func _mporfixfix(a *Mpfix, b *Mpfix) {
x := 0 x := 0
if a.Ovf != 0 || b.Ovf != 0 { if a.Ovf != 0 || b.Ovf != 0 {
if nsavederrors+nerrors == 0 { if nsavederrors+nerrors == 0 {
Yyerror("ovf in mporfixfix") Yyerror("ovf in mporfixfix")
} }
Mpmovecfix(a, 0) _Mpmovecfix(a, 0)
a.Ovf = 1 a.Ovf = 1
return return
} }
@ -382,13 +454,25 @@ func mporfixfix(a *Mpint, b *Mpint) {
} }
} }
func mpandfixfix(a *Mpint, b *Mpint) { func mpandfixfix(a, b *Mpint) {
if a.Ovf || b.Ovf {
if nsavederrors+nerrors == 0 {
Yyerror("ovf in mpandfixfix")
}
mpsetovf(a)
return
}
a.Val.And(&a.Val, &b.Val)
}
func _mpandfixfix(a *Mpfix, b *Mpfix) {
x := 0 x := 0
if a.Ovf != 0 || b.Ovf != 0 { if a.Ovf != 0 || b.Ovf != 0 {
if nsavederrors+nerrors == 0 { if nsavederrors+nerrors == 0 {
Yyerror("ovf in mpandfixfix") Yyerror("ovf in mpandfixfix")
} }
Mpmovecfix(a, 0) _Mpmovecfix(a, 0)
a.Ovf = 1 a.Ovf = 1
return return
} }
@ -416,13 +500,25 @@ func mpandfixfix(a *Mpint, b *Mpint) {
} }
} }
func mpandnotfixfix(a *Mpint, b *Mpint) { func mpandnotfixfix(a, b *Mpint) {
if a.Ovf || b.Ovf {
if nsavederrors+nerrors == 0 {
Yyerror("ovf in mpandnotfixfix")
}
mpsetovf(a)
return
}
a.Val.AndNot(&a.Val, &b.Val)
}
func _mpandnotfixfix(a *Mpfix, b *Mpfix) {
x := 0 x := 0
if a.Ovf != 0 || b.Ovf != 0 { if a.Ovf != 0 || b.Ovf != 0 {
if nsavederrors+nerrors == 0 { if nsavederrors+nerrors == 0 {
Yyerror("ovf in mpandnotfixfix") Yyerror("ovf in mpandnotfixfix")
} }
Mpmovecfix(a, 0) _Mpmovecfix(a, 0)
a.Ovf = 1 a.Ovf = 1
return return
} }
@ -450,13 +546,25 @@ func mpandnotfixfix(a *Mpint, b *Mpint) {
} }
} }
func mpxorfixfix(a *Mpint, b *Mpint) { func mpxorfixfix(a, b *Mpint) {
if a.Ovf || b.Ovf {
if nsavederrors+nerrors == 0 {
Yyerror("ovf in mpxorfixfix")
}
mpsetovf(a)
return
}
a.Val.Xor(&a.Val, &b.Val)
}
func _mpxorfixfix(a *Mpfix, b *Mpfix) {
x := 0 x := 0
if a.Ovf != 0 || b.Ovf != 0 { if a.Ovf != 0 || b.Ovf != 0 {
if nsavederrors+nerrors == 0 { if nsavederrors+nerrors == 0 {
Yyerror("ovf in mporfixfix") Yyerror("ovf in mporfixfix")
} }
Mpmovecfix(a, 0) _Mpmovecfix(a, 0)
a.Ovf = 1 a.Ovf = 1
return return
} }
@ -484,13 +592,12 @@ func mpxorfixfix(a *Mpint, b *Mpint) {
} }
} }
func mplshfixfix(a *Mpint, b *Mpint) { func mplshfixfix(a, b *Mpint) {
if a.Ovf != 0 || b.Ovf != 0 { if a.Ovf || b.Ovf {
if nsavederrors+nerrors == 0 { if nsavederrors+nerrors == 0 {
Yyerror("ovf in mporfixfix") Yyerror("ovf in mplshfixfix")
} }
Mpmovecfix(a, 0) mpsetovf(a)
a.Ovf = 1
return return
} }
@ -504,20 +611,39 @@ func mplshfixfix(a *Mpint, b *Mpint) {
Mpshiftfix(a, int(s)) Mpshiftfix(a, int(s))
} }
func mprshfixfix(a *Mpint, b *Mpint) { func _mplshfixfix(a *Mpfix, b *Mpfix) {
if a.Ovf != 0 || b.Ovf != 0 { if a.Ovf != 0 || b.Ovf != 0 {
if nsavederrors+nerrors == 0 {
Yyerror("ovf in mplshfixfix")
}
_Mpmovecfix(a, 0)
a.Ovf = 1
return
}
s := _Mpgetfix(b)
if s < 0 || s >= Mpprec*Mpscale {
Yyerror("stupid shift: %d", s)
_Mpmovecfix(a, 0)
return
}
_Mpshiftfix(a, int(s))
}
func mprshfixfix(a, b *Mpint) {
if a.Ovf || b.Ovf {
if nsavederrors+nerrors == 0 { if nsavederrors+nerrors == 0 {
Yyerror("ovf in mprshfixfix") Yyerror("ovf in mprshfixfix")
} }
Mpmovecfix(a, 0) mpsetovf(a)
a.Ovf = 1
return return
} }
s := Mpgetfix(b) s := Mpgetfix(b)
if s < 0 || s >= Mpprec*Mpscale { if s < 0 || s >= Mpprec*Mpscale {
Yyerror("stupid shift: %d", s) Yyerror("stupid shift: %d", s)
if a.Neg != 0 { if a.Val.Sign() < 0 {
Mpmovecfix(a, -1) Mpmovecfix(a, -1)
} else { } else {
Mpmovecfix(a, 0) Mpmovecfix(a, 0)
@ -528,11 +654,50 @@ func mprshfixfix(a *Mpint, b *Mpint) {
Mpshiftfix(a, int(-s)) Mpshiftfix(a, int(-s))
} }
func _mprshfixfix(a *Mpfix, b *Mpfix) {
if a.Ovf != 0 || b.Ovf != 0 {
if nsavederrors+nerrors == 0 {
Yyerror("ovf in mprshfixfix")
}
_Mpmovecfix(a, 0)
a.Ovf = 1
return
}
s := _Mpgetfix(b)
if s < 0 || s >= Mpprec*Mpscale {
Yyerror("stupid shift: %d", s)
if a.Neg != 0 {
_Mpmovecfix(a, -1)
} else {
_Mpmovecfix(a, 0)
}
return
}
_Mpshiftfix(a, int(-s))
}
func mpnegfix(a *Mpint) { func mpnegfix(a *Mpint) {
a.Val.Neg(&a.Val)
}
func _mpnegfix(a *Mpfix) {
a.Neg ^= 1 a.Neg ^= 1
} }
func Mpgetfix(a *Mpint) int64 { func Mpgetfix(a *Mpint) int64 {
if a.Ovf {
if nsavederrors+nerrors == 0 {
Yyerror("constant overflow")
}
return 0
}
return a.Val.Int64()
}
func _Mpgetfix(a *Mpfix) int64 {
if a.Ovf != 0 { if a.Ovf != 0 {
if nsavederrors+nerrors == 0 { if nsavederrors+nerrors == 0 {
Yyerror("constant overflow") Yyerror("constant overflow")
@ -550,6 +715,10 @@ func Mpgetfix(a *Mpint) int64 {
} }
func Mpmovecfix(a *Mpint, c int64) { func Mpmovecfix(a *Mpint, c int64) {
a.Val.SetInt64(c)
}
func _Mpmovecfix(a *Mpfix, c int64) {
a.Neg = 0 a.Neg = 0
a.Ovf = 0 a.Ovf = 0
@ -565,7 +734,7 @@ func Mpmovecfix(a *Mpint, c int64) {
} }
} }
func mpdivmodfixfix(q *Mpint, r *Mpint, n *Mpint, d *Mpint) { func mpdivmodfixfix(q *Mpfix, r *Mpfix, n *Mpfix, d *Mpfix) {
var i int var i int
ns := int(n.Neg) ns := int(n.Neg)
@ -573,8 +742,8 @@ func mpdivmodfixfix(q *Mpint, r *Mpint, n *Mpint, d *Mpint) {
n.Neg = 0 n.Neg = 0
d.Neg = 0 d.Neg = 0
mpmovefixfix(r, n) _mpmovefixfix(r, n)
Mpmovecfix(q, 0) _Mpmovecfix(q, 0)
// shift denominator until it // shift denominator until it
// is larger than numerator // is larger than numerator
@ -605,7 +774,7 @@ func mpdivmodfixfix(q *Mpint, r *Mpint, n *Mpint, d *Mpint) {
mprsh(d) mprsh(d)
if mpcmp(d, r) <= 0 { if mpcmp(d, r) <= 0 {
mpaddcfix(q, 1) mpaddcfix(q, 1)
mpsubfixfix(r, d) _mpsubfixfix(r, d)
} }
} }
@ -615,7 +784,7 @@ func mpdivmodfixfix(q *Mpint, r *Mpint, n *Mpint, d *Mpint) {
q.Neg = uint8(ns ^ ds) q.Neg = uint8(ns ^ ds)
} }
func mpiszero(a *Mpint) bool { func mpiszero(a *Mpfix) bool {
for i := Mpprec - 1; i >= 0; i-- { for i := Mpprec - 1; i >= 0; i-- {
if a.A[i] != 0 { if a.A[i] != 0 {
return false return false
@ -624,14 +793,14 @@ func mpiszero(a *Mpint) bool {
return true return true
} }
func mpdivfract(a *Mpint, b *Mpint) { func mpdivfract(a *Mpfix, b *Mpfix) {
var n Mpint var n Mpfix
var d Mpint var d Mpfix
var j int var j int
var x int var x int
mpmovefixfix(&n, a) // numerator _mpmovefixfix(&n, a) // numerator
mpmovefixfix(&d, b) // denominator _mpmovefixfix(&d, b) // denominator
neg := int(n.Neg) ^ int(d.Neg) neg := int(n.Neg) ^ int(d.Neg)
@ -645,7 +814,7 @@ func mpdivfract(a *Mpint, b *Mpint) {
if !mpiszero(&d) { if !mpiszero(&d) {
x |= 1 x |= 1
} }
mpsubfixfix(&n, &d) _mpsubfixfix(&n, &d)
} }
mprsh(&d) mprsh(&d)
@ -657,10 +826,10 @@ func mpdivfract(a *Mpint, b *Mpint) {
a.Neg = uint8(neg) a.Neg = uint8(neg)
} }
func mptestfix(a *Mpint) int { func mptestfix(a *Mpfix) int {
var b Mpint var b Mpfix
Mpmovecfix(&b, 0) _Mpmovecfix(&b, 0)
r := mpcmp(a, &b) r := mpcmp(a, &b)
if a.Neg != 0 { if a.Neg != 0 {
if r > 0 { if r > 0 {

View File

@ -80,7 +80,7 @@ func mpnorm(a *Mpflt) {
} }
} }
Mpshiftfix(&a.Val, s) _Mpshiftfix(&a.Val, s)
mpsetexp(a, int(a.Exp)-s) mpsetexp(a, int(a.Exp)-s)
} }
@ -110,21 +110,21 @@ func mpaddfltflt(a *Mpflt, b *Mpflt) {
var c Mpflt var c Mpflt
mpmovefltflt(&c, b) mpmovefltflt(&c, b)
Mpshiftfix(&c.Val, -s) _Mpshiftfix(&c.Val, -s)
mpaddfixfix(&a.Val, &c.Val, 0) _mpaddfixfix(&a.Val, &c.Val, 0)
goto out goto out
} }
if s < 0 { if s < 0 {
// b is larger, shift a right // b is larger, shift a right
Mpshiftfix(&a.Val, s) _Mpshiftfix(&a.Val, s)
mpsetexp(a, int(a.Exp)-s) mpsetexp(a, int(a.Exp)-s)
mpaddfixfix(&a.Val, &b.Val, 0) _mpaddfixfix(&a.Val, &b.Val, 0)
goto out goto out
} }
mpaddfixfix(&a.Val, &b.Val, 0) _mpaddfixfix(&a.Val, &b.Val, 0)
out: out:
mpnorm(a) mpnorm(a)
@ -193,7 +193,7 @@ func mpdivfltflt(a *Mpflt, b *Mpflt) {
var c Mpflt var c Mpflt
mpmovefltflt(&c, b) mpmovefltflt(&c, b)
Mpshiftfix(&c.Val, Mpscale) _Mpshiftfix(&c.Val, Mpscale)
// divide // divide
mpdivfract(&a.Val, &c.Val) mpdivfract(&a.Val, &c.Val)
@ -222,7 +222,7 @@ func mpgetfltN(a *Mpflt, prec int, bias int) float64 {
} }
for a.Val.A[Mpnorm-1]&Mpsign == 0 { for a.Val.A[Mpnorm-1]&Mpsign == 0 {
Mpshiftfix(&a.Val, 1) _Mpshiftfix(&a.Val, 1)
mpsetexp(a, int(a.Exp)-1) // can set 'a' to zero mpsetexp(a, int(a.Exp)-1) // can set 'a' to zero
s = sigfig(a) s = sigfig(a)
if s == 0 { if s == 0 {
@ -298,7 +298,7 @@ func Mpmovecflt(a *Mpflt, c float64) {
if Mpdebug != 0 /*TypeKind(100016)*/ { if Mpdebug != 0 /*TypeKind(100016)*/ {
fmt.Printf("\nconst %g", c) fmt.Printf("\nconst %g", c)
} }
Mpmovecfix(&a.Val, 0) _Mpmovecfix(&a.Val, 0)
a.Exp = 0 a.Exp = 0
var f float64 var f float64
var l int var l int
@ -323,7 +323,7 @@ func Mpmovecflt(a *Mpflt, c float64) {
if f == 0 { if f == 0 {
break break
} }
Mpshiftfix(&a.Val, Mpscale) _Mpshiftfix(&a.Val, Mpscale)
} }
out: out: