除法结果不正确

2024-02-25

我有一个时间计算器,多年来一直运行良好。然而,一直困扰我的一件事是,如果使用小数秒,结果将成为浮点“错误”的牺牲品。所以,我最近改用这个 BigDecimal 库 https://github.com/dtrebbien/BigDecimal.js.

现在,我遇到了数学错误。这是我今天收到的错误报告中的一个简化测试用例:27436 / 30418正在返回1而不是预期的0.9019659412190151.

为了说明我的问题,下面是 Chrome 中的 Javascript 控制台会话:

> first = 27436
27436
> second = 30418
30418
> first / second
0.9019659412190151   // expected result, but using JS numbers, not BigDecimals
> firstB = new BigDecimal(first.toString())
o
> secondB = new BigDecimal(second.toString())
o
> firstB / secondB
0.9019659412190151 // this is a JS number, not a BigDecimal, so it's susceptible to the problems associated with floating-point.
> firstB.divide(secondB)
o  // BigDecimal object
> firstB.divide(secondB).toString()
"1"  // huh? Why 1?
> firstB.divideInteger(secondB).toString()
"0"

如您所见,divide()方法没有产生我期望的结果。我需要做哪些不同的事情?

Update

以下是针对评论的更多详细信息。

首先,一些人认为使用 BigDecimal 太过分了。可能是这样,但我认为在做出决定之前需要更多细节。这个应用程序是一个时间计算器 http://www.scottseverance.us/html/time_calculator.htm,所以有几件事促使我切换到 BigDecimal。首先,因为这是一个计算器,所以向用户显示正确的答案很重要。如果用户输入0.1 s + 0.2 s,他们期望答案是0.3 s,而不是 Javascript 将向他们显示的答案(0.30000000000000004).

我真的不想将精度限制在 JS 中可以使用的范围之外,以便我可以使用整数,因为我不知道用户需要的最大精度。我认为大多数人从不使用小数秒,但从我收到的电子邮件来看,有些人会这样做。我目前在内部将所有时间存储为秒。

有人建议我将数字存储为精确分数。不幸的是,我不知道这意味着什么。也许是因为我对数学了解不多。我的知识还不足以建立我自己的数学库;这就是我使用 BigDecimal 的原因。它已经存在很长时间了,所以我很犹豫是否说我的问题是由于 BigDecimal 中的错误造成的。我怀疑这是我使用它的方式中的一个错误。

最后,我并不是特别热衷于 BigDecimal。我愿意接受其他建议,只要我可以用我缺乏的数学技能来使用它们。


我还没有在任何生产代码中使用 BigDecimal,但发现这个问题很有趣,所以我尝试一下。你对需要一个是正确的MathContext作为除法函数的参数。根据您的示例,这是我所做的:

console.log(firstB.divide(secondB, new MathContext(100)).toString());

创建一个上下文,告诉 BigDecimal 在科学模式输出中使用 100 位数字:

0.9019659412190150568742192123085015451377473864159379314879347754618975606548754027220724570977710566

还有控制不同输出模式的选项PLAIN, SCIENTIFIC and ENGINEERING+ 各种舍入模式。

完整示例jsfiddle http://jsfiddle.net/cvTr8/

Update:默认输出格式为SCIENTIFIC, not PLAIN。例子here http://jsfiddle.net/cvTr8/1/

更新2:创建了一个小型性能测试here http://jsperf.com/bigdecimal-vs-number,看起来 BigDecimal 比原生 javascript 除法慢大约 10000 倍。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

除法结果不正确 的相关文章

