【问题标题】:What's the difference between a single precision and double precision floating point operation?单精度和双精度浮点运算有什么区别?
【发布时间】:2010-10-22 12:21:45
【问题描述】:

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

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

【问题讨论】:

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

标签: floating-point precision processor operations


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

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

    和往常一样,详情在Wikipedia

    【讨论】:

      【解决方案3】:

      注意: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 FFFFFFFFFFFFFFFFFFFFFFF
        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<255 那么V=(-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=-Infinity
      • 如果 E=2047 且 F 为零且 S 为 0,则 V=Infinity
      • 如果0<E<2047 那么V=(-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,
      二进制浮点运算标准。

      【讨论】:

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

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

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

      【讨论】:

        【解决方案5】:

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

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

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

        【讨论】:

          【解决方案6】:

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

          单精度

          SEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFF.(SIGN+EXPONENT+SIGNIFICAND)

          双精度:

          SEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.(SIGN+EXPONENT+SIGNIFICAND)

          【讨论】:

            【解决方案7】:

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

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

            • 符号、S
            • 1 位
            • 指数,'E'
            • 的8位
            • fraction 的 24 位,也称为 ma​​ntissacoefficient(尽管仅表示 23)。我们称它为“M”(对于尾数,我更喜欢这个名称,因为“分数”可能会被误解)。

            表示:

                      S  EEEEEEEE   MMMMMMMMMMMMMMMMMMMMMMM
            bits:    31 30      23 22                     0
            

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

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

            • 符号、S
            • 1 位
            • 指数,'E'
            • 的11位
            • fraction / ma​​ntissa / coefficient 的 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 sub>...αt+1 × 2p 和初始的 1 可以隐式假设,为额外的位(αt+1)。

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

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

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

            • 单精度:log10(224),大约是7~8位小数
            • 双精度:log10(253),大约是15~16位小数

            【讨论】:

            • 感谢您使用正确的位编号(符号分别为第 31 位和第 63 位)。
            【解决方案8】:

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

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

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

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

            在这里引用@Alessandro

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

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

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

            【讨论】:

              【解决方案9】:

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

              【讨论】:

                【解决方案10】:

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

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

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

                在这里引用@Alessandro

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

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

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

                【讨论】:

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

                  【讨论】:

                    猜你喜欢
                    • 2023-03-18
                    • 2011-01-24
                    • 2018-02-23
                    • 1970-01-01
                    • 2020-05-28
                    • 2020-09-24
                    • 2018-07-06
                    • 2017-08-05
                    • 1970-01-01
                    相关资源
                    最近更新 更多