英文:
How does rounding work in Number.toFixed function?
问题
以下是翻译好的内容:
我正在用Java编写一个API,代码应该像另一个用Node编写的微服务一样运行。
在Node中存在问题的部分是这样的:
const totalValue = // 这个值来自一个查询
const risk = // 这是另一个查询中的百分比值
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));
几天后出现了第一个bug:
totalValue = 62822.65
risk = 10
Node返回:
56540.385.toFixed(2); // "56540.39"
这个特定的数字并没有按我在Java API中期望的方式进行半下舍入。
然而,这个数字是按半下舍入方式进行舍入的:
56540.395.toFixed(2); // "56540.39"
JavaScript中Number.toFixed(2)
背后的逻辑是什么?
如何在Java中复制这个函数的行为?
提前致谢。
英文:
I am coding an API in Java, and the code should behave like another microservice written in Node.
The problematic part written in Node is this:
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;
After a few tests I coded the Java API this way:
BigDecimal totalValue = ...
BigDecimal risk = ...
BigDecimal riskValue = totalValue.multiply(risk.divide(new BigDecimal(100)));
BigDecimal available = totalValue.subtract(riskValue).setScale(2, RoundingMode.HALF_DOWN));
Some days later first bug:
totalValue = 62822.65
risk = 10
Node returns:
56540.385.toFixed(2); // "56540.39"
This specific number is not rounding half down as I expected it to happen in my Java API.
However, this number is rounding half down:
56540.395.toFixed(2); // "56540.39"
What's the logic behind JavaScript Number.toFixed(2)
?
How to copy this function behavior in Java?
Thanks in advance.
答案1
得分: 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
如果你需要关于其他事情的帮助,请随时评论。
英文:
I'm not sure if I understood your question completely. If your question is how to round a double
number up to 2
decimal places, you can do it as follows:
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);
}
}
Output
56540.39
56540.40
Feel free to comment in case you are seeking help regarding something else.
答案2
得分: 1
参考阿文德·库马尔·阿维纳什的回答
问题是,确切的数字 56540.385
和 56540.395
不存在:浮点数始终是基于二进制而不是十进制的。
证明:
56540.385.toPrecision(18); // 返回 "56540.3850000000020"
56540.395.toPrecision(18); // 返回 "56540.3949999999968"
因此表达式 NUMBER.toFixed(2);
经过两个步骤处理:
- 数字 NUMBER 被扫描并转换为最近可能的浮点数。
- 对转换后的数字执行
toFixed()
。
而且,如果了解背后的数学原理,对于两种情况,6540.39
的结果都是正确的。
一个可能的解决方案是将所有计算都以分为单位计算(乘以100),然后对格式化输出使用 (NUMBER/100).toFixed(2)
。
英文:
Referencing the answer by Arvind Kumar Avinash
The problem is, that the exact numbers 56540.385
and 56540.395
does not exist: Floats are always binary based and not decimal based.
Proof:
56540.385.toPrecision(18); // returns "56540.3850000000020"
56540.395.toPrecision(18); // returns "56540.3949999999968"
So the expression NUMBER.toFixed(2);
is processed into 2 steps:
- NUMBER is scanned in transformed to the nearest possible floating point number.
toFixed()
is executed for the transformed number.
And if knowing this mathematics behind the scenes, the result of 6540.39
is correct for both cases.
A possible solution can be to calculate all in cent (factor 100) and then using (NUMBER/100).toFixed(2)
for the formatted output.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论