这种现象是怎样出现的? 在涉及金钱的计算时,这个问题很致命
IEEE 754. 楼主没用过其它开发语言么
原因我知道,只是在js下,9.9 * 100 的结果是990,大部分类似的计算结果都是对的,但是上面的几个是在js下是例外,关键是还不知道怎样处理,有多一点的,也有少了一点的,有统一的处理方式吗?
@dingyuanwu 所有语言都是一样的。要么就用处理浮点数的专用方法/包。 js 可以考虑这个 https://github.com/josdejong/mathjs 或者在数据库进行处理。
请你们再也不要攻击js计算不准确了,哎,又给你们普及知识了。惭愧!
js采用的是双精度浮点数,对于浮点数的计算,结果就是这样子呀
精度问题就从精度角度解决,比如你要求小数点后两位,每次计算完后将数据处理成小数点后两位就行
但是JS自己实际是做了一些处理的,上面给的例子就是 有的结果和预期的一致,有的不一致 没有办法,我们只能自己解决了 但是还是想知道这种部分对,部分错的现象是怎样产生的 在C、C++或者Java中,精度缺失是都会缺失,但是JS做了部分处理,导致了下面的情况:
众所周知,精度问题无论哪个语言都需要 Decimal 去处理的,float 精度有问题,Decimal 处理方式是按字符串处理,可以保证绝对的精度。
bignumber.js 使用这个库可以处理精度问题
@Sirormy Decimal 照样有 入参或者数据库取数 稍微有问题 就呵呵 银行利息啊
@dingyuanwu 测试一下toFixed
// toFixed兼容方法 Number.prototype.toFixed = function (n) { if (n > 20 || n < 0) { throw new RangeError(‘toFixed() digits argument must be between 0 and 20’); } const number = this; if (isNaN(number) || number >= Math.pow(10, 21)) { return number.toString(); } if (typeof (n) == ‘undefined’ || n == 0) { return (Math.round(number)).toString(); }
let result = number.toString();
const arr = result.split('.');
// 整数的情况
if (arr.length < 2) {
result += '.';
for (let i = 0; i < n; i += 1) {
result += '0';
}
return result;
}
const integer = arr[0];
const decimal = arr[1];
if (decimal.length == n) {
return result;
}
if (decimal.length < n) {
for (let i = 0; i < n - decimal.length; i += 1) {
result += '0';
}
return result;
}
result = integer + '.' + decimal.substr(0, n);
const last = decimal.substr(n, 1);
// 四舍五入,转换为整数再处理,避免浮点数精度的损失
if (parseInt(last, 10) >= 5) {
const x = Math.pow(10, n);
result = (Math.round((parseFloat(result) * x)) + 1) / x;
result = result.toFixed(n);
}
return result;
};
看来是得自己处理一下,不完后续可能会有问题
Number.prototype.toPrecision
@nwljy 银行别用 nodejs
@Sirormy 精度问题和 nodejs 有啥关系? 难道 js 没有处理 numberic 的库,或者不能在数据库计算结果? 难道 java 就没这问题?