英文:
Go Float32bit() result not expected
问题
这段代码是用来将十进制数转换为32位单精度浮点数的二进制表示形式。根据IEEE 754标准,32位单精度浮点数由三个部分组成:符号位、指数位和尾数位。
在给定的例子中,我们将十进制数16777219.0转换为二进制表示形式。首先,我们将整数部分和小数部分分开,得到16777219。然后,我们将整数部分转换为二进制形式,得到1 0000 0000 0000 0000 0000 0011。接下来,我们确定尾数位和指数位的值。
尾数位的长度为23位,我们将整数部分的二进制形式中的前23位作为尾数位,得到0000 0000 0000 0000 0000 001。
指数位的计算方式是将指数值加上一个偏移值,对于32位单精度浮点数,偏移值为127。在这个例子中,指数值为24,加上偏移值得到151。然后,我们将151转换为8位的二进制形式,得到10010111。
最后,我们将符号位、指数位和尾数位组合起来,得到最终的32位二进制表示形式:0_10010111_000 0000 0000 0000 0000 0001。
根据这个规则,我们可以将其他的十进制数转换为32位单精度浮点数的二进制表示形式。
英文:
eg: 16777219.0 dec to bit
16777219 -> 1 0000 0000 0000 0000 0000 0011
Mantissa: 23 bit
0000 0000 0000 0000 0000 001
Exponent:
24+127 = 151
151 -> 10010111
Result shoud be:
0_10010111_000 0000 0000 0000 0000 0001
1001011100000000000000000000001
but:
fmt.Printf("%b\n", math.Float32bits(float32(16777219.0)))
// 1001011100000000000000000000010
why the Go Float32bit() result not expected?
reference:
update:
fmt.Printf("16777216.0:%b\n", math.Float32bits(float32(16777216.0)))
fmt.Printf("16777217.0:%b\n", math.Float32bits(float32(16777217.0)))
//16777216.0:1001011100000000000000000000000
//16777217.0:1001011100000000000000000000000
fmt.Printf("16777218.0:%b\n", math.Float32bits(float32(16777218.0)))
//16777218.0:1001011100000000000000000000001
fmt.Printf("16777219.0:%b\n", math.Float32bits(float32(16777219.0)))
fmt.Printf("16777220.0:%b\n", math.Float32bits(float32(16777220.0)))
fmt.Printf("16777221.0:%b\n", math.Float32bits(float32(16777221.0)))
//16777219.0:1001011100000000000000000000010
//16777220.0:1001011100000000000000000000010
//16777221.0:1001011100000000000000000000010
fmt.Printf("000:%f\n", math.Float32frombits(0b_10010111_00000000000000000000000))
// 000:16777216.000000
fmt.Printf("001:%f\n", math.Float32frombits(0b_10010111_00000000000000000000001))
// 001:16777218.000000
fmt.Printf("010:%f\n", math.Float32frombits(0b_10010111_00000000000000000000010))
// 010:16777220.000000
fmt.Printf("011:%f\n", math.Float32frombits(0b_10010111_00000000000000000000011))
// 011:16777222.000000
what is the rules?
答案1
得分: 1
为什么结果不符合预期:你期望的结果是错误的。
IEEE 754标准规定,根据维基百科:
> 如果数字处于中间位置,则四舍五入为最接近的具有偶数最低有效位的值。
因此,当对16777219进行四舍五入时,它处于16777218和16777218之间。选择“向上取整”的选项16777220具有偶数的最低有效位,并且是你观察到的正确结果。
英文:
Why the result is not expected: You're expecting the wrong result.
The IEEE 754 standard specifies that, per Wikipedia:
> if the number falls midway, it is rounded to the nearest value with an even least significant digit.
So when rounding 16777219, which is midway between 16777218 and 16777218. The "round up" option 16777220 gives an even LSB, and is the correct result you're observing.
答案2
得分: 1
Go提供了正确的IEEE-754二进制浮点数结果-四舍五入到最近的偶数。
十进制数16777219的二进制表示为1000000000000000000000011。
对于32位IEEE-754浮点数,24位整数尾数为100000000000000000000001.1。
四舍五入到最近的偶数得到100000000000000000000010。
去掉23位尾数的隐含1位得到00000000000000000000010。
以上是给出的代码的输出结果:
16777219
1000000000000000000000011
1.677722e+07
1001011100000000000000000000010
英文:
Go gives the correct IEEE-754 binary floating point result - round to nearest, ties to even.
> The Go Programming Language Specification
>
> float32 the set of all IEEE-754 32-bit floating-point numbers
Decimal
16777219
is binary
1000000000000000000000011
For 32-bit IEEE-754 floating-point binary binary, the 24-bit integer mantissa is
100000000000000000000001.1
Round to nearest, ties to even gives
100000000000000000000010
Removing the implicit one bit for the 23-bit mantissa gives
00000000000000000000010
package main
import (
"fmt"
"math"
)
func main() {
const n = 16777219
fmt.Printf("%d\n", n)
fmt.Printf("%b\n", n)
f := float32(n)
fmt.Printf("%g\n", f)
fmt.Printf("%b\n", math.Float32bits(f))
}
https://go.dev/play/p/yMaVkuiSJ5A
16777219
1000000000000000000000011
1.677722e+07
1001011100000000000000000000010
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论