如何在Number.toFixed函数中四舍五入?

时间:2020-04-09 21:25:49

标签: javascript java node.js

我正在用Java编写API,并且代码的行为应类似于用Node编写的另一个微服务。

用Node写的问题部分是这样的:

const totalValue =   // this value comes from a query
const risk =         // it is a percentage value from another query

const riskValue = totalValue * (risk / 100);
const available = +(totalValue - riskValue).toFixed(2);

return available;

经过几次测试,我以这种方式编写了Java API:

BigDecimal totalValue = ...
BigDecimal risk = ...

BigDecimal riskValue = totalValue.multiply(risk.divide(new BigDecimal(100)));
BigDecimal available = totalValue.subtract(riskValue).setScale(2, RoundingMode.HALF_DOWN));

几天后,第一个错误:

totalValue = 62822.65
risk = 10

节点返回:

56540.385.toFixed(2); // "56540.39"

这个数字并没有像我期望的那样在Java API中四舍五入。

但是,这个数字四舍五入为一个整数

56540.395.toFixed(2); // "56540.39"

JavaScript Number.toFixed(2)背后的逻辑是什么?

如何在Java中复制此函数行为?

谢谢。

2 个答案:

答案 0 :(得分:1)

我不确定我是否完全理解您的问题。如果您的问题是如何将double的数字四舍五入到2小数位,则可以按照以下步骤操作:

import java.math.BigDecimal;
import java.math.RoundingMode;

public class Main {
    public static void main(String[] args) {
        double n1 = 56540.385;
        BigDecimal rounded1 = BigDecimal.valueOf(n1).setScale(2, RoundingMode.HALF_UP);
        System.out.println(rounded1);

        double n2 = 56540.395;
        BigDecimal rounded2 = BigDecimal.valueOf(n2).setScale(2, RoundingMode.HALF_UP);
        System.out.println(rounded2);
    }
}

输出

56540.39
56540.40

如果您正在寻求其他帮助,请随时发表评论。

答案 1 :(得分:1)

参考Arvind Kumar Avinash的答案

问题在于,确切的数字56540.38556540.395不存在:浮点数始终基于二进制,而不基于十进制。

证明:

56540.385.toPrecision(18); // returns "56540.3850000000020"
56540.395.toPrecision(18); // returns "56540.3949999999968"

因此,表达式NUMBER.toFixed(2);分为两个步骤:

  1. 将NUMBER扫描后转换为最近的可能的浮点数。
  2. toFixed()用于转换后的数字。

如果在幕后了解此数学,则6540.39的结果在两种情况下都是正确的。

一种可能的解决方案是计算所有百分比(因子100),然后对格式化的输出使用(NUMBER/100).toFixed(2)