繁体   English   中英

除法结果不正确

[英]Incorrect division results

我有一个时间计算器,多年来工作得相当好。 但是,总是困扰我的一件事是,如果使用小数秒,结果将成为浮点“错误”的牺牲品。 所以,我最近改用了这个BigDecimal库

现在,我收到了数学错误。 这是我今天收到的错误报告的简化测试用例: 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()方法不会产生我期望的结果。 我需要做些什么不同的事情?

更新

以下是一些更多细节,以回应评论。

首先,有几个人建议使用BigDecimal是过度的。 这可能是,但我认为在做出决定之前需要更多细节。 这个应用程序是一个时间计算器 ,所以有一些事情促使我切换到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

还有控制不同输出模式PLAINSCIENTIFICENGINEERING +各种舍入模式的选项。

关于jsfiddle的完整示例

更新:默认输出格式为SCIENTIFIC ,而不是PLAIN 这里的例子

更新2: 在这里创建了一个微小的性能测试,看起来BigDecimal比原生的javascript分区慢大约10000倍。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM