确定使用整数上的Func检查操作是否导致溢出或下溢?

时间:2015-11-17 18:00:46

标签: c#

我很难确定使用checked的{​​{1}}上的int操作是否导致上溢或下溢。如果我不使用Func<int, int>我找到了确定此方法的方法

Func<int, int>

虽然如果我使用int _Data = Data; // Data is some integer value int scaleValue = int.MaxValue; // Just for completion, could be any value try { checked { Data *= scaleValue; } } catch (System.OverflowException ex) { // Cast the values to float so we can operate beyond the integer range // This way we can check if we went over Max or Min Values if ((float)_Data * (float)scaleValue > int.MaxValue) Data = int.MaxValue; else Data = int.MinValue; } ,那么我就无法使用上面的技巧来确定结果。

Func<int, int>

我看到的唯一选择是“更改”给定int _Data = Data; Func<int, int> scaleFunction = (x) => (x * int.MaxValue); try { checked { Data = scaleFunction(Data); } } catch (System.OverflowException ex) { // How to tell if scaleFunction created under or over flow? if ((float)_Data * (float)scaleValue > int.MaxValue) Data = int.MaxValue; else Data = int.MinValue; } 以便Func<int, int>工作,但如果float的结构未知,那么我不认为它可以改变。

任何人都可以通过偷偷摸摸的方式来实现这一目标吗?

这是我找到原始偷偷摸摸的操作的主题:Determine if integer overflow is over or under bounds

这是我之前提到的一个相关问题,它提供了更多背景知识:Determine if operation will result in overflow?

编辑:在我对此代码的使用中,我无法控制Func<int, int>的创建方式。因此,我不能在其中放置Func<int, int>表达式或阻止它。

我也没有意识到check没有检查其中使用的“内部函数”溢出。如果是这样,我认为这个问题要困难得多。由于无法修改check以使用Func,我们必须手动进行检查。

手工操作的问题在于(目前对我来说) 似乎不可能 。使用检查原始值是否与check的输出值具有相同符号的技巧可能是有意义的。问题是,您无法判断Func是否非法地增加了超过最大值的值,或者是否合法地将值降低到0以下;或者反之亦然。

2 个答案:

答案 0 :(得分:4)

  

在我对这段代码的使用中,我无法控制Func的创建方式。因此,我无法在其中放置检查表达式或阻止它。

然后,你输了。

checked/unchecked是IL级别的任何单个算术指令的属性。它不会跨越方法调用。它不是可以打开或关闭的设置。它分别编译为每个指令的.NET二进制文件。

任何一段代码的作者都会决定checked属性,并且不能更改。

事实上,如果你能够达到其他人的代码并巧妙地改变基本算术指令的行为,那将是危险和不可靠的。

答案 1 :(得分:1)

checked块或表达式(两种口味都存在并且具有相同的效果)不是&#34;继承&#34;通过调用方法,所以你的lambda实际上在未经检查的上下文中成倍增加。

请尝试以下方法:

int _Data = Data;
Func<int, int> scaleFunction = (x) => checked(x * int.MaxValue);
try 
{ 
    Data = scaleFunction(Data); 
} 
catch (System.OverflowException ex)
{
    // handle overflow...
}