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

What's the difference between a single precision and double precision floating point operation?

提问人:meds 提问时间:4/29/2009 最后编辑:Peter Mortensenmeds 更新时间:3/30/2023 访问量:347979

问:

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

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

浮点 精度 处理器 操作

评论

17赞 Roman Zavalov 11/26/2012
CPU 是 64 位的事实通常意味着 CPU 具有 64 位通用寄存器(即整数)和内存地址大小。但它对浮点数学只字未提。例如,Intel IA-32 CPU 是 32 位的,但它们本身支持双精度浮点数。
0赞 rjhcnf 12/29/2020
双精度浮点运算可以表示比单精度浮点更多的数字。这是一本关于从编程角度的浮点的好读物。levelup.gitconnected.com/......

答:

8赞 cletus 4/29/2009 #1

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

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

21赞 Charlie Martin 4/29/2009 #2

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

但这意味着什么呢?如果我们假设IEEE标准,那么单个精度数大约有23位尾数,最大指数约为38;双精度尾数有 52 位,最大指数约为 308。

像往常一样,详细信息在维基百科上。

235赞 VonC 4/29/2009 #3

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

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

来自Webopedia

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

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

IEEE双精度格式实际上具有比单精度格式多一倍以上的精度,以及更大的范围。

来自IEEE浮点运算标准

单精度

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

  • 第一位是符号位 S,

  • 接下来的 8 位是指数位 '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=无穷大
  • 如果那么“1.F”在哪里 旨在表示通过在 F 前面加上前缀 隐式前导 1 和一个二进制点。0<E<255V=(-1)**S * 2 ** (E-127) * (1.F)
  • 如果 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=无穷大
  • 如果那么“1.F”在哪里 旨在表示通过在 F 前面加上前缀 隐式前导 1 和一个二进制点。0<E<2047V=(-1)**S * 2 ** (E-1023) * (1.F)
  • 如果 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,
二进制浮点运算标准。


根据 cs.uaf.edu IEEE浮点标准的注释,“分数”通常被称为尾数

单精度 IEEE FPS 格式由 32 位组成,分为 23 位尾数、8 位指数和符号位:MES

tabular688

  • 归一化的尾数 , 存储在 0-22 位中,隐藏的 位,0,省略。
    因此。
    mbM = m-1

  • 指数 , 表示为以位 23-30 表示的偏置 127 整数。
    因此。
    eE = e+127

  • 符号位 , 表示尾数的符号,表示正值和负值。SS=0S=1

零用 表示。
由于可能是 0 或 1,因此 和 有不同的表示形式。
E = M = 0S+0-0

评论

9赞 Carl Walsh 7/21/2012
我知道这是从你的来源,但我不喜欢这句话:“术语双精度有点用词不当,因为精度并不是真正的双倍。如今,IEEE对单精度和双精度的定义非常普遍,正如您指出的,单精度有23位,双精度有52位,这基本上是精度的两倍......
5赞 VonC 8/28/2013
@ZeroDivide '' 是**
13赞 rfoo 9/28/2013
@CarlWalsh 52/23 != 2 因此,它不是“精度的两倍”
0赞 VonC 12/9/2017
@johnson 有关 easy68k.com/paulrsm/6502/WOZFPPAK.TXTstackoverflow.com/a/28801033/6309 中非规范化值的更多详细信息
3赞 JShorthouse 11/8/2019
@rfoo 如果你想迂腐,当然,它不完全是双倍,而是 52/2 > 23,所以是的,它是双倍的精度,它只是双倍,然后更多。
7赞 codekaizen 4/29/2009 #4

至于“ps3 和 xbxo 360 能否实现双精度浮点运算或仅实现单精度浮点运算,并且在通用中使用是否使用了双精度功能(如果它们存在?

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

2赞 Alex 4/29/2009 #5

双精度意味着数字需要两倍的字长来存储。在 32 位处理器上,字都是 32 位,因此双精度是 64 位。就性能而言,这意味着对双精度数字的操作需要更长的时间才能执行。因此,您可以获得更好的范围,但对性能的影响很小。硬件浮点单元稍微缓解了这种影响,但它仍然存在。

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

这三个系统都可以执行单精度和双精度浮动操作,但由于性能原因,它们可能无法执行。(尽管 N64 之后几乎所有东西都使用 32 位总线,所以......

-3赞 Rajeshwari Hegde 5/1/2009 #6

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

单精度

SEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFF.(SIGN+EXPONENT+SIGNIFICAND)

双精度:

SEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.(SIGN+EXPONENT+SIGNIFICAND)

61赞 Alessandro 2/25/2017 #7

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

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

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

表示法:

          S  EEEEEEEE   MMMMMMMMMMMMMMMMMMMMMMM
bits:    31 30      23 22                     0

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

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

  • 符号 S 的 1 位
  • 指数“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 × 103

这意味着尾数将始终处于以下形式

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

其中 β 是表示的基础。但是由于分数是二进制数,α1 将始终等于 1,因此分数可以改写为 1.α2α3......αt+1 × 2p,可以隐式假设初始 1,从而为额外的位 (αt+1) 腾出空间。

现在,32 的双倍是 64 显然是真的,但这不是这个词的来源。

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

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

  • 单精度:log10(224),约为7~8位十进制
  • 双精度:log10(253),约为15~16位十进制

评论

3赞 Jack_Hu 8/29/2020
感谢您使用正确的位编号(符号分别为第 31 位和第 63 位)。
0赞 John Bollinger 3/23/2023
我不确定为什么你声称它是相关的十进制精度。精度比率与数值基数无关,但直接从二进制精度中得出它最容易:53 位 / 24 位。(不过,可以从以 10 为底的对数中得出相同的比率)。binary64 的精度是 binary32 的两倍一点(加上更宽的指数范围),所以“双精度”并不是那么糟糕的描述,但它也不完全正确。
0赞 John Bollinger 3/23/2023
此外,观察到数字精度与存储大小是不同的东西是完全合理的,但我认为存储大小实际上是术语“双精度”的产生方式,尽管这使得该术语不那么精确。它至少早在 Fortran 的早期就被使用,当时浮点格式比现在要多样化得多,早在 IEEE 754 被起草之前。以 Fortran 77 为例,对象的存储大小被明确指定为 a 或 格式的两倍。DOUBLE PRECISIONREALINTEGER
14赞 SimpleGuy 2/14/2018 #8

添加到这里所有精彩的答案

首先,floatdouble 都用于表示数字、小数。因此,两者之间的区别源于它们可以存储数字的精度。

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

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

在这里引用@Alessandro

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

Float 可以在小数部分准确地存储大约 7-8 位数字,而 Double 可以在小数部分准确存储大约 15-16 位数字

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

0赞 Abdullah Al Mamun 4/1/2018 #9

根据IEEE754 • 浮点存储标准 • 32 位和 64 位标准(单精度和双精度) • 分别为 8 位和 11 位指数 • 用于中间结果的扩展格式(尾数和指数)

1赞 debjbhatt 12/10/2018 #10

首先,float 和 double 都用于表示数字、小数。因此,两者之间的区别源于它们可以存储数字的精度。

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

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

在这里引用@Alessandro

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

Float 可以在小数部分准确存储大约 7-8 位数字,而 Double 可以在小数部分准确存储大约 15-16 位数字

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

9赞 Asad 9/13/2019 #11

所有这些都非常详细地解释了,我不能再补充了。虽然我想用通俗易懂的术语或简单的英语来解释它

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 的变量。这些分数在大型计算中可能构成巨大差异。