为了账号安全,请及时绑定邮箱和手机立即绑定

四舍五入到任意有效位数

四舍五入到任意有效位数

繁花如伊 2019-12-12 14:10:53
您如何将任何数字(不仅是整数> 0)舍入为N个有效数字?例如,如果我想四舍五入到三位有效数字,我正在寻找一个可能采用的公式:1,239,451,回报1,240,00012.1257并返回12.1.0681并返回.06815并返回5自然,不应将算法硬编码为仅处理3的N,尽管这只是一个开始。
查看完整描述

3 回答

?
九州编程

TA贡献1785条经验 获得超4个赞

这是Java中的相同代码,没有12.100000000000001错误,其他答案也有


我还删除了重复的代码,更改power为整数类型以防止n - d完成操作时出现浮动问题,并使长中间体更加清晰


该错误是由大量乘以少量引起的。相反,我将两个相似大小的数字相除。


编辑

修正了更多的错误。添加了对0的检查,因为这会导致NaN。使函数实际使用负数(原始代码不处理负数,因为负数的对数是复数)


public static double roundToSignificantFigures(double num, int n) {

    if(num == 0) {

        return 0;

    }


    final double d = Math.ceil(Math.log10(num < 0 ? -num: num));

    final int power = n - (int) d;


    final double magnitude = Math.pow(10, power);

    final long shifted = Math.round(num*magnitude);

    return shifted/magnitude;

}



查看完整回答
反对 回复 2019-12-13
?
慕尼黑的夜晚无繁华

TA贡献1864条经验 获得超6个赞

这是一个简短而有趣的JavaScript实现:


function sigFigs(n, sig) {

    var mult = Math.pow(10, sig - Math.floor(Math.log(n) / Math.LN10) - 1);

    return Math.round(n * mult) / mult;

}


alert(sigFigs(1234567, 3)); // Gives 1230000

alert(sigFigs(0.06805, 3)); // Gives 0.0681

alert(sigFigs(5, 3)); // Gives 5



查看完整回答
反对 回复 2019-12-13
?
汪汪一只猫

TA贡献1898条经验 获得超8个赞

摘要:


double roundit(double num, double N)

{

    double d = log10(num);

    double power;

    if (num > 0)

    {

        d = ceil(d);

        power = -(d-N);

    }

    else

    {

        d = floor(d); 

        power = -(d-N);

    }


    return (int)(num * pow(10.0, power) + 0.5) * pow(10.0, -power);

}

因此,您需要找到第一个非零数字的小数位,然后保存下N-1个数字,然后根据其余数字舍入第N个数字。


我们可以使用日志来做第一个。


log 1239451 = 6.09

log 12.1257 = 1.08

log 0.0681  = -1.16

因此,对于大于0的数字,请取对数的上限。对于数字<0,请使用日志的底数。


现在我们有数字d:第一种情况为7,第二种情况为2,第三种情况为-2。


我们必须将(d-N)数字四舍五入。就像是:


double roundedrest = num * pow(10, -(d-N));


pow(1239451, -4) = 123.9451

pow(12.1257, 1)  = 121.257

pow(0.0681, 4)   = 681

然后执行标准的舍入操作:


roundedrest = (int)(roundedrest + 0.5);

并撤消战俘。


roundednum = pow(roundedrest, -(power))

功率是上面计算出的功率。


关于准确性:Pyrolistical的答案确实更接近实际结果。但是请注意,无论如何您都不能完全代表12.1。如果按以下方式打印答案:


System.out.println(new BigDecimal(n));

答案是:


Pyro's: 12.0999999999999996447286321199499070644378662109375

Mine: 12.10000000000000142108547152020037174224853515625

Printing 12.1 directly: 12.0999999999999996447286321199499070644378662109375

因此,请使用Pyro的答案!



查看完整回答
反对 回复 2019-12-13
  • 3 回答
  • 0 关注
  • 295 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信