Files

107 lines
4.2 KiB
Swift

import XCTest
@testable import KiteCore
final class BigIntTests: XCTestCase {
func testRoundTripInt() {
for value in [0, 1, -1, 42, -42, Int.max, Int.min, 1234567890, -1234567890] {
let big = BigInt(value)
XCTAssertTrue(big.fitsInt, "\(value) should fit")
XCTAssertEqual(big.toInt(), value)
}
}
func testAddSubAgainstInt() {
let pairs = [(12, 34), (-5, 9), (1000, -1000), (999999, 1), (-7, -8)]
for (a, b) in pairs {
XCTAssertEqual((BigInt(a) + BigInt(b)).toInt(), a + b)
XCTAssertEqual((BigInt(a) - BigInt(b)).toInt(), a - b)
XCTAssertEqual((BigInt(a) * BigInt(b)).toInt(), a * b)
}
}
func testFactorialKnownValue() {
var acc = BigInt.one
for k in 1...100 { acc = acc * BigInt(k) }
let expected = "93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000"
XCTAssertEqual(acc.description, expected)
}
func testDivModAgainstInt() {
let pairs = [(17, 5), (-17, 5), (17, -5), (-17, -5), (100, 7), (5, 17), (0, 3)]
for (a, b) in pairs {
let (q, r) = BigInt.divMod(BigInt(a), BigInt(b))
XCTAssertEqual(q.toInt(), a / b, "quotient \(a)/\(b)")
XCTAssertEqual(r.toInt(), a % b, "remainder \(a)%\(b)")
XCTAssertEqual((q * BigInt(b) + r).toInt(), a, "identity \(a)/\(b)")
}
}
func testBigDivMod() {
var big = BigInt.one
for k in 1...50 { big = big * BigInt(k) }
let divisor = BigInt(string: "1000000000000000000", radix: 10)!
let (q, r) = BigInt.divMod(big, divisor)
XCTAssertEqual((q * divisor + r), big)
XCTAssertTrue(r < divisor)
XCTAssertFalse(r.isNegative)
}
func testModulo() {
XCTAssertEqual(BigInt(-7).modulo(BigInt(3)).toInt(), 2)
XCTAssertEqual(BigInt(7).modulo(BigInt(3)).toInt(), 1)
XCTAssertEqual(BigInt(7).modulo(BigInt(-3)).toInt(), -2)
XCTAssertEqual(BigInt(-7).modulo(BigInt(-3)).toInt(), -1)
}
func testGcd() {
XCTAssertEqual(BigInt.gcd(BigInt(12), BigInt(18)).toInt(), 6)
XCTAssertEqual(BigInt.gcd(BigInt(0), BigInt(5)).toInt(), 5)
var a = BigInt.one
for k in 1...30 { a = a * BigInt(k) }
var b = BigInt.one
for k in 1...20 { b = b * BigInt(k) }
XCTAssertEqual(BigInt.gcd(a, b), b)
}
func testPower() {
XCTAssertEqual(BigInt(2).power(10).toInt(), 1024)
XCTAssertEqual(BigInt(2).power(64).description, "18446744073709551616")
XCTAssertEqual(BigInt(10).power(30).description, "1000000000000000000000000000000")
}
func testStringRoundTrip() {
let samples = [
"0", "1", "-1", "255", "4294967296", "18446744073709551616",
"-93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000",
]
for s in samples {
XCTAssertEqual(BigInt(string: s, radix: 10)?.description, s)
}
}
func testRadixConversion() {
XCTAssertEqual(BigInt(255).toString(radix: 16), "ff")
XCTAssertEqual(BigInt(255).toString(radix: 2), "11111111")
XCTAssertEqual(BigInt(string: "ff", radix: 16)?.toInt(), 255)
XCTAssertEqual(BigInt(string: "-101", radix: 2)?.toInt(), -5)
XCTAssertEqual(BigInt(1000000).toString(radix: 16), "f4240")
}
func testIsqrt() {
XCTAssertEqual(BigInt(0).isqrt().toInt(), 0)
XCTAssertEqual(BigInt(1).isqrt().toInt(), 1)
XCTAssertEqual(BigInt(15).isqrt().toInt(), 3)
XCTAssertEqual(BigInt(16).isqrt().toInt(), 4)
XCTAssertEqual(BigInt(17).isqrt().toInt(), 4)
let big = BigInt(string: "100000000000000000000", radix: 10)!
XCTAssertEqual(big.isqrt().toInt(), 10000000000)
}
func testComparison() {
XCTAssertTrue(BigInt(-5) < BigInt(3))
XCTAssertTrue(BigInt(3) < BigInt(5))
XCTAssertTrue(BigInt(string: "100000000000000000000", radix: 10)! > BigInt(Int.max))
XCTAssertTrue(BigInt(Int.min) < BigInt(0))
}
}