mirror of
https://github.com/golang/go
synced 2024-11-21 21:54:40 -07:00
math: improve math.Log to handle subnormal floating number correctly on amd64
The existing implementation for math.Log on amd64/s390x, math/log_amd64.S, doesn't normalize subnormal IEEE 64-bit floating point number correctly. This only occurs on amd64/s390x. The go implementation of log, which is used on other architecture does handle subnormal floating number correctly. This commit add normalize logic to math/log_amd64.S. Fixes #56600
This commit is contained in:
parent
1c05968c9a
commit
d6edc2c4db
@ -1511,6 +1511,27 @@ var logSC = []float64{
|
||||
NaN(),
|
||||
}
|
||||
|
||||
var vflogBC = []float64{
|
||||
SmallestNonzeroFloat64,
|
||||
LargestSubnormalFloat64,
|
||||
SmallestNormalFloat64,
|
||||
MaxFloat64,
|
||||
-SmallestNonzeroFloat64,
|
||||
-LargestSubnormalFloat64,
|
||||
-SmallestNormalFloat64,
|
||||
-MaxFloat64,
|
||||
}
|
||||
var logBC = []float64{
|
||||
-744.4400719213812,
|
||||
-708.3964185322641,
|
||||
-708.3964185322641,
|
||||
709.782712893384,
|
||||
NaN(),
|
||||
NaN(),
|
||||
NaN(),
|
||||
NaN(),
|
||||
}
|
||||
|
||||
var vflogbSC = []float64{
|
||||
Inf(-1),
|
||||
0,
|
||||
@ -2717,6 +2738,12 @@ func TestLog(t *testing.T) {
|
||||
t.Errorf("Log(%g) = %g, want %g", vflogSC[i], f, logSC[i])
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < len(vflogBC); i++ {
|
||||
if f := Log(vflogBC[i]); !alike(logBC[i], f) {
|
||||
t.Errorf("Log(%g) = %g, want %g", vflogBC[i], f, logBC[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLogb(t *testing.T) {
|
||||
|
@ -14,6 +14,7 @@
|
||||
#define L5 1.818357216161805012e-01 // 0x3FC7466496CB03DE
|
||||
#define L6 1.531383769920937332e-01 // 0x3FC39A09D078C69F
|
||||
#define L7 1.479819860511658591e-01 // 0x3FC2F112DF3E5244
|
||||
#define Two52 4.503599627370496e15 // 0x4330000000000000 (2**52)
|
||||
#define NaN 0x7FF8000000000001
|
||||
#define NegInf 0xFFF0000000000000
|
||||
#define PosInf 0x7FF0000000000000
|
||||
@ -32,7 +33,16 @@ TEXT ·archLog(SB),NOSPLIT,$0
|
||||
CMPQ AX, BX
|
||||
JLE isInfOrNaN
|
||||
// f1, ki := math.Frexp(x); k := float64(ki)
|
||||
MOVQ $0, CX
|
||||
MOVQ BX, X0
|
||||
ANDQ BX, AX
|
||||
JNE isNormal
|
||||
// f, exp = normalize(f)
|
||||
MOVSD $Two52, X1
|
||||
MULSD X1, X0
|
||||
MOVQ X0, BX
|
||||
MOVQ $-52, CX
|
||||
isNormal:
|
||||
MOVQ $0x000FFFFFFFFFFFFF, AX
|
||||
MOVQ AX, X2
|
||||
ANDPD X0, X2
|
||||
@ -41,6 +51,7 @@ TEXT ·archLog(SB),NOSPLIT,$0
|
||||
SHRQ $52, BX
|
||||
ANDL $0x7FF, BX
|
||||
SUBL $0x3FE, BX
|
||||
ADDQ CX, BX
|
||||
XORPS X1, X1 // break dependency for CVTSL2SD
|
||||
CVTSL2SD BX, X1 // x1= k, x2= f1
|
||||
// if f1 < math.Sqrt2/2 { k -= 1; f1 *= 2 }
|
||||
|
Loading…
Reference in New Issue
Block a user