Skip to content

Commit

Permalink
Throw OverflowException rather than ArithmeticException - better defi… (
Browse files Browse the repository at this point in the history
#39)

* Throw OverflowException rather than ArithmeticException - better defined exception should be thrown

* simplify

* fix
  • Loading branch information
LukaszRozmej authored Jan 23, 2024
1 parent 437c8ad commit 4cfbf69
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 120 deletions.
16 changes: 8 additions & 8 deletions src/Nethermind.Int256.Test/UInt256Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public virtual void Subtract((BigInteger A, BigInteger B) test)

resUInt256.Should().Be(resBigInt);
}

[TestCaseSource(typeof(TernaryOps), nameof(TernaryOps.TestCases))]
public virtual void SubtractMod((BigInteger A, BigInteger B, BigInteger M) test)
{
Expand Down Expand Up @@ -162,7 +162,7 @@ public virtual void SubtractOverflow((BigInteger A, BigInteger B) test)
if (uint256a is UInt256 a && uint256b is UInt256 b)
{
a.Invoking(y => y - b)
.Should().Throw<ArithmeticException>()
.Should().Throw<OverflowException>()
.WithMessage($"Underflow in subtraction {a} - {b}");
}
else
Expand Down Expand Up @@ -224,7 +224,7 @@ public virtual void Div((BigInteger A, BigInteger B) test)

resUInt256.Should().Be(resBigInt);
}

