Skip to content

Instantly share code, notes, and snippets.

@LOZORD
Created July 16, 2014 04:36
Show Gist options
  • Save LOZORD/34ae90562e09acee66b4 to your computer and use it in GitHub Desktop.
Save LOZORD/34ae90562e09acee66b4 to your computer and use it in GitHub Desktop.
A Rigorous Sign Determining Algorithm For Real Rational Numbers
# implemented for all real rational numbers
class Float
# determine if a real rational number is zero
# we know a number is zero if one cannot divide another by it
def _is_zero_?
begin
# need to check for any non-zero number
# we might as well put pi in the cache
x = Math::PI.ceil
temp = Random.new.rand(-x..x)
# there is a chance that temp will be zero
# of course, we cannot calculate 0/0
temp += Math::PI if temp.zero?
# now test if this number is zero
# first divide by it
y = temp/self
# otherwise, if the answer is infinity
raise ZeroDivisionError if y == Float::INFINITY
# finally, if the number resembles a zero-like entity
raise ZeroDivisionError if self.to_s.match(/\A(0)+(\.(0)+)?\z/)
rescue ZeroDivisionError
# since you cannot divide with it
# this number must be zero
# (or one of the other two stmts were true)
return true
else
# it is not zero
return false
end
end
# determine if a real rational number is negative
def _is_negative_?
# easy base case (zero is neither negative nor positive)
return false if self._is_zero_?
# examine the angle it makes in the complex 2D plane
angle = self.to_c.angle
# need to find the difference between the mirrored complex vectors
temp = (self.to_c - self.to_c.conj).to_i
# calculate the boundary to find the region in the complex 2D plane where
# the component of the vector becomes negative, scaled back by the
# previously calculated difference (add one to get the ceiling)
# luckily, we have already cached the value of pi,
# so this should be a speedy calculation
pi_floor = (temp + 1) * (Math::PI).floor
# compare the angle to the complex 2D plane boundary
result = angle <=> pi_floor
# result will be 0 if this is a complex number
# --> we are only allowing real rational numbers
puts 'THIS SHOULD NEVER HAPPEN' if result._is_zero_?
# result will be -1 if positive (angle == 0)
# result will be 1 if negative ( [angle == 3.14...] > [floor(3.14...)] )
# use the limit process to determine which direction zero is
# if we are close to zero,
# return the sign of result from our complex plane analysis
# otherwise, continue the limit on the complex plane as the number goes to zero
if ((self+result).floor._is_zero_?)
return (result >= 0)
else
return (self+result)._is_negative_?
end
end
end
# allow discrete integers to have the same methods
class Fixnum
def _is_zero_?
self.to_f._is_zero_?
end
def _is_negative_?
self.to_f._is_negative_?
end
end
# TESTER SCRIPT
puts 'START TEST'
range = 2
(-range..range).each do |i|
neg_res = i._is_negative_?
puts "#{i} is negative? #{neg_res}"
end
puts '** Zero Test **'
puts '0 is zero?'
puts 0._is_zero_?
puts '0 is negative?'
puts 0._is_negative_?
puts '** Decimal Test **'
puts '3.14 is negative?'
puts 3.14._is_negative_?
puts '-41.3 is negative?'
puts -41.3._is_negative_?
puts 'END TEST'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment