[英]golang convert big.Float to big.Int
convert big.Float to big.Int, i write code below, but it overflow with uint64, so what's the correct way to cenvert big.Float to big.Int.将 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)))
}
A big int bigger than uint64
will always cause an overflow as uint64
has fixed size.由于
uint64
具有固定大小, uint64
大于uint64
big int 将始终导致溢出。 You should use the following method on *Float
:您应该在
*Float
上使用以下方法:
func (*Float) Int
The changes required would be:所需的更改是:
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
}
Working example: https://play.golang.org/p/sEhH6iPkrK工作示例: https : //play.golang.org/p/sEhH6iPkrK
使用函数Float.Int(nil)
I have worked with a regular float64 number (not big.Float) and found out that conversion via string is the most precise way.我使用了一个普通的 float64 数字(不是 big.Float),发现通过字符串进行转换是最精确的方法。 Check it out
一探究竟
Note: the example is for float64 -> decimal(,20) conversion.注意:该示例用于 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
}
https://play.golang.org/p/_lkyQ_0udjd https://play.golang.org/p/_lkyQ_0udjd
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.