确定是否整数溢出高于或低于界限(Determine if integer overflow is o

2019-10-17 23:51发布

使用C# ,我有,我需要能够检测整数溢出,并返回一个默认的最小或取决于如果溢出是最大值,由于结果是超过最大值或低于最小值几个自定义类。 我似乎无法找到如何检测到任何地方发生溢出的“类型”的建议。

使用符号值的,以及使用无符号值的:这些类两种类型之间的分歧。

作为一个例子,这里是与Int32值交易的类别之一:

public class Stat32Tf : IStat32T<float>
{
    #region fields

    private int baseValue, baseAdjustment;
    private float baseMultiplier;

    #endregion

    #region ctors

    public Stat32Tf()
    {
        baseValue = 0;
        baseAdjustment = 0;
        baseMultiplier = 1f;
    }

    public Stat32Tf(int baseValue, int baseAdjustment = 0, float baseMultiplier = 1f)
    {
        this.baseValue = baseValue;
        this.baseAdjustment = baseAdjustment;
        this.baseMultiplier = baseMultiplier;
    }

    #endregion

    #region properties

    public int BaseValue
    {
        get 
        { 
            return baseValue; 
        }
        set 
        {
            baseValue = value; 
        }
    }

    public int BaseAdjustment
    {
        get 
        { 
            return baseAdjustment; 
        }
        set 
        { 
            baseAdjustment = value; 
        }
    }

    public float BaseMultiplier
    {
        get 
        { 
            return BaseMultiplier; 
        }
        set 
        { 
            baseMultiplier = value; 
        }
    }

    public int TruncValue
    {
        get 
        { 
            return (int)Value; 
        }
    }

    public float Value
    {
        get 
        { 
            return (baseValue + baseAdjustment) * baseMultiplier; 
        }
    }

    #endregion

}

正如你所看到的,阶级的思想是保持基本值,调整值,并乘数值,并在Value属性返回的总价值。 (该TruncValue属性只是,因为它表明,返回截短整个值,丢弃任何分数值)。

我们的目标是处理溢出,在Value属性的“得到”访问,如果结果超过最大int值,返回int.MaxValue如果它是最小值下,返回int.MinValue,都没有抛实际的溢出错误。 该计划使棘手对我来说,一部分是调整值和乘数可能是负值,以及(根据设计要求)。

什么是安全的方式来实现这一目标? 我一直没能找到解决这种情况的任何资源。 我猜某种运算算法的需要来确定的结果将是过高或过低。

Answer 1:

花车是相当大的。 你期待的get值溢出,或者你希望剧组为int溢出? 如果它只是类似于下面的代码中投的东西可能会奏效。

//This answer is wrong, see below.
public int TruncValue
{
    get
    {
        if (Value > (float)int.MaxValue)
        {
            return int.MaxValue
        }
        else if (Value < (float)int.MinValue)
        {
            return int.MinValue
        }
        else
        {
            return (int)Value;
        }
    }
}

虽然你可能需要对边缘情况下,一些额外的处理。

编辑 - 我与这一些代码起到了一圈,发现一些行为,我没想到,但显然它是在规范。

例如,

var Value = int.MaxValue + int.MaxValue //Ends up returning -2 with no exception in debug mode.
var MaxCalculatedValue = (int.MaxValue + int.MaxValue) * float.MaxValue //Ends up returning something like -3.4... ^38.

你真的可能需要放弃一切铸成double,然后检查是否结果比int大于或小于。

因此,它可能是这个样子:

public float Value
{
    get
    {
        var result = ((double)baseValue + (double)baseAdjustment) * (double)baseMultiplier;
        if (result > (double)int.MaxValue)
        {
           return (float)int.MaxValue)
        }
        if (result < (double)int.MinValue)
        {
           return (float)int.MinValue)
        }
        return (float)result;
    }
}


Answer 2:

只有那里可以下溢案件数量有限:

  • 如果baseValue和baseAdjustment都为负 - >如果Int.MinValue - baseAdjustment> baseValue那么你有一个溢。

  • 如果baseValue + baseAjustment为负,baseMultiplier是肯定的 - >如果溢出异常上升,那么它只能是下溢。

  • 如果baseValue + baseAdjustment是肯定的,但baseMultiplier为负 - >如果溢出异常上升,那么它只能是下溢。

如果你想避免引发/捕获异常,那么它可能是一个比较复杂(你可能想投的结果,只要然后将其与Int.MaxValue;这样,如果结果越过它只会引发异常Long.MaxValue)。



文章来源: Determine if integer overflow is over or under bounds