Skip to content

Commit 65311fc

Browse files
committed
extend tests
1 parent 316864e commit 65311fc

4 files changed

Lines changed: 155 additions & 0 deletions

File tree

Tests/BigNumberTests/Test_BDouble_Extended.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,4 +152,27 @@ class Test_BDouble_Extended: XCTestCase {
152152
let str = z.decimalExpansion(precisionAfterDecimalPoint: 4, rounded: false)
153153
XCTAssertEqual(str, "0.0000")
154154
}
155+
156+
func test_decimal_expansion_repeating_pattern() {
157+
// 1/7 = 0.142857142857... (period 6)
158+
let val = BDouble(1, over: 7)
159+
let expansion = val.decimalExpansion(precisionAfterDecimalPoint: 6000, rounded: false)
160+
let digits = String(expansion.dropFirst(2)) // drop "0."
161+
XCTAssertEqual(digits.count, 6000)
162+
163+
let period = "142857"
164+
for i in stride(from: 0, to: digits.count - 5, by: 6) {
165+
let start = digits.index(digits.startIndex, offsetBy: i)
166+
let end = digits.index(start, offsetBy: 6)
167+
XCTAssertEqual(String(digits[start..<end]), period,
168+
"1/7 period mismatch at position \(i)")
169+
}
170+
}
171+
172+
func test_decimal_expansion_1_over_3() {
173+
let val = BDouble(1, over: 3)
174+
let expansion = val.decimalExpansion(precisionAfterDecimalPoint: 5000, rounded: false)
175+
let digits = String(expansion.dropFirst(2))
176+
XCTAssert(digits.allSatisfy({ $0 == "3" }), "1/3 should be all 3s")
177+
}
155178
}

Tests/BigNumberTests/Test_BIntMath_Extended.swift

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,49 @@ class Test_BIntMath_Extended: XCTestCase {
170170
}
171171
}
172172

173+
func test_fib_large_recurrence() {
174+
// F(n) = F(n-1) + F(n-2) for larger values
175+
for n in [100, 500, 1000, 5000] {
176+
XCTAssertEqual(
177+
BIntMath.fib(n),
178+
BIntMath.fib(n - 1) + BIntMath.fib(n - 2),
179+
"fib(\(n)) != fib(\(n-1)) + fib(\(n-2))"
180+
)
181+
}
182+
}
183+
184+
func test_fib_larger_known_values() {
185+
XCTAssertEqual(BIntMath.fib(100), BInt("354224848179261915075")!)
186+
XCTAssertEqual(BIntMath.fib(300), BInt("222232244629420445529739893461909967206666939096499764990979600")!)
187+
188+
// fib(1000): verify via recurrence and digit count
189+
let f1000 = BIntMath.fib(1000)
190+
XCTAssertEqual(f1000.description.count, 209)
191+
XCTAssert(f1000.description.hasPrefix("4346655768693745643568852767"))
192+
XCTAssertEqual(f1000, BIntMath.fib(999) + BIntMath.fib(998))
193+
}
194+
195+
func test_fib_lucas_identity() {
196+
// F(2k) = F(k) * [2*F(k+1) - F(k)]
197+
for k in [50, 200, 500, 1000] {
198+
let f2k = BIntMath.fib(2 * k)
199+
let fk = BIntMath.fib(k)
200+
let fk1 = BIntMath.fib(k + 1)
201+
XCTAssertEqual(f2k, fk * (BInt(2) * fk1 - fk),
202+
"Lucas identity failed for k=\(k)")
203+
}
204+
}
205+
206+
func test_fib_100000_spot_check() {
207+
let f = BIntMath.fib(100_000)
208+
// Known digit count
209+
XCTAssertEqual(f.description.count, 20899)
210+
// Known prefix
211+
XCTAssert(f.description.hasPrefix("2597406934722"))
212+
// Recurrence: F(100000) = F(99999) + F(99998)
213+
XCTAssertEqual(f, BIntMath.fib(99_999) + BIntMath.fib(99_998))
214+
}
215+
173216
// MARK: - Mersenne
174217

175218
func test_isMersenne() {

Tests/BigNumberTests/Test_Basic_Math.swift

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,60 @@ class Test_Basic_Math: XCTestCase {
242242
}
243243
}
244244

