我最近参加了一次系统编程讲座,我的教授告诉我f == (float)(double) f
是我无法避免的错误。
我知道double
类型在转换为float
时会丢失其数据,但是我相信,仅当double
类型的存储数字不能用{{1}表示时,丢失才会发生}类型。
是不是像float
是真的一样?
图片是我理解的方式
对不起,我没有清楚地提出问题。
问题不是关于声明,而是关于双精度类型转换。 希望您不要因为我的错而浪费宝贵的时间。
答案 0 :(得分:10)
假设IEC 60559,f == (float)(double) f
的结果取决于f
的类型。
进一步假设f
是float
,则表达式没有任何“错误”-它将计算为true
(除非NaN
持有f
,在这种情况下,表达式的计算结果为false
。
另一方面,x == (int)(double)x
(假设x
是int
)存在(潜在)问题,因为双精度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;
(与标题中的效果完全相同,而与int
,float
和double
类型的可用精度无关,即没有精度。) >
编程在某种程度上与精度有关,您也许应该注意声明和表达式之间的区别。 表达式的值可能为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