【问题标题】:Use maxvalue if result too large for int如果结果对于 int 来说太大,则使用 maxvalue
【发布时间】:2016-05-19 06:33:06
【问题描述】:

当 int 超出范围时,C# 中有没有办法使用 maxvalue。 出于我的目的,我不能使用很长的时间。

例子

int a = 842673832;
int b = 2131231321;

int t = a * b;
//if t out of range, t = Int32.MinValue;

【问题讨论】:

  • 您能解释一下有哪些限制吗?比如,你的“目的”是什么?
  • 我不是 C# 程序员,但我认为在这种情况下,您可能可以在其中使用带有逻辑的条件。如果您希望它紧凑,可以使用三元运算符。
  • 我正在使用旧系统,无法对系统进行较大的更改。

标签: c# int


【解决方案1】:

您需要事先对其进行测试或创建very special kind of integer(如链接中的CheckedInt)。

选项 A

要事先对其进行测试,您需要一种可以处理大整数值的数据类型(例如,long):

long t = (long)a * b;
int r = t > int.MaxValue ? int.MaxValue : t < int.MinValue ? : int.MinValue : (int)t;

选项 B

要使用特殊类型的整数,您可能还需要重载基本运算符。

在链接中的示例中,抛出了异常,但您可以将异常更改为实现int.MaxValueint.MinValue,如下所示:

public struct CheckedInt {
    private int Value { get; set; }
    public CheckedInt(int value)
        : this() {
        Value = value;
    }

    public static implicit operator CheckedInt(int me) {
        return new CheckedInt(me);
    }

    public static CheckedInt operator +(CheckedInt lhs, CheckedInt rhs) {
        double testResult = (double)lhs.Value + (double)rhs.Value;
        if (testResult > int.MaxValue)
            return int.MaxValue;
        if (testResult < int.MinValue)
            return int.MinValue; 
        return new CheckedInt(lhs.Value + rhs.Value); //note that direct lhs+rhs will cause StackOverflow
    }

    public static CheckedInt operator -(CheckedInt lhs, CheckedInt rhs) {
        double testResult = (double)lhs.Value - (double)rhs.Value;
        if (testResult > int.MaxValue)
            return int.MaxValue;
        if (testResult < int.MinValue)
            return int.MinValue; 
        return new CheckedInt(lhs.Value - rhs.Value); //note that direct lhs-rhs will cause StackOverflow
    }

    public static CheckedInt operator *(CheckedInt lhs, CheckedInt rhs) {
        double testResult = (double)lhs.Value * (double)rhs.Value;
        if (testResult > int.MaxValue)
            return int.MaxValue;
        if (testResult < int.MinValue)
            return int.MinValue; 
        return new CheckedInt(lhs.Value * rhs.Value); //note that direct lhs*rhs will cause StackOverflow
    }

    public static CheckedInt operator /(CheckedInt lhs, CheckedInt rhs) {
        double testResult = (double)lhs.Value / (double)rhs.Value;
        if (testResult > int.MaxValue)
            return int.MaxValue;
        if (testResult < int.MinValue)
            return int.MinValue; 
        return new CheckedInt(lhs.Value / rhs.Value); //note that direct lhs-rhs will cause StackOverflow
    }

    //Add any other overload that you want

    public override string ToString() { //example
        return Value.ToString();
    }

    public bool Equals(CheckedInt otherInt) { //example
        return Value == otherInt.Value;
    }
}

【讨论】:

  • 感谢您的回答
【解决方案2】:

你可以通过启用overflow checking来试试这个

int t;

try
{
   int a = 842673832;
   int b = 2131231321;

   t = checked(a * b);
}
catch (System.OverflowException e)
{
   t = Int32.MaxValue;
}

【讨论】:

    【解决方案3】:

    如果您希望 t 成为 int 而不是像 Ian 的答案那样更大的类型,您可以在 OverflowException 处找到并将 t 设置为 MaxValue。确保将该部分包含在 checked 关键字中以允许溢出检查。

    int t = 0;
    checked {
        try 
        {
            int a = 842673832;
            int b = 2131231321;
    
            t = a * b;
        }
        catch (OverflowException) 
        {
            t = int.MaxValue;
        }
    }
    

    【讨论】:

    • @DavidPilkington 啊,我一定错过了checked 关键字。我已经更新了我的答案。
    猜你喜欢
    • 1970-01-01
    • 2014-08-06
    • 1970-01-01
    • 2020-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多