drsbhattac
drsbhattac

Reputation: 119

Handling very small numbers in Ruby

I want to multiply more than 10K probability estimates (values between 0 and 1). I am using Ruby. And I used BigDecimal to store the small numbers like,

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

but after few iterations prod becomes zero. Could you please help me how to store the final product in prod(which would be a very small number near to zero)!!

Upvotes: 0

Views: 359

Answers (2)

zmii
zmii

Reputation: 4277

You may use native Ruby Rational class. As a rational number can be represented as a paired integer number; a/b (b>0).

e.g.

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)

So your numbers will be converted to rationals, you may get bigger precision as rational by rational will give you the rational. E.g.

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)

So you will basically deal with multiplication of integers in the numerator and denominator and this is precise.

Upvotes: 0

Andrzej Pronobis
Andrzej Pronobis

Reputation: 36076

What you are describing sounds like a typical case for using log probabilities (http://en.wikipedia.org/wiki/Log_probability). Use of log(y)=log(x1)+log(x2) instead of y=x1*x2 (turn your multiplications into additions of log probabilities) will result in improved speed and numerical stability.

Upvotes: 2

Related Questions