36

I need a way to represent an integer number that can be infinite. I'd prefer not to use a floating point type (double.PositiveInfinity) since the number can never be fractional and this might make the API confusing. What is the best way to do this?

Edit: One idea I haven't seen yet is using int? with null representing infinity. Are there any good reasons not to do this?

13
  • 14
    Make a wrapper type with an infinity flag. Commented Jan 23, 2014 at 15:14
  • 1
    And that wrapper type could hold just one int internally. Under the convention that int.MaxValue represented not itself, but infinity. Commented Jan 23, 2014 at 15:16
  • 2
    Make a Nullable<int> and treat the value null as infinite. Commented Jan 23, 2014 at 15:17
  • 1
    what happens when you subtract 1? OutOfMemoryException? Commented Jan 23, 2014 at 15:17
  • 5
    @MrLister, there are a lot of integer values between double.MaxValue and infinity. An infinite amount infact. Commented Jan 23, 2014 at 15:20

5 Answers 5

48

If you don't need the full range of integer values, you can use the int.MaxValue and int.MinValue constants to represent infinities.

However, if the full range of values is required, I'd suggest either creating a wrapper class or simply going for doubles.

Sign up to request clarification or add additional context in comments.

5 Comments

That will not preserve subtraction.
Was about to offer the same idea in the comment. Btw, he will need a wrapper, because 1 / 0 = DivideByZeroException =D
@SLaks You shouldn't try to add or subtract from infinity anyway.
@SLaks OP didn't specify anything about performing arithmetic, but rather to represent infinities in an API.
In order to make that work -- or any concept of infinity, for that matter -- you'd have to implement implicit operators that check for infinite operands and act accordingly.
6

An example partial implementation along the lines of the comments of SLaks and others (feedback welcome):

Usage:

int x = 4; iint pi = iint.PositiveInfinity; iint ni = iint.NegativeInfinity; Assert.IsTrue(x + pi == iint.PositiveInfinity); Assert.IsTrue(pi + 1 == iint.PositiveInfinity); Assert.IsTrue(pi + (-ni) == iint.PositiveInfinity); Assert.IsTrue((int)((iint)5) == 5); 

Implementation:

public struct iint { private readonly int _int; public iint(int value) { if(value == int.MaxValue || value == int.MinValue) throw new InvalidOperationException("min/max value reserved in iint"); _int = value; } public static explicit operator int(iint @this) { if(@this._int == int.MaxValue || @this._int == int.MinValue) throw new InvalidOperationException("cannot implicit convert infinite iint to int"); return @this._int; } public static implicit operator iint(int other) { if(other == int.MaxValue || other == int.MinValue) throw new InvalidOperationException("cannot implicit convert max-value into to iint"); return new iint(other); } public bool IsPositiveInfinity {get { return _int == int.MaxValue; } } public bool IsNegativeInfinity { get { return _int == int.MinValue; } } private iint(bool positive) { if (positive) _int = int.MaxValue; else _int = int.MinValue; } public static readonly iint PositiveInfinity = new iint(true); public static readonly iint NegativeInfinity = new iint(false); public static bool operator ==(iint a, iint b) { return a._int == b._int; } public static bool operator !=(iint a, iint b) { return a._int != b._int; } public static iint operator +(iint a, iint b) { if (a.IsPositiveInfinity && b.IsNegativeInfinity) throw new InvalidOperationException(); if (b.IsPositiveInfinity && a.IsNegativeInfinity) throw new InvalidOperationException(); if (a.IsPositiveInfinity) return PositiveInfinity; if (a.IsNegativeInfinity) return NegativeInfinity; if (b.IsPositiveInfinity) return PositiveInfinity; if (b.IsNegativeInfinity) return NegativeInfinity; return a._int + b._int; } public static iint operator -(iint a, iint b) { if (a.IsPositiveInfinity && b.IsPositiveInfinity) throw new InvalidOperationException(); if (a.IsNegativeInfinity && b.IsNegativeInfinity) throw new InvalidOperationException(); if (a.IsPositiveInfinity) return PositiveInfinity; if (a.IsNegativeInfinity) return NegativeInfinity; if (b.IsPositiveInfinity) return NegativeInfinity; if (b.IsNegativeInfinity) return PositiveInfinity; return a._int - b._int; } public static iint operator -(iint a) { if (a.IsNegativeInfinity) return PositiveInfinity; if (a.IsPositiveInfinity) return NegativeInfinity; return -a; } /* etc... */ /* other operators here */ } 

2 Comments

Upvoted. While you were posting this, I was writing very similar code (see my answer).
One issue I see (I guess there are issues in my post as well!) is that the sum of say 2,000,000,000 and 2,000,000,000 will "wrap-around" to a negative result. I would expect PositiveInfinity in that case.
1

