如何表示整数无穷大?

Con*_*cer 23 c# infinity

我需要一种方法来表示一个可以是无限的整数.我不想使用浮点类型(double.PositiveInfinity),因为数字永远不会是小数,这可能会使API混乱.做这个的最好方式是什么?

编辑:我还没有看到的一个想法是使用int?null表示无穷大.有没有充分的理由不这样做?

Sma*_*ker 27

如果不需要全范围的整数值,可以使用int.MaxValueint.MinValue常量来表示无穷大.

但是,如果需要全范围的值,我建议创建一个包装类或者只是为了双打.

  • 为了完成这项工作 - 或任何无限的概念 - 你必须实现隐式运算符来检查无限操作数并相应地采取行动. (4认同)
  • @SLaks OP没有指定执行算术的任何内容,而是表示API中的无穷大. (3认同)
  • 这不会保留减法. (2认同)

Jac*_*ack 5

根据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);
Run Code Online (Sandbox Code Playgroud)

实现方式:

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 */
}
Run Code Online (Sandbox Code Playgroud)