javascript正确四舍五入到两位小数,不可能吗?

发布于 2024-09-06 13:09:40 字数 818 浏览 4 评论 0原文

在 php 中,我们有 number_format()。向其传递一个值,例如:

number_format(3.00 * 0.175, 2);

返回0.53,这是我所期望的。

但是,在 JavaScript 中使用 toFixed()

var num = 3.00 * 0.175;
num.toFixed(2);

返回 0.52

好吧,也许 toFixed 不是我想要的...也许是这样的...

var num = 3.17 * 0.175;
var dec = 2;
Math.round( Math.round( num * Math.pow( 10, dec + 1 ) ) / Math.pow( 10, 1 ) ) / Math.pow(10,dec);

不,那也不起作用。它将返回 0.56。

如何在 JavaScript 中获取不给出错误答案的 number_format 函数?

实际上我确实找到了js的number_format的实现,http://phpjs.org/functions/number_format,但它也遇到同样的问题。

JavaScript 的四舍五入是怎么回事?我缺少什么?

In php, we have number_format(). Passing it a value such as:

number_format(3.00 * 0.175, 2);

returns 0.53, which is what I would expect.

However, in JavaScript using toFixed()

var num = 3.00 * 0.175;
num.toFixed(2);

returns 0.52.

Ok, so perhaps toFixed is not what I want... Maybe something like this...

var num = 3.17 * 0.175;
var dec = 2;
Math.round( Math.round( num * Math.pow( 10, dec + 1 ) ) / Math.pow( 10, 1 ) ) / Math.pow(10,dec);

No, that doesn't work either. It will return 0.56.

How can I get a number_format function in JavaScript that doesn't give an incorrect answer?

Actually I did find an implementation of number_format for js, http://phpjs.org/functions/number_format, but it suffers from the same problem.

What is going on here with JavaScript rounding up? What am I missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

宛菡 2024-09-13 13:09:40

JavaScript 在处理浮点数方面表现不佳(许多其他语言也是如此)。

运行时

3.000 * 0.175

当我在浏览器中

0.5249999999999999

,我得到Which will not round up to 0.525 with Math.round。为了避免这种情况,你必须将两边相乘,直到它们成为整数(相对简单,但了解一些技巧会有所帮助)。

为此,我们可以这样说:

function money_multiply (a, b) {
    var log_10 = function (c) { return Math.log(c) / Math.log(10); },
        ten_e  = function (d) { return Math.pow(10, d); },
        pow_10 = -Math.floor(Math.min(log_10(a), log_10(b))) + 1;
    return ((a * ten_e(pow_10)) * (b * ten_e(pow_10))) / ten_e(pow_10 * 2);
}

这可能看起来有点时髦,但这里有一些伪代码:

get the lowest power of 10 of the arguments (with log(base 10))
add 1 to make positive powers of ten (covert to integers)
multiply
divide by conversion factor (to get original quantities)

希望这就是您正在寻找的内容。这是一个示例运行:

3.000 * 0.175
0.5249999999999999

money_multiply(3.000, 0.175);
0.525

JavaScript does badly with floating point numbers (as do many other languages).

When I run

3.000 * 0.175

In my browser, I get

0.5249999999999999

Which will not round up to 0.525 with Math.round. To circumvent this, you kind of have to multiply both sides until you get them to be integers (relatively easy, knowing some tricks help though).

So to do this we can say something like this:

function money_multiply (a, b) {
    var log_10 = function (c) { return Math.log(c) / Math.log(10); },
        ten_e  = function (d) { return Math.pow(10, d); },
        pow_10 = -Math.floor(Math.min(log_10(a), log_10(b))) + 1;
    return ((a * ten_e(pow_10)) * (b * ten_e(pow_10))) / ten_e(pow_10 * 2);
}

This may look kind of funky, but here's some pseudo-code:

get the lowest power of 10 of the arguments (with log(base 10))
add 1 to make positive powers of ten (covert to integers)
multiply
divide by conversion factor (to get original quantities)

Hope this is what you are looking for. Here's a sample run:

