簡體   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