将浮点数转换为整数的C语言方法

48

我正在使用 C(而非C ++)。

我需要将一个浮点数转换为int。我不想四舍五入到最接近的数字,我只想消除整数部分后面的内容。类似这样:

4.9 -> 4.9 -> 4

8
关于发型的事情就说到这里吧——它只是你需要的一个支架。 - Ed Heal
我不明白你所说的“将int转换为二进制数”的意思——int本身就是二进制的……或者你是想将它转换为二进制表示的字符串,例如将14转换为"1110"。无论哪种方式:浮点数是如何涉及到这个转换的? - mafso
阅读了用户3195614的回答后:也许混淆来自于整数除法计算为整数?在C中,5 / 2计算结果为2,而不是2.5 - mafso
任何带有小数点的内容都将被视为浮点数或更大的类型。获取该值的方法是使用库函数int floor(float)(向下取整)或(向上取整)int ceil(float)。 - user3629249
5个回答

77
my_var = (int)my_var;

就是这么简单。如果变量是 int 类型,基本上你不需要它。


1
非常感谢!它起作用了!如果问题太简单,对不起,我是C语言的新手... - A. O.
3
请确保对于负数和大数也要执行相应操作。这可能会更加复杂。如果浮点数是正数且小于您平台上的最大整数,则是安全的。 - Jakub
4
这很好,但它也是未定义行为。 - saolof

17

在C语言中使用

int C = var_in_float;

他们将转换为隐式


简单明了。 - Viraj Mohite

14

如果你想将其舍入为较小的值,只需将其转换即可。

float my_float = 42.8f;
int my_int;
my_int = (int)my_float;          // => my_int=42

如果您需要将其四舍五入到最接近的数,您可以创建一个小函数或定义如下:

#define FLOAT_TO_INT(x) ((x)>=0?(int)((x)+0.5):(int)((x)-0.5))

float my_float = 42.8f;
int my_int;
my_int = FLOAT_TO_INT(my_float); // => my_int=43

注意,最好在强制转换前验证浮点数是否在 INT_MIN 和 INT_MAX 之间。


3
在逻辑中使用宏并不是非常明智的选择,因为人们往往会将它们视为函数。例如,如果您使用 FLOAT_TO_INT(rand()) ,它会表现出奇怪的行为,最好将其作为一个函数来定义。 - DownloadPizza
3
关于:#define FLOAT_TO_INT(x) ((x)>=0?(int)((x)+0.5):(int)((x)-0.5)) 中的字面值 0.5 是一个 double,而你真正需要的是 float。建议更改为:#define FLOAT_TO_INT(x) ((x)>=0.0f?(int)((x)+0.5f):(int)((x)-0.5f)) - user3629249
3
"round it to lower"对于负数来说不正确/不清晰。(int)截断小数部分。 - chux - Reinstate Monica
2
@user3629249 当总和不精确时,(x)+0.5f 可能会给出错误的四舍五入结果。 (x)+0.5 通过使用更宽的 double 数学避免了这种情况。使用 IAC lroundf()roundf() 更好。 - chux - Reinstate Monica

6
double a = 100.3;
printf("%f %d\n", a, (int)(a* 10.0));

Output Cygwin 100.3 1003
Output MinGW: 100.3 1002

使用 (int) 将 double 转换为 int 似乎不是一个安全的方法。

你可以在这里找到更多相关信息:将 double 转换为 int?


很遗憾,这个问题是关于将 float 转换为 int,而不是 double 转换为 int - user3629249
@user3629249,同样的问题也适用于float,但是在这里仅使用float的示例会更好。 - chux - Reinstate Monica

0

好问题!-- 对于我的情况,我还没有找到令人满意的答案, 但我在这里提供的答案适用于我,但可能不具备未来的可靠性...

如果使用gcc(clang?)并定义了-Werror-Wbad-function-cast

int val = (int)pow(10,9);

将会产生以下错误:

error: cast from function call of type 'double' to non-matching type 'int' [-Werror=bad-function-cast]

(有很好的理由,需要考虑溢出和舍入值的情况)

编辑:2020-08-30:因此,我的用例将返回double类型的函数转换为int类型,并选择使用pow()来代替某个私有函数。然后我绕过了更多关于pow()的思考。(请参见下面的评论,了解为什么使用pow()可能存在问题...)。

经过适当的思考(参数传递给pow()是正确的),int val = pow(10,9); 似乎可以在gcc 9.2 x86-64上工作...

但请注意:

printf("%d\n", pow(10,4));

可能输出例如

-1121380856

(对我而言)在哪里

int i = pow(10,4); printf("%d\n", i);

打印

10000

在我尝试的一个特定情况中。


2
pow返回一个double,这就是为什么你不能使用%d打印它的原因。而且,使用pow来实现这个目的是错误的,因为它可能会对整数返回不正确的结果。使用1e4代替,以获得10^4。参见为什么gcc编译器将pow(10,2)输出为99而不是100?为什么pow(10,5)=9,999在C++中?为什么pow(5,2)变成了24? - phuclv
哦,这个(int)14e太好了。这是安全的吗?没有强制转换的1e4具有“double”类型(如pow()案例)。 - tomi
刚刚失去了编辑上面评论的机会--最近我有一个使用 1e6 的情况,但是(像往常一样)我使用了 printf("%d\n", 1e6); 进行测试,结果得到了奇怪的结果。如果确定 const int million = 1e6 是安全的,我会开始使用这样的格式。 - tomi
1
1e6 依赖于编译器进行高质量的 doubleint 转换。比 pow() 更不可能出现问题,但我没有看到 C 规范保证最佳答案。 (int)1e6 的替代方案:为什么在 C 中将 1,000,000,000 写成 100010001000?为什么不安全 - chux - Reinstate Monica
是的,与此示例中的10e4相比,pow()函数不太好(需要通过编辑提交进行修复)。我想知道为什么10e4double而不是int,然后尝试了1.12e112e-3来理解。 - tomi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接