cmd/internal/gc: use 512 bits (rather than 464) for multi-precision arithmetic

The original implementation used 16 int "words" but only 29 bits per word
for a total of 16*29 = 464 bits, with a space consumption of 16*64 = 1024
bits on a 64 bit machine. Switching to 512 bits increases precision while
still using (in the worst case) half the amount of memory per mp value on
a 64 bit machine.

Also: Decreased permitted number of least-significant mantissa bits which
may be incorrect when considering if a precise floating-point constant is
an integer from 29 to 16 bits.

Change-Id: Iee9287056f0e9aa4f06ceac0724ff4674f710c53
Reviewed-on: https://go-review.googlesource.com/8429
Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
Robert Griesemer 2015-04-02 16:34:48 -07:00
parent 14bbab4758
commit a51d5f27e8
5 changed files with 26 additions and 20 deletions

View file

@ -57,10 +57,11 @@ const (
)
const (
// TODO(gri) consider increasing Mpprec to 512 or perhaps 1024
// (this would permit enabling additional tests).
Mpprec = 16 * 29 // == 464, to match original value
Mpdebug = 0
// Maximum size in bits for Mpints before signalling
// overflow and also mantissa precision for Mpflts.
Mpprec = 512
// Turn on for constant arithmetic debugging output.
Mpdebug = false
)
// Mpint represents an integer constant.

View file

@ -35,10 +35,7 @@ func mpmovefltfix(a *Mpint, b *Mpflt) int {
return 0
}
// TODO(gri) reduce the value of delta - currently
// we use the size of a mp-word of the old implementation
// for approximately similar behavior.
const delta = 29 // a reasonably small number of bits > 0
const delta = 16 // a reasonably small number of bits > 0
var t big.Float
t.SetPrec(Mpprec - delta)

View file

@ -32,13 +32,13 @@ func mpmovefltflt(a *Mpflt, b *Mpflt) {
}
func mpaddfltflt(a *Mpflt, b *Mpflt) {
if Mpdebug != 0 {
if Mpdebug {
fmt.Printf("\n%v + %v", Fconv(a, 0), Fconv(b, 0))
}
a.Val.Add(&a.Val, &b.Val)
if Mpdebug != 0 {
if Mpdebug {
fmt.Printf(" = %v\n\n", Fconv(a, 0))
}
}
@ -51,25 +51,25 @@ func mpaddcflt(a *Mpflt, c float64) {
}
func mpsubfltflt(a *Mpflt, b *Mpflt) {
if Mpdebug != 0 {
if Mpdebug {
fmt.Printf("\n%v - %v", Fconv(a, 0), Fconv(b, 0))
}
a.Val.Sub(&a.Val, &b.Val)
if Mpdebug != 0 {
if Mpdebug {
fmt.Printf(" = %v\n\n", Fconv(a, 0))
}
}
func mpmulfltflt(a *Mpflt, b *Mpflt) {
if Mpdebug != 0 {
if Mpdebug {
fmt.Printf("%v\n * %v\n", Fconv(a, 0), Fconv(b, 0))
}
a.Val.Mul(&a.Val, &b.Val)
if Mpdebug != 0 {
if Mpdebug {
fmt.Printf(" = %v\n\n", Fconv(a, 0))
}
}
@ -82,13 +82,13 @@ func mpmulcflt(a *Mpflt, c float64) {
}
func mpdivfltflt(a *Mpflt, b *Mpflt) {
if Mpdebug != 0 {
if Mpdebug {
fmt.Printf("%v\n / %v\n", Fconv(a, 0), Fconv(b, 0))
}
a.Val.Quo(&a.Val, &b.Val)
if Mpdebug != 0 {
if Mpdebug {
fmt.Printf(" = %v\n\n", Fconv(a, 0))
}
}
@ -140,13 +140,13 @@ func mpgetflt32(a *Mpflt) float64 {
}
func Mpmovecflt(a *Mpflt, c float64) {
if Mpdebug != 0 {
if Mpdebug {
fmt.Printf("\nconst %g", c)
}
a.Val.SetFloat64(c)
if Mpdebug != 0 {
if Mpdebug {
fmt.Printf(" = %v\n", Fconv(a, 0))
}
}

View file

@ -99,5 +99,13 @@ const (
f88 = f87 * 88
f89 = f88 * 89
f90 = f89 * 90
f91 = f90 * 91 // ERROR "overflow"
f91 = f90 * 91
f92 = f91 * 92
f93 = f92 * 93
f94 = f93 * 94
f95 = f94 * 95
f96 = f95 * 96
f97 = f96 * 97
f98 = f97 * 98
f99 = f98 * 99 // ERROR "overflow"
)

View file

@ -21,7 +21,7 @@ func main() {
var prec float64
switch runtime.Compiler {
case "gc":
prec = 16 * 29
prec = 512
case "gccgo":
prec = 256
default: