golang将big.Float转换为big.Int

o75abkj4  于 11个月前  发布在  Go
关注(0)|答案(4)|浏览(115)

把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)))
}

字符串

sgtfey8w

sgtfey8w1#

一个大于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/sEhH6iPkrK

bmp9r5qi

bmp9r5qi2#

使用函数Float.Int(nil)

oalqel3c

oalqel3c3#

我曾经处理过一个常规的float 64数字(不大。Float),发现通过字符串进行转换是最精确的方法。
注意:该示例用于float 64-> 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

tp5buhyn

tp5buhyn4#

我的例子,就是把big.Float转换成big.Int

func floatToInt(input *big.Float) *big.Int {
    out, _ := input.Int(new(big.Int))
    return out
}

字符串
为了以防万一,

func intToFloat(input *big.Int) *big.Float {
    return new(big.Float).SetInt(input)
}


我希望它能帮助任何人。

相关问题