2015-05-23 36 views
0

我想乘以10K以上的概率估計值(0到1之間的值)。 我正在使用Ruby。我用BigDecimal來存儲小數字,例如:在Ruby中處理非常小的數字

prod = BigDecimal.new("1") 
prod = prod * BigDecimal.new("#{ngramlm[key]}") 

但是經過幾次迭代後prod就變成了零。你能幫助我如何將最終產品存儲在prod中(這將是一個非常小的數字接近零)!

+0

計算機科學:) 爲什麼你不擴大它們?乘以1000或更大,程序將處理更大的數字。 – zmii

+0

你能舉個例子嗎? BigDecimal似乎對我來說工作正常(10K +乘法)。 – matt

+0

你確定沒有你的值是零嗎? – matt

回答

2

您所描述的內容聽起來像是使用日誌概率的典型案例(http://en.wikipedia.org/wiki/Log_probability)。使用log(y)=log(x1)+log(x2)而不是y=x1*x2(將您的乘法轉換爲對數概率的加法)將會提高速度和數值穩定性。

+0

好主意。迷人! – zmii

0

您可以使用本地Ruby Rational類。 As a rational number can be represented as a paired integer number; a/b (b>0).

例如

Rational(0.3) #=> (5404319552844595/18014398509481984) 
Rational('0.3') #=> (3/10) 
Rational('2/3') #=> (2/3) 

0.3.to_r   #=> (5404319552844595/18014398509481984) 
'0.3'.to_r  #=> (3/10) 
'2/3'.to_r  #=> (2/3) 
0.3.rationalize #=> (3/10) 

所以,您的號碼將被轉換爲有理數,你可能會得到更大的精度通過理性作爲理性會給你合理的。例如。

Rational(2, 3) * Rational(2, 3) #=> (4/9) 
Rational(900) * Rational(1)  #=> (900/1) 
Rational(-2, 9) * Rational(-9, 2) #=> (1/1) 
Rational(9, 8) * 4    #=> (9/2) 

所以你將基本上處理分子和分母中整數的乘法,這是精確的。

+1

Ruby對Rational有一個字面意思:'2/3r * 2/3r#=>(4/9)' – steenslag