Skip to content

Commit de5abc0

Browse files
authored
Merge pull request #77 from IsaMorphic/feature/impl-unit-tests
Feature: implement unit tests for internal `UInt256` type
2 parents 7af6f44 + 3d8d50c commit de5abc0

3 files changed

Lines changed: 220 additions & 5 deletions

File tree

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
/*
2+
* Copyright 2026 Chosen Few Software
3+
* This file is part of QuadrupleLib.
4+
*
5+
* QuadrupleLib is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU Lesser General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* QuadrupleLib is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public License
16+
* along with QuadrupleLib. If not, see <https://www.gnu.org/licenses/>.
17+
*/
18+
19+
using QuadrupleLib.Utilities;
20+
using Xunit;
21+
22+
namespace QuadrupleLib.Tests.Utilities
23+
{
24+
public class UInt256Tests
25+
{
26+
[Fact]
27+
public void IsAddWithoutCarryCorrect()
28+
{
29+
UInt256 one = 1UL;
30+
UInt256 two = 2UL;
31+
Assert.Equal(3UL, one + two);
32+
}
33+
34+
[Fact]
35+
public void IsAddWithCarryCorrect()
36+
{
37+
UInt256 n = UInt256.One + UInt128.MaxValue;
38+
Assert.Equal((UInt128.Zero, UInt128.One), (n._lo, n._hi));
39+
}
40+
41+
[Fact]
42+
public void IsAddWithOverflowZero()
43+
{
44+
UInt256 n = UInt256.MaxValue + UInt256.One;
45+
Assert.Equal(UInt256.Zero, n);
46+
}
47+
48+
[Fact]
49+
public void IsSubtractWithoutBorrowCorrect()
50+
{
51+
UInt256 one = 1UL;
52+
UInt256 three = 3UL;
53+
Assert.Equal(2UL, three - one);
54+
}
55+
56+
[Fact]
57+
public void IsSubtractWithBorrowCorrect()
58+
{
59+
UInt256 n = UInt256.One + UInt128.MaxValue, m = n - UInt256.One;
60+
Assert.Equal((UInt128.MaxValue, UInt128.Zero), (m._lo, m._hi));
61+
}
62+
63+
[Fact]
64+
public void IsSubtractWithUnderflowMaximum()
65+
{
66+
UInt256 n = UInt256.Zero - UInt256.One;
67+
Assert.Equal(UInt256.MaxValue, n);
68+
}
69+
70+
[Theory]
71+
[InlineData(0UL, 0UL, 0)]
72+
[InlineData(0UL, 0UL, 1)]
73+
[InlineData(0UL, 0UL, 2)]
74+
[InlineData(1UL, 1UL, 0)]
75+
[InlineData(1UL, 2UL, 1)]
76+
[InlineData(1UL, 4UL, 2)]
77+
[InlineData(2UL, 2UL, 0)]
78+
[InlineData(2UL, 4UL, 1)]
79+
[InlineData(2UL, 8UL, 2)]
80+
public void IsSmallShiftLeftCorrect(ulong n, ulong m, int amt)
81+
{
82+
UInt256 N = n; N <<= amt;
83+
Assert.Equal(m, N);
84+
}
85+
86+
[Theory]
87+
[InlineData(0UL, 0UL, 0)]
88+
[InlineData(0UL, 0UL, 1)]
89+
[InlineData(0UL, 0UL, 2)]
90+
[InlineData(1UL, 1UL, 0)]
91+
[InlineData(1UL, 2UL, 1)]
92+
[InlineData(1UL, 4UL, 2)]
93+
[InlineData(2UL, 2UL, 0)]
94+
[InlineData(2UL, 4UL, 1)]
95+
[InlineData(2UL, 8UL, 2)]
96+
public void IsLargeShiftLeftCorrect(ulong n, ulong m, int amt)
97+
{
98+
UInt256 N = n; N <<= 128 + amt;
99+
UInt256 M = m; M <<= 128;
100+
Assert.Equal(M, N);
101+
}
102+
103+
[Theory]
104+
[InlineData(0UL, 0)]
105+
[InlineData(0UL, 1)]
106+
[InlineData(0UL, 2)]
107+
[InlineData(1UL, 0)]
108+
[InlineData(1UL, 1)]
109+
[InlineData(1UL, 2)]
110+
[InlineData(2UL, 0)]
111+
[InlineData(2UL, 1)]
112+
[InlineData(2UL, 2)]
113+
public void IsExtraLargeShiftLeftZero(ulong n, int amt)
114+
{
115+
UInt256 N = n; N <<= 256 + amt;
116+
Assert.Equal(UInt256.Zero, N);
117+
}
118+
119+
[Theory]
120+
[InlineData(0UL, 0UL, 0)]
121+
[InlineData(0UL, 0UL, 1)]
122+
[InlineData(0UL, 0UL, 2)]
123+
[InlineData(2UL, 2UL, 0)]
124+
[InlineData(2UL, 1UL, 1)]
125+
[InlineData(2UL, 0UL, 2)]
126+
[InlineData(4UL, 4UL, 0)]
127+
[InlineData(4UL, 2UL, 1)]
128+
[InlineData(4UL, 1UL, 2)]
129+
public void IsSmallShiftRightCorrect(ulong n, ulong m, int amt)
130+
{
131+
UInt256 N = n; N >>= amt;
132+
Assert.Equal(m, N);
133+
}
134+
135+
[Theory]
136+
[InlineData(0UL, 0UL, 0)]
137+
[InlineData(0UL, 0UL, 1)]
138+
[InlineData(0UL, 0UL, 2)]
139+
[InlineData(2UL, 2UL, 0)]
140+
[InlineData(2UL, 1UL, 1)]
141+
[InlineData(2UL, 0UL, 2)]
142+
[InlineData(4UL, 4UL, 0)]
143+
[InlineData(4UL, 2UL, 1)]
144+
[InlineData(4UL, 1UL, 2)]
145+
public void IsLargeShiftRightCorrect(ulong n, ulong m, int amt)
146+
{
147+
UInt256 N = (UInt256)n << 128; N >>= 128 + amt;
148+
Assert.Equal(m, N);
149+
}
150+
151+
[Theory]
152+
[InlineData(0UL, 0)]
153+
[InlineData(0UL, 1)]
154+
[InlineData(0UL, 2)]
155+
[InlineData(2UL, 0)]
156+
[InlineData(2UL, 1)]
157+
[InlineData(2UL, 2)]
158+
[InlineData(4UL, 0)]
159+
[InlineData(4UL, 1)]
160+
[InlineData(4UL, 2)]
161+
public void IsExtraLargeShiftRightZero(ulong n, int amt)
162+
{
163+
UInt256 N = (UInt256)n << 128; N >>= 256 + amt;
164+
Assert.Equal(UInt256.Zero, N);
165+
}
166+
167+
[Theory]
168+
[InlineData(0UL, 0UL, 0)]
169+
[InlineData(0UL, 1UL, -1)]
170+
[InlineData(0UL, 2UL, -1)]
171+
[InlineData(1UL, 0UL, 1)]
172+
[InlineData(1UL, 1UL, 0)]
173+
[InlineData(1UL, 2UL, -1)]
174+
[InlineData(2UL, 0UL, 1)]
175+
[InlineData(2UL, 1UL, 1)]
176+
[InlineData(2UL, 2UL, 0)]
177+
public void IsSmallCompareToCorrect(ulong n, ulong m, int s)
178+
{
179+
UInt256 N = n, M = m;
180+
int S = System.Math.Sign(N.CompareTo(M));
181+
Assert.Equal(s, S);
182+
}
183+
184+
[Theory]
185+
[InlineData(0UL, 0UL, 0)]
186+
[InlineData(0UL, 1UL, -1)]
187+
[InlineData(0UL, 2UL, -1)]
188+
[InlineData(1UL, 0UL, 1)]
189+
[InlineData(1UL, 1UL, 0)]
190+
[InlineData(1UL, 2UL, -1)]
191+
[InlineData(2UL, 0UL, 1)]
192+
[InlineData(2UL, 1UL, 1)]
193+
[InlineData(2UL, 2UL, 0)]
194+
public void IsLargeCompareToCorrect(ulong n, ulong m, int s)
195+
{
196+
UInt256 N = (UInt256)n << 128, M = (UInt256)m << 128;
197+
int S = System.Math.Sign(N.CompareTo(M));
198+
Assert.Equal(s, S);
199+
}
200+
}
201+
}

