Golang将Big.Float转换为Big.Int



将big.float转换为big.int,我在下面编写代码,但它会随着uint64的溢出而溢出,所以什么是cenvert big.float.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)))
}

大于 uint64的大插入总是会导致溢出,因为 uint64具有固定的大小。您应该在*Float上使用以下方法:

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
}

工作示例:https://play.golang.org/p/sehhh6ipkrk

使用函数float.int(nil)

我已经使用了常规的float64号码(不是big.float),并发现通过字符串转换是最精确的方法。检查一下

注意:该示例适用于float64 - >十进制(,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

最新更新