Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting decimal to long while allowing overflow

Tags:

c#

.net

So I'm trying to do an unchecked casting of a decimal (which is used as a "holder" for any number, could be integers, could be floating point numbers, etc). Problem with C# is that it doesn't allow overflowing when converting a decimal to an integer type, even though overflow is acceptable and expected. The unchecked context only works for integer types, not for decimals, so I'm looking for the best way to achieve this.

Here's my current method (for Int32 as an example), and if you have any suggestions, please write it down.

    private static int ToInt32(decimal value)
    {
        if (value is < int.MinValue or > int.MaxValue)
        {
            decimal range = 1L + int.MaxValue - int.MinValue;
            value = ((((value - int.MinValue) % range) + range) % range) + int.MinValue;
        }
        return (int)value;
    }

With this, if I try to convert 2731498700m to an Int32, I'll get -1563468596 (instead of an OverflowException), which is exactly what I want.

like image 615
IgorEisberg Avatar asked Nov 02 '25 19:11

IgorEisberg


1 Answers

This is the fastest method I have found so far, based on the source of Decimal.ToInt32

private static int ToInt32(decimal value)
{
    Span<int> buffer = stackalloc int[4];
    decimal.GetBits(decimal.Truncate(value), buffer);
    return buffer[3] < 0 ? -buffer[0] : buffer[0];
}

Discovered a better method:

private static int ToInt32_1(decimal value)
    => (int)(Int128)value;
like image 120
shingo Avatar answered Nov 04 '25 10:11

shingo