107 lines
4.2 KiB
Swift
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))
|
|
}
|
|
}
|