test(numeric): add bigint arithmetic tests
This commit is contained in:
1 parent
7ddcc0709d
commit
5e1aec0f78
1 file changed
+106
@@ -0,0 +1,106 @@
|
||||
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))
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user