【问题标题】:Can a double represent all values a float can represent?double 可以代表 float 可以代表的所有值吗?
【发布时间】:2010-05-08 21:08:54
【问题描述】:

浮点数无法表示某些 int 值。

但是,double 能否表示 float 可以表示的所有值?

我的直觉说是的,因为 double 有更多的小数位和更多的指数位,但我可能会遗漏一些愚蠢的陷阱。

【问题讨论】:

  • 浮点数无法达到的 int 值有哪些?我以前从未听说过。
  • 随着浮点数变大,可表示值之间的间隔变长。您不能真正将 10000000001 表示为浮点数,即使浮点数可以容纳更大的值。
  • 补充 cHao 所说的,一个 IEEE 浮点数最多只能携带 23/24 位,因为某些位是为符号和指数保留的。
  • 第一句话在具有 16 位整数的平台上不正确

标签: c floating-point int double


【解决方案1】:

是的。

了解浮点数和双精度数的工作原理可能会有所帮助。

无需过多介绍......

取数字152853.5047(木星卫星Io的公转周期,以秒为单位)

在科学计数法中,这个数字是0.1528535047 × 10^6

由于计算机只能理解1和0,所以有办法定义.

尾数 (1528535047) 和指数 (6) 存储在 32 位内……如果我没记错的话,尾数只有 24 位,因此浮点通常更多的是关于精度而不是大小。数字越大,精度越低。

1528535047 = 1011011000110111001100000000111 所以你只能存储前 24 位...最后三个 1 被删除。

由于整数是 32 位的,所以您是对的,浮点数不能准确地包含它。较低的有效数字会从末尾被删除。

任何绝对值小于 2^24(24 位)的 整数 都可以存储而不会丢失精度。 (16,777,216)

这是在浮点数中存储位的方式:

How floats are stores diagram http://phimuemue.wordpress.com/files/2009/06/576px-ieee-754-single-svg1.png

source 一位用于符号,8 位用于指数,23 位用于尾数。因此,要回答您的问题,由于尾数仅保留 23 位,因此无法精确显示 32 位整数。由于需要显示更多数字,它将很快开始删除数字(从右侧开始)。

对于双精度数,您只是增加了它可以存储的位数...实际上,它被称为 双精度,因此任何可以显示为浮点数的数字都能够显示为双重。多余的 0 只是添加到尾数中。

由于这个原因,由于 double 占用 64 位,大多数人在从 32 位 int 转换为 double 时会使用 double。浮点数可以很好地转换 16 位短。

【讨论】:

  • 问题只是关于将所有浮点数表示为双精度数的能力。说“是”的方式很长。
  • 信息太多。但是,如果您要提供这么多信息,那么您会误导您,因为您没有解释有效数字中的最高有效 1 位是隐含的,除了零(这是特殊的)和非规范化数字。最后,我们不能再称它为“尾数”了。我们应该说“有效数字”。
  • 但它相​​当有趣和详细。您可以在开始时说“是”,然后再详细说明。
  • @Pascal:你是对的。我已经做出改变了。我确实有点得意忘形了。我只记得我在做 Comp 时第一次向我解释时所得到的启示。科学。培训班。 @诺曼。感谢您的澄清。
  • @crypticcoder 我的答案是关于修订版 1-3 的其中一个,尽管这个答案的所有优点,但还是缺少了一些东西。 stackoverflow.com/posts/2795794/revisions
【解决方案2】:

n1256 中的 6.2.5/10:

有三种真正的浮动类型, 指定为 float、double 和 long 双倍的。 值的集合 类型 float 是集合的子集 double 类型的值;的集合 double 类型的值是一个子集 长类型值的集合 双倍。

(强调我的)。

实现是否使用 IEEE754 无关紧要,C99 标准保证你想要什么。

【讨论】:

  • 另一个有趣的引用是 n1256 6.3.1.5/1 "Real floating types": "当 float 提升为 double 或 long double,或 double 提升为 long double,其值不变"
【解决方案3】:

是的,double 可以表示 float 可以表示的所有值。

原因如下:

这两个数字都表示为符号、指数和尾数。 float 和 double 的区别在于,指数和尾数的空间更大。

对于指数来说,更宽的范围是没有问题的。您可以用 int 表示所有字节值,指数也是如此。尾数有点不同,但如果你用零填充双尾数的额外位,你将得到 完全与浮点数相同的值。

十进制可能更容易理解:假设您有一个十进制数字,如下所示:

1.99234

这个数字在小数点后面有 5 位小数。如果您必须将相同的数字扩展到小数点后 10 位,您会怎么做?简单:加零:

1.9923400000

它是完全相同的数字,只是在尾数中更准确地表示。

【讨论】:

    【解决方案4】:

    任何float 数字都可以表示为double。我不确定NaN。 (我确信您可以通过在有效数字上附加额外的零来将 float NaN 表示为 double,但我不确定对 NaN 做出反应的软件或硬件是否会以完全相同的方式对这样的 NaN 做出反应.)

    【讨论】:

      【解决方案5】:

      在实践中,是的。但是,我怀疑它是标准要求的。如果出现具有 64 位 ints 的平台(当前 64 位平台上的 AFAIK int 实际上是 32 位,但 long 是 64)出现并且它具有 double 这也是 64 位,那么一些int 值不能表示为 double 值。

      【讨论】:

      • 如果你说你在谈论哪个标准,这将有助于确定它是否在标准中指定。 IEEE 754 暗示双精度浮点数包含单精度浮点数。 C99 强烈鼓励支持 IEEE 754,对于 IEEE 754 单精度使用浮点数,对于 IEEE 754 双精度使用双精度数。
      【解决方案6】:
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-08-06
      • 1970-01-01
      • 2011-04-15
      • 1970-01-01
      • 2011-01-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多