在javascript中,简单的数学运算是,在循环中添加X次数字,得到的结果与之前乘以X然后再添加不同
作为参考,此代码对应。在javascript中,简单的数学运算是,在循环中添加X次数字,得到的结果与之前乘以X然后再添加不同,javascript,math,Javascript,Math,作为参考,此代码对应。 这是一个简单的购物车/结帐程序,它注册一个项目并将其成本添加到总成本中,它还接受一个项目数量值 注意:我以前读过关于javascript在数学方面的怪异之处的文章,所以我没有感到震惊,但我非常好奇并有兴趣了解在这种特殊情况下的行为,所以也许我会获得一些见解,以便在将来能够防止这种情况发生 所以,我有两个解决方案,第一个是OK-ish,第二个没有问题,我想。这是: 1第一个 独立于第一种方法效率低下的事实(多次检查所有可能的情况并反复添加项目成本)。引起我注意的是返回的额外
这是一个简单的购物车/结帐程序,它注册一个项目并将其成本添加到总成本中,它还接受一个项目数量值 注意:我以前读过关于javascript在数学方面的怪异之处的文章,所以我没有感到震惊,但我非常好奇并有兴趣了解在这种特殊情况下的行为,所以也许我会获得一些见解,以便在将来能够防止这种情况发生 所以,我有两个解决方案,第一个是OK-ish,第二个没有问题,我想。这是: 1第一个
独立于第一种方法效率低下的事实(多次检查所有可能的情况并反复添加项目成本)。引起我注意的是返回的额外十进制值
var cashRegister = {
total:0,
add: function(itemCost){
this.total += itemCost;
},
scan: function(item,quantity) {
for (var i = 1 ; i <= quantity ; i++ ){
switch (item) {
case "eggs": this.add(0.98); break;
case "milk": this.add(1.23); break;
case "magazine": this.add(4.99); break;
case "chocolate": this.add(0.45); break;
}
}
}
};
// scan each item 4 times
cashRegister.scan("eggs",4);
console.log('Your bill is '+ cashRegister.total);
cashRegister.scan("milk",4);
console.log('Your bill is '+ cashRegister.total);
cashRegister.scan("magazine",4);
console.log('Your bill is '+ cashRegister.total);
cashRegister.scan("chocolate",4);
console.log('Your bill is '+ cashRegister.total);
第二个此解决方案将项目数量乘以任何碰巧发生的数量
var cashRegister = {
total:0,
add: function(itemCost){
this.total += itemCost;
},
scan: function(item,quantity) {
switch (item) {
case "eggs": this.add(0.98*quantity); break;
case "milk": this.add(1.23*quantity); break;
case "magazine": this.add(4.99*quantity); break;
case "chocolate": this.add(0.45*quantity); break;
}
}
};
// scan each item 4 times
cashRegister.scan("eggs",4);
console.log('Your bill is '+cashRegister.total);
cashRegister.scan("milk",4);
console.log('Your bill is '+cashRegister.total);
cashRegister.scan("magazine",4);
console.log('Your bill is '+cashRegister.total);
cashRegister.scan("chocolate",4);
console.log('Your bill is '+cashRegister.total);
控制台输出是干净的:
Your bill is 3.92
Your bill is 8.84
Your bill is 28.8
Your bill is 30.6
Your bill is 30.6
那么,第一个解决方案是怎么回事,这样就可以返回小数点排版了?事先非常感谢 编辑: 谢谢你试图帮助我解决我的疑问。虽然我意识到我需要清楚地表明我知道“JavaScript使用浮点值作为其数字类型,而精度的损失是造成这种情况的原因” 真正的问题是:
为什么相同的计算在第一个解决方案上会丢失精度,而在第二个解决方案上不会丢失精度?JavaScript使用浮点值作为其
数字类型,精度丢失是导致这种情况的原因。精度损失的原因是,浮点数使用二进制编码格式(很可能),并且它不能精确地表示大多数数字。例如,0.1
不能在IEEE 754中表示:
- 十进制:
0.1
- 二进制表示:
0011110111001
- 十六进制报告。:
0x3DCCCD
- 实际值:
0.1000000149011612
我已经使用了这些结果
所以直接回答你的问题:对浮点数进行更多的运算(多次加法,而不是乘法)会导致错误的积累
一个例子
我最喜欢的精度损失示例之一是以下代码:
var a = 0, b = 0;
for (var i = 1; i < 100; i++) {
a += Math.pow(10, -9*i);
}
for (var j = 100; j < 1; j--) {
b += Math.pow(10, -9*i);
}
alert(a == b);
这将产生“5.57”
ECMAScript标准
根据ECMAScript标准(ECMA-262,版本5.1),数值的定义如下:
与双精度64位二进制格式IEEE 754值相对应的原语值
这就是标准投诉实施为您提供的内容。其他任何可能在后台的内容都是实现细节。这是由于浮点数固有的不精确性造成的。并非所有有理数都可以用二进制浮点表示为精确值,因此您看到的是这种近似的结果。对如何进行这种转换有很好的解释
如果确实需要精确的值,可以使用或其他类似的库 首先,你为什么要用第一种方法呢?第二,如果你把鸡蛋的价格改为0.01
,第二种方法给出的最终总价格是26.720000000000002
。第三,可能对你有帮助……想不想用第一种方式去做,这是无关紧要的。但是谢谢你链接到另一个问题,“不是所有的有理数都可以用浮点表示为精确值”——问题是JS使用二进制浮点。(问题中的所有数字都可以用十进制浮点数精确表示。)我编辑我的问题是为了更好地表达我的问题,谢谢你,兰斯顿我编辑我的问题是为了更好地表达我的问题,谢谢你,梅斯科巴拉兹你添加的示例非常有趣,谢谢你,看来你真的探讨过这个问题,所以我投了赞成票,但它并没有完全回答我的问题,我还不能接受yikes,因为代表率低,所以不能投票,对不起,非常感谢meskobalazs,你的回答对任何在这个问题上发言的人都非常有帮助,这足以接受你的回答,我请我的一个朋友投票支持你。另外,我还猜测javascript虚拟机在加法时的工作方式与乘法时的工作方式非常不同,您对此有进一步的详细信息吗?首先,javascript不是在虚拟机上运行的,而是由javascript引擎运行的。我更新了我的答案,希望它有用。对不起,我是说V8,我用的是chrome。谢谢你提供更多的细节。我可以从这里开始。
var a = 0, b = 0;
for (var i = 1; i < 100; i++) {
a += Math.pow(10, -9*i);
}
for (var j = 100; j < 1; j--) {
b += Math.pow(10, -9*i);
}
alert(a == b);
var num = 5.56789;
var n = num.toFixed(2);