Infinite ranges in C#
Posted by Jonas Elfström Tue, 20 Oct 2009 18:41:00 GMT
I recently learned that C# is compliant with the IEEE 754-1985 for floating point arithmetics. That wasn't a big surprise but that division by zero is defined as Infinity
in it was! It actually kind of bothers me that I didn't know this.
In mathematics division by zero is undefined for real numbers but I guess Infinity
is a more pragmatic result. Or as a friend put it "IEEE stands for Institute of Electrical and Electronics Engineers not Institute of Mathematics"
1 2 3 4 |
double n = 1.0; n = n / 0; if (n > 636413622384679305) System.Console.WriteLine("Yes it certainly is!"); |
This C# code does not throw an exception, it simply leaves n defined as Infinity and writes a line to the console.
Ruby is also IEEE 754-1985 compliant. It even lets you define infinite ranges.
1 2 3 4 5 6 |
Infinity=1.0/0 =>Infinity (1..Infinity).include?(162259276829213363391578010288127) => true (7..Infinity).step(7).take(3).inject(&:+) # 7+14+21 => 42 |
I can't say I see very much use of this but it brings a kind of completeness to the handling of infinities. Unfortunately it seems we don't get that in C# out of the box because Enumerable.Range
takes <int>,<int>
as parameters and there's no Infinity
definition for int
. That's unless someone wrote a generic Range class. Turns out none other than Jon Skeet did in his MiscUtil. Download MiscUtil and then by using MiscUtil.Collections;
you can:
1 2 3 4 5 6 |
double n = 1.0; var infinity = n / 0; var r = new Range<double>(0, infinity); if (r.Contains(4711)) System.Console.WriteLine("Yes it certainly does!"); var sum = r.Step(7.0).Take(3).Sum(); |
And guess what, it works like a charm! 4711
is part of positive infinity and sum
is 42.0 and all is good.
Edit
There's also a couple of predefined constants. Thanks to Eric for pointing that out.
1 2 |
var r = new Range<double>(7, System.Double.PositiveInfinity); var sum = r.Step(7.0).Take(3).Sum(); |
Nice!
Of course you could just use the predefined constants System.Double.PositiveInfinity and System.Double.NegativeInfinity; no need to define your own.
In Ruby 1.9.2 we got Float::INFINITY