Determine if the validated operation using Func on integers resulted in overflow or threading?

It is difficult for me to determine if an operation checked

on int

using was Func<int, int>

causing an overflow or an inadmissibility. If i don't use Func<int, int>

i found a way to define this

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;
}

      

Although if I use Func<int, int>

, then I cannot use my trick above to determine the result.

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;
}

      

The only option I see is to "change" the one given Func<int, int>

to work with float

, but if the structure is Func<int, int>

unknown before, I don't think it can be changed.

Can anyone see a hidden way to do this?

This is the thread where I found the original fake operation: Determine if an integer overflow is over or under a boundary

A related question I asked earlier gives a few more premises: Determine if the operation will overflow?

EDIT: In my use of this code, I have no control over the way it is created Func<int, int>

. This way I cannot express the expression check

or block inside it.

I also didn't realize that it check

didn't overflow the "internal functions" that it used. If so, I think the problem is much more complicated. As a result of the inability to change Func

to use, check

we have to perform a manual check.

The problem with doing this manually is that it (to me at the moment) seems impossible . It might make sense to use the trick of checking if the original value has the same sign as the output value from Func

. The problem is that you cannot determine if you Func

increased the value for max illegally or decreased the value below 0 legally; or vice versa.

+3
c #


source to share


2 answers


In my use of this code, I have no control over how the Func is created. This way I cannot put a test expression or block it inside.

Then you are lost.

checked/unchecked

is a property of any individual arithmetic instruction at the IL level. It doesn't flow through method calls. This is not a setting that you can turn on or off. It is compiled to a .NET binary for each command separately.



The author of any part of the code decides the property checked

and cannot be changed.

In fact, it would be dangerous and unreliable if you could penetrate the code of other peoples and subtly change the behavior of basic arithmetic instructions.

+4


source to share


checked

blocks or expressions (both flavors exist and have the same effects) are not inherited by called methods, so your lambda is actually multiplying in an unchecked context.

Try this instead:



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

      

+1


source to share







All Articles