c - 为什么语句“f == (float)(double)f;” 错误的?
问题描述
我最近参加了系统编程的讲座,我的教授告诉我这f == (float)(double) f
是我无法理解的错误。
我知道double
type 转换为 时会丢失其数据float
,但我相信只有在double
type 中存储的数字不能用float
type 表示时才会发生丢失。
不应该和真实一样x == (int)(double)x;
真实吗?
图片是我理解的方式
很抱歉我没有把我的问题说清楚。
问题不在于声明,而在于双重类型转换。我希望你不要因为我的错而失去你宝贵的时间。
解决方案
假设IEC 60559,结果f == (float)(double) f
取决于f
.
进一步假设f
是 a float
,那么表达式没有任何“错误” - 它将评估为true
(除非f
持有NaN
,在这种情况下,表达式将评估为false
)。
另一方面,x == (int)(double)x
(假设x
是 a int
)是(可能)有问题的,因为双精度 IEC 60559 浮点值只有 53 位的有效位1,int
如果它使用超过 53 位它在您的平台上的价值(诚然很少见)。因此,它将true
在int
s 为 32 位(使用 31 位作为值)false
的平台上进行评估,并可能在int
s 为 64 位(使用 63 位作为值)的平台上进行评估(取决于值)。
C标准(6.3.1.4和6.3.1.5)的相关引用:
当整数类型的值转换为真正的浮点类型时,如果被转换的值可以在新类型中精确表示,则它是不变的。
当实浮点类型的有限值转换为除 以外的整数类型
_Bool
时,小数部分被丢弃(即,该值被截断为 0)。如果整数部分的值不能用整数类型表示,则行为未定义。
当一个真正的浮点类型的值被转换为一个真正的浮点类型时,如果被转换的值可以在新的类型中精确地表示,那么它是不变的。
1双精度 IEC 60559 浮点值由 1 位符号、11 位指数和 53 位有效位组成(其中 1 是隐含的且未存储) - 总共 64 位(已存储)。
推荐阅读
- angular - Angular 9 迁移问题声明 var global: NodeJS.Global & typeof globalThis;
- leaflet - 使用带有传单的草皮
- javascript - 如何使用 JavaScript 和 createElement 添加带有事件的 HTML 元素?
- javascript - 不使用 react-router-dom 渲染
- javascript - 验证对象解构
- javascript - 如何在 JS Intl API 中获取语言中立的语言环境
- java - 将 JsonIgnore 用于其他类中的属性
- django - 如何将静态文件分配给初始 forms.FileField?
- java - 在 Apache Camel xml 验证中使用 xsi:schemaLocation 属性
- python - 如果满足条件,则提取上下行