[TestCaseSource(typeof(BinaryOps), nameof(BinaryOps.TestCases))]
public virtual void And((BigInteger A, BigInteger B) test)
{
Expand Down Expand Up @@ -412,21 +412,21 @@ public virtual void Max_value_is_correct()
{
convert(1).MaximalValue.Should().Be(convert(maxValue));
}

[Test]
public virtual void ToBigEndian_And_Back()
{
byte[] bidEndian = convert(1000000000000000000).ToBigEndian();
new UInt256(bidEndian, true).Should().Be(convert(1000000000000000000));
}

[Test]
public virtual void ToLittleEndian_And_Back()
{
byte[] bidEndian = convert(1000000000000000000).ToLittleEndian();
new UInt256(bidEndian).Should().Be(convert(1000000000000000000));
}

[Test]
public virtual void Check_For_Correct_Big_And_Little_Endian()
{
Expand All @@ -436,14 +436,14 @@ public virtual void Check_For_Correct_Big_And_Little_Endian()
0, 0
};
convert(1000000000000000000).ToBigEndian().Should().BeEquivalentTo(bigEndianRepresentation);

byte[] littleEndianRepresentation =
{
0, 0, 100, 167, 179, 182, 224, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
convert(1000000000000000000).ToLittleEndian().Should().BeEquivalentTo(littleEndianRepresentation);
}

[TestCaseSource(typeof(Convertibles), nameof(Convertibles.TestCases))]
public void Convert(Type type, object value, Type expectedException, string expectedString)
{
Expand Down
221 changes: 109 additions & 112 deletions src/Nethermind.Int256/UInt256.cs
Original file line number Diff line number Diff line change
Expand Up @@ -309,91 +309,91 @@ public bool IsOne
public bool IsZeroOrOne => ((u0 >> 1) | u1 | u2 | u3) == 0;

public UInt256 ZeroValue => Zero;

public UInt256 OneValue => One;

public UInt256 MaximalValue => MaxValue;

private static ReadOnlySpan<byte> s_broadcastLookup => new byte[] {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

// Add sets res to the sum a+b
Expand Down Expand Up @@ -1212,7 +1212,7 @@ internal static (ulong quo, ulong rem) Div64(ulong hi, ulong lo, ulong y)

if (y <= hi)
{
ThrowOverflowException();
ThrowOverflowException("y <= hi");
}

var s = LeadingZeros(y);
Expand Down Expand Up @@ -1586,7 +1586,7 @@ public static void Xor(in UInt256 a, in UInt256 b, out UInt256 res)
{
if (SubtractUnderflow(in a, in b, out UInt256 c))
{
ThrowArithmeticException(in a, in b);
ThrowOverflowException($"Underflow in subtraction {a} - {b}");
}

return c;
Expand All @@ -1611,43 +1611,43 @@ public static explicit operator BigInteger(in UInt256 value)
}

public static explicit operator sbyte(in UInt256 a) =>
a.u1 > 0 || a.u2 > 0 || a.u3 > 0 || a.u0 > (long)sbyte.MaxValue
? throw new OverflowException("Cannot convert UInt256 value to sbyte.")
a.u1 > 0 || a.u2 > 0 || a.u3 > 0 || a.u0 > (long)sbyte.MaxValue
? throw new OverflowException("Cannot convert UInt256 value to sbyte.")
: (sbyte)a.u0;

public static explicit operator byte(in UInt256 a) =>
a.u1 > 0 || a.u2 > 0 || a.u3 > 0 || a.u0 > byte.MaxValue
public static explicit operator byte(in UInt256 a) =>
a.u1 > 0 || a.u2 > 0 || a.u3 > 0 || a.u0 > byte.MaxValue
? throw new OverflowException("Cannot convert UInt256 value to byte.")
: (byte)a.u0;

public static explicit operator short(in UInt256 a) =>
a.u1 > 0 || a.u2 > 0 || a.u3 > 0 || a.u0 > (long)short.MaxValue
? throw new OverflowException("Cannot convert UInt256 value to short.")
public static explicit operator short(in UInt256 a) =>
a.u1 > 0 || a.u2 > 0 || a.u3 > 0 || a.u0 > (long)short.MaxValue
? throw new OverflowException("Cannot convert UInt256 value to short.")
: (short)a.u0;

public static explicit operator ushort(in UInt256 a) =>
a.u1 > 0 || a.u2 > 0 || a.u3 > 0 || a.u0 > ushort.MaxValue
? throw new OverflowException("Cannot convert UInt256 value to ushort.")
public static explicit operator ushort(in UInt256 a) =>
a.u1 > 0 || a.u2 > 0 || a.u3 > 0 || a.u0 > ushort.MaxValue
? throw new OverflowException("Cannot convert UInt256 value to ushort.")
: (ushort)a.u0;

public static explicit operator int(in UInt256 a) =>
a.u1 > 0 || a.u2 > 0 || a.u3 > 0 || a.u0 > int.MaxValue
? throw new OverflowException("Cannot convert UInt256 value to int.")
public static explicit operator int(in UInt256 a) =>
a.u1 > 0 || a.u2 > 0 || a.u3 > 0 || a.u0 > int.MaxValue
? throw new OverflowException("Cannot convert UInt256 value to int.")
: (int)a.u0;

public static explicit operator uint(in UInt256 a) =>
a.u1 > 0 || a.u2 > 0 || a.u3 > 0 || a.u0 > uint.MaxValue
? throw new OverflowException("Cannot convert UInt256 value to uint.")
public static explicit operator uint(in UInt256 a) =>
a.u1 > 0 || a.u2 > 0 || a.u3 > 0 || a.u0 > uint.MaxValue
? throw new OverflowException("Cannot convert UInt256 value to uint.")
: (uint)a.u0;

public static explicit operator long(in UInt256 a) =>
a.u1 > 0 || a.u2 > 0 || a.u3 > 0 || a.u0 > long.MaxValue
? throw new OverflowException("Cannot convert UInt256 value to long.")
public static explicit operator long(in UInt256 a) =>
a.u1 > 0 || a.u2 > 0 || a.u3 > 0 || a.u0 > long.MaxValue
? throw new OverflowException("Cannot convert UInt256 value to long.")
: (long)a.u0;

public static explicit operator ulong(in UInt256 a) =>
a.u1 > 0 || a.u2 > 0 || a.u3 > 0
? throw new OverflowException("Cannot convert UInt256 value to ulong.")
public static explicit operator ulong(in UInt256 a) =>
a.u1 > 0 || a.u2 > 0 || a.u3 > 0
? throw new OverflowException("Cannot convert UInt256 value to ulong.")
: a.u0;

public static UInt256 operator *(in UInt256 a, uint b)
Expand Down Expand Up @@ -1774,22 +1774,22 @@ private static bool LessThan(in UInt256 a, in UInt256 b)
public static bool operator !=(long a, in UInt256 b) => !b.Equals(a);
public static bool operator !=(in UInt256 a, ulong b) => !a.Equals(b);
public static bool operator !=(ulong a, in UInt256 b) => !b.Equals(a);
public static explicit operator UInt256(sbyte a) =>
public static explicit operator UInt256(sbyte a) =>
a < 0 ? throw new ArgumentException($"Expected a positive number and got {a}", nameof(a)) : new UInt256((ulong)a);

public static implicit operator UInt256(byte a) => new(a);

public static explicit operator UInt256(short a) =>
public static explicit operator UInt256(short a) =>
a < 0 ? throw new ArgumentException($"Expected a positive number and got {a}", nameof(a)) : new UInt256((ulong)a);

public static implicit operator UInt256(ushort a) => new(a);

public static explicit operator UInt256(int n) =>
public static explicit operator UInt256(int n) =>
n < 0 ? throw new ArgumentException("n < 0") : new UInt256((ulong)n);

public static implicit operator UInt256(uint a) => new(a);

public static explicit operator UInt256(long a) =>
public static explicit operator UInt256(long a) =>
a < 0 ? throw new ArgumentException($"Expected a positive number and got {a}", nameof(a)) : new UInt256((ulong)a);

public override string ToString() => ((BigInteger)this).ToString();
Expand Down Expand Up @@ -1945,10 +1945,7 @@ public object ToType(Type conversionType, IFormatProvider? provider) =>
private static void ThrowDivideByZeroException() => throw new DivideByZeroException("y == 0");

[DoesNotReturn]
private static void ThrowArithmeticException(in UInt256 a, in UInt256 b) => throw new ArithmeticException($"Underflow in subtraction {a} - {b}");

[DoesNotReturn]
private static void ThrowOverflowException() => throw new OverflowException("y <= hi");
private static void ThrowOverflowException(string message) => throw new OverflowException(message);

[DoesNotReturn]
private static void ThrowNotSupportedException() => throw new NotSupportedException();
Expand Down

0 comments on commit 4cfbf69

Please sign in to comment.