单精度和双精度浮点运算之间有什么区别?


168

单精度浮点运算和双精度浮点运算之间有什么区别?

我对与视频游戏机相关的实用术语特别感兴趣。例如,Nintendo 64是否具有64位处理器,如果可以,这是否意味着它能够进行双精度浮点运算?PS3和Xbox 360可以执行双精度浮点运算还是仅执行单精度运算?通常使用双精度功能吗(如果存在的话)?


17
CPU是64位的事实通常意味着CPU具有64位通用寄存器(即整数)和内存地址大小。但是它并没有说明浮点数学。例如,英特尔IA-32 CPU是32位的,但它们本身支持双精度浮点数。
罗曼·扎瓦洛夫

Answers:


215

注意:Nintendo 64确实具有64位处理器,但是:

许多游戏都利用了芯片的32位处理模式,因为3D游戏通常不需要64位数据类型提供更高的数据精度,而且处理64位数据使用的RAM和缓存是原来的两倍。和带宽,从而降低整体系统性能。

来自Webopedia

双精度一词用词不当,因为精度并不是真正的双精度。
单词double源自这样一个事实,即双精度数使用的位是常规浮点数的两倍。
例如,如果单精度数字需要32位,则其双精度对应数字将为64位长。

额外的位不仅增加了精度,而且增加了可以表示的幅度范围。
提高精度和幅度范围的确切数量取决于程序使用哪种格式表示浮点值。
大多数计算机使用一种称为IEEE浮点格式的标准格式。

实际上,IEEE双精度格式具有更多的精度是单精度格式的两倍,并且范围更大。

来自IEEE标准的浮点运算

单精度

IEEE单精度浮点标准表示需要一个32位的字,该字可以表示为从左到右从0到31的编号。

  • 第一位是符号位S
  • 接下来的八位是指数位“ E”,
  • 最后的23位是分数 'F':

    S EEEEEEEE FFFFFFFFFFFFFFFFFFFFFFF
    0 1      8 9                    31
    

单词表示的值V可以确定如下:

  • 如果E = 255且F不为零,则V = NaN(“非数字”)
  • 如果E = 255且F为零且S为1,则V =-无穷大
  • 如果E = 255且F为零且S为0,则V =无穷大
  • 如果那样的0<E<255V=(-1)**S * 2 ** (E-127) * (1.F) “ 1.F”旨在表示通过在F前面加上隐式前导1和二进制点而创建的二进制数。
  • 如果E = 0且F不为零,则 V=(-1)**S * 2 ** (-126) * (0.F)。这些是“非标准化”值。
  • 如果E = 0且F为零且S为1,则V = -0
  • 如果E = 0且F为零且S为0,则V = 0

特别是,

0 00000000 00000000000000000000000 = 0
1 00000000 00000000000000000000000 = -0

0 11111111 00000000000000000000000 = Infinity
1 11111111 00000000000000000000000 = -Infinity

0 11111111 00000100000000000000000 = NaN
1 11111111 00100010001001010101010 = NaN

0 10000000 00000000000000000000000 = +1 * 2**(128-127) * 1.0 = 2
0 10000001 10100000000000000000000 = +1 * 2**(129-127) * 1.101 = 6.5
1 10000001 10100000000000000000000 = -1 * 2**(129-127) * 1.101 = -6.5

0 00000001 00000000000000000000000 = +1 * 2**(1-127) * 1.0 = 2**(-126)
0 00000000 10000000000000000000000 = +1 * 2**(-126) * 0.1 = 2**(-127) 
0 00000000 00000000000000000000001 = +1 * 2**(-126) * 
                                     0.00000000000000000000001 = 
                                     2**(-149)  (Smallest positive value)

双精度

IEEE双精度浮点标准表示需要一个64位的字,该字可以从0到63从左到右编号。

  • 第一位是符号位S
  • 接下来的11位是指数位'E'和
  • 最后的52位是分数 'F':

    S EEEEEEEEEEE FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
    0 1        11 12                                                63
    

单词表示的值V可以确定如下:

  • 如果E = 2047且F不为零,则V = NaN(“非数字”)
  • 如果E = 2047且F为零且S为1,则V =-无穷大
  • 如果E = 2047且F为零且S为0,则V =无穷大
  • 如果那样的0<E<2047V=(-1)**S * 2 ** (E-1023) * (1.F) “ 1.F”旨在表示通过在F前面加上隐式前导1和二进制点而创建的二进制数。
  • 如果E = 0且F不为零,则 V=(-1)**S * 2 ** (-1022) * (0.F)这些为“未归一化”的值。
  • 如果E = 0且F为零且S为1,则V = -0
  • 如果E = 0且F为零且S为0,则V = 0

参考:
ANSI / IEEE标准754-1985,
二进制浮点算法的标准。


9
我从您的来源知道这一点,但我不喜欢这样的句子:“双精度”一词用词不当,因为精度并不是真正的双精度。如今,单精度和双精度是IEEE普遍定义的,正如您所指出的那样,单精度具有23位的分数,而双精度具有52位-基本上是精度的两倍……
卡尔·沃尔什

5
@ZeroDivide' **'是
VonC

11
@CarlWalsh 52/23!= 2因此,它不是“双精度”
rfoo 2013年


2
@rfoo如果您想学究一点,它并不是精确的两倍,而是52/2> 23,是的,它是精确度的两倍,它只是两倍,然后是更多。
JShorthouse,

42

我读了很多答案,但似乎没有一个能正确解释double这个词的来源。我记得几年前一位大学教授给出的很好的解释。

