将big.Float转换为big.Int,我在下面编写代码,但是它溢出了uint64,那么将big.Float转换为big.Int的正确方法是什么。
package main
import "fmt"
import "math/big"
func FloatToBigInt(val float64) *big.Int {
bigval := new(big.Float)
bigval.SetFloat64(val)
coin := new(big.Float)
coin.SetInt(big.NewInt(1000000000000000000))
bigval.Mul(bigval, coin)
result := new(big.Int)
f,_ := bigval.Uint64()
result.SetUint64(f)
return result
}
func main() {
fmt.Println("vim-go")
fmt.Println(FloatToBigInt(float64(10)))
fmt.Println(FloatToBigInt(float64(20)))
fmt.Println(FloatToBigInt(float64(30)))
fmt.Println(FloatToBigInt(float64(40)))
fmt.Println(FloatToBigInt(float64(50)))
fmt.Println(FloatToBigInt(float64(100)))
fmt.Println(FloatToBigInt(float64(1000)))
fmt.Println(FloatToBigInt(float64(10000)))
}
答案 0 :(得分:3)
大于uint64
的大型int将始终导致溢出,因为uint64
具有固定大小。您应该在*Float
上使用以下method:
func (*Float) Int
所需的更改将是:
func FloatToBigInt(val float64) *big.Int {
bigval := new(big.Float)
bigval.SetFloat64(val)
// Set precision if required.
// bigval.SetPrec(64)
coin := new(big.Float)
coin.SetInt(big.NewInt(1000000000000000000))
bigval.Mul(bigval, coin)
result := new(big.Int)
bigval.Int(result) // store converted number in result
return result
}
答案 1 :(得分:0)
我使用了一个普通的 float64 数字(不是 big.Float),发现通过字符串进行转换是最精确的方法。检查一下
注意:示例是 float64 -> decimal(,20) 转换。
func bigIntViaString(flt float64) (b *big.Int) {
if math.IsNaN(flt) || math.IsInf(flt, 0) {
return nil // illegal case
}
var in = strconv.FormatFloat(flt, 'f', -1, 64)
const parts = 2
var ss = strings.SplitN(in, ".", parts)
// protect from numbers without period
if len(ss) != parts {
ss = append(ss, "0")
}
// protect from ".0" and "0." values
if ss[0] == "" {
ss[0] = "0"
}
if ss[1] == "" {
ss[1] = "0"
}
const (
base = 10
fraction = 20
)
// get fraction length
var fract = len(ss[1])
if fract > fraction {
ss[1], fract = ss[1][:fraction], fraction
}
in = strings.Join([]string{ss[0], ss[1]}, "")
// convert to big integer from the string
b, _ = big.NewInt(0).SetString(in, base)
if fract == fraction {
return // ready
}
// fract < 20, * (20 - fract)
var (
ten = big.NewInt(base)
exp = ten.Exp(ten, big.NewInt(fraction-int64(fract)), nil)
)
b = b.Mul(b, exp)
return
}