How to express infinity in Ruby?
If you use ruby 1.9.2, you can use:
>> Float::INFINITY #=> Infinity
>> 3 < Float::INFINITY #=> true
Or you can create your own constant using the following*:
I've checked that in Ruby 1.8.6, 1.8.7, and 1.9.2 you have Float.infinite?.
PositiveInfinity = +1.0/0.0
=> Infinity
NegativeInfinity = -1.0/0.0
=> -Infinity
CompleteInfinity = NegativeInfinity..PositiveInfinity
=> -Infinity..Infinity
*I've verified this in Ruby 1.8.6 and 1.9.2
RoR: Is there a value for infinite?
Asked and answered here: How to express infinity in Ruby?
but the short of it is:
Float::INFINITY
Is there a way to express 'infinite time'?
It's possible using DateTime::Infinity
class:
future = DateTime.now..DateTime::Infinity.new
future.include?(1_000_000.years.from_now) #=> true
Why is Float::INFINITY == Float::INFINITY in Ruby?
In more technical terms, it all comes down to the IEEE 754 standard for floating-point arithmetics.
The IEEE 754 standard does implicitly define Infinity == Infinity to
be true. The relevant part of the standard is section 5.7: "Four
mutually exclusive relations are possible [between two IEEE 754
values]: less than, equal, greater than, and unordered. The last case
arises when at least one operand is NaN."Between any pair of floating point values exactly one of these four
relations is true. Therefore, since Infinity is not NaN, Infinity is
not unordered with respect to itself. Having one of (Infinity <
Infinity) and (Infinity > Infinity) be true wouldn't be consistent, so
(Infinity == Infinity).
This was taken from http://compilers.iecc.com/comparch/article/98-07-134
How to express Infinity in C in a ruby extension
I found the answer in this question.
rb_const_set(rb_mKernel, rb_intern("Infinity"), rb_float_new(INFINITY));
There are no compiler warnings for this.
For loop... Forever
You can use Numeric#step
without passing a limit:
0.step(by: 2) { |i| puts i }
Output:
0
2
4
6
...
You can also build your own Enumerator
:
step2 = Enumerator.new do |y|
a = 0
loop do
y << a
a += 2
end
end
step2.each { |i| puts i }
Geometric mean in Ruby returning Infinity for large arrays
Your value is overflowing what a Float
can hold. Instead consider using BigDecimal
:
require 'bigdecimal'
def gmean(x)
prod = BigDecimal.new 1
x.each { |v| prod *= BigDecimal.new(v) }
prod ** (1.0 / x.size)
end
gmean(sample_array2).to_f #=> 4711.148446895203
Note that your method can be simplified to a more functional style:
def gmean(xs)
one = BigDecimal.new 1
xs.map { |x| BigDecimal.new x }.inject(one, :*) ** (one / xs.size)
end
Problems with infinite time range in Rails
You cannot store Infinity as part of a time range in Rails. I believe this is because Infinity is going to be inserted as a string value and interpreted as a float when pulled out of the native PSQL oid. So, any date range from Date -> Float will not be viable. But you can manage to create your own range with pseudo (1 million years from now) dates or you can just use two separate date fields and interpret them appropriately in the model. Begin date, end date.
In Rails 4.2+, you can store a Float::INFINITY value inside your datetime type. Example.
User.first.update(begin_date: DateTime.now, end_date: 'infinity')
User.first.end_date # => Infinity
However, end_date
will not be a valid date. You're just storing the string in the database and you're pulling out a float when your call it.
Here's the actual (Rails 4.2) code that handles that:
module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module OID # :nodoc:
class DateTime < Type::DateTime # :nodoc:
include Infinity
def type_cast_for_database(value)
if has_precision? && value.acts_like?(:time) && value.year <= 0
bce_year = format("%04d", -value.year + 1)
super.sub(/^-?\d+/, bce_year) + " BC"
else
super
end
end
def cast_value(value)
if value.is_a?(::String)
case value
when 'infinity' then ::Float::INFINITY
when '-infinity' then -::Float::INFINITY
when / BC$/
astronomical_year = format("%04d", -value[/^\d+/].to_i + 1)
super(value.sub(/ BC$/, "").sub(/^\d+/, astronomical_year))
else
super
end
else
value
end
end
end
end
end
end
end
Again, you will not be able to do date time comparisons with a float. But, it's probably simple enough to have a special case for these two values -::Float::INFINITY
and ::Float::INFINITY
Can someone explain to me NaN in Ruby?
IEEE 754 floating point numbers define -INFINITY +INFINITY and NotANumber to make it possible to react to lets say division by zero. you can also calculate with these for eg 2 + INF = INF
NaN isn't a uniqe ruby feature, they are numeric in java, c++, ... too
Related Topics
Rails Form Validation Conditional Bypass
Rails - Local Variables Versus Instance Variables
How to Create a Hash in Ruby That Compares Strings, Ignoring Case
Heroku App Crash H10 - Bash: Bin/Rails: No Such File or Directory
How to Handle a Thread Issue in Zeromq + Ruby
Windows: Rails: Error Installing Bson_Ext
Downloading Existing Paypal Payments with Rest API
Removing a Model in Rails (Reverse of "Rails G Model Title...")
Switch Theme in an Existing Jekyll Installation
How to Ftp in Ruby Without First Saving the Text File
Is Ruby Really an Interpreted Language If All of Its Implementations Are Compiled into Bytecode
How to Create an Anchor and Redirect to This Specific Anchor in Ruby on Rails
Rails Date Format in Form Field
Heroku: Gemfile.Lock Is Required Issue
Cannot Login to Amazon with Ruby Mechanize