提问人:meds 提问时间:4/29/2009 最后编辑:Peter Mortensenmeds 更新时间:3/30/2023 访问量:347979
单精度浮点运算和双精度浮点运算有什么区别?
What's the difference between a single precision and double precision floating point operation?
问:
单精度浮点运算和双精度浮点运算有什么区别?
我对与视频游戏机相关的实用术语特别感兴趣。例如,任天堂 64 是否具有 64 位处理器,如果有,这是否意味着它能够进行双精度浮点运算?PS3 和 Xbox 360 能否实现双精度浮点运算或仅实现单精度运算,并且通常使用双精度功能(如果存在?
答:
基本上,单精度浮点运算处理 32 位浮点数,而双精度处理 64 位浮点数。
双精度的位数增加了可以存储的最大值,并增加了精度(即有效位数)。
好的,机器的基本区别在于双精度使用的位数是单精度的两倍。在通常的实现中,单精度为 32 位,双精度为 64 位。
但这意味着什么呢?如果我们假设IEEE标准,那么单个精度数大约有23位尾数,最大指数约为38;双精度尾数有 52 位,最大指数约为 308。
像往常一样,详细信息在维基百科上。
注意:Nintendo 64 确实有 64 位处理器,但是:
许多游戏利用了芯片的 32 位处理模式,因为 3D 游戏通常不需要 64 位数据类型提供更高的数据精度,而且处理 64 位数据使用两倍的 RAM、缓存和带宽,从而降低了整体系统性能。
来自Webopedia:
术语双精度有点用词不当,因为精度并不是真正的双倍。
double 一词源自这样一个事实,即双精度数字使用的位数是常规浮点数的两倍。
例如,如果单精度数字需要 32 位,则其双精度对应数字的长度为 64 位。
额外的位不仅提高了精度,还增加了可以表示的幅度范围。
精度和幅度范围增加的确切数量取决于程序用于表示浮点值的格式。
大多数计算机使用称为 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<255
V=(-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<2047
V=(-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 位指数和符号位:
M
E
S
归一化的尾数 , 存储在 0-22 位中,隐藏的 位,
0
,省略。
因此。m
b
M = m-1
指数 , 表示为以位 23-30 表示的偏置 127 整数。
因此。e
E = e+127
符号位 , 表示尾数的符号,表示正值和负值。
S
S=0
S=1
零用 表示。
由于可能是 0 或 1,因此 和 有不同的表示形式。E = M = 0
S
+0
-0
评论
至于“ps3 和 xbxo 360 能否实现双精度浮点运算或仅实现单精度浮点运算,并且在通用中使用是否使用了双精度功能(如果它们存在?
我相信这两个平台都无法实现双浮点。最初的 Cell 处理器只有 32 位浮点数,与 XBox 360 所基于的 ATI 硬件 (R600) 相同。Cell 后来获得了双浮点支持,但我很确定 PS3 不会使用这种芯片。
双精度意味着数字需要两倍的字长来存储。在 32 位处理器上,字都是 32 位,因此双精度是 64 位。就性能而言,这意味着对双精度数字的操作需要更长的时间才能执行。因此,您可以获得更好的范围,但对性能的影响很小。硬件浮点单元稍微缓解了这种影响,但它仍然存在。
N64 使用基于 MIPS R4300i 的 NEC VR4300,这是一个 64 位处理器,但该处理器通过 32 位宽总线与系统的其余部分进行通信。因此,大多数开发人员使用 32 位数字,因为它们速度更快,而且当时的大多数游戏不需要额外的精度(因此他们使用浮点数而不是双精度数)。
这三个系统都可以执行单精度和双精度浮动操作,但由于性能原因,它们可能无法执行。(尽管 N64 之后几乎所有东西都使用 32 位总线,所以......
单精度数字使用 32 位,MSB 是符号位,而双精度数字使用 64 位,MSB 是符号位
单精度
SEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFF.(SIGN+EXPONENT+SIGNIFICAND)
双精度:
SEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.(SIGN+EXPONENT+SIGNIFICAND)
我读了很多答案,但似乎没有一个能正确解释 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位十进制
评论
DOUBLE PRECISION
REAL
INTEGER
添加到这里所有精彩的答案
首先,float 和 double 都用于表示数字、小数。因此,两者之间的区别源于它们可以存储数字的精度。
例如:我必须存储 123.456789 一个人可能只能存储 123.4567,而其他人可能能够存储确切的 123.456789。
所以,基本上我们想知道数字可以存储多少精度,这就是我们所说的精度。
在这里引用@Alessandro
精度表示正确的十进制位数, 即没有任何表示错误或近似值。在 换句话说,它表示可以安全地使用多少个十进制数字。
Float 可以在小数部分准确地存储大约 7-8 位数字,而 Double 可以在小数部分准确存储大约 15-16 位数字
因此,float 可以存储两倍的小数部分。这就是为什么 Double 被称为双倍浮点数
根据IEEE754 • 浮点存储标准 • 32 位和 64 位标准(单精度和双精度) • 分别为 8 位和 11 位指数 • 用于中间结果的扩展格式(尾数和指数)
首先,float 和 double 都用于表示数字、小数。因此,两者之间的区别源于它们可以存储数字的精度。
例如:我必须存储 123.456789 一个人可能只能存储 123.4567,而另一个人可能能够存储确切的 123.456789。
所以,基本上我们想知道数字可以存储多少精度,这就是我们所说的精度。
在这里引用@Alessandro
精度表示正确的十进制位数,即没有任何表示错误或近似值。换句话说,它表示可以安全地使用多少个十进制数字。
Float 可以在小数部分准确存储大约 7-8 位数字,而 Double 可以在小数部分准确存储大约 15-16 位数字
因此,double 可以存储两倍于浮点数的小数部分。这就是为什么 Double 被称为双倍浮点数
所有这些都非常详细地解释了,我不能再补充了。虽然我想用通俗易懂的术语或简单的英语来解释它
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 的变量。这些分数在大型计算中可能构成巨大差异。
评论