从std :: round转换为int是否安全?

Ste*_*art 8 c++ floating-point rounding

我有一个关于带签名的std :: round的问题:double round (double x);

假设我有这段代码:

int i = std::round(0.9);
Run Code Online (Sandbox Code Playgroud)

在这种情况下,std::round应该返回1.00000000000,但这是令人不安的接近0.9999999999999,我担心浮点错误将最终四舍五入.

我希望如此i == 1,但这有保证吗?

Ron*_*Ron 9

std::round函数返回一个浮点值," 将中间情况舍入为零 ".对于任何doubleint隐式转换,编译器会发出警告:

从'double'转换为'int',可能会丢失数据

如果要返回整数值,请使用std :: lroundstd :: lrint.


Bat*_*eba 6

是.只要你没有溢出接收类型.

你在这里没有任何顾虑:std::round(0.9)完全 回合1.0,所以i == 1 保证

该标准坚持要求归还的最接近的积分值double.

请注意,对于IEEE754 double,超过52次方2的所有值都是整数值!其中的一个推论是,您的舍入候选数字已经是一个整数值,因此该函数会减少为无操作.因此,例如,std::round(4503599627370496.5)将返回4503599627370496的事实与4503599627370496.5不能首先表示为事实的事实有关double.

作为最后的技术点,请注意std::round表现得非常好,部分原因在于任何数量的形式a.5(德语舍入中的转换点)都是二元有理数,因此可以用二进制浮点表示.这就是为什么替代方法(如添加0.5和截断)可能会引入错误的原因,因为如果您这样做,可以引入笑话数字.


BoB*_*ish 5

C++标准遵循C标准.在N1570(~C11)中,描述round如下:

这些round函数将它们的参数四舍五入为浮点格式的最接近的整数值,无论当前的舍入方向如何,都将中间的情况四舍五入.

然而,正如罗恩所指出的那样,诸如lrint完全符合你想要的功能.

  • "请注意,这可能不是最接近的整数"这是错误的.这将是.如果数字不是整数,则它周围的两个整数都可用.如果它是整数,则无所事事. (2认同)