为什么很多(旧)程序使用floor(0.5 + input)而不是round(input)?

这个差异就在于我所相信的返回值给出的input是相信的,比如这个代码 :

int main() { std::cout.precision(100); double input = std::nextafter(0.05, 0.0) / 0.1; double x1 = floor(0.5 + input); double x2 = round(input); std::cout << x1 << std::endl; std::cout << x2 << std::endl; } 

其输出:

 1 0 

但是最后他们只是不同的结果,一个select了自己喜欢的结果。 我看到许多使用floor(0.5 + input)而不是round(input)的“旧”C / C ++程序。

有什么历史原因吗? 在CPU上最便宜?

std::round是在C ++ 11中引入的。 在此之前,只有std::floor可用,所以程序员正在使用它。

没有任何历史的原因。 这种偏差从今年开始就已经出现了。 当他们感觉非常非常调皮的时候,民间做这个。 这是一个严重的浮点algorithm滥用,许多经验丰富的专业程序员都为此付出代价。 即使是Java bods也能达到1.7版本。 有趣的家伙。

我的猜想是,直到C ++ 11(尽pipeC在C99中得到C),一个体面的德国式圆整函数还没有正式可用,但是这实际上并不是采用所谓的替代方法的借口。

这是事情: floor(0.5 + input)并不总是恢复相同的结果作为相应的std::round调用!

原因是非常微妙的:德国四舍五入的截止点a.5是一个整数a ,由宇宙的巧合性质,是一个二元的理性 。 因为这可以完全用IEEE754浮点数来表示,直到52的2次方,然后舍入是无用的, std::round总是正常工作。 对于其他浮点scheme,请参阅文档。

但是double 0.5会导致不精确,导致某些值稍微不足或过冲。 如果你仔细想一想,把两个double精度值加在一起 ​​- 即不知情的denary转换的开始 – 并且应用一个非常强大的input函数(比如四舍五入的函数)的函数,肯定会以泪结束。

不要这样做

参考: 为什么Math.round(0.49999999999999994)返回1

我想这是你犯错的地方:

但是最后他们只是不同的结果,一个select了自己喜欢的结果。 我看到许多使用floor(0.5 + input)而不是round(input)的“旧”C / C ++程序。

事实并非如此。 您必须为该域select正确的舍入scheme 。 在金融应用程序中,您将使用银行家的规则(不使用浮动方式)。 然而,在采样时,使用static_cast<int>(floor(f + .5))static_cast<int>(floor(f + .5))产生较less的采样噪声,这会增加dynamic范围。 alignment像素时,即将位置转换为屏幕坐标,使用任何其他舍入方法将产生空洞,间隙和其他伪像。

一个简单的原因可能是有不同的舍入数字的方法,所以除非你知道使用的方法,否则你可能会得到不同的结果。

用floor(),你可以和结果保持一致。 如果浮点数是.5或更大,添加它将碰到下一个int。 但是.49999只会减小十进制。

许多程序员适应用其他语言编程时学到的习惯用法。 并不是所有的语言都有round()函数,在这些语言中,使用floor(x + 0.5)作为替代是正常的。 当这些程序员开始使用C ++时,他们并不总是意识到有一个内置的round() ,他们继续使用他们习惯的样式。

换句话说,就是因为你看到很多代码做了一些事情,这并不意味着有这样的理由。 你可以在每种编程语言中find这个例子。 记住鲟鱼的法则 :

百分之九十的一切都是废话