如何在现代C ++中将浮点数转换为整数

6

虽然看起来很奇怪,但我找不到如何将 float 清晰地转换为 int

这种技术

int int_value = (int)(float_value + 0.5);

触发一个事件。
warning: use of old-style cast

在GCC中,如何以现代化、简单的方式将float转换为int?(当然会有精度损失)


2
最现代的方式是 std::round - chris
int int_value = float_value + .5f; 这行代码是做什么的?提示:0.5 是一个 double 类型。 - Aki Suihkonen
@chris round会返回一个浮点数。你可以调用lround,但它返回的是long而不是int。哦,现在我明白了,你只是在谈论四舍五入部分,而不是强制转换为int部分。这将教训我在评论之前阅读整个问题:-) - Praetorian
@Praetorian,虽然我相信它保证返回一些可以截断到正确数字的东西。但是我真的忘记了lround的存在。longint大小相同的可能性很大。 - chris
1
作为一个附注,许多(专家术语:)浮点数不能被转换为整数,因为它们超出了整数范围。 - NoSenseEtAl
3个回答

8

正如Josh在评论中指出的那样,+ 0.5 不是非常可靠。为了更安全,您可以将 static_caststd::round 结合使用,像这样:

int int_value = static_cast<int>(std::round(float_value));

涉及到转换部分,请参考这篇优秀的文章进行了解。


5
“+0.5”是一种非常不可靠的四舍五入方法,这是由于浮点数计算问题所致。请参阅http://blog.frama-c.com/index.php?post/2013/05/02/nearbyintf1。 - Josh Kelley
static_cast 在这里完全没有作用;一旦你完成了 std::round,你可以忘记它(如果流不适合,将得到未定义的行为),或者你可以将结果分配给一个 float,并在执行赋值之前检查其是否大于 std::numeric_limits<int>::max() 和小于 std::numeric_limits<int>::min()。(lexical_cast 是非常糟糕的想法,因为它不起作用。) - James Kanze
@JamesKanze:省略强制类型转换会导致精度损失的警告吗? - Victor Sand
@VictorSand 编译器可以警告任何它觉得需要的内容,包括在存在强制类型转换的情况下。但实际上...显式强制类型转换是告诉编译器你知道自己在做什么的传统方式,这不是疏忽,所以我会期望强制类型转换对警告产生影响。 - James Kanze

1
尝试:
int int_value = static_cast<int>(float_value + 0.5);

FYI: C++中的不同转换提供了关于C++引入的4种转换的非常好的解释。

1
你可以考虑以下内容
int int_value = boost::lexical_cast<int>(float_value);
lexical_cast有一个好处,就是适用于所有基本类型、STL字符串等。这也意味着您不必执行(float_value + 0.5)之类的操作。

如果中间字符串包含小数点,那么这种方法就行不通了,而对于浮点数来说,这种情况很可能发生。或者,如果浮点数非常大,也会出现问题。此外,对于负值的四舍五入,您需要减去0.5,因此四舍五入并不容易。 - Ulrich Eckhardt

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