[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Float Question

ARMANDO PADILLA

12/1/2007 7:26:00 AM

This is probably the stupidest question ive ever had to ask on any board
so im sorry lol. :-p

Yes i've googled and found a solution but i cant believe that the
solution presented is correct or that the great minds behind ruby did
not include something like this.

I want to get a float 2.3333 to display as 2.33 or 2.333 etc.

Now, i read the manual, Numerical, Float, Math sections but could not
find a way to do this. Yes you can use string manipulation but that
just defeats the purpose of having something like this built into the
Float stack.

ex. someFloat = Float.new(2) ==> 2.12
someFloat = Float.new(5) => 2.12345

Any thoughts?
11 Answers

Chris Cummer

12/1/2007 7:58:00 AM

0

What you're looking for is sprintf() though I suspect you know that
already from your comment below. Ie:

sprintf( "%0.02f", 234.2342342)

You deride this as "string manipulation" though in effect as soon as
you display the number that's what you're doing, no matter where or
why you want to display it. The number only exists as a true float as
long as you don't look at it; as soon as you do, you've forced it to
achieve stringness.

Makes sense?


On 30-Nov-07, at 11:29 PM, Armando Padilla wrote:

> This is probably the stupidest question ive ever had to ask on any
> board so im sorry lol. :-p
>
> Yes i've googled and found a solution but i cant believe that the
> solution presented is correct or that the great minds behind ruby
> did not include something like this.
>
> I want to get a float 2.3333 to display as 2.33 or 2.333 etc.
>
> Now, i read the manual, Numerical, Float, Math sections but could
> not find a way to do this. Yes you can use string manipulation but
> that just defeats the purpose of having something like this built
> into the Float stack.
>
> ex. someFloat = Float.new(2) ==> 2.12
> someFloat = Float.new(5) => 2.12345
>
> Any thoughts?
>
>


ARMANDO PADILLA

12/1/2007 8:27:00 AM

0

Hey Chris thanks for the feedback. Yea im using that but i was looking
for something built into the Float stack. Something along the lines of
Float.new(<number of values after decimal here>). Basically something
without the need to use sprintf.

Next release of Ruby request? lol



Chris Cummer wrote:
> What you're looking for is sprintf() though I suspect you know that
> already from your comment below. Ie:
>
> sprintf( "%0.02f", 234.2342342)
>
> You deride this as "string manipulation" though in effect as soon as
> you display the number that's what you're doing, no matter where or
> why you want to display it. The number only exists as a true float as
> long as you don't look at it; as soon as you do, you've forced it to
> achieve stringness.
>
> Makes sense?
>
>
> On 30-Nov-07, at 11:29 PM, Armando Padilla wrote:
>
>> This is probably the stupidest question ive ever had to ask on any
>> board so im sorry lol. :-p
>>
>> Yes i've googled and found a solution but i cant believe that the
>> solution presented is correct or that the great minds behind ruby
>> did not include something like this.
>>
>> I want to get a float 2.3333 to display as 2.33 or 2.333 etc.
>>
>> Now, i read the manual, Numerical, Float, Math sections but could
>> not find a way to do this. Yes you can use string manipulation but
>> that just defeats the purpose of having something like this built
>> into the Float stack.
>>
>> ex. someFloat = Float.new(2) ==> 2.12
>> someFloat = Float.new(5) => 2.12345
>>
>> Any thoughts?
>>
>>
>
>

Pat Maddox

12/1/2007 9:04:00 AM

0

Or even the current release!

class Float
def truncate(places = 0)
return to_i if places == 0
sprintf( "%0.#{places}f", self).to_f
end
end

irb(main):007:0> 234.2342342.truncate 2
=> 234.23
irb(main):008:0> 234.2342342.truncate
=> 234

On Dec 1, 2007 12:30 AM, Armando Padilla <mando81@prodigy.net> wrote:
> Hey Chris thanks for the feedback. Yea im using that but i was looking
> for something built into the Float stack. Something along the lines of
> Float.new(<number of values after decimal here>). Basically something
> without the need to use sprintf.
>
> Next release of Ruby request? lol
>
>
>
>
> Chris Cummer wrote:
> > What you're looking for is sprintf() though I suspect you know that
> > already from your comment below. Ie:
> >
> > sprintf( "%0.02f", 234.2342342)
> >
> > You deride this as "string manipulation" though in effect as soon as
> > you display the number that's what you're doing, no matter where or
> > why you want to display it. The number only exists as a true float as
> > long as you don't look at it; as soon as you do, you've forced it to
> > achieve stringness.
> >
> > Makes sense?
> >
> >
> > On 30-Nov-07, at 11:29 PM, Armando Padilla wrote:
> >
> >> This is probably the stupidest question ive ever had to ask on any
> >> board so im sorry lol. :-p
> >>
> >> Yes i've googled and found a solution but i cant believe that the
> >> solution presented is correct or that the great minds behind ruby
> >> did not include something like this.
> >>
> >> I want to get a float 2.3333 to display as 2.33 or 2.333 etc.
> >>
> >> Now, i read the manual, Numerical, Float, Math sections but could
> >> not find a way to do this. Yes you can use string manipulation but
> >> that just defeats the purpose of having something like this built
> >> into the Float stack.
> >>
> >> ex. someFloat = Float.new(2) ==> 2.12
> >> someFloat = Float.new(5) => 2.12345
> >>
> >> Any thoughts?
> >>
> >>
> >
> >
>
>

HiddenBek

12/1/2007 9:17:00 AM

0

You can monkey patch Float to do this, basically. Whether or not it's
a good idea is another matter entirely.

class Float
def to_s
#force all Floats to 2 decimal places
"%.2f" % self
end
end

puts 1.2345678 # => 1.23

Or maybe:

class Float
attr_accessor :decimals
alias_method :default_to_s, :to_s
def to_s
decimals ? "%.#{decimals}f" % self : default_to_s
end
end

a = 1.234567
puts a # => 1.234567
a.decimals = 2
puts a # => 1.23

Chris Cummer

12/1/2007 9:33:00 AM

0

On 1-Dec-07, at 12:30 AM, Armando Padilla wrote:

> Hey Chris thanks for the feedback. Yea im using that but i was
> looking for something built into the Float stack. Something along
> the lines of Float.new(<number of values after decimal here>).
> Basically something without the need to use sprintf.

In that case the monkey-patch suggestions made by others would do the
trick for you. I personally wouldn't like to see anything like this in
the Float class proper since it really isn't part of the float itself
but rather an operation on the string representation of it.

Of the m-p suggestions made (is this question now mp-complete?), I
like Pat Maddox's truncate() the best:

> class Float
> def truncate(places = 0)
> return to_i if places == 0
> sprintf( "%0.#{places}f", self).to_f
> end
> end

Robert Klemme

12/1/2007 10:22:00 AM

0

On 01.12.2007 09:26, Armando Padilla wrote:
> Hey Chris thanks for the feedback. Yea im using that but i was looking
> for something built into the Float stack.

Class != stack.

> Something along the lines of
> Float.new(<number of values after decimal here>). Basically something
> without the need to use sprintf.

I fail to see where the issue with using (s)printf is. Anyway, if you
do not like the syntax of sprintf you can as well do this:

irb(main):001:0> f=1.0/3
=> 0.333333333333333
irb(main):002:0> "%.2f" % f
=> "0.33"

> Next release of Ruby request? lol

Probably not. As others have demonstrated, you can easily do this in
Ruby today. But it seems, few people know the star operator in printf
format strings. You can do this:

irb(main):021:0> module Precision
irb(main):022:1> def format(decimals,total=0)
irb(main):023:2> sprintf "%*.*f", total, decimals, self
irb(main):024:2> end
irb(main):025:1> end
=> nil
irb(main):026:0> f=1.0/3
=> 0.333333333333333
irb(main):027:0> f.format 3
=> "0.333"
irb(main):028:0> f.format 3,10
=> " 0.333"

Kind regards

robert

Chris Cummer

12/1/2007 11:21:00 AM

0

On 1-Dec-07, at 2:25 AM, Robert Klemme wrote:

> But it seems, few people know the star operator in printf format
> strings. You can do this:
>
> irb(main):021:0> module Precision
> irb(main):022:1> def format(decimals,total=0)
> irb(main):023:2> sprintf "%*.*f", total, decimals, self
> irb(main):024:2> end
> irb(main):025:1> end

You're right, I didn't know that one at all and it seems quite handy.
Thanks for the tip.

ARMANDO PADILLA

12/1/2007 5:00:00 PM

0

> I fail to see where the issue with using (s)printf is.

If i use sprintf im assuming that the argument is changed to a string
type. If then i chose to calculate additional values with this string
type i would have to reconvert it to a float. On the surface its fine,
i wouldnt mind doing it but I need speed and any less lines that ruby
will translate too in terms of machine language is beneficial to me.

I actually like Maddox truncate example. Thanks Maddox. i wasnt aware
of both that feature and *.format <digit here> Klemme suggested.



Robert Klemme wrote:
> On 01.12.2007 09:26, Armando Padilla wrote:
>> Hey Chris thanks for the feedback. Yea im using that but i was
>> looking for something built into the Float stack.
>
> Class != stack.
>
>> Something along the lines of Float.new(<number of values after decimal
>> here>). Basically something without the need to use sprintf.
>
> I fail to see where the issue with using (s)printf is. Anyway, if you
> do not like the syntax of sprintf you can as well do this:
>
> irb(main):001:0> f=1.0/3
> => 0.333333333333333
> irb(main):002:0> "%.2f" % f
> => "0.33"
>
>> Next release of Ruby request? lol
>
> Probably not. As others have demonstrated, you can easily do this in
> Ruby today. But it seems, few people know the star operator in printf
> format strings. You can do this:
>
> irb(main):021:0> module Precision
> irb(main):022:1> def format(decimals,total=0)
> irb(main):023:2> sprintf "%*.*f", total, decimals, self
> irb(main):024:2> end
> irb(main):025:1> end
> => nil
> irb(main):026:0> f=1.0/3
> => 0.333333333333333
> irb(main):027:0> f.format 3
> => "0.333"
> irb(main):028:0> f.format 3,10
> => " 0.333"
>
> Kind regards
>
> robert

unbewusst.sein

12/1/2007 5:26:00 PM

0

Armando Padilla <mando81@prodigy.net> wrote:

>
> I actually like Maddox truncate example. Thanks Maddox. i wasnt aware
> of both that feature and *.format <digit here> Klemme suggested.

I'm using that :

def aprox( eps = 1.0e-10 )
( self / eps ).round * eps
end


with :
a_float = 1.2345678901234567890
epss = [ 1.0e-10, 1.0e-8, 1.0e-6, 1.0e-4, 1.0e-2, 1.0, 1.0e2]
epss.each do | eps |
puts "#{a_float}.aprox( #{eps} ) -o-> #{a_float.aprox( eps )}"
end

gives :
1.23456789012346.aprox( 1.0e-10 ) -o-> 1.2345678901
1.23456789012346.aprox( 1.0e-08 ) -o-> 1.23456789
1.23456789012346.aprox( 1.0e-06 ) -o-> 1.234568
1.23456789012346.aprox( 0.0001 ) -o-> 1.2346
1.23456789012346.aprox( 0.01 ) -o-> 1.23
1.23456789012346.aprox( 1.0 ) -o-> 1.0
1.23456789012346.aprox( 100.0 ) -o-> 0.0

I'm also using an aproximate float comparator :
def ===( aFloat, eps = 1.0e-10)
begin
clazz = aFloat.class.to_s
raise "Argument \"#{aFloat}\" must be a Float (being of
#{clazz})." if clazz != "Float"
( self > aFloat - eps ) && ( self < aFloat + eps )
rescue
puts "An error occurred: #{$!}"
nil
end
end

with :
vref = 2.0
val = [ 2.00000000002, 2.00000002, 2.00002, 2.002 ]
val.each do | v |
puts "( #{vref} ===? #{v} ) = #{( vref === v )}"
puts "( #{vref} ===? #{v}, 1.0e-8 ) = #{( vref.===(v, 1.0e-8) )}"
puts "( #{vref} ===? #{v}, 1.0e-6 ) = #{( vref.===(v, 1.0e-6) )}"
puts "( #{vref} ===? #{v}, 1.0e-4 ) = #{( vref.===(v, 1.0e-4) )}"
end

gives :
( 2.0 ===? 2.00000000002 ) = true
( 2.0 ===? 2.00000000002, 1.0e-8 ) = true
( 2.0 ===? 2.00000000002, 1.0e-6 ) = true
( 2.0 ===? 2.00000000002, 1.0e-4 ) = true
( 2.0 ===? 2.00000002 ) = false
( 2.0 ===? 2.00000002, 1.0e-8 ) = false
( 2.0 ===? 2.00000002, 1.0e-6 ) = true
( 2.0 ===? 2.00000002, 1.0e-4 ) = true
( 2.0 ===? 2.00002 ) = false
( 2.0 ===? 2.00002, 1.0e-8 ) = false
( 2.0 ===? 2.00002, 1.0e-6 ) = false
( 2.0 ===? 2.00002, 1.0e-4 ) = true
( 2.0 ===? 2.002 ) = false
( 2.0 ===? 2.002, 1.0e-8 ) = false
( 2.0 ===? 2.002, 1.0e-6 ) = false
( 2.0 ===? 2.002, 1.0e-4 ) = false
--
Une Bévue

Gary Wright

12/1/2007 5:36:00 PM

0


On Dec 1, 2007, at 12:04 PM, Armando Padilla wrote:
> If i use sprintf im assuming that the argument is changed to a
> string type. If then i chose to calculate additional values with
> this string type i would have to reconvert it to a float. On the
> surface its fine, i wouldnt mind doing it but I need speed and any
> less lines that ruby will translate too in terms of machine
> language is beneficial to me.


This statement just confused me more. sprintf doesn't change the
underlying objects--it just creates a string representation of them.
You are free to use the original objects as you like.

It sounds like you aren't primarily interested in the format of the
string representation of a float but instead would like to compute
a rounded or truncated value. That is a completely different
problem. Pat's solution included a roundtrip conversion to a
decimal/string representation, which is going to be inaccurate and
expensive. Of course if you want to 'round' a float then you'll
want to round to a power of two to avoid conversion problems.

Maybe BigDecimal objects would work better for you? You could
at least avoid the base2/base10 conversion problems.

Gary Wright