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.
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With