项目中偶然发现没有逢5进位,原来使用了新的进位规则:四舍六入五成双
示例:
double a=3.444;
double b=4.446;
double c1=3.435;
double c2=3.445;
double c3=3.4351;
double c4=3.4451;
QString strA=QString::number(a,'f',2);
QString strB=QString("%1").arg(b,0,'f',2);//另一种输出相应精度值的方法
QString strC1=QString::number(c1,'f',2);
QString strC2=QString::number(c2,'f',2);
QString strC3=QString::number(c3,'f',2);
QString strC4=QString::number(c4,'f',2);
qDebug()<<"a: "<<a<<"->"<<strA;
qDebug()<<"b: "<<b<<"->"<<strB;
qDebug()<<"c1: "<<c1<<"->"<<strC1;
qDebug()<<"c2: "<<c2<<"->"<<strC2;
qDebug()<<"c3: "<<c3<<"->"<<strC3;
qDebug()<<"c4: "<<c4<<"->"<<strC4;
输出:
a: 3.444 -> "3.44" //4舍;
b: 4.446 -> "4.45" //6入;
c1: 3.435 -> "3.44" //5看奇偶,奇数(3)进位;
c2: 3.445 -> "3.44" //5看奇偶,偶数(4)不进位;
c3: 3.4351 -> "3.44" //5后面还有非0数,不管奇偶都进位;
c4: 3.4451 -> "3.45" //5后面还有非0数,不管奇偶都进位;
此外,发现个别数据存在问题,如9.975
按此规则,应该是9.98
,但实际是9.97
;
推测是浮点数的存储和计算中的不精确性,即实际存储的可能是9.974999999...
解决方法是自行写函数进行四舍五入:
double roundDouble(double value, int decimalPlaces) {
double factor = pow(10.0, decimalPlaces);
return round(value * factor) / factor;
}
roundDouble(9.975,2)
输出为9.98
另外,加上一个很小的值也是一个方法,如加上0.0000000001
变成9.9750000001
,这时再用QString::number
可得到9.98
,但是这样5看奇偶的规则就失效了。
想四舍五入而不是四舍六入五成双,可使用前面的函数roundDouble
,另一种写法:
double getPrecision(double value,int pre)
{
double offset=0.5;
if(pre<1) return value;
double prod=qPow(10.0,pre);
if(value<0) offset=-offset;
int tmp=(int)(value*prod+offset);
double ret=tmp/prod;
return ret;
}
评论区