Javascript浮点加法解决方法

标签 javascript floating-point

好了, float 问题我们都知道了,比如:

0.23 - 1 + 1 = 0.22999999999999998

由于在 javascript 中,与其他语言不同,所有数字实际上都是 float ,并且没有 int/decimal,因此有各种库和解决方法(例如 BigDecimal)来处理此问题。这是最好讨论的here .

我正在创建一个支持 float 的“数字微调器”控件,显然我不希望用户单击“向上”然后“向下”并获得与开始时不同的数字,所以我尝试编写一种解决方法 - 某种“addPrecise”方法。

我的想法如下:

  1. 取出我要相加的两个数字,并算出它们的“精度” - 小数点后有多少位数字。
  2. 将两个数字作为 float 相加
  3. 申请toFixed()两者中精度最高的结果

例如:

float #1: 1.23
float #2: -1

通常添加它们会导致 0.22999999999999998但如果我采用最大小数位数,即 #1 的 2 位数字,并应用 toFixed(2)我得到0.23如我所愿。

我已经使用以下代码完成了此操作,但我对此不满意。

function addPrecise(f1, f2){
    var floatRegex = /[^\d\-]/;
    var f1p =  floatRegex.exec(f1.toString()) ? f1.toString().split(floatRegex.exec(f1.toString()))[1].length : 0;
    var f2p =  floatRegex.exec(f2.toString()) ? f2.toString().split(floatRegex.exec(f2.toString()))[1].length : 0;
    var precision = Math.max(f1p,f2p);
    return parseFloat((parseFloat(f1) + parseFloat(f2)).toFixed(precision));
}

(值得注意的是,我使用正则表达式来查找“浮点”,因为在其他语言环境中它可能是逗号而不是句点。我还考虑到我得到 Int (没有意义)在这种情况下它的精度是 0。)

有没有更干净/更简单/更好的方法来做到这一点?

编辑:我还想指出,找到一种可靠的方法来提取小数位数也是问题的一部分。我不确定我的方法。

最佳答案

此问题的适当解决方案是:

  1. 确定小数点后需要多少位数字,例如 d
  2. 读取用户的输入并将其转换为按 10d 缩放的整数。
  3. 使用整数进行所有算术运算。
  4. 向用户显示值时,将其除以 10d 进行显示。

更多详细信息:

  1. 如果所有工作都是以用户输入的数据为单位,则小数点后所需的位数 d 与用户接受的位数相同。 (例如,如果要使用步长的分数进行一些算术运算,则可能需要更多的数字。)
  2. 当用户输入时,应将其转换为缩放后的整数。请注意,用户输入的是字符串(不是 float ;用户键入时只是字符串),并且该字符串应该是数字(表示数字的字符)。处理此输入的一种方法是调用库例程将此数字转换为 float ,然后乘以 10d,然后将浮点结果四舍五入为最接近的整数(以补偿浮点舍入误差)。对于合理大小的数字,这总是会产生完全期望的结果;浮点舍入误差不会成为问题。 (应拒绝过大的用户输入。)处理此输入的另一种方法是编写自己的代码,将数字直接转换为缩放整数,完全避免 float 。
  3. 只要仅使用加法、乘法和减法(例如,将步长乘以步数并与先前值相加),并且不超出整数范围,则所有算术都是准确的;没有舍入错误。如果使用除法,则必须重新考虑这种方法。
  4. 与读取输入一样,显示输出可以在浮点和库例程的帮助下执行,也可以通过编写自己的代码直接转换来执行。要使用浮点,请将整数转换为浮点,除以 10d,然后使用库例程对其进行格式化,不超过 d 位。 (在库例程中使用默认格式转换可能会导致显示超过 d 位数字。如果仅显示 d 位数字,并且 d 是合理的小数,则格式化过程中发生的浮点舍入错误将不可见。)

只要注意确保算术在合理范围内完全使用整数(或能够以浮点格式精确表示的其他值),就可以仅使用浮点来实现上述所有内容.

关于Javascript浮点加法解决方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18227244/

相关文章:

javascript - 在 JavaScript 中,是否有一种将数字转换为字符串的解析 JSON 的方法?

math - float 学坏了吗?

c - float 组到字节转换为 null

javascript - 如何在 Angularjs 中的 div 内左右滚动

javascript - 使用 jQuery 将文本和元素包裹在另一个元素中

javascript - 如何在 express + passport js 中删除注销时的 cookie?

floating-point - 为什么是float "single precision"?

c#-4.0 - 如何在 C# 中将 SQLiteDataReader 值转换为 float

javascript - 如何将对象的链接传输给匿名函数?

包含括号的 JavaScript 正则表达式模式