Veerasundaravel's Ruby on Rails Weblog

March 30, 2010

Ruby Float comparison issues

Filed under: Ruby — Tags: , , , , , , — Veerasundaravel @ 5:43 am

When I tried to compare a floating value expression, I got strange output like below

>> (1.2 – 1.0) == 0.2
>> false

Floating point numbers represent an extremely wide range of values – much wider than their integer counterparts. This is handled through an exponent and mantissa. For this ability, they trade off precision. Think about the case of adding a large floating point number to a small floating point number:

So assume if you are going to store money values as float means, you will loss the precision and it will give you false comparision. On this case use smallest denomination such as cents, and convert the cents to dollors in front end or use a custom Money column type.

We can use Decimal arithmetic which is also useful for general calculation, because it provides the correct comparision for these type of float numbers, where floating point arithmetic often introduces subtle errors because of the conversion between base 10 and base 2.

So, if you need to compare Floats and you are not receiving the expected response, you can use the BigDecimal class instead:

(BigDecimal.new(“1.2”) – BigDecimal(“1.0”)) == BigDecimal(“0.2”)

Advertisements

March 27, 2010

Better way of creating custom classes

Hi Everyone,

I tried to create one custom class and assign some attributes to that class object. Where I tried to build a custom class like below:

class Property
attr_accessor :id, :title, :description, :price
end

output:

property = Property.new
property.id = 1
property.title = ‘Flats near beach road’
property.price = ‘52522’
puts property.inspect
#<Property:0xb77c7290 @title=”Flats near beach road”, @id=1, @price=”52522″>

Oh its not good, for each attributes I’m running a separate assignment statements. But in active record you can create an object with assignment like below:

property = Property.new(:id=>1, :title=>”Flats near beach road”, :price=>’52522′)

So its need little change in your class Property, follow the below:

class Property

attr_accessor :id, :title, :description, :price
def initialize(attributes=nil)
return if attributes.nil?
attributes.each { |att,value| self.send(“#{att}=”, value) }
result = yield self if block_given?
result
end

end

property = Property.new(:id=>1, :title=>”Flats near beach road”, :price=>’52522′)
puts property.inspect
#<Property:0xb77c7290 @title=”Flats near beach road”, @id=1, @price=”52522″>

puts property.title #Flats near beach road
puts property.price #52522

%d bloggers like this: