[#53944] [ruby-trunk - Bug #8210][Open] Multibyte character interfering with end-line character within a regex — "sawa (Tsuyoshi Sawada)" <sawadatsuyoshi@...>

14 messages 2013/04/03

[#53974] [ruby-trunk - Feature #8215][Open] Support accessing Fiber-locals and backtraces for a Fiber — "halorgium (Tim Carey-Smith)" <ruby-lang-bugs@...>

14 messages 2013/04/03

[#54095] [ruby-trunk - Feature #8237][Open] Logical method chaining via inferred receiver — "wardrop (Tom Wardrop)" <tom@...>

34 messages 2013/04/08

[#54138] [ruby-trunk - Bug #8241][Open] If uri host-part has underscore ( '_' ), 'URI#parse' raise 'URI::InvalidURIError' — "neocoin (Sangmin Ryu)" <neocoin@...>

9 messages 2013/04/09

[#54185] [CommonRuby - Feature #8257][Open] Exception#cause to carry originating exception along with new one — "headius (Charles Nutter)" <headius@...>

43 messages 2013/04/11

[#54196] Encouraging use of CommonRuby — Charles Oliver Nutter <headius@...>

I think we need to do more to encourage the use of the CommonRuby

20 messages 2013/04/11
[#54200] Re: Encouraging use of CommonRuby — Marc-Andre Lafortune <ruby-core-mailing-list@...> 2013/04/11

Hi,

[#54211] Re: Encouraging use of CommonRuby — "NARUSE, Yui" <naruse@...> 2013/04/12

As far as I understand, what is CommonRuby and the process over CommonRuby

[#54215] Re: Encouraging use of CommonRuby — Charles Oliver Nutter <headius@...> 2013/04/12

On Thu, Apr 11, 2013 at 11:25 PM, NARUSE, Yui <naruse@airemix.jp> wrote:

[#54207] [CommonRuby - Feature #8258][Open] Dir#escape_glob — "steveklabnik (Steve Klabnik)" <steve@...>

15 messages 2013/04/12

[#54218] [CommonRuby - Feature #8259][Open] Atomic attributes accessors — "funny_falcon (Yura Sokolov)" <funny.falcon@...>

43 messages 2013/04/12

[#54288] [CommonRuby - Feature #8271][Open] Proposal for moving to a more visible, formal process for feature requests — "headius (Charles Nutter)" <headius@...>

15 messages 2013/04/15

[#54333] Requesting Commit Access — Aman Gupta <ruby@...1.net>

Hello ruby-core,

16 messages 2013/04/16

[#54473] [Backport 200 - Backport #8299][Open] Minor error in float parsing — "bobjalex (Bob Alexander)" <bobjalex@...>

27 messages 2013/04/19

[#54532] [ruby-trunk - Bug #8315][Open] mkmf does not include include paths from pkg_config anymore — "Hanmac (Hans Mackowiak)" <hanmac@...>

11 messages 2013/04/23

[#54621] [ruby-trunk - Feature #8339][Open] Introducing Geneartional Garbage Collection for CRuby/MRI — "ko1 (Koichi Sasada)" <redmine@...>

43 messages 2013/04/27
[#54643] [ruby-trunk - Feature #8339] Introducing Geneartional Garbage Collection for CRuby/MRI — "authorNari (Narihiro Nakamura)" <authorNari@...> 2013/04/28

[#54649] Re: [ruby-trunk - Feature #8339] Introducing Geneartional Garbage Collection for CRuby/MRI — SASADA Koichi <ko1@...> 2013/04/28

(2013/04/28 9:23), authorNari (Narihiro Nakamura) wrote:

[#54657] Re: [ruby-trunk - Feature #8339][Open] Introducing Geneartional Garbage Collection for CRuby/MRI — Magnus Holm <judofyr@...> 2013/04/28

On Sat, Apr 27, 2013 at 8:19 PM, ko1 (Koichi Sasada)

[#54665] [ruby-trunk - Bug #8344][Open] Status of Psych and Syck — "Eregon (Benoit Daloze)" <redmine@...>

18 messages 2013/04/28

[ruby-core:54007] Re: [ruby-trunk - Bug #7829] Rounding error in Ruby Time

From: David MacMahon <davidm@...>
Date: 2013-04-05 01:08:06 UTC
List: ruby-core #54007
On Apr 3, 2013, at 6:30 PM, Tanaka Akira wrote:

> 2013/4/4 David MacMahon <davidm@astro.berkeley.edu>:
>> 
>>>> f=57563.232824357045
>> => 57563.232824357045
>> 
>>>> puts "%016x\n"*5 % [f, f.to_r.to_f, f.to_s.to_f, f.to_s.to_r.to_f, f.rationalize.to_f].pack('D*').unpack('Q*')
>> 40ec1b67734c10e7
>> 40ec1b67734c10e7
>> 40ec1b67734c10e7
>> 40ec1b67734c10e6 <=== String#to_r "error"
>> 40ec1b67734c10e7
>> => nil
> 
> I don't think that String#to_r is wrong.
> 
> % ruby -e 'f=57563.232824357045
> p f, f.to_s, f.to_s.to_r
> '
> 57563.232824357045
> "57563.232824357045"
> (11512646564871409/200000000000)
> 
> String#to_r is correct because
> 57563.232824357045 == 11512646564871409/200000000000 in mathematical sense.
> 
> The "error" is caused by Froat#to_s and it is expected.

Of course you're right about String#to_r being correct.  I think Float#to_s is correct as well.  I think the problem is actually in Rational#to_f.

Each distinct Float value has (or should have, IMHO) an unambiguous String representation such that f.to_s.to_f == f, discounting NaN and Infinity for which this relationship doesn't hold due to a limitation (bug?) of String#to_f.

String#to_r works correctly as you pointed out.

The problem occurs because the Rational returned by String#to_r is reduced.  When converting the reduced fraction of this example to Float, Rational#to_f effectively computes:

>> 11512646564871409.to_f/200000000000.to_f
=> 57563.23282435704 <=== does NOT equal original value

instead of the un-reduced computation of:

>> 57563232824357045.to_f/1000000000000.to_f
=> 57563.232824357045 <=== DOES equal original value

As you can see, these two expressions do not product equal answers.  This limitation of Rational#to_f can also be seen by using BigDecimal to convert from Rational to Float:

>> class Rational
>>   def to_f_via_bd
>>     (BigDecimal.new(numerator)/denominator).to_f
>>   end
>> end

>> f=57563.232824357045
=> 57563.232824357045

>> f.to_s.to_r.to_f
=> 57563.23282435704 <=== does NOT equal f

>> f.to_s.to_r.to_f_via_bd
=> 57563.232824357045 <=== DOES equal f

This same limitation also explains the problem I saw with Float.rationalize:

>> 1.501852784991644e-17.rationalize.to_f
=> 1.5018527849916442e-17 <=== does NOT equal original value

>> 1.501852784991644e-17.rationalize.to_f_via_bd
=> 1.501852784991644e-17 <=== DOES equal original value

In an earlier message I wrote: "Converting Float to Rational is 'perfect' in that the conversion back to Float results in the same (limited precision) value."  The above examples shows that this is not true.  I think this could be considered a bug in Rational#to_f.

> Anyway, I'm sure now that Float#rationalize should not be used
> internally/automatically.

I agree with this.  Float#rationalize returns a Rational that is an approximation of the Float.  This approximation is good enough that converting the Rational back to Float (avoiding intermediate rounding errors!) returns the original Float, but the Rational is NOT an exact representation.  This is not a problem when using a single DateTime object, but performing math on a DateTime object that contains such an approximation seems like a bad idea.

On the other hand, Float#to_s works well and String#to_r returns a Rational that exactly equals the floating point number represented by the String.  What about changing num_exact() in time.c to handle Floats by converting to String and then to Rational rather than calling Float#to_r?

> Anyone can use it as Time.utc(1970,1,1,0,0,12.860.rationalize) and it
> may (or may not) solve problem, though.

Or even better: Time.utc(1970,1,1,0,0,12.860.to_s.to_r).

Dave


In This Thread