我需要一种方法来表示一个可以是无限的整数。我不想使用浮点类型(double.PositiveInfinity),因为数字永远不会是小数,这可能会使API混乱。这样做的最佳方式是什么?
编辑:我还没有看到的一个想法是使用int? null表示无穷大。有没有很好的理由不这样做?
答案 0 :(得分:24)
如果您不需要全范围的整数值,则可以使用int.MaxValue
和int.MinValue
常量来表示无穷大。
但是,如果需要全范围的值,我建议创建一个包装类或者只是为了双打。
答案 1 :(得分:4)
示例部分实现,与SLaks和其他人的评论一致(欢迎反馈):
<强>用法:强>
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);
<强>实施强>
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 :(得分:1)
您的API可以使用int.MaxValue
表示正无穷大值和int.MinValue
- 负无穷大的约定。
但是你仍然需要在某处记录它,可能你需要使用无限整数进行一些操作:
/// <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;
}
}
答案 3 :(得分:1)
另一部分实施(我看杰克更快):
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
}
答案 4 :(得分:-3)
C#有一个类型,BigInteger类是无限大小
http://msdn.microsoft.com/en-us/library/system.numerics.biginteger.aspx
如果你希望类具有无穷大的表示 - 那么将BigInteger包装在一个给它一个无穷大标志的类中。
您必须重新定义所有标准运算符和转换才能使其生效。
如何对无限工作进行操作取决于您的域名。
(例如,在某些形式的数学中,你希望2 x无穷大=无穷大而有些你不喜欢)。
细节的实施方式实际上取决于您的域名问题,而且您的问题并不清楚。