Eric I. wrote:
> On May 19, 7:44 pm, "Michael W. Ryder" <_mwry... / worldnet.att.net>
> wrote:
>> My question is why doesn't Float know how to deal with prefixes such as
>> Hex?  I wouldn't care if it tossed out invalid hex numbers such as 0x1h
>> but it should at least try.  As far as I am concerned the only
>> difference between Float and Integer should be the return type, not what
>> types they can handle.
> 
> Well you're asking "why", and I suppose you'd have to address the
> question to the core Ruby team.  However, I can venture a guess, for
> whatever that might be worth.  And there are three elements to my
> guess.
> 
> First, Float() and Integer() work like Ruby itself.  In Ruby code you
> can hardcode integer literals using 17 (dec), 021 (oct), or 0x11
> (hex).  But you can only hardcode floating point literals using base
> ten.  Admittedly, that's a bit of a punt since you'll probably ask why
> Ruby works that way.
> 
> Second, I've never had the need to represent a floating point value as
> a hexadecimal literal or string.  With integers you sometimes need bit
> masks and such.  Perhaps there are domains where this would be very
> useful.  But I imagine most programmers don't typically run into
> them.  And like anything, people are more likely to do things that
> they believe will be useful, or they scratch their own itches.
> 

I think my main concern was this was yet another "gotcha" that only came 
up if you tested for it.  My original conversion for strings to floats 
was a simple: x = Float(x) if (Float(x) rescue false).  This works fine 
for "12", and "12.34" but crashes if I use "0x11" or any other hex 
value, something Integer does not.  What I ended up having to do is:

temp = nil
temp = Float(x) if (Float(x) rescue false)
if temp == nil
   temp = Integer(x) if (Integer(x) rescue false)
end
if temp == nil
   x = 0
else
   x = temp
end

As you can see this is much more code, and that is before I add in more 
code for error handling.


> And my third reason is that there might be ambiguity in how to
> interpret such a string.  The representation of floating point values
> as a bit pattern is typically done using IEEE 754.  So, if we wanted
> to represent a PI as a floating point double as a hexadecimal
> constant, I think it would be "0x400921fb54442d18".  However that
> could also be interpreted as the integer 4,614,256,656,552,045,848.
> 
> Given your original post, you seem to be thinking that hexadecimal
> constants would include a "." to separate the whole part from the
> fractional part.  In that case, I imagine pi would be represented as
> "0x3.243f6a8885a3".
> 
Actually I wouldn't care if it couldn't handle floating point numbers in 
any base except 10 as it doesn't appear to be able to do so in other 
methods like sprintf or printf.  I don't think it would have been that 
hard to allow Float to handle strings like '0x11' as the code has 
already been created for Integer.

> But for those programmers out there who'd want some type of
> functionality, they may not be unified in their preference for the
> format -- IEEE 754 or with an included decimal point.
> 
> I don't know how satisfying you'll find those answers, but they're the
> best I can do.
> 

I have no problem with your replies and can see that maybe the original 
implementation was made to work correctly for a small subset of possible 
values rather than try to handle everything with possible problems.  As 
I mentioned earlier I was trying to take the section on duck typing 
seriously and make my class handle as many reasonable inputs as 
possible.  I will probably try to include arrays and strings like "17 4" 
as inputs once I finish the inputs for Integers, Floats, Rationals, and 
Strings in any combination.
I hadn't thought about adding the ability to display Rational numbers in 
other bases but that should be trivial, at least compared to Floating 
point numbers.  I would use something like 0x11/0x4 to represent 17/4. 
Since the numerator and denominator of my Rational numbers are always 
Integers converting should be easy.


> By the way, if you want to include such functionality in your Rational
> project, the following Ruby snippets might be helpful.
> 
> To figure out how pi would be represented as an IEEE 754 encoded
> value, I used the following Ruby code:
> 
>     "0x" + [Math::PI].pack("G").unpack("H*").first
> 
> If you're unfamiliar with the methods, you may be interested in
> reading the documentation on Array#pack and String#unpack.
> 
> To figure out how pi would be represented in the other form, I used
> this Ruby code:
> 
>     fractional_hex_digits = 12  # how many hex digits right of decimal
>     "0x" +
>       Math::PI.floor.to_s(16) +
>       "." +
>       ((Math::PI - Math::PI.floor) *
>          16**fractional_hex_digits).floor.to_s(16)
> 
> If you plan on using any of this code, please check my work since it
> comes with absolutely to warranties.
> 
> Best,
> 
> Eric
> 
> ====
> 
> LearnRuby.com offers Rails & Ruby HANDS-ON public & ON-SITE
> workshops.
>    Ruby Fundamentals Wkshp          June 16-18     Ann Arbor, Mich.
>    Ready for Rails Ruby Wkshp       June 23-24     Ann Arbor, Mich.
>    Ruby on Rails Wkshp              June 25-27     Ann Arbor, Mich.
>    Ruby Plus Rails Combo Wkshp      June 23-27     Ann Arbor, Mich
> Please visit http://LearnRuby.com for all the details.