C++ C+中为0.501+;舍入算法,C+中的Excel舍入+;
我有以下常规舍入的遗留代码(向上舍入一半,类似于Excel舍入函数中的舍入)。我有关于这个代码的问题C++ C+中为0.501+;舍入算法,C+中的Excel舍入+;,c++,algorithm,floating-point,rounding,C++,Algorithm,Floating Point,Rounding,我有以下常规舍入的遗留代码(向上舍入一半,类似于Excel舍入函数中的舍入)。我有关于这个代码的问题 为什么使用0.50倍加法?我理解,应该使用0.5加法来实现“四舍五入”条件,但为什么会有0.501?我们的经验表明,0.501在实践中效果良好,它引入的舍入误差(当RoundFloat与Excel舍入不同时)远小于0.5。为什么呢?浮点计算是否偏向于给出比理想情况下更小的值,并且0.501纠正了这些偏向 虽然0.501在大多数情况下效果良好,但某些值存在问题,例如RoundFloat(7.334
double LongLong( double value ) {
long long l = ( long long ) value;
return l;
}
double RoundFloat( double * value, double * tonearest ) {
double ad;
long long mzr;
double resval;
if ( ( *tonearest < 0 ) || ( *tonearest > 6 ) ) return * value;
if ( *value < 0.000000001 )
ad = -0.501;
else
ad = 0.501;
mzr = LongLong(*value);
resval = *value - mzr;
switch ( ( long ) *tonearest )
{
case 0 : resval= LongLong( resval+ad);
case 1 : resval= LongLong( resval*10+ad)/10;
case 2 : resval= LongLong( resval*100+ad)/100;
case 3 : resval= LongLong( resval*1000+ad)/1000;
case 4 : resval= LongLong( resval*10000+ad)/10000;
case 5 : resval= LongLong( resval*100000+ad)/100000;
case 6 : resval= LongLong( resval*1000000+ad)/1000000;
default: resval= resval;
}
resval = resval+mzr;
return resval;
}
double LongLong(双值){
长l=(长l)值;
返回l;
}
双圆浮点(双*值,双*音调最短){
双重广告;
长mzr;
双重resval;
if((*tonearest<0)| |(*tonearest>6))返回*值;
如果(*值<0.000000001)
ad=-0.501;
其他的
ad=0.501;
mzr=LongLong(*值);
resval=*值-mzr;
开关((长)*音调最大)
{
案例0:resval=LongLong(resval+ad);
案例1:resval=LongLong(resval*10+ad)/10;
案例二:resval=LongLong(resval*100+ad)/100;
案例三:resval=LongLong(resval*1000+ad)/1000;
案例四:resval=LongLong(resval*10000+ad)/10000;
案例5:resval=LongLong(resval*100000+ad)/100000;
案例6:resval=LongLong(resval*1000000+ad)/1000000;
默认值:resval=resval;
}
resval=resval+mzr;
返回resval;
}
(我将此答案限制为IEEE754浮点,这是Excel使用的。)
Excel使用0.5(圆角轴),因为这是正确的做法。注意,0.5(作为二元有理数)可以用浮点精确表示
使用0.501是任意的,过于不对称,并且显示出对浮点的理解不足
由于数字略小于0.5,且0.5是最接近的可表示数字,因此可能会产生一些虚假效果。所以你的“少一点”数字会被四舍五入,即使它真的应该被四舍五入。但这更多的是因为这个数字一开始就不能准确地表示出来。因此,尽管0.5会给你一些奇怪的效果,但它平均比0.501或类似的效果更精确。而做一些事情,比如增加超过0.5,将搞乱四舍五入是最佳的情况
虽然我集中讨论了0.5,但所有舍入效应都可以用相同的方式解释,尽管在其他情况下舍入轴本身可能无法表示
像Excel一样,学会接受这种效果。(请记住,Excel可以以一种对用户隐藏这些效果的方式格式化数据,因此它似乎做了一些比实际更特殊的事情。)如果计算精度超过15位有效数字是绝对关键的,那么请使用支持任意精度的类。(我将此答案限制为IEEE754浮点,这是Excel使用的。)
Excel使用0.5(舍入轴),因为这是正确的做法。请注意,0.5(作为二元有理数)可以用浮点精确表示
使用0.501是任意的,过于不对称,并且显示出对浮点的理解不足
你可以得到一些虚假的效果,因为一个数字比0.5小一点,而0.5是最接近的可表示数字数字被四舍五入,即使它真的应该被四舍五入。但这更多的是因为这个数字在一开始就不能准确地表示。因此,尽管0.5会给你一些奇怪的效果,但它平均比0.501或类似的数字更准确。而做一些事情,比如加上0.5以上,会把情况搞砸四舍五入是最佳选择
虽然我集中讨论了0.5,但所有舍入效应都可以用相同的方式解释,尽管在其他情况下舍入轴本身可能无法表示
学习使用效果,就像Excel一样。(请记住,Excel可以以一种对用户隐藏这些效果的方式格式化数据,因此它似乎在做一些比实际更特殊的事情。)如果计算精确到超过15位有效数字是绝对关键的,那么请使用支持任意精度的类