Your API can use a convention that int.MaxValue represents positive infinity value and int.MinValue - negative infinity.

But you still need to document it somewhere and, may be you will need some operations with your infinite integer:

 /// <summary> /// Making int infinity /// ... /// </summary> public static class IntExtension { public const int PositiveInfinity = int.MaxValue; public const int NegativeInfinity = int.MinValue; public static bool IsPositiveInfinity(this int x) { return x == PositiveInfinity; } public static bool IsNegativeInfinity(this int x) { return x == NegativeInfinity; } public static int Operation(this int x, int y) { // ... return PositiveInfinity; } } 

2 Comments

PositiveInfinity / PositiveInfinity != 1 math.stackexchange.com/questions/181304/…
@Jodrell Yes, but this question is not about how to implement operations with infinities. Representing is the only task
1

Another partial implementation (I see Jack was faster):

struct InfinityInt { readonly int Value; InfinityInt(int value, bool allowInfinities) { if (!allowInfinities && (value == int.MinValue || value == int.MaxValue)) throw new ArgumentOutOfRangeException("value"); Value = value; } public InfinityInt(int value) : this(value, false) { } public static InfinityInt PositiveInfinity = new InfinityInt(int.MaxValue, true); public static InfinityInt NegativeInfinity = new InfinityInt(int.MinValue, true); public bool IsAnInfinity { get { return Value == int.MaxValue || Value == int.MinValue; } } public override string ToString() { if (Value == int.MinValue) return double.NegativeInfinity.ToString(); if (Value == int.MaxValue) return double.PositiveInfinity.ToString(); return Value.ToString(); } public static explicit operator int(InfinityInt ii) { if (ii.IsAnInfinity) throw new OverflowException(); return ii.Value; } public static explicit operator double(InfinityInt ii) { if (ii.Value == int.MinValue) return double.NegativeInfinity; if (ii.Value == int.MaxValue) return double.PositiveInfinity; return ii.Value; } public static explicit operator InfinityInt(int i) { return new InfinityInt(i); // can throw } public static explicit operator InfinityInt(double d) { if (double.IsNaN(d)) throw new ArgumentException("NaN not supported", "d"); if (d >= int.MaxValue) return PositiveInfinity; if (d <= int.MinValue) return NegativeInfinity; return new InfinityInt((int)d); } static InfinityInt FromLongSafely(long x) { if (x >= int.MaxValue) return PositiveInfinity; if (x <= int.MinValue) return NegativeInfinity; return new InfinityInt((int)x); } public static InfinityInt operator +(InfinityInt a, InfinityInt b) { if (a.IsAnInfinity || b.IsAnInfinity) { if (!b.IsAnInfinity) return a; if (!a.IsAnInfinity) return b; if (a.Value == b.Value) return a; throw new ArithmeticException("Undefined"); } return FromLongSafely((long)a.Value + (long)b.Value); } public static InfinityInt operator *(InfinityInt a, InfinityInt b) { if (a.IsAnInfinity || b.IsAnInfinity) { if (a.Value == 0 || b.Value == 0) throw new ArithmeticException("Undefined"); return (a.Value > 0) == (b.Value > 0) ? PositiveInfinity : NegativeInfinity; } return FromLongSafely((long)a.Value * (long)b.Value); } // and so on, and so on } 

Comments

-3

C# has a type for this the BigInteger class is unlimited size

http://msdn.microsoft.com/en-us/library/system.numerics.biginteger.aspx

If you want the class to have a representation of infinity -- then wrap BigInteger in a class that gives it an infinity flag.

You will have to redefine all standard operators and conversions to get this to work.

How exactly to have operations on infinity work depends on your domain.

(For example in some forms of math you would like 2 x infinity = infinity and in some you don't).

How the details are implemented really depend on your domain problem and are not clear from your question.

6 Comments

No, a BigInteger cannot hold the specific value "infinite".
BigInteger can hold the whole valid range of int plus extra. Where some of extra can be infinite (to example, any value higher than int.MaxValue + 1are Infinite). Still a care should be made than using such Infinity in calculations +Infinity - 2 = int.MaxValue - 1, while it should still stay Infinity somehow.
There are a variety of BigInteger classes around, on CodePlex, CodeProject, etc, and one from MS in System.Numerics. The MS one doesn't have an Infinity flag. What quality the others are I don't know, but given most of them operate on a string representation of a number they will not be fast.
@JeppeStigNielsen, is infinite a specific value?
@Sinatr - my point was that those functions need to added to your class to support the domain
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.