How do deal with huge numbers and keep them accurate?

Hello all, I wrote the following code:

require “bigdecimal”
require “bigdecimal/math”
include BigMath
odd = gets.chomp.to_f
result = odd/3.0
puts result.to_f
blank = gets.chomp

the code works just fine when the input is upto 15 digits, but
afterwards the code fails to give the correct output.

a few good examples:
odd=1231231
result=410410.333333333

odd=123123123123121 (15 digits)
result=41041041041040.3

so far so good,now:
odd=1231231231231231 (16 digits)
result=4.1041041041041e+014 (given with no remainder)
[It’s a wrong answer! the result should have been —
410410410410410.33333]

What do i need to chance in the code to make it happen?
in the future i should deal with larger numbers and the accuracy is
essential.

thanks in advanced, tomi.

On Sun, Sep 14, 2008 at 8:18 AM, Tomi Z. [email protected] wrote:

Hello all, I wrote the following code:

require “bigdecimal”
require “bigdecimal/math”
include BigMath
odd = gets.chomp.to_f

This gives you a float, NOT a bigdecimal.

result = odd/3.0
puts result.to_f

Try

odd = BigDecimal.new(gets.chomp)
puts odd/3 # or odd/3.0


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

-------- Original-Nachricht --------

Datum: Sun, 14 Sep 2008 21:18:45 +0900
Von: Tomi Z. [email protected]
An: [email protected]
Betreff: how do deal with huge numbers and keep them accurate?

the code works just fine when the input is upto 15 digits, but
odd=1231231231231231 (16 digits)
Posted via http://www.ruby-forum.com/.
Dear Tomi,

in addition to Rick’s post, I#d like to say that in Ruby, you can easily
calculate correctly with fractions, using
the built-in Rational class:

require “rational”

a_numerator=1233444534455555555555
a_denominator=3
a=Rational(a_numerator,1)+Rational(1,a_denominator)
p a
p ((a.numerator-1)/3)==a_numerator

Conversion between Fixnum and Bignum is automatic.

Best regards,

Axel

On Sun, Sep 14, 2008 at 10:24 AM, Axel E. [email protected] wrote:

result=4.1041041041041e+014 (given with no remainder)

Dear Tomi,

in addition to Rick’s post, I#d like to say that in Ruby, you can easily
calculate correctly with fractions, using
the built-in Rational class:

Yes, I should have pointed out that even

1231231 / 3 => 410410.333333333

Isn’t really the ‘correct answer’. Since the correct answer has an
infinite
number of 3’s after the decimail point.

A big decimal is still a float, albeit a float with lots of digits and
in
decimal rather than binary, but it still has the characteristics of a
float,
there are an infinite number of numbers which can’t be exactly
represented.

Of course neither Floats nor Rationals can represent irrational numbers
exactly.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

On Sun, Sep 14, 2008 at 7:18 AM, Tomi Z. [email protected] wrote:

the code works just fine when the input is upto 15 digits, but
odd=1231231231231231 (16 digits)
result=4.1041041041041e+014 (given with no remainder)
[It’s a wrong answer! the result should have been —
410410410410410.33333]

What do i need to chance in the code to make it happen?
in the future i should deal with larger numbers and the accuracy is
essential.

thanks in advanced, tomi.

require ‘bigdecimal’
require ‘bigdecimal/math’
include BigMath
a = BigDecimal(‘1231231231231231’)
b = 3.0
puts a/b
b = BigDecimal(‘3’)
puts a/b

Todd

On Sun, Sep 14, 2008 at 10:47 AM, Todd B. [email protected]
wrote:

so far so good,now:

require ‘bigdecimal’
require ‘bigdecimal/math’
include BigMath
a = BigDecimal(‘1231231231231231’)
b = 3.0
puts a/b
b = BigDecimal(‘3’)
puts a/b

Oops, didn’t clarify. What Rick said, but make sure your denominator
is also a BigDecimal instance. Least common denominator operation
(Float object), I suppose.

Todd

thanks u all for taking a few minutes to answer me. I’m really
embarrassed cause I wanted to simplify the question so, I didn’t wrote
down the actual code. I also sorry for not posting any answer yesterday.
so once more, your help would be very much appreciate…

(I’ll drop the 3 lines at the beginning cause I don’t sure about them,
and don’t want to mislead you. (talking about: include… require…
etc).

this is what i want to achieve with that code:

number = gets.chomp.to_f
divider = 3.0
while number % divider != 0
divider += 1.0
end
puts divider.to_s
if divider == 3.0
puts "the number can be divided by " + divider.to_s
else
puts “can’t be divided”
end

that’s it. sorry for repeating myself… once more:
i want the ability to input a number like this:
333333333333333333333333333333331
we all know that the answer will be something like that:
1111…111.333333
but the code will give me the answer that it can be divide by 3, and
that’s the main problem in that code.

Thanks in advanced, Tomiz.
p.s. i have tried to implement all of your suggestions with no luck.
I’ve add the code for your comfort.

-------- Original-Nachricht --------

Datum: Tue, 16 Sep 2008 00:34:15 +0900
Von: “Todd B.” [email protected]
An: [email protected]
Betreff: Re: how do deal with huge numbers and keep them accurate?

this is what i want to achieve with that code:
puts “can’t be divided”
Thanks in advanced, Tomiz.
=> #BigDecimal:b7d08754,‘0.3E1’,4(8)
irb(main):004:0> (n % d).to_f
=> 1.0

Looks fine to me.

Todd

Dear Tomi,

as Todd said, using Float is the problem… Of course you can divide any
Float by any other Float (excluding 0.0).
But you could do the following, e.g.,

axel@alecrim:~$ irb
irb(main):001:0> a=122222222222222222222222222222222222222
=> 122222222222222222222222222222222222222
irb(main):002:0> b=333333333333333333
=> 333333333333333333
irb(main):003:0> a%b
=> 111111111111111233
irb(main):004:0> a.class
=> Bignum
irb(main):005:0> b.class
=> Bignum
irb(main):006:0>

Conversions are automatic there, ie. b=3 would be a Fixnum.
Number a will be divisible by b if a%b==0.

Best regards,

Axel

to Rick, Axle and todd) … thank u very much for helping me, the code
is running.
I’ve deleted the float. earlier i thought that this format - 0.3E1 - in
the output was wrong. but now it’s good.
U R the BEST! thanks, tomiz.

On Mon, Sep 15, 2008 at 9:36 AM, Tomi Z. [email protected] wrote:

end
p.s. i have tried to implement all of your suggestions with no luck.
I’ve add the code for your comfort.

Once again, you are using floats…

irb(main):001:0> require ‘bigdecimal’
=> true
irb(main):002:0> n = Bigdecimal(‘333333333333333333333333333333331’)
=> #<BigDecimal:b7cf7418,'0.3333333333 3333333333 333333333
331E33,36(40)>
irb(main):003:0> d = Bigdecimal(‘3’)
=> #BigDecimal:b7d08754,‘0.3E1’,4(8)
irb(main):004:0> (n % d).to_f
=> 1.0

Looks fine to me.

Todd