3.000 * 0.175
0.5249999999999999

money_multiply(3.000, 0.175);
0.525
栖竹 2024-09-13 13:09:40

toFixed 函数工作正常。它会截断超过指定数量的小数位数。

The toFixed function is working correctly. It truncates past the specified amount of fraction digits.

花开柳相依 2024-09-13 13:09:40

为何拥有全部权力??为什么不稍微添加小于 1/2 一分圆形

(3.00 * 0.175 + 0.0049).toFixed(2)

从来没有过任何会计师都会抱怨产出。

Why all the powers?? Why not just add slightly less than 1/2 a cent and round:

(3.00 * 0.175 + 0.0049).toFixed(2)

Never had any accountants complain about the output.

甜警司 2024-09-13 13:09:40

我认为您遇到的问题是浮点数学而不是舍入本身。

使用 firebug 控制台进行测试,记录给定 0.524999...3.00 * 0.175 的结果。因此,将这个数字向下舍入实际上是正确的。

我不知道是否有一个好的解决方案来解决您的问题,但根据我使用货币时的经验:使用最小单位(美分)进行工作然后转换以显示会更容易。

I think the problem you are encountering is with floating point math as opposed to the rounding itself.

Using the firebug console for testing, logging the result of 3.00 * 0.175 given 0.524999.... So rounding this number down is actually correct.

I don't know if there is a good solution to your problem, but in my experience when working with currency: it is easier to work in the smallest unit (cents) and then convert for display.

站稳脚跟 2024-09-13 13:09:40

为什么不直接使用 Math.round( num * Math.pow( 10, dec ) ) / Math.pow( 10, dec) ) ?

编辑:我明白了,问题是 3 * 0.175 给你 0.52499999999999991 ,导致你想要一个额外的舍入步骤。也许只添加少量就可以了:

Math.round( num * Math.pow( 10, dec ) + 0.000000001 ) / Math.pow( 10, dec) )

Why didn't you just use Math.round( num * Math.pow( 10, dec ) ) / Math.pow( 10, dec) )?

EDIT: I see, the problem is that 3 * 0.175 gives you 0.52499999999999991, leading you to want an additional rounding step. Maybe just adding a small amount would work:

Math.round( num * Math.pow( 10, dec ) + 0.000000001 ) / Math.pow( 10, dec) )

巷雨优美回忆 2024-09-13 13:09:40

我知道这已经很旧了,但这就是我通常解决舍入问题的方法。这可以很容易地放入函数中,但现在我只是放入简单的变量。如果这不起作用,您可以使用 Money_format() 或 number_format() 作为 php.js 的开始(更多信息如下)。

var n = (3.00 * 0.175);
n = Math.round(n * Math.pow(10, 3)) / Math.pow(10, 3);
Math.round(n*100)/100;

结果为 0.53 (0.5249999999999999)

var n = (3.00 * 0.175);
n = Math.round(n * Math.pow(10, 3)) / Math.pow(10, 3);
Math.round(n*100)/100;

结果为 0.56 (0.55475)

看起来 php.js 存储库也在 GitHub 上保持 https://github.com/kvz/phpjs 因此,如果没有未正确执行的功能,则可以提交问题。

无论如何,我认为这些信息可能会对以后查找的人有所帮助。

I know this is old but this is how I usually solve a rounding problem. This can be put in a function easily but for now I just put in simple vars for right now. If this doesn't work you could use money_format() or number_format() as a start from php.js (more info below).

var n = (3.00 * 0.175);
n = Math.round(n * Math.pow(10, 3)) / Math.pow(10, 3);
Math.round(n*100)/100;

comes out to 0.53 (0.5249999999999999)

var n = (3.00 * 0.175);
n = Math.round(n * Math.pow(10, 3)) / Math.pow(10, 3);
Math.round(n*100)/100;

comes out to 0.56 (0.55475)

It also looks like the php.js repo is being kept up on GitHub https://github.com/kvz/phpjs so if there isn't a function that is not performing correctly an issue can be submitted.

Anyway figured this information may help someone looking later on.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文