Commit c12e1b0b authored by Robert Griesemer's avatar Robert Griesemer

cmd/compile: update vendored math/big to latest version

This makes the rounding bug fix in math/big for issue 14651 available
to the compiler.

- changes to cmd/compile/internal/big fully automatic via script
- added test case for issue
- updated old test case with correct test data

Fixes #14651.

Change-Id: Iea37a2cd8d3a75f8c96193748b66156a987bbe40
Reviewed-on: https://go-review.googlesource.com/20818Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 7c86263b
......@@ -158,21 +158,6 @@ var sumVW = []argVW{
{nat{585}, nat{314}, 271, 0},
}
var prodVW = []argVW{
{},
{nat{0}, nat{0}, 0, 0},
{nat{0}, nat{_M}, 0, 0},
{nat{0}, nat{0}, _M, 0},
{nat{1}, nat{1}, 1, 0},
{nat{22793}, nat{991}, 23, 0},
{nat{0, 0, 0, 22793}, nat{0, 0, 0, 991}, 23, 0},
{nat{0, 0, 0, 0}, nat{7893475, 7395495, 798547395, 68943}, 0, 0},
{nat{0, 0, 0, 0}, nat{0, 0, 0, 0}, 894375984, 0},
{nat{_M << 1 & _M}, nat{_M}, 1 << 1, _M >> (_W - 1)},
{nat{_M << 7 & _M}, nat{_M}, 1 << 7, _M >> (_W - 7)},
{nat{_M << 7 & _M, _M, _M, _M}, nat{_M, _M, _M, _M}, 1 << 7, _M >> (_W - 7)},
}
var lshVW = []argVW{
{},
{nat{0}, nat{0}, 0, 0},
......
This diff is collapsed.
......@@ -829,7 +829,7 @@ func TestFloatFloat32(t *testing.T) {
}{
{"0", 0, Exact},
// underflow
// underflow to zero
{"1e-1000", 0, Below},
{"0x0.000002p-127", 0, Below},
{"0x.0000010p-126", 0, Below},
......@@ -843,25 +843,39 @@ func TestFloatFloat32(t *testing.T) {
{"1p-149", math.SmallestNonzeroFloat32, Exact},
{"0x.fffffep-126", math.Float32frombits(0x7fffff), Exact}, // largest denormal
// special cases (see issue 14553)
{"0x0.bp-149", math.Float32frombits(0x000000000), Below}, // ToNearestEven rounds down (to even)
{"0x0.cp-149", math.Float32frombits(0x000000001), Above},
{"0x1.0p-149", math.Float32frombits(0x000000001), Exact},
// special denormal cases (see issues 14553, 14651)
{"0x0.0000001p-126", math.Float32frombits(0x00000000), Below}, // underflow to zero
{"0x0.0000008p-126", math.Float32frombits(0x00000000), Below}, // underflow to zero
{"0x0.0000010p-126", math.Float32frombits(0x00000000), Below}, // rounded down to even
{"0x0.0000011p-126", math.Float32frombits(0x00000001), Above}, // rounded up to smallest denormal
{"0x0.0000018p-126", math.Float32frombits(0x00000001), Above}, // rounded up to smallest denormal
{"0x1.0000000p-149", math.Float32frombits(0x00000001), Exact}, // smallest denormal
{"0x0.0000020p-126", math.Float32frombits(0x00000001), Exact}, // smallest denormal
{"0x0.fffffe0p-126", math.Float32frombits(0x007fffff), Exact}, // largest denormal
{"0x1.0000000p-126", math.Float32frombits(0x00800000), Exact}, // smallest normal
{"0x0.8p-149", math.Float32frombits(0x000000000), Below}, // rounded down to even
{"0x0.9p-149", math.Float32frombits(0x000000001), Above}, // rounded up to smallest denormal
{"0x0.ap-149", math.Float32frombits(0x000000001), Above}, // rounded up to smallest denormal
{"0x0.bp-149", math.Float32frombits(0x000000001), Above}, // rounded up to smallest denormal
{"0x0.cp-149", math.Float32frombits(0x000000001), Above}, // rounded up to smallest denormal
{"0x1.0p-149", math.Float32frombits(0x000000001), Exact}, // smallest denormal
{"0x1.7p-149", math.Float32frombits(0x000000001), Below},
{"0x1.8p-149", math.Float32frombits(0x000000002), Above},
{"0x1.9p-149", math.Float32frombits(0x000000002), Above},
{"0x2.0p-149", math.Float32frombits(0x000000002), Exact},
{"0x2.8p-149", math.Float32frombits(0x000000002), Below}, // ToNearestEven rounds down (to even)
{"0x2.8p-149", math.Float32frombits(0x000000002), Below}, // rounded down to even
{"0x2.9p-149", math.Float32frombits(0x000000003), Above},
{"0x3.0p-149", math.Float32frombits(0x000000003), Exact},
{"0x3.7p-149", math.Float32frombits(0x000000003), Below},
{"0x3.8p-149", math.Float32frombits(0x000000004), Above}, // ToNearestEven rounds up (to even)
{"0x3.8p-149", math.Float32frombits(0x000000004), Above}, // rounded up to even
{"0x4.0p-149", math.Float32frombits(0x000000004), Exact},
{"0x4.8p-149", math.Float32frombits(0x000000004), Below}, // ToNearestEven rounds down (to even)
{"0x4.8p-149", math.Float32frombits(0x000000004), Below}, // rounded down to even
{"0x4.9p-149", math.Float32frombits(0x000000005), Above},
// specific case from issue 14553
......@@ -907,7 +921,7 @@ func TestFloatFloat32(t *testing.T) {
x := makeFloat(tx)
out, acc := x.Float32()
if !alike32(out, tout) || acc != tacc {
t.Errorf("%s: got %g (%#x, %s); want %g (%#x, %s)", tx, out, math.Float32bits(out), acc, test.out, math.Float32bits(test.out), tacc)
t.Errorf("%s: got %g (%#08x, %s); want %g (%#08x, %s)", tx, out, math.Float32bits(out), acc, test.out, math.Float32bits(test.out), tacc)
}
// test that x.SetFloat64(float64(f)).Float32() == f
......@@ -929,21 +943,30 @@ func TestFloatFloat64(t *testing.T) {
}{
{"0", 0, Exact},
// underflow
// underflow to zero
{"1e-1000", 0, Below},
{"0x0.0000000000001p-1023", 0, Below},
{"0x0.00000000000008p-1022", 0, Below},
// denormals
{"0x0.0000000000000cp-1022", math.SmallestNonzeroFloat64, Above}, // rounded up to smallest denormal
{"0x0.0000000000001p-1022", math.SmallestNonzeroFloat64, Exact}, // smallest denormal
{"0x0.00000000000010p-1022", math.SmallestNonzeroFloat64, Exact}, // smallest denormal
{"0x.8p-1073", math.SmallestNonzeroFloat64, Exact},
{"1p-1074", math.SmallestNonzeroFloat64, Exact},
{"0x.fffffffffffffp-1022", math.Float64frombits(0x000fffffffffffff), Exact}, // largest denormal
// special cases (see issue 14553)
{"0x0.bp-1074", math.Float64frombits(0x00000000000000000), Below}, // ToNearestEven rounds down (to even)
{"0x0.cp-1074", math.Float64frombits(0x00000000000000001), Above},
// special denormal cases (see issues 14553, 14651)
{"0x0.00000000000001p-1022", math.Float64frombits(0x00000000000000000), Below}, // underflow to zero
{"0x0.00000000000004p-1022", math.Float64frombits(0x00000000000000000), Below}, // underflow to zero
{"0x0.00000000000008p-1022", math.Float64frombits(0x00000000000000000), Below}, // rounded down to even
{"0x0.00000000000009p-1022", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal
{"0x0.0000000000000ap-1022", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal
{"0x0.8p-1074", math.Float64frombits(0x00000000000000000), Below}, // rounded down to even
{"0x0.9p-1074", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal
{"0x0.ap-1074", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal
{"0x0.bp-1074", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal
{"0x0.cp-1074", math.Float64frombits(0x00000000000000001), Above}, // rounded up to smallest denormal
{"0x1.0p-1074", math.Float64frombits(0x00000000000000001), Exact},
{"0x1.7p-1074", math.Float64frombits(0x00000000000000001), Below},
......@@ -951,15 +974,15 @@ func TestFloatFloat64(t *testing.T) {
{"0x1.9p-1074", math.Float64frombits(0x00000000000000002), Above},
{"0x2.0p-1074", math.Float64frombits(0x00000000000000002), Exact},
{"0x2.8p-1074", math.Float64frombits(0x00000000000000002), Below}, // ToNearestEven rounds down (to even)
{"0x2.8p-1074", math.Float64frombits(0x00000000000000002), Below}, // rounded down to even
{"0x2.9p-1074", math.Float64frombits(0x00000000000000003), Above},
{"0x3.0p-1074", math.Float64frombits(0x00000000000000003), Exact},
{"0x3.7p-1074", math.Float64frombits(0x00000000000000003), Below},
{"0x3.8p-1074", math.Float64frombits(0x00000000000000004), Above}, // ToNearestEven rounds up (to even)
{"0x3.8p-1074", math.Float64frombits(0x00000000000000004), Above}, // rounded up to even
{"0x4.0p-1074", math.Float64frombits(0x00000000000000004), Exact},
{"0x4.8p-1074", math.Float64frombits(0x00000000000000004), Below}, // ToNearestEven rounds down (to even)
{"0x4.8p-1074", math.Float64frombits(0x00000000000000004), Below}, // rounded down to even
{"0x4.9p-1074", math.Float64frombits(0x00000000000000005), Above},
// normals
......@@ -1005,7 +1028,7 @@ func TestFloatFloat64(t *testing.T) {
x := makeFloat(tx)
out, acc := x.Float64()
if !alike64(out, tout) || acc != tacc {
t.Errorf("%s: got %g (%#x, %s); want %g (%#x, %s)", tx, out, math.Float64bits(out), acc, test.out, math.Float64bits(test.out), tacc)
t.Errorf("%s: got %g (%#016x, %s); want %g (%#016x, %s)", tx, out, math.Float64bits(out), acc, test.out, math.Float64bits(test.out), tacc)
}
// test that x.SetFloat64(f).Float64() == f
......
......@@ -333,9 +333,9 @@ func (x *Float) fmtB(buf []byte) []byte {
return strconv.AppendInt(buf, e, 10)
}
// fmtP appends the string of x in the format 0x." mantissa "p" exponent
// with a hexadecimal mantissa and a binary exponent, or 0" if x is zero,
// ad returns the extended buffer.
// fmtP appends the string of x in the format "0x." mantissa "p" exponent
// with a hexadecimal mantissa and a binary exponent, or "0" if x is zero,
// and returns the extended buffer.
// The mantissa is normalized such that 0.5 <= 0.mantissa < 1.0.
// The sign of x is ignored, and x must not be an Inf.
func (x *Float) fmtP(buf []byte) []byte {
......@@ -374,12 +374,11 @@ func min(x, y int) int {
}
// Format implements fmt.Formatter. It accepts all the regular
// formats for floating-point numbers ('e', 'E', 'f', 'F', 'g',
// 'G') as well as 'b', 'p', and 'v'. See (*Float).Text for the
// interpretation of 'b' and 'p'. The 'v' format is handled like
// 'g'.
// formats for floating-point numbers ('b', 'e', 'E', 'f', 'F',
// 'g', 'G') as well as 'p' and 'v'. See (*Float).Text for the
// interpretation of 'p'. The 'v' format is handled like 'g'.
// Format also supports specification of the minimum precision
// in digits, the output field width, as well as the format verbs
// in digits, the output field width, as well as the format flags
// '+' and ' ' for sign control, '0' for space or zero padding,
// and '-' for left or right justification. See the fmt package
// for details.
......
......@@ -52,16 +52,16 @@ func writeMultiple(s fmt.State, text string, count int) {
}
}
// Format is a support routine for fmt.Formatter. It accepts
// the formats 'b' (binary), 'o' (octal), 'd' (decimal), 'x'
// (lowercase hexadecimal), and 'X' (uppercase hexadecimal).
// Format implements fmt.Formatter. It accepts the formats
// 'b' (binary), 'o' (octal), 'd' (decimal), 'x' (lowercase
// hexadecimal), and 'X' (uppercase hexadecimal).
// Also supported are the full suite of package fmt's format
// verbs for integral types, including '+', '-', and ' '
// for sign control, '#' for leading zero in octal and for
// hexadecimal, a leading "0x" or "0X" for "%#x" and "%#X"
// respectively, specification of minimum digits precision,
// output field width, space or zero padding, and left or
// right justification.
// flags for integral types, including '+' and ' ' for sign
// control, '#' for leading zero in octal and for hexadecimal,
// a leading "0x" or "0X" for "%#x" and "%#X" respectively,
// specification of minimum digits precision, output field
// width, space or zero padding, and '-' for left or right
// justification.
//
func (x *Int) Format(s fmt.State, ch rune) {
// determine base
......
......@@ -20,7 +20,10 @@ func main() {
bits uint32
}{
{0e+00, 0x00000000},
{1e-45, 0x00000000},
{1e-46, 0x00000000},
{0.5e-45, 0x00000000},
{0.8e-45, 0x00000001},
{1e-45, 0x00000001},
{2e-45, 0x00000001},
{3e-45, 0x00000002},
{4e-45, 0x00000003},
......
// run
// Copyright 2016 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.
// This test checks if the compiler's internal constant
// arithmetic correctly rounds up floating-point values
// that become the smallest denormal value.
//
// See also related issue 14553 and test issue14553.go.
package main
import (
"fmt"
"math"
)
const (
p149 = 1.0 / (1 << 149) // 1p-149
p500 = 1.0 / (1 << 500) // 1p-500
p1074 = p500 * p500 / (1<<74) // 1p-1074
)
const (
m0000p149 = 0x0 / 16.0 * p149 // = 0.0000p-149
m1000p149 = 0x8 / 16.0 * p149 // = 0.1000p-149
m1001p149 = 0x9 / 16.0 * p149 // = 0.1001p-149
m1011p149 = 0xb / 16.0 * p149 // = 0.1011p-149
m1100p149 = 0xc / 16.0 * p149 // = 0.1100p-149
m0000p1074 = 0x0 / 16.0 * p1074 // = 0.0000p-1074
m1000p1074 = 0x8 / 16.0 * p1074 // = 0.1000p-1074
m1001p1074 = 0x9 / 16.0 * p1074 // = 0.1001p-1074
m1011p1074 = 0xb / 16.0 * p1074 // = 0.1011p-1074
m1100p1074 = 0xc / 16.0 * p1074 // = 0.1100p-1074
)
func main() {
test32(float32(m0000p149), f32(m0000p149))
test32(float32(m1000p149), f32(m1000p149))
test32(float32(m1001p149), f32(m1001p149))
test32(float32(m1011p149), f32(m1011p149))
test32(float32(m1100p149), f32(m1100p149))
test64(float64(m0000p1074), f64(m0000p1074))
test64(float64(m1000p1074), f64(m1000p1074))
test64(float64(m1001p1074), f64(m1001p1074))
test64(float64(m1011p1074), f64(m1011p1074))
test64(float64(m1100p1074), f64(m1100p1074))
}
func f32(x float64) float32 { return float32(x) }
func f64(x float64) float64 { return float64(x) }
func test32(a, b float32) {
abits := math.Float32bits(a)
bbits := math.Float32bits(b)
if abits != bbits {
panic(fmt.Sprintf("%08x != %08x\n", abits, bbits))
}
}
func test64(a, b float64) {
abits := math.Float64bits(a)
bbits := math.Float64bits(b)
if abits != bbits {
panic(fmt.Sprintf("%016x != %016x\n", abits, bbits))
}
}
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