dongwuli5105 2015-06-17 16:25
浏览 719
已采纳

如何以正确的方式将float64数字更改为uint64?

package main

func main() {
    var n float64 = 6161047830682206209
    println(uint64(n))
}

The output will be:

6161047830682206208

It looks like that when float64 change to uint64, the fraction is discarded.

  • 写回答

1条回答 默认 最新

  • dongle19863 2015-06-17 16:42
    关注

    The problem here is the representation of constants and floating point numbers.

    Constants are represented in arbitrary precision. Floating point numbers are represented using the IEEE 754 standard.

    Spec: Constants:

    Numeric constants represent values of arbitrary precision and do not overflow.

    Spec: Numeric types:

    float64     the set of all IEEE-754 64-bit floating-point numbers
    

    In IEEE 754 the double precision which is using 64 bits (float64 in Go) 53 bits are used to store the digits. This means the max digits (max number) that can be represented is the number of digits of 2<<52 which is (1 bit is for sign):

    2<<52        : 9007199254740992
    Your constant: 6161047830682206209
    

    15.95 digits to be precise (16 digits, but not all values that you can describe with 16 digits, only up to 9007199254740992).

    The integer constant you try to put into a variable of type float64 simply does not fit into 52 bits so it has to be rounded and digits (or bits) will be cut off (lost).

    You can verify this by printing the original n float64 number:

    var n float64 = 6161047830682206209
    fmt.Printf("%f
    ", n)
    fmt.Printf("%d
    ", uint64(n))
    

    Output:

    6161047830682206208.000000
    6161047830682206208
    

    The problem is not with conversion, the problem is that the float64 value you try to convert is already not equal to the constant you tried to assign to it.

    Just for curiosity:

    Try the same with a much bigger number: +500 compared to the first const:

    n = 6161047830682206709 // +500 compared to first!
    fmt.Printf("%f
    ", n2)
    fmt.Printf("%d
    ", uint64(n2))
    

    Output still the same (the last digits / bits are cut off, +500 included!):

    6161047830682206208.000000
    6161047830682206208
    

    Try a smaller number whose digits can be represented precisely using 52 bits (less than ~16 digits):

    n = 7830682206209
    fmt.Printf("%f
    ", n)
    fmt.Printf("%d
    ", uint64(n))
    

    Output:

    7830682206209.000000
    7830682206209
    

    Try it on the Go Playground.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 BP神经网络控制倒立摆
  • ¥20 要这个数学建模编程的代码 并且能完整允许出来结果 完整的过程和数据的结果
  • ¥15 html5+css和javascript有人可以帮吗?图片要怎么插入代码里面啊
  • ¥30 Unity接入微信SDK 无法开启摄像头
  • ¥20 有偿 写代码 要用特定的软件anaconda 里的jvpyter 用python3写
  • ¥20 cad图纸,chx-3六轴码垛机器人
  • ¥15 移动摄像头专网需要解vlan
  • ¥20 access多表提取相同字段数据并合并
  • ¥20 基于MSP430f5529的MPU6050驱动,求出欧拉角
  • ¥20 Java-Oj-桌布的计算