245+
func test_Multiplication_large_roundtrip() {
246+
// (a*b)/a == b for large operands
247+
let a = BIntMath.randomBInt(bits: 10_000)
248+
let b = BIntMath.randomBInt(bits: 10_000)
249+
let product = a * b
250+
XCTAssertEqual(product / a, b)
251+
XCTAssertEqual(product / b, a)
252+
}
253+
254+
func test_Multiplication_commutative_large() {
255+
let a = BIntMath.randomBInt(bits: 50_000)
256+
let b = BIntMath.randomBInt(bits: 50_000)
257+
XCTAssertEqual(a * b, b * a)
258+
}
259+
260+
func test_Multiplication_distributive() {
261+
let a = BIntMath.randomBInt(bits: 5_000)
262+
let b = BIntMath.randomBInt(bits: 5_000)
263+
let c = BIntMath.randomBInt(bits: 5_000)
264+
XCTAssertEqual(a * (b + c), a * b + a * c)
265+
}
266+
267+
func test_Multiplication_known_square() {
268+
let base = BInt(10) ** 1000
269+
XCTAssertEqual(base * base, BInt(10) ** 2000)
270+
}
271+
272+
func test_Factorial_consistency() {
273+
// n! == n * (n-1)!
274+
XCTAssertEqual(BInt(1000).factorial(), BInt(1000) * BInt(999).factorial())
275+
XCTAssertEqual(BInt(10000).factorial(), BInt(10000) * BInt(9999).factorial())
276+
}
277+
278+
func test_Factorial_trailing_zeros() {
279+
// Trailing zeros in n! = sum of floor(n/5^k)
280+
func expectedTrailingZeros(_ n: Int) -> Int {
281+
var count = 0; var p = 5
282+
while p <= n { count += n / p; p *= 5 }
283+
return count
284+
}
285+
for n in [100, 1000, 5000, 10000] {
286+
let str = BInt(n).factorial().description
287+
let zeros = str.reversed().prefix(while: { $0 == "0" }).count
288+
XCTAssertEqual(zeros, expectedTrailingZeros(n), "\(n)! trailing zeros")
289+
}
290+
}
291+
292+
func test_Exponentiation_10_pow_large() {
293+
let str = (BInt(10) ** 10_000).description
294+
XCTAssertEqual(str.count, 10_001)
295+
XCTAssertEqual(str.first, "1")
296+
XCTAssert(str.dropFirst().allSatisfy({ $0 == "0" }))
297+
}
298+
245299
func test_Power() {
246300
// Reference issue #41
247301
let TWO : BInt = 2

Tests/BigNumberTests/Test_String_Conversions_Extended.swift

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,41 @@ class Test_String_Conversions_Extended: XCTestCase {
7474
}
7575
}
7676

77+
// MARK: - Hex string for large numbers
78+
79+
func test_hex_known_power_of_two() {
80+
XCTAssertEqual((BInt(1) << 64).asString(radix: 16), "10000000000000000")
81+
XCTAssertEqual(((BInt(1) << 128) - 1).asString(radix: 16),
82+
"ffffffffffffffffffffffffffffffff")
83+
XCTAssertEqual((BInt(1) << 256).asString(radix: 16),
84+
"1" + String(repeating: "0", count: 64))
85+
}
86+
87+
func test_hex_roundtrip_factorial() {
88+
// Roundtrip 1500! through hex — matches the benchmark
89+
let fac = BInt(1500).factorial()
90+
let hex = fac.asString(radix: 16)
91+
let back = BInt(hex, radix: 16)!
92+
XCTAssertEqual(back, fac, "1500! hex roundtrip failed")
93+
}
94+
95+
func test_hex_vs_decimal_consistency() {
96+
// Verify hex and decimal representations refer to the same number
97+
let big = BInt(1000).factorial()
98+
let fromDec = BInt(big.description)!
99+
let fromHex = BInt(big.asString(radix: 16), radix: 16)!
100+
XCTAssertEqual(fromDec, fromHex)
101+
}
102+
103+
func test_large_radix_roundtrips() {
104+
let big = BInt(500).factorial()
105+
for radix in [2, 8, 16, 32, 36] {
106+
let str = big.asString(radix: radix)
107+
let back = BInt(str, radix: radix)!
108+
XCTAssertEqual(back, big, "500! roundtrip failed for base \(radix)")
109+
}
110+
}
111+
77112
// MARK: - Bytes roundtrip extended
78113

79114
func test_bytes_roundtrip_extended() {

0 commit comments

Comments
 (0)