mirror of
https://github.com/golang/go
synced 2024-11-25 04:57:56 -07:00
gc: correct rounding of denormal constants
Fixes #1463. R=rsc CC=golang-dev https://golang.org/cl/4079060
This commit is contained in:
parent
fb9fc886ff
commit
cf63e34b1d
@ -179,7 +179,7 @@ mpdivfltflt(Mpflt *a, Mpflt *b)
|
||||
double
|
||||
mpgetflt(Mpflt *a)
|
||||
{
|
||||
int s, i;
|
||||
int s, i, e;
|
||||
uvlong v, vm;
|
||||
double f;
|
||||
|
||||
@ -200,12 +200,12 @@ mpgetflt(Mpflt *a)
|
||||
a->exp -= 1;
|
||||
}
|
||||
|
||||
// the magic numbers (64, 63, 53, 10) are
|
||||
// the magic numbers (64, 63, 53, 10, -1074) are
|
||||
// IEEE specific. this should be done machine
|
||||
// independently or in the 6g half of the compiler
|
||||
|
||||
// pick up the mantissa in a uvlong
|
||||
s = 53;
|
||||
// pick up the mantissa and a rounding bit in a uvlong
|
||||
s = 53+1;
|
||||
v = 0;
|
||||
for(i=Mpnorm-1; s>=Mpscale; i--) {
|
||||
v = (v<<Mpscale) | a->val.a[i];
|
||||
@ -224,13 +224,26 @@ mpgetflt(Mpflt *a)
|
||||
if(s > 0)
|
||||
v = (v<<s) | (a->val.a[i]>>(Mpscale-s));
|
||||
|
||||
// gradual underflow
|
||||
e = Mpnorm*Mpscale + a->exp - 53;
|
||||
if(e < -1074) {
|
||||
s = -e - 1074;
|
||||
if(s > 54)
|
||||
s = 54;
|
||||
v |= vm & ((1ULL<<s) - 1);
|
||||
vm >>= s;
|
||||
e = -1074;
|
||||
}
|
||||
|
||||
//print("vm=%.16llux v=%.16llux\n", vm, v);
|
||||
// round toward even
|
||||
if(v != (1ULL<<63) || (vm&1ULL) != 0)
|
||||
vm += v>>63;
|
||||
if(v != 0 || (vm&2ULL) != 0)
|
||||
vm = (vm>>1) + (vm&1ULL);
|
||||
else
|
||||
vm >>= 1;
|
||||
|
||||
f = (double)(vm);
|
||||
f = ldexp(f, Mpnorm*Mpscale + a->exp - 53);
|
||||
f = ldexp(f, e);
|
||||
|
||||
if(a->val.neg)
|
||||
f = -f;
|
||||
|
@ -121,9 +121,8 @@ var ftoatests = []ftoaTest{
|
||||
|
||||
// http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
|
||||
{2.2250738585072012e-308, 'g', -1, "2.2250738585072014e-308"},
|
||||
// TODO: uncomment after fixing issue 1463.
|
||||
// http://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
|
||||
// {2.2250738585072011e-308, 'g', -1, "2.225073858507201e-308"},
|
||||
{2.2250738585072011e-308, 'g', -1, "2.225073858507201e-308"},
|
||||
}
|
||||
|
||||
func TestFtoa(t *testing.T) {
|
||||
|
30
test/fixedbugs/bug321.go
Normal file
30
test/fixedbugs/bug321.go
Normal file
@ -0,0 +1,30 @@
|
||||
// $G $D/$F.go && $L $F.$A && ./$A.out || echo BUG: bug321
|
||||
|
||||
// Copyright 2011 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.
|
||||
|
||||
// Troublesome floating point constants. Issue 1463.
|
||||
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func check(test string, got, want float64) bool {
|
||||
if got != want {
|
||||
fmt.Println(test, "got", got, "want", want)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func main() {
|
||||
good := true
|
||||
// http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
|
||||
good = good && check("2.2250738585072012e-308", 2.2250738585072012e-308, 2.2250738585072014e-308)
|
||||
// http://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
|
||||
good = good && check("2.2250738585072011e-308", 2.2250738585072011e-308, 2.225073858507201e-308)
|
||||
if !good {
|
||||
panic("fail")
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user