c - printf() 中大浮点数的奇怪行为并分配给 int
问题描述
根据我的计算,将浮点值转换为计算机存储的二进制值(符号、指数、尾数格式),在 32 位中,1 位用于符号,8 位用于指数。
所以只剩下 23 位来表示这个数字。
所以我认为具有正确行为的浮点值范围只有 0-0xffffff(基本上只有 3 个字节值),而不是 0-0xffffffff。这个对吗?
下面代码的奇怪行为是否与这个概念有关?
int main(void)
{
float a=2555555555;
printf("%f\n",a);
int b = a;
printf("%d",b);
return 0;
}
输出:
a = 2555555584.000000
b = -2147483648
解决方案
关于您的程序,首先要注意的是该值2555555555
超出了(有符号的)32 位整数类型的范围。从您的程序的输出来看,您的系统上似乎int
是 32 位类型,所以2555555555
不能是int
.
根据标准,2555555555
将是 along int
或long long int
,这取决于是否long int
足够大。
下一个相关部分是:
当整数类型的值转换为真正的浮点类型时,如果被转换的值可以在新类型中精确表示,则它是不变的。如果要转换的值在可以表示但不能精确表示的值范围内,则结果是最近的较高或最近的较低可表示值,以实现定义的方式选择。如果要转换的值超出可表示的值范围,则行为未定义。
(强调我的。)
因为2555555555
需要至少 32 位尾数才能准确表示,所以它不适合 32 位float
. 这就是为什么a
最终包含2555555584
type 的最接近的可表示值float
。
int b = a;
本节适用:
当实浮点类型的有限值转换为除 以外的整数类型
_Bool
时,小数部分被丢弃(即,该值被截断为 0)。如果整数部分的值不能用整数类型表示,则行为未定义。
(强调我的。)
2555555584
,所讨论的整数值,不能用带符号的 32 位 表示int
。这部分代码具有未定义的行为。
推荐阅读
- batch-file - 如何从回声中设置变量?
- android - openid/AppAuth 从 Activity 外部调用 startActivity()
- javascript - AJAX:未捕获的类型错误:无法读取 null 的属性“长度”
- reactjs - 为什么样式不能是 React 中的纯字符串?
- python - 饼图中的百分比未添加
- deployment - Ansible 中的单个变量如何根据主机实例具有不同的值?
- sql - 使用 group by 的 Sql 查询耗时太长
- c++ - 避免 std::upper_bound 崩溃
- wordpress - Woocommerce 默认 CSV 导出器/导入器中的 post_status
- python - 线程在不点击 tkinter 的情况下运行?