我正在尝试更好地理解浮点运算,并且看到了一些指向“每个计算机科学家应该了解的浮点运算知识”的链接。
我仍然不明白像 0.1
或 0.5
这样的数字是如何以 float 和小数形式存储的。
谁能解释一下内存是如何布局的?
我知道 float 由两部分组成(即,某事物的幂数)。
最佳答案
我总是将人们引向 Harald Schmidt's online converter , 以及 Wikipedia IEEE754-1985 article及其漂亮的图片。
对于这两个特定值,您会得到(对于 0.1):
s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm 1/n
0 01111011 10011001100110011001101
| || || || || || +- 8388608
| || || || || |+--- 2097152
| || || || || +---- 1048576
| || || || |+------- 131072
| || || || +-------- 65536
| || || |+----------- 8192
| || || +------------ 4096
| || |+--------------- 512
| || +---------------- 256
| |+------------------- 32
| +-------------------- 16
+----------------------- 2
符号是正的,这很简单。
指数是64+32+16+8+2+1 = 123 - 127 bias = -4
, 所以乘数是 2<sup>-4</sup>
或 1/16
.
尾数很粗。它由 1
组成(隐式基数)加上(对于所有那些每个值都为 1/(2<sup>n</sup>)
的位,因为 n
从 1
开始并向右增加),{1/2, 1/16, 1/32, 1/256, 1/512, 1/4096, 1/8192, 1/65536, 1/131072, 1/1048576, 1/2097152, 1/8388608}
.
当你把所有这些加起来,你会得到 1.60000002384185791015625
.
当您将其乘以乘数时,您会得到 0.100000001490116119384765625
,这就是为什么他们说你不能代表 0.1
完全像一个 IEEE754 float ,并为回答 "why doesn't 0.1 + 0.1 + 0.1 == 0.3?"
的人提供了很多关于 SO 的机会类型问题:-)
0.5 的例子要简单得多。它表示为:
s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm
0 01111110 00000000000000000000000
这意味着它是隐式基础,1
,加上没有其他添加剂(所有尾数位为零)。
符号再次为正。指数为 64+32+16+8+4+2 = 126 - 127 bias = -1
.因此乘数是2<sup>-1</sup>
这是 1/2
或 0.5
.
所以最终值为1
乘以 0.5
, 或 0.5
.瞧!
有时我发现用小数来思考它更容易。
数字 1.345 相当于
1 + 3/10 + 4/100 + 5/1000
或:
-1 -2 -3
1 + 3*10 + 4*10 + 5*10
同样,十进制的 IEEE754 表示 0.8125
是:
s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm
0 01111110 10100000000000000000000
以 1 为隐式基数,这等同于二进制:
01111110-01111111
1.101 * 2
或:
-1
(1 + 1/2 + 1/8) * 2 (no 1/4 since that bit is 0)
变成:
(8/8 + 4/8 + 1/8) * 1/2
然后变成:
13/8 * 1/2 = 0.8125
关于c# - 0.1在浮点运算和小数中如何表示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3448777/