Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
1453bfd
- Started migrating to TUnit
crookseta May 23, 2025
0c09db6
- Added number data source interfaces
crookseta May 26, 2025
613012d
- Implemented interfaces to data source classes.
crookseta May 26, 2025
31dbbb3
- Structurized missing data sources classes
crookseta May 26, 2025
636538e
- Added more tests for UInt256.
crookseta May 28, 2025
e7e8b7e
- Fixed typo on method call.
crookseta May 29, 2025
cc8ccd2
- Populated test classes.
crookseta May 30, 2025
ca06d9a
- Added signed 256-bit addition tests.
crookseta May 30, 2025
7e184e3
Added tests for Int256 methods: op_CheckedDecrement, op_CheckedIncrem…
crookseta Jun 14, 2025
58c849d
Merge branch 'main' into unit-test-migration
crookseta Jun 14, 2025
2b4875a
Added tests for Int256 methods: op_ShiftLeft, op_ShiftRight, op_Unsig…
crookseta Jun 17, 2025
f129f70
Merge branch 'main' into unit-test-migration
crookseta Jun 19, 2025
cc5fe58
- Added signed 256-bit Is* method tests.
crookseta Jun 30, 2025
574ab2d
MaxMagnitude, MaxMagnitudeNumber, MinMagnitude, MinMagnitudeNumber, M…
crookseta Aug 1, 2025
85294d3
Int256 TryParse Tests
crookseta Aug 19, 2025
d3371f2
MaxNumber, MinNumber, Log2, DivRem, LeadingZeroCount, PopCount, ReadB…
crookseta Sep 11, 2025
ded7058
Merge branch 'dev' into unit-test-migration
crookseta Sep 19, 2025
de0cbf0
Updated unit test project to .net 10
crookseta Sep 19, 2025
736439a
WriteBigEndian, WriteLittleEndian, Max, Min, Sign, CopySign and Clamp…
crookseta Sep 20, 2025
83e6109
-Added Log10 Tests.
crookseta Sep 22, 2025
11a4491
Fixed typo
crookseta Sep 22, 2025
a39e497
Added op_ShiftLeft, op_ShiftRight and op_UnsignedShiftRight tests.
crookseta Sep 24, 2025
43332d7
-Added TryParse Quad test.
crookseta Oct 1, 2025
0422598
-Fixed deprecated using.
crookseta Oct 21, 2025
4a4b93c
Merge remote-tracking branch 'origin/unit-test-migration' into unit-t…
crookseta Oct 21, 2025
6cbc0cf
Added remaining tests for INumberBase methods.
crookseta Nov 4, 2025
58e2faa
-Added tests for Json Converter.
crookseta Nov 4, 2025
e96cff8
Updated TUnit.
crookseta Nov 4, 2025
c414422
Added UInt512 Sign tests.
crookseta Nov 12, 2025
860a885
Remove old test project.
crookseta Nov 25, 2025
d00ea3f
-Added Max, Min, IsPow2, Log2, ReadBigEndian, ReadLittleEndian, GetBy…
crookseta Nov 26, 2025
9e52f19
-Added PopCount, WriteBigEndian and WriteLittleEndian UInt512 test data.
crookseta Nov 27, 2025
faec3e1
Merge branch 'dev' into unit-test-migration
crookseta Dec 5, 2025
e0e5ed7
-Added RotateLeft, RotateRight and TrailingZeroCount UInt512 test data.
crookseta Dec 5, 2025
11a295b
-Added LeadingZeroCount UInt512 test data.
crookseta Dec 5, 2025
c3efb46
-Added DivRem UInt512 test data.
crookseta Dec 6, 2025
3dcf9fe
-Use CultureInfo.InvariantInfo for floating point parsing.
crookseta Dec 11, 2025
7b3d06c
-Added Tests for Int512 methods: op_AdditionTestData, op_CheckedAddit…
crookseta Dec 19, 2025
a1f449c
-Added Tests for Int512 methods: op_IncrementTestData, op_CheckedIncr…
crookseta Dec 23, 2025
3cd609d
Replace parsing with constructor.
crookseta Dec 25, 2025
1b743d3
Added Tests for Int512 methods: op_MultiplyTestData, op_CheckedMultip…
crookseta Dec 25, 2025
e9d6454
Merge branch 'main' into unit-test-migration
crookseta Jan 24, 2026
f5005af
-Data for previously buggy values on casting.
crookseta Jan 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
371 changes: 371 additions & 0 deletions src/MissingValues.Tests/Core/CalculatorTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,371 @@
using MissingValues.Internals;
using MissingValues.Tests.Data;
using static MissingValues.Tests.Data.CalculatorDataSources;

