You are not doing the same operation in Go and in Python. In Go you divide 2 floating point numbers, while in Python you divide 2 integer numbers. The results are only "roughly" equal because the input numbers you provide lose precision, and the accuracy of the floating point operation is also limited (insufficient).
If you perform the same integer division in Go (using the big.Int
type), you get the same result:
i, ok := big.NewInt(0).SetString("26959535291011309493156476344723991336010898738574164086137773096960000000", 10)
if !ok {
panic("invalid")
}
j, ok := big.NewInt(0).SetString("14484162361", 10)
if !ok {
panic("invalid")
}
k := big.NewInt(0).Quo(i, j)
fmt.Println(k)
This outputs:
1861311315012765306929610463010191006516769515973403833769533170
If you want to perform floating point division in Go, don't use float64
type to represent your inputs, as they are limited in precision. This will happen because you created your input numbers using big.NewFloat()
which has a parameter of float64
type, so the constants you pass will be implicitly converted to float64
and you already lose precision.
Instead use the big.Float
type, and specify your input as string
values and set it using Float.SetString()
; and manually increase the precision (using Float.SetPrec()
). If you do so, you will get the "same" result (same in the integer part, plus some fraction value):
x, ok := big.NewFloat(0).SetPrec(500).SetString("26959535291011309493156476344723991336010898738574164086137773096960")
if !ok {
panic("invalid")
}
y, ok := big.NewFloat(0).SetPrec(500).SetString("14484.162361")
if !ok {
panic("invalid")
}
z := new(big.Float).SetPrec(500).Quo(x, y)
fmt.Println(fmt.Sprintf("%f", z))
Output:
1861311315012765306929610463010191006516769515973403833769533170.518151
Try the examples on the Go Playground.
Note that precision of Float.Quo()
depends on:
Precision, rounding, and accuracy reporting are as for Add.
Which is:
If z's precision is 0, it is changed to the larger of x's or y's precision before the operation. Rounding is performed according to z's precision and rounding mode; and z's accuracy reports the result error relative to the exact (not rounded) result.