我遇到了一个奇怪的问题,我想做一些基本的数学检查。我读到应该避免使用浮点数,所以我决定用10000乘以我的数值,因为我的值可能介于0.9和0.0025之间。
除了0.56和0.57这两个值外,一切正常:
var result = 0.57 * 10000
结果是:5699.999999999999,我希望得到5700!但0.56也出现错误,其他值都正确,我错在哪里了?
我遇到了一个奇怪的问题,我想做一些基本的数学检查。我读到应该避免使用浮点数,所以我决定用10000乘以我的数值,因为我的值可能介于0.9和0.0025之间。
除了0.56和0.57这两个值外,一切正常:
var result = 0.57 * 10000
结果是:5699.999999999999,我希望得到5700!但0.56也出现错误,其他值都正确,我错在哪里了?
最佳解决方案是使用toFixed(x)方法,并将x设置为应始终大于预期结果小数位数的数字(我通常在那里输入8)。
但是,您不应像kirilloid一样使用黑客方式,而是将结果再次转换为数字,以删除任何不需要的小数。之后,对该数字执行所需的任何格式设置。
因此,这将返回所需的结果:
var result = +(0.57 * 10000).toFixed(8)
现在的结果将是5700
加号(+)前面的操作将 "toFixed" 返回的字符串结果转换为数字。
希望这有所帮助!
编辑 2019:
根据这篇文章,似乎我们不能信任 "toFixed" 的结果:https://dev59.com/wXRB5IYBdhLWcg3wUVtd#661757 最好使用以下代码:
function fixRounding(value, precision) {
var power = Math.pow(10, precision || 0);
return Math.round(value * power) / power;
}
var multiply = function(a, b) {
var commonMultiplier = 1000000;
a *= commonMultiplier;
b *= commonMultiplier;
return (a * b) / (commonMultiplier * commonMultiplier);
};
这个操作只适用于已知范围内的数字。因此,将数字四舍五入到小于commonMultiplier
的小数点可能是一个不错的主意。
> multiply(3, .1)
< 0.3
> multiply(5, .03)
< 0.15
var result = 0.57 * 10000;
alert (Math.round(result));
Math.round(0.57 * 10)
将返回 6
而不是 5.7
,更好的方法是使用 @George Mavritsakis 的答案 Math.round(value * power) / power
。 - gluttony在 Javascript 中(实际上,在大多数编程语言中),您可以选择整数或浮点数。如果您写入“0.57”,则会将其强制转换为浮点数,其中精度是受限的。
如果您需要绝对精度,则必须专门使用整数。
value.toFixed(4).substr(-4).replace(/^0+/, "");
这里有一个解决方案,可能有点复杂,但可以在不进行四舍五入的情况下获得最终结果,然后只需使用correctMultiply(a,b)函数即可。
function moveDecimalPointRight(value,power){
const s = value.toString();
const a = s.split('.');
if(a.length>1){
return Number(a[0]+a[1].substr(0,power)+'.'+a[1].substr(power));
}else{
return value;
}
}
function moveDecimalPointLeft(value,power){
const s = value.toString();
const a = s.split('.');
const _al = a[0].length;
while(a[0].length<power+_al){
a[0] = '0'+a[0];
}
if(a.length>1){
return Number(
a[0].substr(0,a[0].length-power)
+'.'+a[0].substr(-power)
+a[1]);
}else{
return Number(
a[0].substr(0,a[0].length-power)
+'.'+a[0].substr(-power));
}
}
function afterDecimal(num) {
if (Number.isInteger(num)) {
return 0;
}
return Number(num).toString().split('.')[1].length;
}
function correctMultiply(a,b) {
const _ad = afterDecimal(a);
const _bd = afterDecimal(b);
const _a = moveDecimalPointRight(a,_ad);
const _b = moveDecimalPointRight(b,_bd);
const _r = _a * _b;
return moveDecimalPointLeft(_r,_ad+_bd);
}
console.log(correctMultiply(0.57,10000));
console.log(correctMultiply(0.57,0.57));