我正在尝试将十进制数截断为小数位。像这样的东西:
5.467 -> 5.46
985.943 -> 985.94
toFixed(2)
做了几乎正确的事情,但它使value四舍五入。我不需要四舍五入的值。希望这在javascript中是可能的。
我正在尝试将十进制数截断为小数位。像这样的东西:
5.467 -> 5.46
985.943 -> 985.94
toFixed(2)
做了几乎正确的事情,但它使value四舍五入。我不需要四舍五入的值。希望这在javascript中是可能的。
Dogbert 的回答很好,但如果您的代码可能必须处理负数,则Math.floor
其本身可能会产生意想不到的结果。
例如Math.floor(4.3) = 4
,但是Math.floor(-4.3) = -5
使用类似这样的辅助函数来获得一致的结果:
truncateDecimals = function (number) {
return Math[number < 0 ? 'ceil' : 'floor'](number);
};
// Applied to Dogbert's answer:
var a = 5.467;
var truncated = truncateDecimals(a * 100) / 100; // = 5.46
这是这个函数的一个更方便的版本:
truncateDecimals = function (number, digits) {
var multiplier = Math.pow(10, digits),
adjustedNum = number * multiplier,
truncatedNum = Math[adjustedNum < 0 ? 'ceil' : 'floor'](adjustedNum);
return truncatedNum / multiplier;
};
// Usage:
var a = 5.467;
var truncated = truncateDecimals(a, 2); // = 5.46
// Negative digits:
var b = 4235.24;
var truncated = truncateDecimals(b, -2); // = 4200
如果这不是我们想要的行为,请Math.abs
在第一行插入一个调用:
var multiplier = Math.pow(10, Math.abs(digits)),
编辑: shendz 正确地指出,使用此解决方案 witha = 17.56
将错误地生成17.55
. 有关为什么会发生这种情况的更多信息,请阅读每个计算机科学家应该知道的关于浮点运算的知识。不幸的是,使用 javascript 编写一个消除所有浮点错误来源的解决方案非常棘手。在另一种语言中,您将使用整数或十进制类型,但使用 javascript ......
这个解决方案应该是100% 准确的,但它也会变慢:
function truncateDecimals (num, digits) {
var numS = num.toString(),
decPos = numS.indexOf('.'),
substrLength = decPos == -1 ? numS.length : 1 + decPos + digits,
trimmedResult = numS.substr(0, substrLength),
finalResult = isNaN(trimmedResult) ? 0 : trimmedResult;
return parseFloat(finalResult);
}
对于那些需要速度但又想避免浮点错误的人,可以试试BigDecimal.js 之类的东西。您可以在这个 SO 问题中找到其他 javascript BigDecimal 库:“是否有一个好的 Javascript BigDecimal 库?” 这是一篇关于Javascript 数学库的好博文
更新:
所以,毕竟事实证明,舍入错误总是困扰着你,无论你如何努力补偿它们。因此,应该通过精确地用十进制表示法来表示数字来解决这个问题。
Number.prototype.toFixedDown = function(digits) {
var re = new RegExp("(\\d+\\.\\d{" + digits + "})(\\d)"),
m = this.toString().match(re);
return m ? parseFloat(m[1]) : this.valueOf();
};
[ 5.467.toFixedDown(2),
985.943.toFixedDown(2),
17.56.toFixedDown(2),
(0).toFixedDown(1),
1.11.toFixedDown(1) + 22];
// [5.46, 985.94, 17.56, 0, 23.1]
基于其他人的编译的旧的容易出错的解决方案:
Number.prototype.toFixedDown = function(digits) {
var n = this - Math.pow(10, -digits)/2;
n += n / Math.pow(2, 53); // added 1360765523: 17.56.toFixedDown(2) === "17.56"
return n.toFixed(digits);
}
var a = 5.467;
var truncated = Math.floor(a * 100) / 100; // = 5.46
您可以通过为 toFixed 减去 0.5 来修复舍入,例如
(f - 0.005).toFixed(2)
考虑利用双波浪线:~~
.
取号。乘以小数点后的有效数字,以便您可以使用截断到零位~~
。将该乘数除掉。利润。
function truncator(numToTruncate, intDecimalPlaces) {
var numPower = Math.pow(10, intDecimalPlaces); // "numPowerConverter" might be better
return ~~(numToTruncate * numPower)/numPower;
}
我试图抵制~~
用括号包装调用;我相信,操作顺序应该使其正常工作。
alert(truncator(5.1231231, 1)); // is 5.1
alert(truncator(-5.73, 1)); // is -5.7
alert(truncator(-5.73, 0)); // is -5
编辑:回顾过去,我无意中也处理了小数点左边四舍五入的情况。
alert(truncator(4343.123, -2)); // gives 4300.
寻找这种用法的逻辑有点古怪,并且可能会从快速重构中受益。但它仍然有效。好运不如好运。