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

时间:2010-06-21 01:14:08

标签: javascript currency rounding

在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 http://phpjs.org/functions/number_format找到了number_format的实现,但是它遇到了同样的问题。

这里有什么用JavaScript四舍五入?我错过了什么?

6 个答案:

答案 0 :(得分:12)

JavaScript在浮点数方面表现不佳(和许多其他语言一样)。

当我跑步时

3.000 * 0.175

在我的浏览器中,我得到了

0.5249999999999999

Math.round不会向上舍入到0.525。为了避免这种情况,你需要将两边相乘,直到你得到它们为整数(相对容易,知道一些技巧可以帮助)。

为此,我们可以这样说:

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

答案 1 :(得分:3)

toFixed功能正常运行。它会截断超过指定数量的小数位数。

答案 2 :(得分:3)

为什么所有权力?为什么不稍微添加less than 1/2 a centround

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

从未有任何会计师抱怨输出。

答案 3 :(得分:1)

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

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

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

答案 4 :(得分:0)

为什么不使用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) )

答案 5 :(得分:0)

我知道这已经过时了,但这就是我通常解决舍入问题的方法。这可以很容易地放在一个功能中,但是现在我只需要输入简单的变量。如果这不起作用,你可以使用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 repo正在GitHub上保持https://github.com/kvz/phpjs,所以如果没有正确执行的功能,可以提交问题。

无论如何认为这些信息可能会帮助后来的人。