Files
even-perfect-numbers-scanner/PerfectNumbers.Core.Tests/MersenneNumberResidueGpuTesterTests.cs
T

107 lines
3.0 KiB
C#

using FluentAssertions;
using PerfectNumbers.Core.Gpu;
using Xunit;
using UInt128 = System.UInt128;
namespace PerfectNumbers.Core.Tests;
public class MersenneNumberResidueGpuTesterTests
{
private static bool LastDigitIsSeven(ulong exponent) => (exponent & 3UL) == 3UL;
[Theory]
[InlineData(false)]
[InlineData(true)]
[Trait("Category", "Fast")]
public void Scan_handles_various_prime_exponents(bool useGpuOrder)
{
var tester = new MersenneNumberResidueGpuTester(useGpuOrder);
RunCase(tester, 23UL, 2UL, expectedPrime: false);
RunCase(tester, 29UL, 37UL, expectedPrime: false);
RunCase(tester, 31UL, 1_000UL, expectedPrime: true);
RunCase(tester, 89UL, 1_001UL, expectedPrime: true);
RunCase(tester, 107UL, 1_001UL, expectedPrime: true);
RunCase(tester, 127UL, 1_001UL, expectedPrime: true);
}
[Theory]
[InlineData(false)]
[InlineData(true)]
[Trait("Category", "Fast")]
public void Scan_recognizes_all_known_small_mersenne_primes(bool useGpuOrder)
{
var tester = new MersenneNumberResidueGpuTester(useGpuOrder);
foreach (ulong exponent in MersennePrimeTestData.Exponents)
{
RunCase(tester, exponent, 1UL, expectedPrime: true);
}
}
[Theory]
[InlineData(false)]
[InlineData(true)]
[Trait("Category", "Fast")]
public void Scan_handles_multiple_sets_without_false_positives(bool useGpuOrder)
{
var tester = new MersenneNumberResidueGpuTester(useGpuOrder);
bool isPrime = true;
bool exhausted = false;
UInt128 perSetLimit = 1_666_667UL;
UInt128 setCount = 3UL;
UInt128 overallLimit = 5_000_000UL;
tester.Scan(
127UL,
(UInt128)127UL << 1,
LastDigitIsSeven(127UL),
perSetLimit,
setCount,
overallLimit,
ref isPrime,
ref exhausted);
isPrime.Should().BeTrue();
exhausted.Should().BeTrue();
isPrime = true;
exhausted = false;
perSetLimit = 20_000_000UL;
setCount = 5UL;
overallLimit = 100_000_000UL;
tester.Scan(
107UL,
(UInt128)107UL << 1,
LastDigitIsSeven(107UL),
perSetLimit,
setCount,
overallLimit,
ref isPrime,
ref exhausted);
isPrime.Should().BeTrue();
exhausted.Should().BeTrue();
}
private static void RunCase(MersenneNumberResidueGpuTester tester, ulong exponent, ulong maxK, bool expectedPrime)
{
bool isPrime = true;
bool exhausted = false;
tester.Scan(
exponent,
(UInt128)exponent << 1,
LastDigitIsSeven(exponent),
(UInt128)maxK,
UInt128.One,
(UInt128)maxK,
ref isPrime,
ref exhausted);
isPrime.Should().Be(expectedPrime);
exhausted.Should().BeTrue();
}
}