Float Question

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?

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?

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?

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?
>>
>>
>
>

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

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:

···

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

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

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

···

On 01.12.2007 09:26, Armando Padilla wrote:

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

···

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

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 >). 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

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

···

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.

--
Une Bévue

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

···

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.

> 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.

But this is *exactly* what you asked for. Quoting from your original posting:

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

You are clearly asking for a string representation with specific properties, namely the number of digits after the decimal point.

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.

Maybe we should start over with you stating what it is that you want to do.

And please, do not top post.

Regards

  robert

···

On 01.12.2007 17:59, Armando Padilla wrote: