Go Float32bit() 结果不符合预期

huangapple go评论60阅读模式
英文:

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

huangapple
  • 本文由 发表于 2023年2月6日 11:43:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/75357159.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定