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
- Why float32(deadbeef) integer part is not equal to uint32(deadbeef) integer part? no fractional part after deadbeef
- 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?
Because the precision range of
float
is not complete enough to represent the part ofuint32
, 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 offloat64
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.