在进行计算时可以信任javascript吗?

时间:2015-02-01 15:50:42

标签: javascript floating-point-precision

我正在实施发票系统,其中所有内容都通过javascript动态添加到dom上,我正在使用javascript对浏览器本身进行一些计算。 例如,我正在计算每个发票行的数量和单位价格并生成总和

价格可以是浮点数

但我不确定这是否应该被信任,如果有人对javascript有同样的苛求请注释:)

我不知道但是javascript在我看来并不像其他编程语言那样受到像PHP那样的信任,这是我的意见,但是如果你能说服我那么做

由于

4 个答案:

答案 0 :(得分:2)

Javascript使用几乎所有语言用于浮点计算的相同数据类型。双精度浮点数据类型非常常见,因为处理器内置了对它的支持。

浮点数的精度有限,大多数带小数部分的数字都无法准确表示。但是,对于您将要使用的内容,精度足以显示正确的结果。

你应该意识到精度有限。显示结果时,应确保将其格式化(并舍入)为要显示的精度。否则,有限精度可能会显示为14.9500000000000001而非14.95的价格。

答案 1 :(得分:1)

根据JavaScript's specifications,所有数字都是64位精度(如64位浮点精度)。

this post,你有3个解决方案:

  1. 使用Decimal for JavaScript的一些实现,如BigDecimal.js
  2. 只需选择要保留的固定位数,例如(Math.floor(y/x) * x).toFixed(2)
  3. 切换到纯整数,将价格视为分数。这可能会导致整个项目发生重大变化

答案 2 :(得分:1)

财务计算通常需要特定的固定规则(例如)何时以及如何舍入(在哪个方向上)等 这意味着您将经常保持内部小计精度,直到您转到计算的下一部分(例如根据规则集添加税)。

IEEE-754浮点(在javascript中使用)将为您提供2^53的最大准确度(如果您将其视为整数)。
现在,您的“工作”是假装javascript不支持浮点并使用最简单的方法自行替换:减小最大整数范围以获得所需的浮点精度,并查看结果范围是否适合您的需要。如果没有,那么您可能需要一个外部高精度数学库(尽管大多数基本操作都很容易实现)。

首先确定所需的内部精度(包括预期的舍入行为的溢出数字):例如3位数:
FLOOR((2^53)/(10^3)) = FLOOR(9.007.199.254.740.992/1000) = 9.007.199.254.740,000
如果这个范围足够,那么您不需要其他库,只需将您的输入10^float_digits相乘并保持每个计算部分的内部精度,同时根据计算所需的规则对每个步骤进行舍入(您仍然需要在使用高精度外部数学库时这样做。

对于(视觉)输出,再次应用适当的舍入,然后将剩余值除以10^(floatDigits-roundingDigit(s))并将其传递给Number.prototype.toFixed()(然后在需要时将其填充为零)。



至于你关于javascript与其他编程语言的可信度的另一个问题:甚至可以在浏览器内的javascript上启动/运行使用 LINUX:http://bellard.org/jslinux/
让它沉入片刻...
现在如果我告诉你这甚至可以在IE6中运行...非常谦卑。甚至服务器也可以在javascript(node.js)上运行..

希望这有帮助(它不适合评论)。

答案 3 :(得分:0)

其他答案解决了JavaScript使用浮点数代表金钱的问题。

使用JavaScript进行涉及金融交易的计算存在一个单独的问题。 因为代码是在客户端计算机上的浏览器中执行的,所以您只能信任结果,以便您可以信任客户端。

因此,如果客户告诉您,您应该只依靠JavaScript来计算您可以理所当然的事情。 例如,如果您正在编写电子商务网站,您可以信任代码,告诉您客户想要购买的内容,以及客户的送货地址是什么,但您需要自己计算商品的价格以防止客户告诉你更低的价格。

您正在处理的发票系统完全有可能仅在您的组织内部使用。 如果是这种情况,您可以忽略整个答案。 但是,如果您的应用程序将被客户用来访问和操作他们的发票和订单,那么这是您必须考虑的事情。