是浮点文本“;。1”;同“;0.1”;在C中?

是浮点文本“;。1”;同“;0.1”;在C中?,c,C,在C程序的源文本中,.1和0.1是否具有相同的值?.1表示十分之一,与0.1相同。然而,由于C标准缺乏严格性,.1和0.1不一定按照C 2018 6.4.2.5转换为相同的内部值。在所有质量合理的编译器中,它们将是平等的。(6.4.4.2.5表示“相同源形式的所有浮动常数应转换为具有相同值的相同内部格式。”脚注77给出了具有相同数学值但不一定转换为相同内部值的源形式示例。) 源文本中的浮点常量转换为内部格式。最常见的是使用基于二进制的格式。大多数十进制数字,包括.1,不能用二进制浮点精确表示。因

在C程序的源文本中,
.1
0.1
是否具有相同的值?

.1
表示十分之一,与
0.1
相同。然而,由于C标准缺乏严格性,
.1
0.1
不一定按照C 2018 6.4.2.5转换为相同的内部值。在所有质量合理的编译器中,它们将是平等的。(6.4.4.2.5表示“相同源形式的所有浮动常数应转换为具有相同值的相同内部格式。”脚注77给出了具有相同数学值但不一定转换为相同内部值的源形式示例。)

源文本中的浮点常量转换为内部格式。最常见的是使用基于二进制的格式。大多数十进制数字,包括.1,不能用二进制浮点精确表示。因此,当它们被转换时,结果被四舍五入(二进制)为一个可表示的值。在典型的C实现中,
.1
变成0.1000000000000000555115123125782702118158340451015625

所有好的编译器都会将
.1
0.1
转换为相同的值。C标准对此松懈的原因是,涉及指数或许多数字的其他浮点文本(在某种意义上)很难(在某种程度上)转换为具有理想舍入的二进制浮点。历史上,有一些C实现伪造了转换。C标准通过不严格要求浮点值的处理来适应这些实现。(如今,好的算法已经为人所知,任何好的编译器都应该将浮点文本转换为最接近的可表示值,并将其绑定到甚至更低的数字,除非用户另有要求。)


因此,C标准不保证
.1
0.1
具有相同的值。然而,在实践中,他们会的。

如果你只是谈论基线C标准,Eric的答案是正确的,它基本上不保证浮点
1.0==42.0
是一个有效的实现选择。但这并不是很有帮助

如果您希望在C中有任何合理的浮点行为,那么您需要一个支持附录F(IEEE浮点语义与C的对齐)的实现,这是标准的可选部分。您可以通过检查预定义宏
\uuuuu STDC\u IEC\uu559\uuuu
来判断您的实现是否支持(或声称支持)附录F


假设附录F,浮点文字的解释不可随意使用,
.1
0.1
必然是相同的。

@WeatherVane:嗯,根据C标准,
.1
0.1
允许不同!根据C 2018 6.4.4.2 5,具有相同源形式的常数必须转换为相同的内部值,但对于具有不同源形式的常数没有这样的规则。@WeatherVane我不确定
sizeof
与此有什么关系。。。。引用的段落意味着
0.1==.1
不一定正确。@EugeneSh。这表明他们都被转换成了
double
@WeatherVane是的,但标准的东西是谈论价值,而不是类型。@EricPostFischil:我通常会对任何生成我想要提升的答案的问题进行提升投票。这可能是正确的,但它并不能回答初学者在第一次用科学致盲之前提出的简单问题。正如被问到的,缺少的
0
是隐含的,并且两者都有相同的值,每个编译器都编写过。@WeatherVane:它回答了第一句中的简单问题。它说,
.1
0.1
通常在第三句、第三段的第一句和最后一句中是相等的,但它们总是相等的。有什么实际用途的编译器会使它们与众不同,并对标准指手画脚?由jxh链接的示例与此大不相同。正如您在上文中所评论的“我认为这个问题在这一点上不是一个好的工具”。@WeatherVane然而,如果您查看upvotes,那么很明显地会重视这种标准thumpery,无论它是否与OP的需求有任何关系。@SteveSummit我理解这一点,但是我从不期望浮点变量的准确性,这比我从对数表或计算尺上所做的还要多,尽管埃里克以前就喜欢这样叫我!Re“您可以判断您的实现是否支持…”:不完全支持。如果
\uu STDC\u IEC\u 559\uuu
,则实施声称支持附件F。如果不支持,则不表示是否支持附件F。具体而言,一个实现可能支持很多附录F,包括特定程序员在某些情况下关心的功能,但在一些次要方面有所欠缺,因此无法定义
\uu STDC\u IEC\u 559\uu
。一些预处理器指示符(如可变长度数组的指示符)对于选择一组或另一组代码非常有用。但这一条可能没有预期的那么有用。@EricPostpischil:所有这些都与我写的内容不一致。“通过检查预定义的宏
\uu STDC\u IEC\u 559\uu
,您可以判断您的实现是否支持(或声称支持)附录F。”是不正确的,因为C标准只要求如果实现定义了
\uuuuu STDC\uu IEC\uu559\uuuuu
,则它符合。它不要求如果应用程序符合,则定义
\uuuu STDC\uu IEC\uu559\uuu
。所以你不能完全从这个预处理器符号中分辨出来。有些C编译器是独立于标准库实现的,因此即使编译器本身所做的一切都符合要求,编译器也无法定义符号,因为它可能……与不符合要求的库配对。如果未定义符号,则实现仍可能符合