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.

···

--
Posted via http://www.ruby-forum.com/.

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

···

On Sun, Sep 14, 2008 at 8:18 AM, Tomi Zzzz <tomi_z@nana.co.il> wrote:

--
Rick DeNatale

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

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

Datum: Sun, 14 Sep 2008 21:18:45 +0900
Von: Tomi Zzzz <tomi_z@nana.co.il>
An: ruby-talk@ruby-lang.org
Betreff: 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.
--
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

···

--
Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen!
Ideal für Modem und ISDN: GMX Handytarife 2024 | jetzt wechseln & sparen

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 7:18 AM, Tomi Zzzz <tomi_z@nana.co.il> wrote:

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.

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.

···

On Sun, Sep 14, 2008 at 10:24 AM, Axel Etzold <AEtzold@gmx.de> wrote:

> 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.
> --
> 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:

--
Rick DeNatale

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

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

···

On Sun, Sep 14, 2008 at 10:47 AM, Todd Benson <caduceass@gmail.com> wrote:

On Sun, Sep 14, 2008 at 7:18 AM, Tomi Zzzz <tomi_z@nana.co.il> wrote:

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.

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

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.

Attachments:
http://www.ruby-forum.com/attachment/2683/forum.rb

···

--
Posted via http://www.ruby-forum.com/.

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

···

On Mon, Sep 15, 2008 at 9:36 AM, Tomi Zzzz <tomi_z@nana.co.il> wrote:

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 Benson" <caduceass@gmail.com>
An: ruby-talk@ruby-lang.org
Betreff: Re: how do deal with huge numbers and keep them accurate?

> 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.

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

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

···

On Mon, Sep 15, 2008 at 9:36 AM, Tomi Zzzz <tomi_z@nana.co.il> wrote:

--
Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen!
Ideal für Modem und ISDN: Handytarif Vergleich 2023 | alle Anbieter vergleichen | GMX

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.

···

--
Posted via http://www.ruby-forum.com/.