Как хранить большой float64 в строке без переполнения? - PullRequest
0 голосов
/ 01 февраля 2019
func main() {
        target := 20190201518310870.0
        fmt.Println(int64(target))
        z3 := big.NewInt(int64(target))
        fmt.Println(z3)
}

Результат 20190201518310872

Как преобразовать его, а не переполнить?

1 Ответ

0 голосов
/ 01 февраля 2019

Проблема в том, что даже ваш введенный target номер не равен константе, которую вы ему присваиваете.

Тип float64 использует формат с плавающей запятой двойной точности (IEEE 754) для хранения числа, которое имеет конечные биты для использования (всего 64 бита, но только 53 бита используются для хранения значения).Это означает, что он может приблизительно хранить ~ 16 цифр, но ваш входной номер имеет 17, поэтому он будет округлен до ближайшего представимого float64.

Если вы напечатаете target, вы увидите точное число, которое«передан» на big.Int:

target := 20190201518310870.0
fmt.Printf("%f\n", target)

Выходы (попробуйте на Go Playground ):

20190201518310872.000000

Обратите внимание, что это работает, если входконстанта «вписывается» в float64:

target := 20190201518310.0
fmt.Printf("%f\n", target)
fmt.Println(int64(target))
z3 := big.NewInt(int64(target))
fmt.Println(z3)

Выходы (попробуйте на Go Playground ):

20190201518310.000000
20190201518310
20190201518310

Если вам нужно работать с большимичисла, точно такие как 20190201518310870.0, вы должны использовать другой тип, чтобы сохранить его в первую очередь, например, string, big.Int или big.Float, но не float64.

Например:

target := "20190201518310870"
fmt.Println(target)
z3, ok := big.NewInt(0).SetString(target, 10)
fmt.Println(z3, ok)

Вывод (попробуйте на Go Playground ):

20190201518310870
20190201518310870 true
...