QuadrupleLib/AssemblyInfo.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
using System.Runtime.CompilerServices;
2+
3+
[assembly: InternalsVisibleTo("QuadrupleLib.Tests")]
Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@
1616
* along with QuadrupleLib. If not, see <https://www.gnu.org/licenses/>.
1717
*/
1818

19-
namespace QuadrupleLib
19+
using System.Numerics;
20+
using System.Runtime.InteropServices;
21+
22+
namespace QuadrupleLib.Utilities
2023
{
24+
[StructLayout(LayoutKind.Sequential)]
2125
internal struct UInt256 : IEquatable<UInt256>, IComparable<UInt256>, IComparable
2226
{
2327
private static readonly UInt256 _zero = new();
@@ -34,11 +38,11 @@ internal struct UInt256 : IEquatable<UInt256>, IComparable<UInt256>, IComparable
3438

3539

3640
#if BIGENDIAN
37-
private readonly UInt128 _hi;
38-
private readonly UInt128 _lo;
41+
public readonly UInt128 _hi;
42+
public readonly UInt128 _lo;
3943
#else
40-
private readonly UInt128 _lo;
41-
private readonly UInt128 _hi;
44+
public readonly UInt128 _lo;
45+
public readonly UInt128 _hi;
4246
#endif
4347
private UInt256(UInt128 lo, UInt128 hi)
4448
{
@@ -263,5 +267,12 @@ public override int GetHashCode()
263267
{
264268
return HashCode.Combine(_lo, _hi);
265269
}
270+
271+
public override string ToString()
272+
{
273+
BigInteger n = _hi;
274+
n = (n << 128) | _lo;
275+
return n.ToString();
276+
}
266277
}
267278
}

0 commit comments

Comments
 (0)