Skip to content

Commit c7b9418

Browse files
konardclaude
andcommitted
Add tests to verify precalculated factorial and Catalan constants
Adds two tests that independently compute factorial and Catalan numbers using BigInteger arithmetic and verify they match the precalculated constants in Math._factorials and Math._catalans. Computations that exceed 10 seconds are skipped with a note to use external resources (OEIS A000142 for factorials, OEIS A000108 for Catalan numbers). Fixes #59 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent b28480c commit c7b9418

1 file changed

Lines changed: 83 additions & 0 deletions

File tree

csharp/Platform.Numbers.Tests/MathTests.cs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,52 @@
11
using System;
2+
using System.Diagnostics;
3+
using System.Numerics;
24
using Xunit;
35

46
namespace Platform.Numbers.Tests
57
{
68
public static class MathTests
79
{
10+
private static readonly TimeSpan ComputationTimeLimit = TimeSpan.FromSeconds(10);
11+
12+
/// <summary>
13+
/// Computes factorial of n using BigInteger so it never overflows.
14+
/// Returns null if computation exceeds the time limit.
15+
/// </summary>
16+
private static BigInteger? ComputeFactorialWithTimeLimit(ulong n)
17+
{
18+
var stopwatch = Stopwatch.StartNew();
19+
BigInteger result = BigInteger.One;
20+
for (ulong i = 2; i <= n; i++)
21+
{
22+
result *= i;
23+
if (stopwatch.Elapsed > ComputationTimeLimit)
24+
{
25+
return null;
26+
}
27+
}
28+
return result;
29+
}
30+
31+
/// <summary>
32+
/// Computes the nth Catalan number from scratch using the formula:
33+
/// C(n) = (2n)! / ((n+1)! * n!)
34+
/// Returns null if computation exceeds the time limit.
35+
/// </summary>
36+
private static BigInteger? ComputeCatalanWithTimeLimit(ulong n)
37+
{
38+
var twoNFact = ComputeFactorialWithTimeLimit(2 * n);
39+
if (twoNFact is null) return null;
40+
41+
var nPlusOneFact = ComputeFactorialWithTimeLimit(n + 1);
42+
if (nPlusOneFact is null) return null;
43+
44+
var nFact = ComputeFactorialWithTimeLimit(n);
45+
if (nFact is null) return null;
46+
47+
return twoNFact / (nPlusOneFact * nFact);
48+
}
49+
850
[Theory]
951
[InlineData(0ul, 1ul)]
1052
[InlineData(1ul, 1ul)]
@@ -107,5 +149,46 @@ public static void MaximumConstantsTest()
107149
Assert.Equal(20ul, Math.MaximumFactorialNumber);
108150
Assert.Equal(36ul, Math.MaximumCatalanIndex);
109151
}
152+
153+
[Fact]
154+
public static void PrecalculatedFactorialsMatchComputedValues()
155+
{
156+
// Verify that every precalculated factorial constant in Math._factorials is actually
157+
// a correct factorial value, computed independently using BigInteger arithmetic.
158+
// Only computes values that finish within 10 seconds; larger values would need
159+
// verification via an external trusted resource (e.g. OEIS A000142: https://oeis.org/A000142).
160+
for (ulong n = 0; n <= Math.MaximumFactorialNumber; n++)
161+
{
162+
var computed = ComputeFactorialWithTimeLimit(n);
163+
if (computed is null)
164+
{
165+
// Computation exceeded 10 seconds — skip and rely on external verification.
166+
continue;
167+
}
168+
var precalculated = Math.Factorial<ulong>(n);
169+
Assert.Equal((ulong)computed, precalculated);
170+
}
171+
}
172+
173+
[Fact]
174+
public static void PrecalculatedCatalansMatchComputedFactorials()
175+
{
176+
// Verify that every precalculated Catalan constant in Math._catalans is actually
177+
// a correct Catalan number, computed from scratch using the formula:
178+
// C(n) = (2n)! / ((n+1)! * n!)
179+
// Only computes values that finish within 10 seconds; larger values would need
180+
// verification via an external trusted resource (e.g. OEIS A000108: https://oeis.org/A000108).
181+
for (ulong n = 0; n <= Math.MaximumCatalanIndex; n++)
182+
{
183+
var computed = ComputeCatalanWithTimeLimit(n);
184+
if (computed is null)
185+
{
186+
// Computation exceeded 10 seconds — skip and rely on external verification.
187+
continue;
188+
}
189+
var precalculated = Math.Catalan<ulong>(n);
190+
Assert.Equal((ulong)computed, precalculated);
191+
}
192+
}
110193
}
111194
}

0 commit comments

Comments
 (0)