回顾VonC的回答风格,精度浮点表示使用32位字。

  • 1个比特的标志,S
  • 指数 8位,“ E”
  • 分数的 24位,也称为尾数系数(即使仅表示23位)。我们称它为“ M”(对于尾数,我更喜欢这个名称,因为“ fraction”可能会被误解)。

表示:

          S  EEEEEEEE   MMMMMMMMMMMMMMMMMMMMMMM
bits:    31 30      23 22                     0

(只需指出,符号位是最后一个,而不是第一个。)

精度浮点表示使用64位的一个字。

  • 1个比特的标志,S
  • 指数 “ E”的11位
  • 分数 / 尾数 / 系数的 53位(即使仅表示52位),“ M”

表示:

           S  EEEEEEEEEEE   MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
bits:     63 62         52 51                                                  0

您可能会注意到,我写道,两种类型的尾数都比其表示形式具有更多的信息。实际上,尾数是一个数字,没有所有非有意义的数字0。例如,

  • 0.000124变为0.124×10 -3
  • 237.141变为0.237141×10 3

这意味着尾数将始终为

0.α 1 α 2 ...α ×β p

其中β是表示的基础。但是由于部分是二进制数,α 1将总是等于1,从而该部分可以被改写为1.α 2 α 3 ...α t + 1的 ×2 p和初始1可以被隐含地假定,给额外的空间(αt + 1)。

现在,很明显32的两倍是64,但这不是单词的来源。

精度表示十进制数字是多少正确的,即没有任何表示错误或近似的。换句话说,它指示一个人可以安全使用多少个十进制数字。

话虽如此,很容易估计可以安全使用的小数位数:

  • 单精度:log 10(2 24),大约7〜8个十进制数字
  • 双精度:log 10(2 53),大约15〜16个十进制数字

19

好的,机器的基本区别是双精度使用的位是单精度的两倍。在通常的实现中,单位是32位,双位是64位。

但这是什么意思呢?如果我们采用IEEE标准,则单个精度数字的尾数约为23位,最大指数约为38;双精度的尾数为52位,最大指数约为308。

像往常一样,详细信息在Wikipedia上


11

要在此处添加所有精彩的答案

首先浮点数精度数都用于表示数字小数。因此,两者之间的差异源于它们可以存储数字的精度。

例如:我必须存储123.456789,一个可能只能存储123.4567,而另一个可能能够存储确切的123.456789。

因此,基本上,我们想知道数字可以存储多少精度,这就是我们所说的精度。

在这里引用@亚历山德罗

精度表示正确的小数位数,即没有任何形式的表示误差或近似值。换句话说,它指示一个人可以安全使用多少个十进制数字。

浮点数可以精确地存储小数部分中的7-8位数字,而Double可以精确地存储小数部分中的15-16位数字

因此,浮子可以存储两倍的分数部分。这就是为什么Double称为double float的原因


7

关于“ ps3和xbxo 360可以执行双精度浮点运算还是仅执行单精度运算,并且一般使用双精度功能(如果存在的话)吗?”

我相信这两个平台都不能使用双浮点数。原始的Cell处理器只有32位浮点数,与XBox 360基于的ATI硬件(R600)相同。后来,Cell获得了双浮点支持,但是我很确定PS3不会使用该芯片。


5

基本上单精度浮点算术处理32位浮点数,而双精度 64位。

具有双精度的位数增加了可存储的最大值,并提高了精度(即有效位数)。


5

所有人都进行了详尽的解释,我无能为力了。虽然我想用Layman的术语或简单的英语来解释

1.9 is less precise than 1.99
1.99 is less precise than 1.999
1.999 is less precise than 1.9999

.....

能够存储或表示“ 1.9”的变量所提供的精度要低于能够保持或表示1.9999的变量。在大型计算中,这些分数可能会产生巨大差异。


2

双精度表示数字需要两倍的字长来存储。在32位处理器上,字都是32位,因此双精度字是64位。就性能而言,这意味着对双精度数字进行的运算需要更长的时间才能执行。这样您可以获得更好的射程,但对性能的影响很小。硬件浮点单元可以稍微减轻这种影响,但仍然存在。

N64使用的是基于MIPS R4300i的NEC VR4300,它是64位处理器,但是该处理器通过32位宽的总线与系统的其余部分进行通信。因此,大多数开发人员使用32位数字是因为它们速度更快,并且当时大多数游戏都不需要额外的精度(因此,他们使用浮点数而不是双精度数)。

这三个系统都可以执行单精度和双精度浮点运算,但是可能不是因为性能。(尽管n64之后的几乎所有东西都使用32位总线,所以...)


1

首先浮点数和双精度数都用于表示数字小数。因此,两者之间的差异源于它们可以存储数字的精度。

例如:我必须存储123.456789,一个可能只能存储123.4567,而另一个可能只能存储精确的123.456789。

因此,基本上,我们想知道数字可以存储多少精度,这就是我们所说的精度。

在这里引用@亚历山德罗

精度表示正确的小数位数,即没有任何形式的表示误差或近似值。换句话说,它指示一个人可以安全使用多少个十进制数字。

浮点数可以精确存储小数部分中的7-8位数字,而Double可以精确存储小数部分中的15-16位数字

因此,double可以存储浮点数的两倍的小数部分。这就是为什么Double称为double float的原因



-3

单精度数字使用32位,其中MSB为符号位,而双精度数字使用64位,MSB为符号位

单精度

SEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFF.(SIGN+EXPONENT+SIGNIFICAND)

双精度:

SEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.(SIGN+EXPONENT+SIGNIFICAND)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.