Javascript toFixed方法未按中的预期工作
在处理大量数据时,我发现了一些奇怪的问题Javascript toFixed方法未按中的预期工作,javascript,angularjs,Javascript,Angularjs,在处理大量数据时,我发现了一些奇怪的问题 (99999999999999.9).toFixed(2) returns "99999999999999.91" 何处为 (99999999999999.8).toFixed(2) returns "99999999999999.80" 我需要的是 (99999999999999.9).toFixed(2) should return "99999999999999.90" 如何解决此问
(99999999999999.9).toFixed(2) returns "99999999999999.91"
何处为
(99999999999999.8).toFixed(2) returns "99999999999999.80"
我需要的是
(99999999999999.9).toFixed(2) should return "99999999999999.90"
如何解决此问题?您肯定遇到了浮点精度错误。 如果您的特定用例不需要特别敏感,您可以使用
(Math.round(yourValue*100)/100).toFixed(2)
还有一种更新的处理方法,使用
特别是玩分数
minimumFractionDigits: 2,
maximumFractionDigits: 2
当然,若你们需要一些更健壮的,能够很好地处理其他边缘情况的,也可以提供帮助
var a = new Decimal(99999999999999.9);
console.log(a.toFixed(2))
在这里,您肯定遇到了浮点精度错误。 如果您的特定用例不需要特别敏感,您可以使用
(Math.round(yourValue*100)/100).toFixed(2)
还有一种更新的处理方法,使用
特别是玩分数
minimumFractionDigits: 2,
maximumFractionDigits: 2
当然,若你们需要一些更健壮的,能够很好地处理其他边缘情况的,也可以提供帮助
var a = new Decimal(99999999999999.9);
console.log(a.toFixed(2))
您基本上无法做到这一点,这是由于数字在浮点中的表示以及javascript在后台的工作方式: Javascript用于表示内存中的符号9999999999显示为
0 10000101101 0110101111001100010000011110100011111111111111111010
这是一个由3个整数部分组成的数字:
首先,符号0表示它是正的
然后是指数乘数-1069。我们从中减去1023以允许负指数,因此乘数为'2^1069-1023
然后是尾数-data-1.421085471520199wikipedia上显示的计算没有mathjax,这有点难以显示
因此,根据wolfram alpha 9999999999999.903472220635136,总值为+1.421085471520199*2^1069-1023=
正如你所看到的,它不能精确地显示十进制精度。这是由于尾数有限,我们可以看到,如果我们更改尾数的最后一位,则高出1会得到9.999999999245828438884352×10^13。下面的一个是9.99999999998893984717996032×10^13
因此,9.99999999998893984717996032×10^13和9.999999999999993472220635136×10^13之间的所有内容都表示为相同的数字-您不会注意到其中的差异。[*]
至于为什么在本例中再次显示浮点时会向上取整:这有点难以解释,但我想这是由于实现的原因
现在我们能预测这个吗?为什么它不是十进制的呢?这很容易解释。一个数字系统有不同的基数,通常我们使用基数10,而计算机使用基数2作为内在单位
这个选择有着牵强的后果:当在某个基数中工作时,你只能表示该基数的基本因子的倍数的分数。IE基数10有基本因子2和5。所以我们可以显示任何分数,它是这些分数的倍数:
1/2 => 0.5
1/5 => 0.2
2/5 => 0.4
1/10 = 1/2*1/5 => 0.1
然而,1/3不能被描述为这两个分数的倍数,也不能被描述为1/7或1/6——因此在10进制中,我们不能准确地将它们写成小数
类似地,基2只有素数因子2。以“.9”结尾的数字在十进制中始终是基于1/5的分数,它不是二进制的一部分-因此不能用二进制描述
现在有了解决方案,通常存在提供所谓的十进制软件包的库,这些软件包以十进制表示数字,并用手动计算取代内部计算机FPU
[*]:ps我不知道它是否真的是这些边界-因此浮点解释器是否总是向上取整,或者解释器是否向最近的浮点取整。了解JS解释器的人可以回答这个问题。你基本上无法做到这一点,这是因为数字在浮点中的表示以及javascript在后台的工作方式: Javascript用于表示内存中的符号9999999999显示为
0 10000101101 0110101111001100010000011110100011111111111111111010
这是一个由3个整数部分组成的数字:
首先,符号0表示它是正的
然后是指数乘数-1069。我们从中减去1023以允许负指数,因此乘数为'2^1069-1023
然后是尾数-data-1.421085471520199wikipedia上显示的计算没有mathjax,这有点难以显示
因此,根据wolfram alpha 9999999999999.903472220635136,总值为+1.421085471520199*2^1069-1023=
正如你所看到的,它不能精确地显示十进制精度。这是由于尾数有限,我们可以看到,如果我们更改尾数的最后一位,则高出1会得到9.999999999245828438884352×10^13。下面的一个是9.99999999998893984717996032×10^13
因此,9.99999999998893984717996032×10^13和9.999999999999993472220635136×10^13之间的所有内容都表示为相同的数字-您不会注意到其中的差异。[*]
至于为什么在本例中再次显示浮点时会向上取整:这有点难以解释,但我想这是由于实现的原因
现在可以
我们能预测吗?为什么它不是十进制的呢?这很容易解释。一个数字系统有不同的基数,通常我们使用基数10,而计算机使用基数2作为内在单位
这个选择有着牵强的后果:当在某个基数中工作时,你只能表示该基数的基本因子的倍数的分数。IE基数10有基本因子2和5。所以我们可以显示任何分数,它是这些分数的倍数:
1/2 => 0.5
1/5 => 0.2
2/5 => 0.4
1/10 = 1/2*1/5 => 0.1
然而,1/3不能被描述为这两个分数的倍数,也不能被描述为1/7或1/6——因此在10进制中,我们不能准确地将它们写成小数
类似地,基2只有素数因子2。以“.9”结尾的数字在十进制中始终是基于1/5的分数,它不是二进制的一部分-因此不能用二进制描述
现在有了解决方案,通常存在提供所谓的十进制软件包的库,这些软件包以十进制表示数字,并用手动计算取代内部计算机FPU
[*]:ps我不知道它是否真的是这些边界-因此浮点解释器是否总是向上取整,或者解释器是否向最近的浮点取整。有JS解释器知识的人可以回答这个问题。可能您遇到了浮点精度错误?是的,这是一个财务应用程序,即使是1个paise也会产生差异。如果您需要这种精度,我建议使用库。JS本身不合适请推荐一些库您在下面的答案中已经有了建议?可能您遇到了浮点精度错误?是的,这是一个财务应用程序,即使是1个paise也会产生差异如果您需要此精度级别,我建议使用库。JS本身不合适请建议一些库您在下面的答案中已经有了建议?Math.round99999999999.9*100/100.toFixed2返回99999999999999.91 Decimal.JS好吗?Math.round99999999999999999.9*100/100.toFixed2返回99999999999999.91 Decimal.JS好吗?