2

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

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

C++呢?

4

4 回答 4

5

你不是在问是否0.0总是准确地表示。

在语句assert(n == 0)中,在比较发生之前0转换为。因此,只有在从to转换为不可重现double的情况下才能触发断言。这是一个比您所要求的要弱得多的限制,并且几乎肯定会成立(尽管我想不出一个标准参考来保证它不在我的脑海中)。0intdouble

对于你打算问的问题:

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

于 2011-04-14T22:04:36.943 回答
5

C 标准确实对浮点值的表示方式设置了一些限制。在§5.2.4.2.2 Characteristics of floating types中,浮点数必须表现出好像它们是由模型定义的特性:

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 节中的以下限制:

当整数类型的值转换为真正的浮点类型时,如果被转换的值可以在新类型中精确表示,则它是不变的。

It follows that zero must always be unchanged when converted from the integer 0 to a floating point type. Therefore the assertion must always hold.

于 2011-04-15T00:43:50.413 回答
2

比较会将整数提升为双精度。您要问的是编译器是否保证每次将相同的整数转换为双精度时都进行相同的转换。我相信是的。

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

于 2011-04-14T22:08:24.730 回答
1

C99 不强制要求 IEEE754,只推荐它。有一个符合 IEEE 754 的编译平台可以定义的符号(附件 F)。如果编译器定义了这个符号,那么是的,断言将被保证成立。当字面常量可以精确地表示为浮点数时,那么这个浮点数就是你在编译程序中必须得到的。

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

于 2011-04-14T22:02:35.160 回答