双0.0是否总是在便携式C中完全表示?

时间:2011-04-14 21:57:53

标签: c++ c bit-representation inexact-arithmetic

以下代码是否可以在具有符合ANSI标准的C编译器的所有环境中工作?

double n = 0;
assert(n == 0);

C ++怎么样?

4 个答案:

答案 0 :(得分:5)

您不会询问0.0是否总是完全代表。

在语句assert(n == 0)中,0在比较发生之前转换为double。因此,只有在0int转换为double时,才能触发断言。这是一个比你所要求的要弱得多的限制,几乎可以肯定(尽管我不能想到一个标准参考来保证它不在我的头顶)。

关于你想问的问题:

正如其他人提到的,C标准并不要求浮点类型映射到IEEE-754,但我不知道任何C编译器使用的浮点表示没有精确的零表示。也就是说,对于C实现而言,使用double的格式并不完全为零是“合法的”。

答案 1 :(得分:5)

C标准确实对浮点值的表示方式施加了一些限制。在§5.2.4.2.2浮动类型的特征中,浮点数必须表现出类似于模型定义的特征:

  

x = sb e Σ k = 1..p f k b -k

其中:

  • s 是标志,必须为±1;
  • b 是基础,必须是整数> 1;
  • e 是指数,必须是e min 和e max 之间的整数;
  • p 是精度;和
  • f k 是非负整数< b - 有效数字的数字。

在此模型下,零总是能够准确表示 - 它只需要将所有有效位数 f k 设为零。

鉴于§6.3.1.4中的以下限制:

  

当整数类型的值为   转换为真正的浮动类型,如果   转换的值可以是   完全代表新类型,   它没有变化。

因此,当从整数0转换为浮点类型时,零必须始终保持不变。因此,断言必须始终保持。

答案 2 :(得分:2)

比较会将整数提升为double。您要问的是,每次将相同的整数转换为double时,编译器是否保证执行相同的转换。我相信它是。

不仅如此,任何足够小的整数都可以用double精确表示。我无法想象任何编译器会在那种情况下进行转换,但这并不精确。

答案 3 :(得分:1)

C99不强制要求IEEE754,只推荐它。 IEEE 754兼容编译平台可以定义符号(附件F)。 如果编译器定义了这个符号,那么肯定断言将保持不变。当文字常量完全可以表示为浮点数时,那么这个浮点数就是你在编译程序中必须得到的数字。

我想不出任何没有零的非IEEE 754浮点系统,或者没有理由不将源代码中的文字0映射到它。