Skip to content

Instantly share code, notes, and snippets.

@ajlai
Last active December 21, 2015 07:48
Show Gist options
  • Save ajlai/6273601 to your computer and use it in GitHub Desktop.
Save ajlai/6273601 to your computer and use it in GitHub Desktop.
Ruby rounds_to? Allows for a rough equality check to an implicit precision provided by the input `numeric` argument
class Numeric
# Returns true if for any i, self.round(i) == numeric
#
# Usage:
#
# 149.835.rounds_to?(0) #=> true
# 149.835.rounds_to?(100) #=> true
# 149.835.rounds_to?(150) #=> true
# 149.835.rounds_to?(149.8) #=> true
# 149.835.rounds_to?(149.84) #=> true
# 149.835.rounds_to?(149.835) #=> true
#
def rounds_to?(numeric)
return true if self == numeric || zero?
diff = (self - numeric).abs
round(-diff.order_of_magnitude - 1) == numeric
end
# See http://en.wikipedia.org/wiki/Order_of_magnitude (Order of magnitude of a number)
#
# Usage:
#
# 100.order_of_magnitude #=> 2
# 10.order_of_magnitude #=> 1
# 1.order_of_magnitude #=> 0
# 0.order_of_magnitude #=> 0
# 0.1.order_of_magnitude #=> -1
# 0.01.order_of_magnitude #=> -2
#
def order_of_magnitude
zero? ? 0 : Math.log10(abs).floor
end
end
require 'rspec/expectations'
# Made as a simpler to use specific case implemention of https://www.relishapp.com/rspec/rspec-expectations/v/2-14/docs/built-in-matchers/be-within-matcher
#
# Usage:
#
# describe 149.835 do
# it { should round_to(149.84) }
# end
#
# # deliberate failure
# describe 149.835 do
# it { should round_to(149) }
# end
# #=> expected 149.835 to round to 149
#
RSpec::Matchers.define :round_to do |numeric|
match do |actual|
actual.rounds_to?(numeric)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment