【发布时间】:2015-11-18 04:44:35
【问题描述】:
我很难确定使用Func<int, int> 对int 进行的checked 操作是否会导致上溢或下溢。如果我不使用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 上工作,但如果事先不知道Func<int, int> 的结构,那么我认为它不能改变。
谁能看到一个偷偷摸摸的方法来完成这个?
这是我发现原始偷偷摸摸操作的线程:Determine if integer overflow is over or under bounds
这是我之前提出的一个相关问题,提供了更多背景信息:Determine if operation will result in overflow?
编辑:在我使用此代码时,我无法控制 Func<int, int> 的创建方式。因此,我不能在其中放置 check 表达式或将其阻塞。
我也没有意识到check 不会检查其中使用的溢出“内部函数”。如果是这样,我认为这个问题要困难得多。由于无法将Func 修改为使用check,我们必须手动进行检查。
手工操作的问题是它(目前对我来说)似乎不可能。使用检查原始值是否与Func 的输出值具有相同符号的技巧可能是有意义的。问题是您无法判断 Func 是否非法将值增加到超过最大值,或者是否合法地将值减小到 0 以下;反之亦然。
【问题讨论】:
-
你应该把 check 放在 lambda 里面。像这样
x => { checked { return x*int.MaxValue; } };你能改变功能吗? -
@M.kazemAkhgary 你甚至可以通过使用
checked表达式而不是checked块来编写更简单的代码:x => checked(x * int.MaxValue) -
同样,当对 int 的操作不溢出时,并不意味着它下溢。尽管在这两种情况下运行时都会引发溢出异常。但是您可以假设当结果小于
int.MinValue时,它会下溢。你也必须检查下溢。而不是else ....你应该这样做else if ((double)_Data * (double)scaleValue < int.MinValue) .... -
@M.kazemAkhgary 所以
check块只会在操作溢出时抛出OverflowException而不会为下溢抛出一个? -
在测试后似乎在任何一种情况下都会抛出
OverflowException。因此,如果已检查的块引发异常,则只有两种情况超出或不足。检查一个案例,发现它是假的,一定意味着另一个案例是真的。
标签: c#