Ruby 1.9.2 float precision

D

Diogo Almeida

Hello,

The Liquid templating engine has the following tests passing till ruby
1.9.2 rc1:

assert_template_result "4.66666666666667", "{{ 14 | divided_by:'3.0' }}"
#equals to 14/3.0 in irb
assert_template_result "6.3", "{{ '2.1' | times:3 }}" #equals to 2.1*3
in irb

However, as far as I could understand, the float precision has been
changed with RC1 and the first assertion now returns 15 decimal digits
instead of 14:
ruby-1.9.2-rc1 > 14/3.0
=> 4.666666666666667

And the second returns the same 15 decimal digits instead of 1:
ruby-1.9.2-rc1 > 2.1*3
=> 6.300000000000001

Even though I realize that the templating engine should not be messing
with the ruby pre-defined precisions, I would like to ask what would be
the recommended way to get all ruby versions to behave the same?

For instance, I've noticed that in both 1.9.1 and 1.9.2-rc1 the
instruction (14/3.0).to_r returns the exact same rational, just
differing when using the #to_f

Best regards
 
R

Robert Klemme

2010/7/13 Diogo Almeida said:
The Liquid templating engine has the following tests passing till ruby
1.9.2 rc1:

assert_template_result "4.66666666666667", "{{ 14 | divided_by:'3.0' }}"
#equals to 14/3.0 in irb
assert_template_result "6.3", "{{ '2.1' | times:3 }}" #equals to 2.1*3
in irb

However, as far as I could understand, the float precision has been
changed with RC1 and the first assertion now returns 15 decimal digits
instead of 14:
ruby-1.9.2-rc1 > 14/3.0
=A0=3D> 4.666666666666667

And the second returns the same 15 decimal digits instead of 1:
ruby-1.9.2-rc1 > 2.1*3
=A0=3D> 6.300000000000001

Even though I realize that the templating engine should not be messing
with the ruby pre-defined precisions, I would like to ask what would be
the recommended way to get all ruby versions to behave the same?

For instance, I've noticed that in both 1.9.1 and 1.9.2-rc1 the
instruction (14/3.0).to_r returns the exact same rational, just
differing when using the #to_f

I question the validity of the test. Expecting a particular
formatting of a float number without giving a concrete format is at
least fragile (as you have discovered) - I would even call it wrong.
Different than for integers there is no common agreed way to convert
floats to strings so if you want a particular formatting you need to
make it part of the test. An alternative would be a regexp match
against \A4\.6+7\z

irb(main):001:0> /\A4\.6+7\z/ =3D~ (14.0/3).to_s
=3D> 0

Kind regards

robert

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 
D

Diogo Almeida

Robert said:
2010/7/13 Diogo Almeida <[email protected]>:

I question the validity of the test. Expecting a particular
formatting of a float number without giving a concrete format is at
least fragile (as you have discovered) - I would even call it wrong.
Different than for integers there is no common agreed way to convert
floats to strings so if you want a particular formatting you need to
make it part of the test. An alternative would be a regexp match
against \A4\.6+7\z

irb(main):001:0> /\A4\.6+7\z/ =~ (14.0/3).to_s
=> 0

Yes, I found it odd when I saw it myself. Though, since this was a
recent change I figured someone could know how to fallback to the "old
formatting", without having to use regex, or other alternative
approaches.

Best regards.
 
C

Caleb Clausen

Yes, I found it odd when I saw it myself. Though, since this was a
recent change I figured someone could know how to fallback to the "old
formatting", without having to use regex, or other alternative
approaches.

1.9.2 has been changed so that float.to_s.to_f always round-trips with
a minimal string representation. This was not true in the past. This
new behavior is better; there's no flag or anything to get the old
behavior back. I suggest you follow Robert's suggestions for fixing
the test.
 
R

Roger Pack

Even though I realize that the templating engine should not be messing
with the ruby pre-defined precisions, I would like to ask what would be
the recommended way to get all ruby versions to behave the same?

I think it's something like this for <= 1.9.1

class Float
def to_s
num = "%.12f" % self
num.sub /\.0+$/, ''
end
end
 
D

Diogo Almeida

Roger said:
I think it's something like this for <= 1.9.1

class Float
def to_s
num = "%.12f" % self
num.sub /\.0+$/, ''
end
end

Thanks Roger. I'll wait and see if the guys from shopify will accept my
new assertions based on regexp, so they don't change the new behaviors
introduced with the latest versions.

Best regards.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top