namespace MissingValues.Tests.Core;

public class CalculatorTests
{
[Test]
public async Task AddWithCarry_NoOverflow_ReturnsCorrectSumAndZeroCarry()
{
ulong a = 10;
ulong b = 20;

ulong result = Calculator.AddWithCarry(a, b, out ulong carry);

using var _ = Assert.Multiple();

await Assert.That(result).IsEqualTo(30UL);
await Assert.That(carry).IsEqualTo(0UL);
}
[Test]
public async Task AddWithCarry_MaxValueAndOne_ReturnsZeroAndCarry()
{
ulong a = ulong.MaxValue;
ulong b = 1;

ulong result = Calculator.AddWithCarry(a, b, out ulong carry);

using var _ = Assert.Multiple();

await Assert.That(result).IsEqualTo(0UL);
await Assert.That(carry).IsEqualTo(1UL);
}
[Test]
public async Task AddWithCarry_OverflowCase_ReturnsCorrectResultAndCarry()
{
ulong a = ulong.MaxValue - 1;
ulong b = 5;

ulong result = Calculator.AddWithCarry(a, b, out ulong carry);

using var _ = Assert.Multiple();

await Assert.That(result).IsEqualTo(3UL);
await Assert.That(carry).IsEqualTo(1UL);
}
[Test]
public async Task AddWithCarry_AddZero_ReturnsSameValueAndZeroCarry()
{
ulong a = 123456789;
ulong b = 0;

ulong result = Calculator.AddWithCarry(a, b, out ulong carry);

using var _ = Assert.Multiple();

await Assert.That(result).IsEqualTo(a);
await Assert.That(carry).IsEqualTo(0UL);
}
[Test]
public async Task AddWithCarry_BothZero_ReturnsZeroAndZeroCarry()
{
ulong a = 0;
ulong b = 0;

ulong result = Calculator.AddWithCarry(a, b, out ulong carry);

using var _ = Assert.Multiple();

await Assert.That(result).IsEqualTo(0UL);
await Assert.That(carry).IsEqualTo(0UL);
}
[Test]
public async Task AddWithCarry_ExactMaxValueSum_ReturnsMaxValueAndZeroCarry()
{
ulong a = ulong.MaxValue / 2;
ulong b = ulong.MaxValue / 2;

ulong result = Calculator.AddWithCarry(a, b, out ulong carry);

using var _ = Assert.Multiple();

await Assert.That(result).IsEqualTo(ulong.MaxValue - 1);
await Assert.That(carry).IsEqualTo(0UL);
}
[Test]
public async Task AddWithCarry_CarryOnlyTriggeredWhenOverflow()
{
ulong a = ulong.MaxValue;
ulong b = 0;

ulong result = Calculator.AddWithCarry(a, b, out ulong carry);

using var _ = Assert.Multiple();

await Assert.That(result).IsEqualTo(ulong.MaxValue);
await Assert.That(carry).IsEqualTo(0UL);
}

[Test]
public async Task BigMulAdd_SimpleMultiplicationAndAddition()
{
ulong a = 2;
ulong b = 3;
ulong c = 5;

var (hi, lo) = Calculator.BigMulAdd(a, b, c);

using var _ = Assert.Multiple();

await Assert.That(hi).IsEqualTo(0UL);
await Assert.That(lo).IsEqualTo(11UL);
}
[Test]
public async Task BigMulAdd_WithOverflowFromLowToHigh()
{
ulong a = ulong.MaxValue;
ulong b = 2;
ulong c = 1;

var (hi, lo) = Calculator.BigMulAdd(a, b, c);

using var _ = Assert.Multiple();

await Assert.That(hi).IsEqualTo(1UL);
await Assert.That(lo).IsEqualTo(0xFFFFFFFFFFFFFFFFUL);
}
[Test]
public async Task BigMulAdd_MaxValues()
{
ulong a = ulong.MaxValue;
ulong b = ulong.MaxValue;
ulong c = ulong.MaxValue;

var (hi, lo) = Calculator.BigMulAdd(a, b, c);

using var _ = Assert.Multiple();

await Assert.That(hi).IsEqualTo(0xFFFFFFFFFFFFFFFFUL);
await Assert.That(lo).IsEqualTo(0UL);
}
[Test]
public async Task BigMulAdd_NoCarryOrOverflow()
{
ulong a = 1000;
ulong b = 1000;
ulong c = 1;

var (hi, lo) = Calculator.BigMulAdd(a, b, c);

using var _ = Assert.Multiple();

await Assert.That(hi).IsEqualTo(0UL);
await Assert.That(lo).IsEqualTo(1_000_001UL);
}
[Test]
public async Task BigMulAdd_CausesCarryFromAdditionOnly()
{
ulong a = ulong.MaxValue;
ulong b = 1;
ulong c = 1;

var (hi, lo) = Calculator.BigMulAdd(a, b, c);

using var _ = Assert.Multiple();

await Assert.That(hi).IsEqualTo(1UL);
await Assert.That(lo).IsEqualTo(0UL);
}
[Test]
public async Task BigMulAdd_CausesNoCarryWithZeroInputs()
{
ulong a = 0;
ulong b = 0;
ulong c = 0;

var (hi, lo) = Calculator.BigMulAdd(a, b, c);

using var _ = Assert.Multiple();

await Assert.That(hi).IsEqualTo(0UL);
await Assert.That(lo).IsEqualTo(0UL);
}

[Test]
public async Task DivRemByUInt32_BasicDivision()
{
ulong left = 100;
uint right = 7;

var (quotient, remainder) = Calculator.DivRemByUInt32(left, right);

using var _ = Assert.Multiple();

await Assert.That(quotient).IsEqualTo(14UL);
await Assert.That(remainder).IsEqualTo(2U);
}
[Test]
public async Task DivRemByUInt32_DivideByOne()
{
ulong left = 1234567890123456789;
uint right = 1;

var (quotient, remainder) = Calculator.DivRemByUInt32(left, right);

using var _ = Assert.Multiple();

await Assert.That(quotient).IsEqualTo(left);
await Assert.That(remainder).IsEqualTo(0U);
}
[Test]
public async Task DivRemByUInt32_DivideByMaxUInt32()
{
ulong left = (ulong)uint.MaxValue + 1;
uint right = uint.MaxValue;

var (quotient, remainder) = Calculator.DivRemByUInt32(left, right);

using var _ = Assert.Multiple();

await Assert.That(quotient).IsEqualTo(1UL);
await Assert.That(remainder).IsEqualTo(1U);
}
[Test]
public async Task DivRemByUInt32_ZeroDividend()
{
ulong left = 0;
uint right = uint.MaxValue;

var (quotient, remainder) = Calculator.DivRemByUInt32(left, right);

using var _ = Assert.Multiple();

await Assert.That(quotient).IsEqualTo(0UL);
await Assert.That(remainder).IsEqualTo(0U);
}
[Test]
public async Task DivRemByUInt32_ExactDivision()
{
ulong left = 400;
uint right = 20;

var (quotient, remainder) = Calculator.DivRemByUInt32(left, right);

using var _ = Assert.Multiple();

await Assert.That(quotient).IsEqualTo(20UL);
await Assert.That(remainder).IsEqualTo(0U);
}
[Test]
public async Task DivRemByUInt32_MaxValues()
{
ulong left = ulong.MaxValue;
uint right = uint.MaxValue;

var (quotient, remainder) = Calculator.DivRemByUInt32(left, right);

using var _ = Assert.Multiple();

await Assert.That(quotient).IsEqualTo(ulong.MaxValue / uint.MaxValue);
await Assert.That(remainder).IsEqualTo((uint)(ulong.MaxValue % uint.MaxValue));
}
[Test]
public async Task DivRemByUInt32_DivideByZero_Throws()
{
ulong left = 100;
uint right = 0;

await Assert.That(() => Calculator.DivRemByUInt32(left, right)).Throws<DivideByZeroException>();
}

[Test]
public async Task DivRemByUInt64_BasicDivision()
{
UInt128 left = new UInt128(0, 1000);
ulong right = 30;

var (quotient, remainder) = Calculator.DivRemByUInt64(left, right);

using var _ = Assert.Multiple();

await Assert.That(quotient).IsEqualTo(new UInt128(0, 33));
await Assert.That(remainder).IsEqualTo(10UL);
}
[Test]
public async Task DivRemByUInt64_ZeroDividend()
{
UInt128 left = new UInt128(0, 0);
ulong right = 12345;

var (quotient, remainder) = Calculator.DivRemByUInt64(left, right);

using var _ = Assert.Multiple();

await Assert.That(quotient).IsEqualTo(UInt128.Zero);
await Assert.That(remainder).IsEqualTo(0UL);
}
[Test]
public async Task DivRemByUInt64_DivideByOne()
{
UInt128 left = new UInt128(123456789, 9876543210);
ulong right = 1;

var (quotient, remainder) = Calculator.DivRemByUInt64(left, right);

using var _ = Assert.Multiple();

await Assert.That(quotient).IsEqualTo(new UInt128(123456789, 9876543210));
await Assert.That(remainder).IsEqualTo(0UL);
}
[Test]
public async Task DivRemByUInt64_ExactDivision()
{
UInt128 left = new UInt128(0, 1000);
ulong right = 1000;

var (quotient, remainder) = Calculator.DivRemByUInt64(left, right);

using var _ = Assert.Multiple();

await Assert.That(quotient).IsEqualTo(new UInt128(0, 1));
await Assert.That(remainder).IsEqualTo(0UL);
}
[Test]
public async Task DivRemByUInt64_UpperBitsUsed()
{
UInt128 left = new UInt128(1, 0);
ulong right = 2;

var (quotient, remainder) = Calculator.DivRemByUInt64(left, right);

using var _ = Assert.Multiple();

await Assert.That(quotient).IsEqualTo(new UInt128(0, 1UL << 63));
await Assert.That(remainder).IsEqualTo(0UL);
}
[Test]
public async Task DivRemByUInt64_MaxValues()
{
UInt128 left = UInt128.MaxValue;
ulong right = ulong.MaxValue;

var (quotient, remainder) = Calculator.DivRemByUInt64(left, right);

using var _ = Assert.Multiple();

await Assert.That(quotient).IsEqualTo(UInt128.MaxValue / ulong.MaxValue);
await Assert.That(remainder).IsEqualTo((ulong)(UInt128.MaxValue % ulong.MaxValue));
}
[Test]
public async Task DivRemByUInt64_DivideByZero_Throws()
{
UInt128 left = new UInt128(1, 0);
ulong right = 0;

await Assert.That(() => Calculator.DivRemByUInt64(left, right)).Throws<DivideByZeroException>();
}

[Test]
[MethodDataSource(typeof(CalculatorDataSources), nameof(Log10TestData))]
public async Task Log10_DataDriven(UInt512 value, int expected)
{
await Assert.That(BitHelper.Log10(in value)).IsEqualTo(expected);
}
[Test]
public async Task Log10_NegativeInput_Throws()
{
await Assert.That(() => BitHelper.Log10(in Int512.NegativeOne)).Throws<ArgumentException>();
}
}
Loading