rounding to n decimal digits

D

David Garamond

I often do this:

class Float
def round_n(n=0)
raise FloatDomainError unless self.finite?
raise ArgumentError unless n.class == Fixnum && n >= 0
sprintf("%.#{n}f", self).to_f
end

def ceil_n(n=0)
raise FloatDomainError unless self.finite?
raise ArgumentError unless n.class == Fixnum && n >= 0
(self*10**n).ceil.to_f / 10**n
end

def floor_n(n=0)
raise FloatDomainError unless self.finite?
raise ArgumentError unless n.class == Fixnum && n >= 0
(self*10**n).floor.to_f / 10**n
end
end

However I can't help get the feeling that Ruby already has something
like this. Did I indeed miss it?
 
T

Todd Gardner

David Garamond said:
I often do this:

class Float
def round_n(n=0)
raise FloatDomainError unless self.finite?
raise ArgumentError unless n.class == Fixnum && n >= 0
sprintf("%.#{n}f", self).to_f
end

def ceil_n(n=0)
raise FloatDomainError unless self.finite?
raise ArgumentError unless n.class == Fixnum && n >= 0
(self*10**n).ceil.to_f / 10**n
end

def floor_n(n=0)
raise FloatDomainError unless self.finite?
raise ArgumentError unless n.class == Fixnum && n >= 0
(self*10**n).floor.to_f / 10**n
end
end

However I can't help get the feeling that Ruby already has something
like this. Did I indeed miss it?

I don't know if this is what you want and I am thinking that there is
an easier way but this is pretty simple.

puts a=1.1568753256
puts digits=3
puts b=(a)*10**digits
puts c=(b).round
puts c.to_f/10**digits

Just my $0.02 worth,

Todd
 
T

Todd Gardner

David Garamond said:
I often do this:

class Float
def round_n(n=0)
raise FloatDomainError unless self.finite?
raise ArgumentError unless n.class == Fixnum && n >= 0
sprintf("%.#{n}f", self).to_f
end

def ceil_n(n=0)
raise FloatDomainError unless self.finite?
raise ArgumentError unless n.class == Fixnum && n >= 0
(self*10**n).ceil.to_f / 10**n
end

def floor_n(n=0)
raise FloatDomainError unless self.finite?
raise ArgumentError unless n.class == Fixnum && n >= 0
(self*10**n).floor.to_f / 10**n
end
end

However I can't help get the feeling that Ruby already has something
like this. Did I indeed miss it?

And you can combine the lines...

puts a=1.1568753256
puts digits=3
puts ((a).*10**digits).round.to_f/10**digits

Todd
 
M

Michael C. Libby

And you can combine the lines...

puts a=1.1568753256
puts digits=3
puts ((a).*10**digits).round.to_f/10**digits

That's the same technique he's using for ceil and floor-- seems like the
best approach available (the only thing left to do now is test whether
multiply and divide is faster than sprintf). Except that instead of
defining round_n, ceil_n, and floor_n, I would probably just redefine
the existing Float#round, Float#ceil and Float#floor methods. Because
he's got n=0 in the method signature existing code that depends on the
default behavior of Float should be fine.

It would be nice if Ruby had this type of thing built-in to those
commands, though.

-Michael Libby
 
C

Cai Li

David said:
I often do this:

class Float
def round_n(n=0)
raise FloatDomainError unless self.finite?
raise ArgumentError unless n.class == Fixnum && n >= 0
sprintf("%.#{n}f", self).to_f
end

def ceil_n(n=0)
raise FloatDomainError unless self.finite?
raise ArgumentError unless n.class == Fixnum && n >= 0
(self*10**n).ceil.to_f / 10**n
end

def floor_n(n=0)
raise FloatDomainError unless self.finite?
raise ArgumentError unless n.class == Fixnum && n >= 0
(self*10**n).floor.to_f / 10**n
end
end

However I can't help get the feeling that Ruby already has something
like this. Did I indeed miss it?
What I'm looking for in Ruby is a command causing all arithmetic to be
rounded to special digits.
Like we do in Matlab:
 
D

David Garamond

Michael said:
That's the same technique he's using for ceil and floor-- seems like the
best approach available (the only thing left to do now is test whether
multiply and divide is faster than sprintf). Except that instead of
defining round_n, ceil_n, and floor_n, I would probably just redefine
the existing Float#round, Float#ceil and Float#floor methods. Because
he's got n=0 in the method signature existing code that depends on the
default behavior of Float should be fine.

Btw, if you want to override #round, #ceil, #floor, remember to return a
Fixnum if n=0 to avoid breaking other code.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top