截断(非舍入)javascript 中的十进制数
2022-08-30 05:12:13
我正在尝试将十进制数截断到小数位。像这样:
5.467 -> 5.46
985.943 -> 985.94
toFixed(2)
做了正确的事情,但它会四舍五入价值。我不需要四舍五入的值。希望这在javascript中是可能的。
我正在尝试将十进制数截断到小数位。像这样:
5.467 -> 5.46
985.943 -> 985.94
toFixed(2)
做了正确的事情,但它会四舍五入价值。我不需要四舍五入的值。希望这在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正确地指出,使用此解决方案将错误地产生。有关发生这种情况的原因的更多信息,请阅读每个计算机科学家应该了解的浮点算术。不幸的是,编写一个消除所有浮点错误源的解决方案对于javascript来说非常棘手。在另一种语言中,你会使用整数或十进制类型,但是使用javascript...a = 17.56
17.55
此解决方案应该是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);
}