为什么很多(旧)程序使用floor(0.5 + input)而不是round(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

但最终它们只是不同的结果,我们选择它的首选。我看到很多“旧”C / C ++程序使用floor(0.5 + input)而不是round(input)

有没有历史原因?最便宜的CPU?

答案


std::round在C ++ 11中引入。在此之前,只有std::floor程序员才能使用它。


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

我的猜测是,直到C ++ 11(尽管C在C99中获得它们)之前,一种体面的开箱即用的德语舍入函数还没有正式可用,但这实际上不适用于采用所谓的替代方法。

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

原因很微妙:德国舍入的截止点,a.5因为整数a是由宇宙的巧合特性构成的二元理性。由于这可以精确地表示为IEEE754浮点数,直到52的2次方,然后舍入是无操作的,std::round总是正常工作。对于其他浮点方案,请参阅文档。

但是增加0.5一个double可能会导致不精确性,导致一些数值略低或超过。如果你仔细想一想,将两个double值加在一起 ​​- 即不知情的denary转换的开始 – 并且应用一个非常强大的输入函数(比如舍入函数)的函数,一定会以泪结束。

不要这样做

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


 

我认为这是你犯错的地方:

但最终它们只是不同的结果,我们选择它的首选。我看到许多使用floor(0.5 + input)而不是round(input)的“旧”C / C ++程序。

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


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

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


许多程序员修改了使用其他语言进行编程时学到的习惯用法。并非所有的语言都有round()功能,在这些语言中,floor(x + 0.5)用作替代品是正常的。当这些程序员开始使用C ++时,他们并不总是意识到这是内置的round(),他们继续使用他们习惯的风格。

换句话说,仅仅因为你看到很多代码能够实现某些功能,这并不意味着这样做的充分理由。你可以在每种编程语言中找到这个例子。记住鲟鱼的法则

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

添加评论

友情链接:蝴蝶教程