为什么语句“ f ==(float)(double)f;”错误?

时间:2019-03-28 14:16:12

标签: c

我最近参加了一次系统编程讲座,我的教授告诉我f == (float)(double) f是我无法避免的错误。

我知道double类型在转换为float时会丢失其数据,但是我相信,仅当double类型的存储数字不能用{{1}表示时,丢失才会发生}类型。

是不是像float是真的一样?

图片是我理解的方式

enter image description here


对不起,我没有清楚地提出问题。

问题不是关于声明,而是关于双精度类型转换。 希望您不要因为我的错而浪费宝贵的时间。

3 个答案:

答案 0 :(得分:10)

假设IEC 60559f == (float)(double) f的结果取决于f的类型。

进一步假设ffloat,则表达式没有任何“错误”-它将计算为true(除非NaN持有f ,在这种情况下,表达式的计算结果为false

另一方面,x == (int)(double)x(假设xint)存在(潜在)问题,因为双精度IEC 60559浮点值仅对有效位具有53位 1 ,如果您的平台上int的值使用的位数超过53位,则它不能表示true的所有可能值。因此,它将在int为32位(使用31位作为值)的平台上求值为false,并在int s的平台上求值为_Bool是64位(值使用63位)(取决于值)。

C标准(6.3.1.4和6.3.1.5)的相关引用:

  

当整数类型的值转换为实数浮点型时,如果要转换的值可以用新类型精确表示,则它保持不变。

  

当实数浮点型的有限值转换为{{1}}以外的整数类型时,小数部分将被丢弃(即,该值将被截断为零)。如果整数部分的值不能用整数类型表示,则行为是不确定的。

  

当实数浮点型值转换为实数浮点型时,如果要转换的值可以用新类型精确表示,则它不变。


1 双精度IEC 60559浮点值包括1位符号,11位指数和53位有效位数(其中1表示但未存储)-总共64个(存储的)位。

答案 1 :(得分:1)

按照字面意思回答问题,

  

为什么“ f ==(float)(double)f;”语句错误?

该陈述“错误”与浮点值的表示没有任何关系,而是因为任何编译器都对其进行了微不足道的优化,因此您可能还保存了用于存储它的电子。它完全等同于语句

1;

或者,如果您愿意,可以声明(来自原始问题)

x == (int)(double)x;

(与标题中的效果完全相同,而与intfloatdouble类型的可用精度无关,即没有精度。) >

编程在某种程度上与精度有关,您也许应该注意声明表达式之间的区别。 表达式的值可能为true或false或其他值,但是当您添加分号(如您在问题中所做的那样)时,它会成为 statement (如您在问题中称之为“错误”),并且在没有副作用的情况下,编译器可以随意将其丢弃。

答案 2 :(得分:0)

NaN通过float => double => float保留,但它们并不相等。

#include <math.h>
#include <stdio.h>

int main(void) {
    float f = HUGE_VALF;
    printf("%d\n", f == (float)(double) f);
    f = NAN;
    printf("%d\n", f == (float)(double) f);
    printf("%d\n", f == f);
}

打印

1
0 
0