在JavaScript中使用带小数点的浮点数的最佳方法是什么?

时间:2014-07-11 23:16:45

标签: javascript floating-point decimal

我做了一个调查,我看到有一个完整的网站向您解释使用浮动的正确方法是什么:http://floating-point-gui.de/

在Java中,我总是使用BigDecimal作为浮点数,以确保一切都能正常工作而不会让我感到困惑。例如:

BigDecimal a = new BigDecimal("0.1");
BigDecimal b = new BigDecimal("0.2");
BigDecimal c = a.add(b); // returns a BigDecimal representing exactly 0.3
                         // instead of this number: 0.30000000000000004 that can 
                         // easily confuse me

然而在JavaScript中我意识到没有内置库(至少在我看过的Math对象中)

所以我到目前为止找到的最好的方法是使用它正在做的JavaScript库!在我的项目中,我正在使用这个:https://github.com/dtrebbien/BigDecimal.js

虽然我认为这是我能找到的最好的图书馆,但图书馆并不是那么重要。我的主要问题是:

  1. 使用像BigDecimal这样的库最好的方法来使用JavaScript的浮点数是最好的方法吗?还是我错过了什么?我想做基本的计算,如添加,乘法...... e.t.c。
  2. 有没有其他建议的方法,例如在JavaScript中添加两个浮点数?
  3. 例如,假设我想拥有:0.1 + 0.2。使用BigDecimal库,我将:

    var a = new BigDecimal("0.1");
    var b = new BigDecimal("0.2");
    
    console.log(a.add(b).toString()); //returns exactly 0.3
    

    那么有没有其他方法可以在JavaScript中添加0.1 + 0.2并且精确到0.3,而无需实际舍入数字? 作为参考,JavaScript中的以下示例将不起作用:

    var a = 0.1;
    var b = 0.2;
    console.log(a + b); //This will have as an output: 0.30000000000000004
    

5 个答案:

答案 0 :(得分:3)

由于javascript中的所有数字都是64位,一般来说,在javascript中进行浮点数aritmetic的最佳方法是直接使用数字。

但是,如果您特别遇到需要比64位更高精度的问题,那么您需要做类似的事情。

但是,我强烈建议您强烈考虑是否有这样的用例。

如果您的问题是一些影响您的比较的小数字,那么有一些功能可以专门处理这类事情。我建议您查看Number.prototype.toFixed(n)函数,并查看this dicussion on almostEquals,它建议您使用epsilon进行浮点比较。

答案 1 :(得分:1)

如果您不依赖于高精度,可以使用toFixed(n)方法:

var a = 0.1;
var b = 0.2;
var sum = a + b;
console.log(sum.toFixed(1)); 

您的计算显示第17个浮点的精度损失,在大多数情况下这不是一个大问题 如果你想让输出正确,我会建议你去toFixed()。

答案 2 :(得分:0)

这里有几点需要考虑。

很多时候人们使用“浮动”这个词时,他们真正意味着使用固定小数

固定十进制

例如,美国货币是一个固定的小数。

$12.40
$0.90

在这种情况下,总是是两个小数点。

如果您的值符合JavaScript整数(2^53-1)9007199254740991的范围,那么您可以简单地使用美分并以此方式存储所有值。

1240
90

浮点小数

现在,浮点是处理极端数字范围并且小数点实际移动或浮动的地方。

12.394
1294856.9458566
.0000000998984
49586747435893

在浮点的情况下,精确到53个重要(这意味着大约15位精度)。对于很多事情来说,足够好。

大十进制课程

如果您需要超出JavaScript本机编号范围的内容,则应该只查看大十进制类。 BigDecimal类比本机数学慢得多,你必须使用函数式编程而不是使用数学运算符。

答案 3 :(得分:0)

JavaScript不支持运算符重载,因此没有内置的方法可以使用BigNumbers进行自然计算,例如“0.1 + 0.2”。

你可以做的是使用math.js,它有一个表达式解析器支持BigNumbers:

math.config({
  number: 'bignumber',  // Default type of number: 'number' or 'bignumber'
  precision: 64         // Number of significant digits for BigNumbers
});

math.eval('0.1 + 0.2'); // returns a BigNumber, 0.3

请参阅文档:http://mathjs.org/docs/datatypes/bignumbers.html

答案 4 :(得分:0)

您可以事先将操作数转换为整数

(0.1 * 10 + 0.2 * 10)/ 10

会给出确切的答案,但是人们可能不想处理那些浮点数的东西