Commit a51d5f27 authored by Robert Griesemer's avatar Robert Griesemer

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/8429Reviewed-by: 's avatarRuss Cox <rsc@golang.org>
parent 14bbab47
...@@ -57,10 +57,11 @@ const ( ...@@ -57,10 +57,11 @@ const (
) )
const ( const (
// TODO(gri) consider increasing Mpprec to 512 or perhaps 1024 // Maximum size in bits for Mpints before signalling
// (this would permit enabling additional tests). // overflow and also mantissa precision for Mpflts.
Mpprec = 16 * 29 // == 464, to match original value Mpprec = 512
Mpdebug = 0 // Turn on for constant arithmetic debugging output.
Mpdebug = false
) )
// Mpint represents an integer constant. // Mpint represents an integer constant.
......
...@@ -35,10 +35,7 @@ func mpmovefltfix(a *Mpint, b *Mpflt) int { ...@@ -35,10 +35,7 @@ func mpmovefltfix(a *Mpint, b *Mpflt) int {
return 0 return 0
} }
// TODO(gri) reduce the value of delta - currently const delta = 16 // a reasonably small number of bits > 0
// 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
var t big.Float var t big.Float
t.SetPrec(Mpprec - delta) t.SetPrec(Mpprec - delta)
......
...@@ -32,13 +32,13 @@ func mpmovefltflt(a *Mpflt, b *Mpflt) { ...@@ -32,13 +32,13 @@ func mpmovefltflt(a *Mpflt, b *Mpflt) {
} }
func mpaddfltflt(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)) fmt.Printf("\n%v + %v", Fconv(a, 0), Fconv(b, 0))
} }
a.Val.Add(&a.Val, &b.Val) a.Val.Add(&a.Val, &b.Val)
if Mpdebug != 0 { if Mpdebug {
fmt.Printf(" = %v\n\n", Fconv(a, 0)) fmt.Printf(" = %v\n\n", Fconv(a, 0))
} }
} }
...@@ -51,25 +51,25 @@ func mpaddcflt(a *Mpflt, c float64) { ...@@ -51,25 +51,25 @@ func mpaddcflt(a *Mpflt, c float64) {
} }
func mpsubfltflt(a *Mpflt, b *Mpflt) { func mpsubfltflt(a *Mpflt, b *Mpflt) {
if Mpdebug != 0 { if Mpdebug {
fmt.Printf("\n%v - %v", Fconv(a, 0), Fconv(b, 0)) fmt.Printf("\n%v - %v", Fconv(a, 0), Fconv(b, 0))
} }
a.Val.Sub(&a.Val, &b.Val) a.Val.Sub(&a.Val, &b.Val)
if Mpdebug != 0 { if Mpdebug {
fmt.Printf(" = %v\n\n", Fconv(a, 0)) fmt.Printf(" = %v\n\n", Fconv(a, 0))
} }
} }
func mpmulfltflt(a *Mpflt, b *Mpflt) { func mpmulfltflt(a *Mpflt, b *Mpflt) {
if Mpdebug != 0 { if Mpdebug {
fmt.Printf("%v\n * %v\n", Fconv(a, 0), Fconv(b, 0)) fmt.Printf("%v\n * %v\n", Fconv(a, 0), Fconv(b, 0))
} }
a.Val.Mul(&a.Val, &b.Val) a.Val.Mul(&a.Val, &b.Val)
if Mpdebug != 0 { if Mpdebug {
fmt.Printf(" = %v\n\n", Fconv(a, 0)) fmt.Printf(" = %v\n\n", Fconv(a, 0))
} }
} }
...@@ -82,13 +82,13 @@ func mpmulcflt(a *Mpflt, c float64) { ...@@ -82,13 +82,13 @@ func mpmulcflt(a *Mpflt, c float64) {
} }
func mpdivfltflt(a *Mpflt, b *Mpflt) { func mpdivfltflt(a *Mpflt, b *Mpflt) {
if Mpdebug != 0 { if Mpdebug {
fmt.Printf("%v\n / %v\n", Fconv(a, 0), Fconv(b, 0)) fmt.Printf("%v\n / %v\n", Fconv(a, 0), Fconv(b, 0))
} }
a.Val.Quo(&a.Val, &b.Val) a.Val.Quo(&a.Val, &b.Val)
if Mpdebug != 0 { if Mpdebug {
fmt.Printf(" = %v\n\n", Fconv(a, 0)) fmt.Printf(" = %v\n\n", Fconv(a, 0))
} }
} }
...@@ -140,13 +140,13 @@ func mpgetflt32(a *Mpflt) float64 { ...@@ -140,13 +140,13 @@ func mpgetflt32(a *Mpflt) float64 {
} }
func Mpmovecflt(a *Mpflt, c float64) { func Mpmovecflt(a *Mpflt, c float64) {
if Mpdebug != 0 { if Mpdebug {
fmt.Printf("\nconst %g", c) fmt.Printf("\nconst %g", c)
} }
a.Val.SetFloat64(c) a.Val.SetFloat64(c)
if Mpdebug != 0 { if Mpdebug {
fmt.Printf(" = %v\n", Fconv(a, 0)) fmt.Printf(" = %v\n", Fconv(a, 0))
} }
} }
......
...@@ -99,5 +99,13 @@ const ( ...@@ -99,5 +99,13 @@ const (
f88 = f87 * 88 f88 = f87 * 88
f89 = f88 * 89 f89 = f88 * 89
f90 = f89 * 90 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"
) )
...@@ -21,7 +21,7 @@ func main() { ...@@ -21,7 +21,7 @@ func main() {
var prec float64 var prec float64
switch runtime.Compiler { switch runtime.Compiler {
case "gc": case "gc":
prec = 16 * 29 prec = 512
case "gccgo": case "gccgo":
prec = 256 prec = 256
default: default:
......
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