Why `GO` integer `uint32` numbers are not equal after being converted to `float32`

36 views Asked by At

Why is the float32 integer part inconsistent with the original uint32 integer part after uint32 integer is converted to float32, but the float64 integer part is consistent with the original uint32 after converting it to float64.

import (
    "fmt"
)

const (
    deadbeef = 0xdeadbeef
    aa       = uint32(deadbeef)
    bb       = float32(deadbeef)
)

func main() {
    fmt.Println(aa)
    fmt.Println("%f",bb)
}

The result printed is:

3735928559
3735928576.000000

The explanation given in the book is that float32 is rounded up

Analyzed the binary information of 3735928559, 3735928576


3735928559: 1101 1110 1010 1101 1011 1110 1110 1111
3735928576: 1101 1110 1010 1101 1011 1111 0000 0000

It is found that 3735928576 is the result of setting the last eight positions of 3735928559 to 0 and the ninth last position to 1.

And this case is the result of rounding off the last 8 digits

const (
    deadbeef = 0xdeadbeef - 238
    aa       = uint32(deadbeef)
    bb       = float32(deadbeef)
)

func main() {
    fmt.Println(aa)
    fmt.Printf("%f",bb)
}

The result printed is:

3735928321
3735928320

Its binary result is

3735928321:1101 1110 1010 1101 1011 1110 0000 0000
3735928320:1101 1110 1010 1101 1011 1110 0000 0001

  1. Why float32(deadbeef) integer part is not equal to uint32(deadbeef) integer part? no fractional part after deadbeef
  2. Why float32(deadbeef) integer part differs from uint32(deadbeef) integer part by > 1

Why does this happen? If there is rounding up or down, what is the logic?

1

There are 1 answers

0
Kan Robert On

Because the precision range of float is not complete enough to represent the part of uint32, the real effective number of digits is actually seriously insufficient.

The precision of float32 can only provide about 6 decimal digits (after representing post-scientific notation, 6 decimal places) The precision of float64 provides about 15 decimal digits (after representing post-scientific notation, 15 decimal places)

So it's normal for this to happen.

And this is not only the Go language that will exist, but all languages that need to deal with this will have this problem.