随机推荐

  • 如何使用 animate 方法进行连续循环?

    如何使用一个连续循环动画animate 在这个例子中 我想做的就是无休止地旋转一个白色方块 myBall new Layer x 100 y 100 width 200 height 200 borderRadius 20px backgr
  • Excel VBA:获取单击按钮的行[重复]

    这个问题在这里已经有答案了 我正在尝试在 Excel 中创建一个按钮 将特定范围的单元格从活动工作簿复制到另一个工作簿 当我指定固定范围时 该范围的复制工作得很好 但我对如何找出单击的按钮的行感到困惑 每行包含 7 个左右的单元格 第 8
  • 无法获取总金额

    大家好 我已经解决了最初的问题 但现在它无法正确添加 我不确定该怎么做以及我哪里出了问题 任何帮助 将不胜感激 导入java util Scanner 公开课动物园 公共静态无效主 字符串 args int quantity confirm
  • 微调器的文本大小

    如何减小微调器的字体大小 我已将微调器大小减小到 35 像素 因此我的文本被切成两半 我怎么做 我也不希望事先选择任何东西 默认文本应该是 select some value 经过一些测试 有一个比继承 ArrayAdapter 更简单的方
  • 如何在自定义控件中包含光标(插入符号)?

    我被指派用 C 和 Windows 窗体制作自定义网格控件 我不确定的一件事是如何处理显示闪烁的光标 插入符号 以指示单元格编辑正在进行的位置以及将显示下一个字符 有谁知道这是如何使用标准文本框完成的 是否有一个标准框架结构可以为我做到这一
  • 列表理解中的 if/else

    我有一个清单xs包含字符串的混合物和None价值观 如何使用列表理解在每个字符串上调用函数 但将None价值观 而不是将它们传递给函数 I tried f x for x in xs if x is not None else 但它给出了S
  • 阿拉伯标签在 Geoserver 中无法正确显示

    我已随 Tomcat 安装了 geoserver 但文本标签无法正确显示 我在哪里可以设置geosever中的阿拉伯编码 标签在 QGIS 中显示得很好 但是当我将其发布到 geoserver 中时 我遇到了这个问题 1 https i s
  • 在 Bash 中比较两个字符串时出现“找不到命令”错误

    我的整个脚本目前是这样的 bin sh clear blanko Dummy Variablen variable Testvariable if variable blanko then echo Nichts da else echo
  • React setState 不更新状态

    所以我有这个 let total newDealersDeckTotal reduce function a b return a b 0 console log total tittal outputs correct total set
  • 如何增加 Google Cloud Run 中的内存限制?

    我正在使用 Cloud Run Cloud Firestore 构建一个简单的基于 Flask 的应用程序 有一种方法会带来大量数据 并且日志显示此错误 Memory limit of 244M exceeded with 248M use
  • 为什么 Python 装饰器不能跨定义链接?

    为什么以下两个脚本不等效 摘自另一个问题 了解 Python 装饰器 https stackoverflow com questions 739654 understanding python decorators def makebold
  • 在Webpack中构建dist文件夹后,如何将bundle.js和css文件移动到statics文件夹中?

    当我运行我的npm run build or npm run build dev 它在根目录中创建index html manage2 bundle js 和manage2 css 文件 我需要将这些文件移动到静态目录中 因此 下面生成的i
  • 有没有一种简单的方法可以在 Google 云中的项目之间克隆 SQL 实例?

    我想知道是否存在一种简单的方法可以在 Google Cloud 中的项目之间克隆 sql 实例 我知道我可以将数据导出到存储桶 请参阅img 1 但我发现这有点麻烦 如果有人有一个简单的方法来做到这一点 我们将不胜感激 没有 快速 方法可以
  • Pandas:合并数据框而不创建新列

    我有 2 个具有相同列的数据框 df1 pd DataFrame Abe 1 True Ben 2 True Charlie 3 True columns Name Number Other df2 pd DataFrame Derek 4
  • 使用 Python 加载 SQL_VARIANT 数据类型时出错

    我正在使用 Python 2 7 和 SQLAlchemy 0 7 8 来查询我没有创建的数据库 我在查询包含以下内容的表时遇到问题SQL VARIANT数据类型 我收到错误 sqlalchemy exc DBAPIError 错误 ODB
  • Flutter如何检测设备语言?

    我有一个问题 如何检测设备语言 并据此在应用程序最初启动时给出正确的语言 如果可能 请提供带有代码的示例 Calling Localizations localeOf context languageCode应该返回你的语言代码 如果未提供
  • 如果用户在浏览器中禁用了 JavaScript,如何使用不同的 CSS 样式表?

    我正在为某人开发一个网站 我使用的 CSS 样式需要 JavaScript 用于小屏幕上下拉导航栏的按钮 如果用户启用了 JavaScript 我如何使用一种样式表 如果用户禁用 JavaScript 我如何使用另一种样式表 有两种方法可以
  • 如何以良好的方式使用 SQL NULL 值和 JSON?

    Go 类型如Int64 and String不能存储空值 所以我发现我可以使用sql NullInt64 https golang org pkg database sql NullInt64 and sql NullString http
  • 在发布模式下未针对异步方法调用 IDisposable.Dispose()

    我在 VS2015 1 上使用 NET 4 6 1 在 VB NET 14 中编写了以下 WPF 示例应用程序 Class MainWindow Public Sub New InitializeComponent End Sub Priv
  • 除法结果不正确

    我有一个时间计算器 多年来一直运行良好 然而 一直困扰我的一件事是 如果使用小数秒 结果将成为浮点 错误 的牺牲品 所以 我最近改用这个 BigDecimal 库 https github com dtrebbien BigDecimal