[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

precision loss with pack/unpack ?

Luis Parravicini

8/9/2007 7:07:00 PM

Hello

I'm reading Java class files using ruby and found some problems when
handling float values. The numbers are stored using IEEE 754 format.
After several hours trying and thinking I might be using unpack the
wrong way, I've wrote the following code which packs a Float and then
immediately unpacks it. And the result is different from the original
value.

------------
a = 0.1234567
b = [a].pack('g').unpack('g')[0]

puts "#{a} =? #{b} => #{a == b}"
------------

outputs:

0.1234567 =? 0.123456701636314 => false

I came accross this doc, which states that in Perl this happens too
(http://perldoc.perl.org/functions...) "Note that Perl uses
doubles internally for all numeric calculation, and converting from
double into float and thence back to double again will lose precision
(i.e., unpack("f", pack("f", $foo)) will not in general equal $foo)."
Maybe Ruby is doing the same Perl does?



Any help will be appreciated

Thanks


--
Luis Parravicini
http://ktulu.co...

3 Answers

Robert Dober

8/9/2007 7:40:00 PM

0

On 8/9/07, Luis Parravicini <lparravi@gmail.com> wrote:
> Hello
>
> I'm reading Java class files using ruby and found some problems when
> handling float values. The numbers are stored using IEEE 754 format.
> After several hours trying and thinking I might be using unpack the
> wrong way, I've wrote the following code which packs a Float and then
> immediately unpacks it. And the result is different from the original
> value.
>
> ------------
> a = 0.1234567
> b = [a].pack('g').unpack('g')[0]

Hmm I am not sure that this is exactly related but I would rather find
this behavior normal, given my old memories of floating number
representation, look at this e.g.

irb(main):004:0> 0.1234567 + 1000 - 1000
=> 0.12345670000002

If you use enough bits you are fine:

b = [a].pack('G').unpack('G')

HTH
Robert

--
[...] as simple as possible, but no simpler.
-- Attributed to Albert Einstein

Konrad Meyer

8/9/2007 9:12:00 PM

0

On Thursday 09 August 2007 12:06:31 pm Luis Parravicini wrote:
> Hello
>
> I'm reading Java class files using ruby and found some problems when
> handling float values. The numbers are stored using IEEE 754 format.
> After several hours trying and thinking I might be using unpack the
> wrong way, I've wrote the following code which packs a Float and then
> immediately unpacks it. And the result is different from the original
> value.

Yes, small differences are common with floats. The best way to compare them
is with something like that demonstrated in:
http://www.cygnus-software.com/papers/comparingfloats/Comparing%20floating%20point%20numbers.htm#_To...

> ------------
> a = 0.1234567
> b = [a].pack('g').unpack('g')[0]
>
> puts "#{a} =? #{b} => #{a == b}"
> ------------
>
> outputs:
>
> 0.1234567 =? 0.123456701636314 => false
>
> I came accross this doc, which states that in Perl this happens too
> (http://perldoc.perl.org/functions...) "Note that Perl uses
> doubles internally for all numeric calculation, and converting from
> double into float and thence back to double again will lose precision
> (i.e., unpack("f", pack("f", $foo)) will not in general equal $foo)."
> Maybe Ruby is doing the same Perl does?

Ruby uses doubles internally for floats as well. Loss of precision is
common, but the above link should work well for you.

> Any help will be appreciated
>
> Thanks

No problem, glad to (try to) help.

--
Konrad Meyer <konrad@tylerc.org> http://konrad.sobertil...

Vu Nang Luc

8/10/2007 1:18:00 AM

0

On 10 Tha ng T?m, 02:06, "Luis Parravicini" <lparr...@gmail.com>
wrote:
>And the result is different from the original
> value.
>
> ------------
> a = 0.1234567
> b = [a].pack('g').unpack('g')[0]
>
> puts "#{a} =? #{b} => #{a == b}"
> ------------
>
> outputs:
>
> 0.1234567 =? 0.123456701636314 => false
>

It's quite common with float or double representation. Because float/
double can not represent ALL value within its range so some loss
precision happens. It may happen right after assignment:
eg: On my machine:

> a = a= 100.1001001003333
>a
100.100100100333 (the last digit gone?)