To_f and the format of E notation

Hi,

I am parsing an ASCII file with floating point numbers that have a
slightly unusual format in order to save space (each floating point
number is limited to 8 characters, one being the decimal point). For
example, all the following strings are acceptable representations of the
number 7:
7.0 .7E1 0.7+1 .70+1 7.E+0 70.-1

I thought that adding the missing E for numbers in E notation (but
without the E) before calling to_f would be enough. So I came up with
the following regex:

irb(main):001:0> “70.-1”.sub(/([\d.])[eE]?([±])/, ‘\1e\2’)
=> “70.e-1”

However, to_f gives a wrong number:

irb(main):002:0> “70.-1”.sub(/([\d.])[eE]?([±])/, ‘\1e\2’).to_f
=> 70.0

Inserting 0e instead of just e fixes the problem:

irb(main):003:0> “70.-1”.sub(/([\d.])[eE]?([±])/, ‘\10e\2’).to_f
=> 7.0

My questions:

  • Why Ruby cannot convert the first string to a float correctly? It
    apparently expects digits after the decimal point, otherwise it stops
    the conversion. Is there some specification for the exponential notation
    format? I could not find any. On the other hand, other languages can
    handle it well, e.g., in Python:

float(“70.e-1”)
7.0
I tested in C/C++ and Java with the same (correct) result.

  • Is there a better (faster, more elegant, more concise) way of
    converting such strings to floats?

Thanks,

Vladimir

On Jan 29, 2014, at 18:31, Vladimir, Chalupecky
[email protected] wrote:

irb(main):001:0> “70.-1”.sub(/([\d.])[eE]?([±])/, ‘\1e\2’)
=> “70.e-1”

Remember, we use “.” for many things, the most important being method
dispatch.

That string looks like sending a method named ‘e’ to the integer 70:
70.e() - 1

Full fledged floats have both an integer part and a fractional part, or
they’re integers with scientific notation:

70e-1
70.0e-1

That disambiguates them from methods.

70e-1
=> 7.0
70.0e-1
=> 7.0
70.e-1
NoMethodError: undefined method e' for 70:Fixnum from (irb):2 from /usr/bin/irb:12:in

I see. Thanks for the help.
Cheers,
Vladimir