overflow(v, t)
fv := newMpflt()
-
- // *fv = *oldv
mpmovefltflt(fv, oldv)
// convert large precision literal floating
)
const (
- // TODO(gri) replace these with a single precision constant.
- Mpscale = 29 // safely smaller than bits in a long
- Mpprec = 16 // Mpscale*Mpprec is max number of bits
+ // 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
)
+++ /dev/null
-// 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.
-
-package gc
-
-import (
- "cmd/internal/gc/big"
- "cmd/internal/obj"
- "fmt"
-)
-
-func Mpcmpfixfix(a, b *Mpint) int {
- return a.Val.Cmp(&b.Val)
-}
-
-func mpcmpfixc(b *Mpint, c int64) int {
- return b.Val.Cmp(big.NewInt(c))
-}
-
-func mpcmpfltflt(a *Mpflt, b *Mpflt) int {
- return a.Val.Cmp(&b.Val)
-}
-
-func mpcmpfltc(b *Mpflt, c float64) int {
- var a Mpflt
-
- Mpmovecflt(&a, c)
- return mpcmpfltflt(b, &a)
-}
-
-func mpsubfixfix(a, b *Mpint) {
- a.Val.Sub(&a.Val, &b.Val)
-}
-
-func mpsubfltflt(a *Mpflt, b *Mpflt) {
- if Mpdebug != 0 {
- fmt.Printf("\n%v - %v", Fconv(a, 0), Fconv(b, 0))
- }
-
- a.Val.Sub(&a.Val, &b.Val)
-
- if Mpdebug != 0 {
- fmt.Printf(" = %v\n\n", Fconv(a, 0))
- }
-}
-
-func mpaddcflt(a *Mpflt, c float64) {
- var b Mpflt
-
- Mpmovecflt(&b, c)
- mpaddfltflt(a, &b)
-}
-
-func mpmulcflt(a *Mpflt, c float64) {
- var b Mpflt
-
- Mpmovecflt(&b, c)
- mpmulfltflt(a, &b)
-}
-
-func mpdivfixfix(a, b *Mpint) {
- a.Val.Quo(&a.Val, &b.Val)
-}
-
-func mpmodfixfix(a, b *Mpint) {
- a.Val.Rem(&a.Val, &b.Val)
-}
-
-func Mpmovefixflt(a *Mpflt, b *Mpint) {
- if b.Ovf {
- // sign doesn't really matter but copy anyway
- a.Val.SetInf(b.Val.Sign() < 0)
- return
- }
- a.Val.SetInt(&b.Val)
-}
-
-func mpmovefltfix(a *Mpint, b *Mpflt) int {
- if _, acc := b.Val.Int(&a.Val); acc == big.Exact {
- return 0
- }
-
- const delta = Mpscale // a reasonably small number of bits > 0
- var t big.Float
- t.SetPrec(Mpscale*Mpprec - delta)
-
- // try rounding down a little
- t.SetMode(big.ToZero)
- t.Set(&b.Val)
- if _, acc := t.Int(&a.Val); acc == big.Exact {
- return 0
- }
-
- // try rounding up a little
- t.SetMode(big.AwayFromZero)
- t.Set(&b.Val)
- if _, acc := t.Int(&a.Val); acc == big.Exact {
- return 0
- }
-
- return -1
-}
-
-func mpmovefixfix(a, b *Mpint) {
- a.Val.Set(&b.Val)
-}
-
-func mpmovefltflt(a *Mpflt, b *Mpflt) {
- a.Val.Set(&b.Val)
-}
-
-//
-// floating point input
-// required syntax is [+-]d*[.]d*[e[+-]d*] or [+-]0xH*[e[+-]d*]
-//
-func mpatoflt(a *Mpflt, as string) {
- for len(as) > 0 && (as[0] == ' ' || as[0] == '\t') {
- as = as[1:]
- }
-
- f, ok := a.Val.SetString(as)
- if !ok {
- // At the moment we lose precise error cause;
- // the old code additionally distinguished between:
- // - malformed hex constant
- // - decimal point in hex constant
- // - constant exponent out of range
- // - decimal point and binary point in constant
- // TODO(gri) use different conversion function or check separately
- Yyerror("malformed constant: %s", as)
- a.Val.SetUint64(0)
- }
-
- if f.IsInf() {
- Yyerror("constant too large: %s", as)
- a.Val.SetUint64(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)
- }
-}
-
-func Bconv(xval *Mpint, flag int) string {
- if flag&obj.FmtSharp != 0 {
- return fmt.Sprintf("%#x", &xval.Val)
- }
- return xval.Val.String()
-}
-
-func Fconv(fvp *Mpflt, flag int) string {
- if flag&obj.FmtSharp != 0 {
- return fvp.Val.Format('g', 6)
- }
- return fvp.Val.Format('b', 0)
-}
package gc
-// shift left by s (or right by -s)
-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))
- }
-}
+import (
+ "cmd/internal/gc/big"
+ "cmd/internal/obj"
+ "fmt"
+)
/// implements fix arithmetic
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 {
+ if a.Val.BitLen()+extra > Mpprec {
mpsetovf(a)
}
return a.Ovf
}
+func mpmovefixfix(a, b *Mpint) {
+ a.Val.Set(&b.Val)
+}
+
+func mpmovefltfix(a *Mpint, b *Mpflt) int {
+ if _, acc := b.Val.Int(&a.Val); acc == big.Exact {
+ 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
+ var t big.Float
+ t.SetPrec(Mpprec - delta)
+
+ // try rounding down a little
+ t.SetMode(big.ToZero)
+ t.Set(&b.Val)
+ if _, acc := t.Int(&a.Val); acc == big.Exact {
+ return 0
+ }
+
+ // try rounding up a little
+ t.SetMode(big.AwayFromZero)
+ t.Set(&b.Val)
+ if _, acc := t.Int(&a.Val); acc == big.Exact {
+ return 0
+ }
+
+ return -1
+}
+
func mpaddfixfix(a, b *Mpint, quiet int) {
if a.Ovf || b.Ovf {
if nsavederrors+nerrors == 0 {
- Yyerror("ovf in mpaddxx")
+ Yyerror("ovf in mpaddfixfix")
}
mpsetovf(a)
return
}
}
+func mpsubfixfix(a, b *Mpint) {
+ if a.Ovf || b.Ovf {
+ if nsavederrors+nerrors == 0 {
+ Yyerror("ovf in mpsubfixfix")
+ }
+ mpsetovf(a)
+ return
+ }
+
+ a.Val.Sub(&a.Val, &b.Val)
+
+ if mptestovf(a, 0) {
+ Yyerror("constant subtraction overflow")
+ }
+}
+
func mpmulfixfix(a, b *Mpint) {
if a.Ovf || b.Ovf {
if nsavederrors+nerrors == 0 {
}
}
+func mpdivfixfix(a, b *Mpint) {
+ if a.Ovf || b.Ovf {
+ if nsavederrors+nerrors == 0 {
+ Yyerror("ovf in mpdivfixfix")
+ }
+ mpsetovf(a)
+ return
+ }
+
+ a.Val.Quo(&a.Val, &b.Val)
+
+ if mptestovf(a, 0) {
+ // can only happen for div-0 which should be checked elsewhere
+ Yyerror("constant division overflow")
+ }
+}
+
+func mpmodfixfix(a, b *Mpint) {
+ if a.Ovf || b.Ovf {
+ if nsavederrors+nerrors == 0 {
+ Yyerror("ovf in mpmodfixfix")
+ }
+ mpsetovf(a)
+ return
+ }
+
+ a.Val.Rem(&a.Val, &b.Val)
+
+ if mptestovf(a, 0) {
+ // should never happen
+ Yyerror("constant modulo overflow")
+ }
+}
+
func mporfixfix(a, b *Mpint) {
if a.Ovf || b.Ovf {
if nsavederrors+nerrors == 0 {
a.Val.Xor(&a.Val, &b.Val)
}
+// shift left by s (or right by -s)
+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))
+ }
+}
+
func mplshfixfix(a, b *Mpint) {
if a.Ovf || b.Ovf {
if nsavederrors+nerrors == 0 {
}
s := Mpgetfix(b)
- if s < 0 || s >= Mpprec*Mpscale {
+ if s < 0 || s >= Mpprec {
Yyerror("stupid shift: %d", s)
Mpmovecfix(a, 0)
return
}
s := Mpgetfix(b)
- if s < 0 || s >= Mpprec*Mpscale {
+ if s < 0 || s >= Mpprec {
Yyerror("stupid shift: %d", s)
if a.Val.Sign() < 0 {
Mpmovecfix(a, -1)
Mpshiftfix(a, int(-s))
}
+func Mpcmpfixfix(a, b *Mpint) int {
+ return a.Val.Cmp(&b.Val)
+}
+
+func mpcmpfixc(b *Mpint, c int64) int {
+ return b.Val.Cmp(big.NewInt(c))
+}
+
func mpnegfix(a *Mpint) {
a.Val.Neg(&a.Val)
}
func Mpmovecfix(a *Mpint, c int64) {
a.Val.SetInt64(c)
}
+
+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)
+ }
+}
+
+func Bconv(xval *Mpint, flag int) string {
+ if flag&obj.FmtSharp != 0 {
+ return fmt.Sprintf("%#x", &xval.Val)
+ }
+ return xval.Val.String()
+}
package gc
import (
+ "cmd/internal/obj"
"fmt"
"math"
)
+/// implements float arihmetic
+
func newMpflt() *Mpflt {
var a Mpflt
- a.Val.SetPrec(Mpscale * Mpprec)
+ a.Val.SetPrec(Mpprec)
return &a
}
-/// implements float arihmetic
+func Mpmovefixflt(a *Mpflt, b *Mpint) {
+ if b.Ovf {
+ // sign doesn't really matter but copy anyway
+ a.Val.SetInf(b.Val.Sign() < 0)
+ return
+ }
+ a.Val.SetInt(&b.Val)
+}
+
+func mpmovefltflt(a *Mpflt, b *Mpflt) {
+ a.Val.Set(&b.Val)
+}
func mpaddfltflt(a *Mpflt, b *Mpflt) {
if Mpdebug != 0 {
}
}
+func mpaddcflt(a *Mpflt, c float64) {
+ var b Mpflt
+
+ Mpmovecflt(&b, c)
+ mpaddfltflt(a, &b)
+}
+
+func mpsubfltflt(a *Mpflt, b *Mpflt) {
+ if Mpdebug != 0 {
+ fmt.Printf("\n%v - %v", Fconv(a, 0), Fconv(b, 0))
+ }
+
+ a.Val.Sub(&a.Val, &b.Val)
+
+ if Mpdebug != 0 {
+ fmt.Printf(" = %v\n\n", Fconv(a, 0))
+ }
+}
+
func mpmulfltflt(a *Mpflt, b *Mpflt) {
if Mpdebug != 0 {
fmt.Printf("%v\n * %v\n", Fconv(a, 0), Fconv(b, 0))
}
}
+func mpmulcflt(a *Mpflt, c float64) {
+ var b Mpflt
+
+ Mpmovecflt(&b, c)
+ mpmulfltflt(a, &b)
+}
+
func mpdivfltflt(a *Mpflt, b *Mpflt) {
if Mpdebug != 0 {
fmt.Printf("%v\n / %v\n", Fconv(a, 0), Fconv(b, 0))
}
}
+func mpcmpfltflt(a *Mpflt, b *Mpflt) int {
+ return a.Val.Cmp(&b.Val)
+}
+
+func mpcmpfltc(b *Mpflt, c float64) int {
+ var a Mpflt
+
+ Mpmovecflt(&a, c)
+ return mpcmpfltflt(b, &a)
+}
+
func mpgetfltN(a *Mpflt, prec int, bias int) float64 {
var x float64
switch prec {
func mpnegflt(a *Mpflt) {
a.Val.Neg(&a.Val)
}
+
+//
+// floating point input
+// required syntax is [+-]d*[.]d*[e[+-]d*] or [+-]0xH*[e[+-]d*]
+//
+func mpatoflt(a *Mpflt, as string) {
+ for len(as) > 0 && (as[0] == ' ' || as[0] == '\t') {
+ as = as[1:]
+ }
+
+ f, ok := a.Val.SetString(as)
+ if !ok {
+ // At the moment we lose precise error cause;
+ // the old code additionally distinguished between:
+ // - malformed hex constant
+ // - decimal point in hex constant
+ // - constant exponent out of range
+ // - decimal point and binary point in constant
+ // TODO(gri) use different conversion function or check separately
+ Yyerror("malformed constant: %s", as)
+ a.Val.SetUint64(0)
+ }
+
+ if f.IsInf() {
+ Yyerror("constant too large: %s", as)
+ a.Val.SetUint64(0)
+ }
+}
+
+func Fconv(fvp *Mpflt, flag int) string {
+ if flag&obj.FmtSharp != 0 {
+ return fvp.Val.Format('g', 6)
+ }
+ return fvp.Val.Format('b', 0)
+}