如何用浮点算术和小数表示 0.1

发布于 2024-09-14 04:47:29 字数 181 浏览 6 评论 0原文

我试图更好地理解浮点算术,并且看到了一些“每个计算机科学家应该了解浮点算术”的链接。

我仍然不明白像 0.10.5 这样的数字如何存储在浮点数和小数中。

有人可以解释一下内存是如何排列的吗?

我知道浮点数是由两部分组成(即一个数字的幂次方)。

I am trying to understand floating point arithmetic better and have seen a few links to 'What Every Computer Scientist Should Know About Floating Point Arithmetic'.

I still don't understand how a number like 0.1 or 0.5 is stored in floats and as decimals.

Can someone please explain how it is laid out is memory?

I know about the float being two parts (i.e., a number to the power of something).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

帅气尐潴 2024-09-21 04:47:29

我总是向人们推荐 Harald Schmidt 的在线转换器,以及 维基百科 IEEE754-1985 文章 及其漂亮的图片。

对于这两个特定值,您将得到(对于 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 - 127bias = -4,因此乘数为 2-41/16

尾数很粗。它由 1 (隐式基数)加上(对于所有这些位,每个位的值都是 1/(2n) 作为 n1 开始,向右递增),{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浮点数,并为人们提供了如此多的机会回答“为什么不 0.1 + 0.1 + 0.1 == 0.3?” 类型的问题:-)


0.5 的例子要容易得多。它表示为:

s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm
0 01111110 00000000000000000000000

这意味着它是隐式基数 1,加上没有其他添加剂(所有尾数位均为零)。

该迹象再次呈阳性。指数为 64+32+16+8+4+2 = 126 - 127 偏差 = -1。因此乘数为 2-1,即 1/20.5

因此最终值是 1 乘以 0.5,即 0.5。瞧!


我有时发现用十进制来思考更容易。

数字 1.345 相当于

1 + 3/10   + 4/100 + 5/1000

or:

        -1       -2      -3
1 + 3*10   + 4*10  + 5*10

类似地,十进制 0.8125 的 IEEE754 表示为:

s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm
0 01111110 10100000000000000000000

隐式基数为 1,相当于二进制:

         01111110-01111111
1.101 * 2

or:

                     -1
(1   + 1/2 + 1/8) * 2     (no 1/4 since that bit is 0)

变为:

(8/8 + 4/8 + 1/8) * 1/2

and then 变为:

13/8 * 1/2 = 0.8125

I've always pointed people towards Harald Schmidt's online converter, along with the Wikipedia IEEE754-1985 article with its nice pictures.

For those two specific values, you get (for 0.1):

s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm    1/n
0 01111011 10011001100110011001101
           |  ||  ||  ||  ||  || +- 8388608
           |  ||  ||  ||  ||  |+--- 2097152
           |  ||  ||  ||  ||  +---- 1048576
           |  ||  ||  ||  |+-------  131072
           |  ||  ||  ||  +--------   65536
           |  ||  ||  |+-----------    8192
           |  ||  ||  +------------    4096
           |  ||  |+---------------     512
           |  ||  +----------------     256
           |  |+-------------------      32
           |  +--------------------      16
           +-----------------------       2

The sign is positive, that's pretty easy.

The exponent is 64+32+16+8+2+1 = 123 - 127 bias = -4, so the multiplier is 2-4 or 1/16.

The mantissa is chunky. It consists of 1 (the implicit base) plus (for all those bits with each being worth 1/(2n) as n starts at 1 and increases to the right), {1/2, 1/16, 1/32, 1/256, 1/512, 1/4096, 1/8192, 1/65536, 1/131072, 1/1048576, 1/2097152, 1/8388608}.

When you add all these up, you get 1.60000002384185791015625.

When you multiply that by the multiplier, you get 0.100000001490116119384765625, which is why they say you cannot represent 0.1 exactly as an IEEE754 float, and provides so much opportunity on SO for people answering "why doesn't 0.1 + 0.1 + 0.1 == 0.3?"-type questions :-)


The 0.5 example is substantially easier. It's represented as:

s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm
0 01111110 00000000000000000000000

which means it's the implicit base, 1, plus no other additives (all the mantissa bits are zero).

The sign is again positive. The exponent is 64+32+16+8+4+2 = 126 - 127 bias = -1. Hence the multiplier is 2-1 which is 1/2 or 0.5.

So the final value is 1 multiplied by 0.5, or 0.5. Voila!


I've sometimes found it easier to think of it in terms of decimal.

The number 1.345 is equivalent to

1 + 3/10   + 4/100 + 5/1000

or:

        -1       -2      -3
1 + 3*10   + 4*10  + 5*10

Similarly, the IEEE754 representation for decimal 0.8125 is:

s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm
0 01111110 10100000000000000000000

With the implicit base of 1, that's equivalent to the binary:

         01111110-01111111
1.101 * 2

or:

                     -1
(1   + 1/2 + 1/8) * 2     (no 1/4 since that bit is 0)

which becomes:

(8/8 + 4/8 + 1/8) * 1/2

and then becomes:

13/8 * 1/2 = 0.8125
风月客 2024-09-21 04:47:29

请参阅维基百科条目IEEE 组

基本上,有一个符号、一个数字和一个指数。如果源基数具有目标基数中不存在的因子,则一个基数中的数字无法在另一基数中有限地表示。例如,1/3 不能表示为有限十进制数,但表示为三进制(以 3 为基数)数很简单:(0.1)3

因此 0.5 有一个有限二进制表示,(0.1)2,即 2-1,但 0.1 有一个重复< /em> 表示,因为 2 和 10 有一个不共同的因子 (5)。

See the Wikipedia entry and the IEEE group, first.

Basically, there's a sign, a number, and an exponent. A number in one base cannot be represented finitely in another base if the source base has factors not present in the destination base. For instance, 1/3 cannot be represented as a finite decimal number, but is trivial to represent as a ternary (base-3) number: (0.1)3.

So 0.5 has a finite binary representation, (0.1)2, that is, 2-1, but 0.1 has a repeating representation because 2 and 10 have a factor (5) not in common.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文