C 中从 Float 到 Int 的类型转换导致数字大不相同,为啥?

Posted

技术标签:

【中文标题】C 中从 Float 到 Int 的类型转换导致数字大不相同,为啥?【英文标题】:Type-Casting in C from Float to Int results in wildly different number, why?C 中从 Float 到 Int 的类型转换导致数字大不相同,为什么? 【发布时间】:2020-07-27 20:05:49 【问题描述】:

输入:

#include <stdio.h>
    #include <math.h>
    
    int main(void)
    
        printf("%i", (int)pow(10,10));
        
        return 0;
    

输出:

-2147483648

由于某种原因,pow() 在我运行它时会产生 double 而不是 int(我使用的是 Pow(),因为由于某种原因,指数没有编码到 C 中)。有什么原因吗?

【问题讨论】:

你知道int可以存储的最大数量是多少吗? 你的目标是什么?您可以在 printf 中使用 .0 格式而不是强制转换吗? 【参考方案1】:

(int)pow(...) 的强制转换是将double 值转换为整数类型。 double 是 C 中可用的真正浮点类型之一。

关于将浮点类型转换为整数的规则可以在in C11 draft 6.3.1.4p4 找到,但是cppreference real floatinf-integer conversion 上有更简单的版本:

任何实浮点类型的有限值都可以隐式转换 到任何整数类型。除非上面的布尔转换涵盖, 规则是:

The fractional part is discarded (truncated towards zero). 
如果结果值可以由目标类型表示,则使用该值 否则,行为未定义

假设您有一个健全的平台,您的 sizeof(int) 是 4 和 INT_MAX=2147483647pow(10, 10) 的结果是 (double)10000000000.0,它的小数部分无法在目标整数类型 (int) 中表示。你的代码行为就是undefined。

【讨论】:

【参考方案2】:

4 字节整数可以容纳的最大值范围为 -2,147,483,648 到 2,147,483,647。 10^10 的结果是 10,000,000,000,超出了限制,转换溢出,产生了意想不到的结果。就是这样。

【讨论】:

and the integer overflows 呈现的代码中没有溢出。 @Rohan Bari 谢谢!我完全忘记了对变量的大小限制 不,没有“溢出”。 “溢出”是什么操作?在什么意义上? @KamilCuk:10,000,000,000 到int 的转换溢出。 C 标准没有为“溢出”定义专门的 C 含义,因此这只是指不适合目标格式的结果的普通用法。 C 2018 6.3.1.4 1 讨论了浮点到整数的转换,并说“如果整数部分的值不能用整数类型表示,则行为未定义。” @RohanBari:转换的行为不是由 C 标准定义的,但我们观察到的结果 -2,147,483,648 也不是“意外的”。虽然我们不能依赖它,因为没有一些规范说这将是结果,但这是一个常见的、并不令人惊讶或完全出乎意料的结果。例如,英特尔指令通常会为浮点到整数的转换生成这个。

以上是关于C 中从 Float 到 Int 的类型转换导致数字大不相同,为啥?的主要内容,如果未能解决你的问题,请参考以下文章

是否总是可以将`int`转换为`float`

怎么把float型转换成int

怎么把float型转换成int

c#中int向float型转换。

请问C语言中如何将int转换为float

c语言里怎么把float转换为char型?