【问题标题】:Matlab representation of floating point numbers浮点数的Matlab表示
【发布时间】:2016-05-17 12:02:02
【问题描述】:

realmax('single') 的 Matlab 结果为 ans = 3.4028e+38。我试图理解为什么这个数字出现在计算机的二进制表示中,但我有点困惑。

我知道 realmax('single') 是 32 位单精度表示的最高浮点数。这意味着二进制表示由 1 位符号、23 位尾数和 8 位指数组成。而 3.4028e+38 是最高单精度浮点数的十进制表示,但我不知道这个数字是怎么推导出来的。

现在,输入 2^128 给出的答案与 3.4028e+38 相同,但我不明白其中的相关性。

从二进制表示的角度来看,为什么 3.4028e+38 是 32 位格式的浮点数的最大返回结果?谢谢。

【问题讨论】:

  • 是的,我自己在尝试理解这一点时看过这篇维基百科文章。尽管对许多人来说似乎很简单,但我仍然对如何导出最大的单精度浮点数感到困惑。我希望有人能给出一些解释,以帮助消除我的困惑。

标签: matlab binary floating-point


【解决方案1】:

正如IEEE754 指定的,最大幅度指数为 Emax=12710=7F16=0111 11112 。这在 8 个指数位中编码为 25410=FE16=1111 11102。指数 25510=FF16=1111 11112 保留用于表示无穷大,因此 25410 是最大的可用。从导致 25410-12710=12710 的指数位中减去指数偏差 12710。当所有 23 个尾数位都设置为 1 时,获得最大尾数。可以表示的最大值为 1.111111111111111111111112x2127=3.402823510子>x1038

site 可让您设置表示的位并查看以十进制、二进制和十六进制表示的 IEEE754 值。

还要注意最大值小于2^128。您可以使用format long 更精确地表示 MATLAB 中的数字输出。它们相似的原因是因为 1.111111111111111111111112x2127 接近 102x2127=12x2128.

【讨论】:

  • 具体来说,realmax('single') == (single(2)-eps('single'))*single(2)^127,其中eps('single')single(2)^-23。双精度:realmax('single') == 2^128-2^104.
【解决方案2】:

作为计算机中数字的单精度二进制浮点表示的先驱,我首先讨论十进制数的所谓“科学记数法”。

使用以 10 为底的数字系统,每个正十进制数在集合 {1..9} 中都有第一个非零前导数字。 (所有其他数字都在集合 {0..9} 中。)数字的小数点总是可以通过乘以数字基数 10 的适当幂 10^n 来移动到该前导数字的最右边。例如0.012345 = 1.2345*10^n 其中 n = -2。这意味着每个非零数 x 的十进制表示可以采用以下形式

    x = (+/-)(i.jklm...)*10^n ; where i is in the set {1,2,3,4,5,6,7,8,9}.

前导小数因子(i.jklm...),称为x的“尾数”,是区间[1,10)中的一个数,即大于等于1且小于10。尾数的最大值可以是 9.9999... 所以数字 x 的实际“大小”是存储在指数因子 10^n 中的整数。如果 x 很大,则 n >> 0,而如果 x 很小,则 n

我们现在想使用与计算机存储数字相关的以 2 为底的数字系统来重新审视这些想法。计算机内部使用以 2 为底的数字表示数字,而不是更熟悉的以 10 为底的数字。数字的“二进制”表示中使用的所有数字都属于集合 {0,1}。使用与我们在十进制表示中相同的思维方式以二进制表示形式表示 x,我们看到每个正数 x 都具有以下形式

    x = (+/-)(i.jklm...)*2^n ; where i = 1, 

而其余数字属于 {0,1}。

这里领先的二进制因子(尾数)i.jklm...位于区间[1,2),而不是与十进制系统中尾数相关的区间[1,10)。此处尾数以二进制数 1.1111... 为界,它始终小于 2,因为实际上永远不会有无限位数。和以前一样,数字 x 的实际“大小”存储在整数指数因子 2^n 中。当 x 很大时 n >> 0 并且当 x 非常小时 n

x 的(单精度)二进制表示的标准约定是通过在计算机内存中准确存储 32 位(0 或 1)来实现的。第一位用于表示数字的算术“符号”。这使得 31 位要分布在 x 的尾数 (i.jklm...) 和指数因子 2^n 之间。 (回想一下 i.jklmn 中的 i = 1 ......所以它的表示不需要 31 位中的任何一个。)此时,一个重要的“权衡”开始发挥作用:

专用于 x 的尾数 (i.jkl...) 的位越多,可用于在其指数因子 2^n 中表示指数 n 的位就越少。通常 23 位专用于 x 的尾数。 (不难证明,在十进制系统中,x 的精度大约为 7 位,这对于大多数科学工作来说已经足够了。)由于第一个位专门用于存储 x 的符号,因此剩下 8 位可用于表示因子 2^n 中的 n。由于我们希望允许非常大的 x 和非常小的 x,因此决定以

的形式存储 2^n
    2^n = 2^(m-127) ; n = m - 127,

存储指数 m 而不是 n。利用 8 位,这意味着 m 属于二进制整数集合 {000000,00000001,....11111111}。由于人类更容易在十进制系统中思考,这意味着 m 属于值集合 {0,1,....255}。减去-127,这意味着2^n又属于数集{-127,-126,...0,1,2...128},即

    -127 <= n <= 128. 

x 的二进制浮点表示的最大指数因子 2^n 可以被视为 2^n = 2^128,或者在十进制系统中查看(使用任何计算器计算 2^128)

                     2^n <= 3.4028...*10^38.

综上所述,在IEEE格式的计算机中,单精度浮点数可能存储的最大数x是形式为的数

                    x = y*(3.4028...*10^38).

这里尾数 y 位于(半闭半开)区间 [1,2) 中。

为简单起见,Matlab 将“最大”可能的浮点数的“大小”报告为指数因子 2^128 = 3.4028*10^38 的最大大小。从这个讨论中我们看到,使用 32 位二进制浮点表示可以存储的最大浮点数实际上加倍为 max_x = 6.8056*10^38。

【讨论】:

    猜你喜欢
    • 2015-08-10
    • 2020-09-03
    • 1970-01-01
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    相关资源
    最近更新 更多