-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Closed
Closed
Copy link
Labels
FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone
Description
Go version
go version go1.22.3 darwin/arm64
Output of go env in your module/workspace:
GO111MODULE='on'
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/sonumb/Library/Caches/go-build'
GOENV='/Users/sonumb/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/sonumb/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/sonumb/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.22.3'
GCCGO='gccgo'
AR='ar'
CC='clang'
CXX='clang++'
CGO_ENABLED='1'
GOMOD='/dev/null'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/7n/2904fqr55nv8px1km09jjnmw0000gp/T/go-build968614564=/tmp/go-build -gno-record-gcc-switches -fno-common'What did you do?
a.go
package main
/*
#include <stdlib.h>
#include <math.h>
*/
import "C"
//export CExp
func CExp(x float64) float64 {
ret := C.exp(C.double(x)) // This result are same with result of math.Exp() on amd64/darwin.
return float64(ret)
}b.go
package main
import (
"fmt"
"math"
)
//----------------------------------------------------------------
// same with math/exp.go
func GoExp(x float64) float64 {
const (
Ln2Hi = 6.93147180369123816490e-01
Ln2Lo = 1.90821492927058770002e-10
Log2e = 1.44269504088896338700e+00
Overflow = 7.09782712893383973096e+02
Underflow = -7.45133219101941108420e+02
NearZero = 1.0 / (1 << 28) // 2**-28
)
// special cases
switch {
case math.IsNaN(x) || math.IsInf(x, 1):
return x
case math.IsInf(x, -1):
return 0
case x > Overflow:
return math.Inf(1)
case x < Underflow:
return 0
case -NearZero < x && x < NearZero:
return 1 + x
}
// reduce; computed as r = hi - lo for extra precision.
var k int
switch {
case x < 0:
k = int(Log2e*x - 0.5)
case x > 0:
k = int(Log2e*x + 0.5)
}
hi := x - float64(k)*Ln2Hi
lo := float64(k) * Ln2Lo
// compute
return expmulti(hi, lo, k)
}
func expmulti(hi, lo float64, k int) float64 {
const (
P1 = 1.66666666666666657415e-01 /* 0x3FC55555; 0x55555555 */
P2 = -2.77777777770155933842e-03 /* 0xBF66C16C; 0x16BEBD93 */
P3 = 6.61375632143793436117e-05 /* 0x3F11566A; 0xAF25DE2C */
P4 = -1.65339022054652515390e-06 /* 0xBEBBBD41; 0xC5D26BF1 */
P5 = 4.13813679705723846039e-08 /* 0x3E663769; 0x72BEA4D0 */
)
r := hi - lo
t := r * r
c := r - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))))
y := 1 - ((lo - (r*c)/(2-c)) - hi)
// TODO(rsc): make sure Ldexp can handle boundary k
return math.Ldexp(y, k)
}
//----------------------------------------------------------------
func main() {
var a float64 = 63.5
// C.exp()
ret := CExp(a) * 10000.0
fmt.Println(ret, math.Mod(ret, 100.0))
// math.Exp() true haveArchExp
ret = math.Exp(a) * 10000.0
fmt.Println(ret, math.Mod(ret, 100.0))
// math.Exp() false haveArchExp
ret = GoExp(a) * 10000.0
fmt.Println(ret, math.Mod(ret, 100.0))
}What did you see happen?
We expected the results of the exp() function from the C library and Go's math.Exp() to be the same on arm64/darwin. However, they were not.
$ go run a.go b.go
3.7818090853912896e+31 84 # same result in amd64/darwin
3.78180908539129e+31 80
3.78180908539129e+31 80
Python result on arm64/darwin was below.
# builtin math
$ python3 -c "import math; print((math.exp(63.5)*10000.0)%100.0)"
84.0
# numpy
$ python3 -c "import numpy as np; print((np.exp(63.5)*10000)%100)"
84.0
What did you expect to see?
I think that when the OS and architecture are different, the results of functions can vary. However, at the very least, the consistency of the results of functions in the 'math' package should be guaranteed, regardless of the OS or architecture.
run above codes on "arm64/darwin"
$ go run a.go b.go
3.7818090853912896e+31 84 # same result in amd64/darwin
3.7818090853912896e+31 84
3.7818090853912896e+31 84
Metadata
Metadata
Assignees
Labels
FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.