ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

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

D
David K

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

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

Webopedia

术语双精度有点用词不当,因为精度并不是真正的双精度。 double 这个词源于这样一个事实,即双精度数使用的位数是常规浮点数的两倍。例如,如果一个单精度数需要 32 位,那么它的双精度数将是 64 位长。额外的位不仅增加了精度,还增加了可以表示的幅度范围。增加精度和幅度范围的确切数量取决于程序用于表示浮点值的格式。大多数计算机使用称为 IEEE 浮点格式的标准格式。

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

IEEE standard for floating point arithmetic

单精度

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

第一位是符号位,S,

接下来的八位是指数位,'E',和

最后 23 位是小数“F”:S EEEEEEEE FFFFFFFFFFFFFFFFFFFFF 0 1 8 9 31

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

如果 E=255 且 F 非零,则 V=NaN(“非数字”)

如果 E=255 且 F 为零且 S 为 1,则 V=-Infinity

如果 E=255 且 F 为零且 S 为 0,则 V=Infinity

如果 0

如果 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 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 0 1 11 12 63

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

如果 E=2047 且 F 非零,则 V=NaN(“非数字”)

如果 E=2047 且 F 为零且 S 为 1,则 V=-Infinity

如果 E=2047 且 F 为零且 S 为 0,则 V=Infinity

如果 0

如果 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,二进制浮点算术标准。


我从您的消息来源知道这一点,但我不喜欢这句话:“双精度一词用词不当,因为精度并不是真正的双精度。”如今,单精度和双精度由 IEEE 普遍定义,正如您指出的那样,单精度在分数中有 23 位,而双精度有 52 位——这基本上是精度的两倍......
@ZeroDivide '**' 是 Exponentiation
@CarlWalsh 52/23 != 2 因此,它不是“精度加倍”
@johnson 您在 easy68k.com/paulrsm/6502/WOZFPPAK.TXTstackoverflow.com/a/28801033/6309 中有更多关于非规范化值的详细信息
@rfoo 如果您想确定一点,它不完全是两倍,而是 52/2 > 23 所以是的,它是精度的两倍,它只是两倍,然后是更多。
A
Alessandro

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

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

1 位符号,S

指数 'E' 的 8 位

分数为 24 位,也称为尾数或系数(即使仅表示 23 位)。我们称它为“M”(对于尾数,我更喜欢这个名称,因为“分数”可能会被误解)。

表示:

          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 × 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位十进制数字


感谢您使用正确的位编号(符号分别为第 31 位和第 63 位)。
C
Charlie Martin

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

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

与往常一样,详细信息位于 Wikipedia


S
SimpleGuy

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

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

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

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

在这里引用@Alessandro

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

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

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


A
Asad

所有人都已经详细解释了,我没有什么可以补充的了。虽然我想用通俗易懂的术语或简单的英语来解释它

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


c
cletus

基本上 single precision 浮点运算处理 32 位浮点数,而 double precision 处理 64 位。

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


c
codekaizen

至于“ps3 和 xbxo 360 能否实现双精度浮点运算或仅实现单精度,并且在一般情况下使用的是双精度功能(如果存在的话?)”这个问题。

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


A
Alex

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

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

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


d
debanjanbe

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

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

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

在这里引用@Alessandro

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

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

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


A
Abdullah Al Mamun

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


S
Steve Bennett

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

单精度

SEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFF.(SIGN+EXPONENT+SIGNIFICAND)

双精度:

SEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.(SIGN+EXPONENT+SIGNIFICAND)