mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
The test used Int.min and Int.max assuming that they are 64-bit integers. Use 64-bit integers explicitly instead.
590 lines
28 KiB
Swift
590 lines
28 KiB
Swift
// RUN: %target-run-simple-swift
|
|
// REQUIRES: executable_test
|
|
// UNSUPPORTED: use_os_stdlib, back_deployment_runtime
|
|
|
|
import StdlibUnittest
|
|
defer { runAllTests() }
|
|
|
|
var Int128Tests = TestSuite("Int128Tests")
|
|
|
|
Int128Tests.test("Memory layout") {
|
|
if #available(SwiftStdlib 6.0, *) {
|
|
// Size and stride must both be 16B.
|
|
expectEqual(MemoryLayout<Int128>.size, 16)
|
|
expectEqual(MemoryLayout<Int128>.stride, 16)
|
|
// Alignment must be at least that of UInt64, and no more than 16B.
|
|
expectTrue(
|
|
MemoryLayout<Int128>.alignment >= MemoryLayout<Int64>.alignment
|
|
)
|
|
expectTrue(MemoryLayout<Int128>.alignment <= 16)
|
|
|
|
// Size and stride must both be 16B.
|
|
expectEqual(MemoryLayout<UInt128>.size, 16)
|
|
expectEqual(MemoryLayout<UInt128>.stride, 16)
|
|
// Alignment must be at least that of UInt64, and no more than 16B.
|
|
expectTrue(
|
|
MemoryLayout<UInt128>.alignment >= MemoryLayout<UInt64>.alignment
|
|
)
|
|
expectTrue(MemoryLayout<UInt128>.alignment <= 16)
|
|
}
|
|
}
|
|
|
|
@available(SwiftStdlib 6.0, *)
|
|
extension UInt128 {
|
|
var high: UInt64 { UInt64(truncatingIfNeeded: self >> 64) }
|
|
var low: UInt64 { UInt64(truncatingIfNeeded: self) }
|
|
|
|
init(tenToThe n: Int) {
|
|
let tens: [UInt64] = [
|
|
1,
|
|
10,
|
|
100,
|
|
1000,
|
|
10000,
|
|
100000,
|
|
1000000,
|
|
10000000,
|
|
100000000,
|
|
1000000000,
|
|
10000000000,
|
|
100000000000,
|
|
1000000000000,
|
|
10000000000000,
|
|
100000000000000,
|
|
1000000000000000,
|
|
10000000000000000,
|
|
100000000000000000,
|
|
1000000000000000000,
|
|
10000000000000000000
|
|
]
|
|
if n <= 19 { self.init(tens[n]) }
|
|
else if n <= 38 {
|
|
let (hi, lo) = tens[19].multipliedFullWidth(by: tens[n - 19])
|
|
self = UInt128(hi) << 64 | UInt128(lo)
|
|
}
|
|
else { fatalError() }
|
|
}
|
|
}
|
|
|
|
@available(SwiftStdlib 6.0, *)
|
|
extension Int128 {
|
|
var high: Int64 { Int64(truncatingIfNeeded: self >> 64) }
|
|
var low: UInt64 { UInt64(truncatingIfNeeded: self) }
|
|
|
|
init(tenToThe n: Int) {
|
|
self.init(bitPattern: UInt128(tenToThe: n))
|
|
}
|
|
}
|
|
|
|
Int128Tests.test("Literals") {
|
|
if #available(SwiftStdlib 6.0, *) {
|
|
expectEqual(1, UInt128(tenToThe: 0))
|
|
expectEqual(10, UInt128(tenToThe: 1))
|
|
expectEqual(100, UInt128(tenToThe: 2))
|
|
expectEqual(1000, UInt128(tenToThe: 3))
|
|
expectEqual(10000, UInt128(tenToThe: 4))
|
|
expectEqual(100000, UInt128(tenToThe: 5))
|
|
expectEqual(1000000, UInt128(tenToThe: 6))
|
|
expectEqual(10000000, UInt128(tenToThe: 7))
|
|
expectEqual(100000000, UInt128(tenToThe: 8))
|
|
expectEqual(1000000000, UInt128(tenToThe: 9))
|
|
expectEqual(10000000000, UInt128(tenToThe: 10))
|
|
expectEqual(100000000000, UInt128(tenToThe: 11))
|
|
expectEqual(1000000000000, UInt128(tenToThe: 12))
|
|
expectEqual(10000000000000, UInt128(tenToThe: 13))
|
|
expectEqual(100000000000000, UInt128(tenToThe: 14))
|
|
expectEqual(1000000000000000, UInt128(tenToThe: 15))
|
|
expectEqual(10000000000000000, UInt128(tenToThe: 16))
|
|
expectEqual(100000000000000000, UInt128(tenToThe: 17))
|
|
expectEqual(1000000000000000000, UInt128(tenToThe: 18))
|
|
expectEqual(10000000000000000000, UInt128(tenToThe: 19))
|
|
expectEqual(100000000000000000000, UInt128(tenToThe: 20))
|
|
expectEqual(1000000000000000000000, UInt128(tenToThe: 21))
|
|
expectEqual(10000000000000000000000, UInt128(tenToThe: 22))
|
|
expectEqual(100000000000000000000000, UInt128(tenToThe: 23))
|
|
expectEqual(1000000000000000000000000, UInt128(tenToThe: 24))
|
|
expectEqual(10000000000000000000000000, UInt128(tenToThe: 25))
|
|
expectEqual(100000000000000000000000000, UInt128(tenToThe: 26))
|
|
expectEqual(1000000000000000000000000000, UInt128(tenToThe: 27))
|
|
expectEqual(10000000000000000000000000000, UInt128(tenToThe: 28))
|
|
expectEqual(100000000000000000000000000000, UInt128(tenToThe: 29))
|
|
expectEqual(1000000000000000000000000000000, UInt128(tenToThe: 30))
|
|
expectEqual(10000000000000000000000000000000, UInt128(tenToThe: 31))
|
|
expectEqual(100000000000000000000000000000000, UInt128(tenToThe: 32))
|
|
expectEqual(1000000000000000000000000000000000, UInt128(tenToThe: 33))
|
|
expectEqual(10000000000000000000000000000000000, UInt128(tenToThe: 34))
|
|
expectEqual(100000000000000000000000000000000000, UInt128(tenToThe: 35))
|
|
expectEqual(1000000000000000000000000000000000000, UInt128(tenToThe: 36))
|
|
expectEqual(10000000000000000000000000000000000000, UInt128(tenToThe: 37))
|
|
expectEqual(100000000000000000000000000000000000000, UInt128(tenToThe: 38))
|
|
|
|
expectEqual(1, Int128(tenToThe: 0))
|
|
expectEqual(10, Int128(tenToThe: 1))
|
|
expectEqual(100, Int128(tenToThe: 2))
|
|
expectEqual(1000, Int128(tenToThe: 3))
|
|
expectEqual(10000, Int128(tenToThe: 4))
|
|
expectEqual(100000, Int128(tenToThe: 5))
|
|
expectEqual(1000000, Int128(tenToThe: 6))
|
|
expectEqual(10000000, Int128(tenToThe: 7))
|
|
expectEqual(100000000, Int128(tenToThe: 8))
|
|
expectEqual(1000000000, Int128(tenToThe: 9))
|
|
expectEqual(10000000000, Int128(tenToThe: 10))
|
|
expectEqual(100000000000, Int128(tenToThe: 11))
|
|
expectEqual(1000000000000, Int128(tenToThe: 12))
|
|
expectEqual(10000000000000, Int128(tenToThe: 13))
|
|
expectEqual(100000000000000, Int128(tenToThe: 14))
|
|
expectEqual(1000000000000000, Int128(tenToThe: 15))
|
|
expectEqual(10000000000000000, Int128(tenToThe: 16))
|
|
expectEqual(100000000000000000, Int128(tenToThe: 17))
|
|
expectEqual(1000000000000000000, Int128(tenToThe: 18))
|
|
expectEqual(10000000000000000000, Int128(tenToThe: 19))
|
|
expectEqual(100000000000000000000, Int128(tenToThe: 20))
|
|
expectEqual(1000000000000000000000, Int128(tenToThe: 21))
|
|
expectEqual(10000000000000000000000, Int128(tenToThe: 22))
|
|
expectEqual(100000000000000000000000, Int128(tenToThe: 23))
|
|
expectEqual(1000000000000000000000000, Int128(tenToThe: 24))
|
|
expectEqual(10000000000000000000000000, Int128(tenToThe: 25))
|
|
expectEqual(100000000000000000000000000, Int128(tenToThe: 26))
|
|
expectEqual(1000000000000000000000000000, Int128(tenToThe: 27))
|
|
expectEqual(10000000000000000000000000000, Int128(tenToThe: 28))
|
|
expectEqual(100000000000000000000000000000, Int128(tenToThe: 29))
|
|
expectEqual(1000000000000000000000000000000, Int128(tenToThe: 30))
|
|
expectEqual(10000000000000000000000000000000, Int128(tenToThe: 31))
|
|
expectEqual(100000000000000000000000000000000, Int128(tenToThe: 32))
|
|
expectEqual(1000000000000000000000000000000000, Int128(tenToThe: 33))
|
|
expectEqual(10000000000000000000000000000000000, Int128(tenToThe: 34))
|
|
expectEqual(100000000000000000000000000000000000, Int128(tenToThe: 35))
|
|
expectEqual(1000000000000000000000000000000000000, Int128(tenToThe: 36))
|
|
expectEqual(10000000000000000000000000000000000000, Int128(tenToThe: 37))
|
|
expectEqual(100000000000000000000000000000000000000, Int128(tenToThe: 38))
|
|
|
|
expectEqual(0, UInt128.zero)
|
|
expectEqual(0xffffffffffffffff_ffffffffffffffff, UInt128.max)
|
|
expectEqual(340282366920938463463374607431768211455, UInt128.max)
|
|
|
|
expectEqual(0, Int128.zero)
|
|
expectEqual(0x7fffffffffffffff_ffffffffffffffff, Int128.max)
|
|
expectEqual(170141183460469231731687303715884105727, Int128.max)
|
|
expectEqual(-0x8000000000000000_0000000000000000, Int128.min)
|
|
expectEqual(-170141183460469231731687303715884105728, Int128.min)
|
|
}
|
|
}
|
|
|
|
@available(SwiftStdlib 6.0, *)
|
|
func testConversion(
|
|
_ input: some BinaryFloatingPoint,
|
|
_ r0: UInt128?,
|
|
exact: Bool = false,
|
|
line: UInt = #line
|
|
) {
|
|
var r1: UInt128? = nil
|
|
var r2: Int128? = nil
|
|
var r3: Int128? = nil
|
|
|
|
if let r0 {
|
|
if r0 == 0 { r1 = 0 }
|
|
if r0 <= Int128.max { r2 = Int128(bitPattern: r0) }
|
|
if r0 <= UInt128(bitPattern: Int128.max) &+ 1 {
|
|
r3 = Int128(bitPattern: 0 &- r0)
|
|
}
|
|
expectEqual(UInt128( input), r0, line: line)
|
|
if let r1 { expectEqual(UInt128(-input), r1, line: line) }
|
|
if let r2 { expectEqual( Int128( input), r2, line: line) }
|
|
if let r3 { expectEqual( Int128(-input), r3, line: line) }
|
|
}
|
|
|
|
if exact {
|
|
expectEqual(UInt128(exactly: input), r0, line: line)
|
|
expectEqual(UInt128(exactly: -input), r1, line: line)
|
|
expectEqual( Int128(exactly: input), r2, line: line)
|
|
expectEqual( Int128(exactly: -input), r3, line: line)
|
|
} else {
|
|
expectEqual(UInt128(exactly: input), nil, line: line)
|
|
expectEqual(UInt128(exactly: -input), nil, line: line)
|
|
expectEqual( Int128(exactly: input), nil, line: line)
|
|
expectEqual( Int128(exactly: -input), nil, line: line)
|
|
}
|
|
}
|
|
|
|
Int128Tests.test("Conversion from Double") {
|
|
if #available(SwiftStdlib 6.0, *) {
|
|
|
|
func testCase(
|
|
_ input: Double,
|
|
_ r0: UInt128?,
|
|
exact: Bool = false,
|
|
line: UInt = #line
|
|
) { testConversion(input, r0, exact: exact, line: line) }
|
|
|
|
testCase(.zero, 0, exact: true)
|
|
testCase(.leastNonzeroMagnitude, 0)
|
|
testCase(.leastNormalMagnitude, 0)
|
|
testCase(0x1.fffffffffffffp-1, 0)
|
|
testCase(0x1.0000000000000p0, 1, exact: true)
|
|
testCase(0x1.0000000000001p0, 1)
|
|
testCase(0x1.fffffffffffffp51, 0x000fffffffffffff)
|
|
testCase(0x1.0000000000000p52, 0x0010000000000000, exact: true)
|
|
testCase(0x1.0000000000001p52, 0x0010000000000001, exact: true)
|
|
testCase(0x1.fffffffffffffp63, 0x0000000000000000_fffffffffffff800, exact: true)
|
|
testCase(0x1.0000000000000p64, 0x0000000000000001_0000000000000000, exact: true)
|
|
testCase(0x1.0000000000001p64, 0x0000000000000001_0000000000001000, exact: true)
|
|
testCase(0x1.fffffffffffffp115, 0x000fffffffffffff_8000000000000000, exact: true)
|
|
testCase(0x1.0000000000000p116, 0x0010000000000000_0000000000000000, exact: true)
|
|
testCase(0x1.0000000000001p116, 0x0010000000000001_0000000000000000, exact: true)
|
|
testCase(0x1.fffffffffffffp126, 0x7ffffffffffffc00_0000000000000000, exact: true)
|
|
testCase(0x1.0000000000000p127, 0x8000000000000000_0000000000000000, exact: true)
|
|
testCase(0x1.0000000000001p127, 0x8000000000000800_0000000000000000, exact: true)
|
|
testCase(0x1.fffffffffffffp127, 0xfffffffffffff800_0000000000000000, exact: true)
|
|
testCase(0x1.0000000000000p128, nil)
|
|
testCase(0x1.0000000000001p128, nil)
|
|
testCase(0x1.fffffffffffffp1023, nil)
|
|
testCase(.infinity, nil)
|
|
testCase(.nan, nil)
|
|
}
|
|
}
|
|
|
|
Int128Tests.test("Conversion from Float") {
|
|
if #available(SwiftStdlib 6.0, *) {
|
|
|
|
func testCase(
|
|
_ input: Float,
|
|
_ r0: UInt128?,
|
|
exact: Bool = false,
|
|
line: UInt = #line
|
|
) { testConversion(input, r0, exact: exact, line: line) }
|
|
|
|
testCase(.zero, 0, exact: true)
|
|
testCase(.leastNonzeroMagnitude, 0)
|
|
testCase(.leastNormalMagnitude, 0)
|
|
testCase(0x1.fffffep-1, 0)
|
|
testCase(0x1.000000p0, 1, exact: true)
|
|
testCase(0x1.000002p0, 1)
|
|
testCase(0x1.fffffep22, 0x00000000007fffff)
|
|
testCase(0x1.000000p23, 0x0000000000800000, exact: true)
|
|
testCase(0x1.000002p23, 0x0000000000800001, exact: true)
|
|
testCase(0x1.fffffep63, 0x0000000000000000_ffffff0000000000, exact: true)
|
|
testCase(0x1.000000p64, 0x0000000000000001_0000000000000000, exact: true)
|
|
testCase(0x1.000002p64, 0x0000000000000001_0000020000000000, exact: true)
|
|
testCase(0x1.fffffep86, 0x00000000007fffff_8000000000000000, exact: true)
|
|
testCase(0x1.000000p87, 0x0000000000800000_0000000000000000, exact: true)
|
|
testCase(0x1.000002p87, 0x0000000000800001_0000000000000000, exact: true)
|
|
testCase(0x1.fffffep126, 0x7fffff8000000000_0000000000000000, exact: true)
|
|
testCase(0x1.000000p127, 0x8000000000000000_0000000000000000, exact: true)
|
|
testCase(0x1.000002p127, 0x8000010000000000_0000000000000000, exact: true)
|
|
testCase(0x1.fffffep127, 0xffffff0000000000_0000000000000000, exact: true)
|
|
testCase(.infinity, nil)
|
|
testCase(.nan, nil)
|
|
}
|
|
}
|
|
|
|
#if !((os(macOS) || targetEnvironment(macCatalyst)) && arch(x86_64))
|
|
Int128Tests.test("Conversion from Float16") {
|
|
if #available(SwiftStdlib 6.0, *) {
|
|
|
|
func testCase(
|
|
_ input: Float16,
|
|
_ r0: UInt128?,
|
|
exact: Bool = false,
|
|
line: UInt = #line
|
|
) { testConversion(input, r0, exact: exact, line: line) }
|
|
|
|
testCase(.zero, 0, exact: true)
|
|
testCase(.leastNonzeroMagnitude, 0)
|
|
testCase(.leastNormalMagnitude, 0)
|
|
testCase(0x1.ffcp-1, 0)
|
|
testCase(0x1.000p0, 1, exact: true)
|
|
testCase(0x1.004p0, 1)
|
|
testCase(0x1.ffcp9, 0x3ff)
|
|
testCase(0x1.000p10, 0x400, exact: true)
|
|
testCase(0x1.004p10, 0x401, exact: true)
|
|
testCase(0x1.ffcp15, 0xffe0, exact: true)
|
|
testCase(.infinity, nil)
|
|
testCase(.nan, nil)
|
|
}
|
|
}
|
|
#endif
|
|
|
|
Int128Tests.test("Conversion from integers") {
|
|
if #available(SwiftStdlib 6.0, *) {
|
|
expectEqual(Int128(truncatingIfNeeded: -1), -1)
|
|
expectEqual(Int128(truncatingIfNeeded: Int8.min), -0x80)
|
|
expectEqual(Int128(truncatingIfNeeded: Int8.max), 0x0000000000000000_000000000000007f)
|
|
expectEqual(Int128(truncatingIfNeeded: UInt8.max), 0x0000000000000000_00000000000000ff)
|
|
expectEqual(Int128(truncatingIfNeeded: Int64.min), -0x8000000000000000)
|
|
expectEqual(Int128(truncatingIfNeeded: Int64.max), 0x0000000000000000_7fffffffffffffff)
|
|
expectEqual(Int128(truncatingIfNeeded: UInt64.max), 0x0000000000000000_ffffffffffffffff)
|
|
|
|
expectEqual(Int128(exactly: -1), -1)
|
|
expectEqual(Int128(exactly: Int8.min), -0x80)
|
|
expectEqual(Int128(exactly: Int8.max), 0x7f)
|
|
expectEqual(Int128(exactly: UInt8.max), 0xff)
|
|
expectEqual(Int128(exactly: Int64.min), -0x8000000000000000)
|
|
expectEqual(Int128(exactly: Int64.max), 0x7fffffffffffffff)
|
|
expectEqual(Int128(exactly: UInt64.max), 0xffffffffffffffff)
|
|
|
|
expectEqual(Int128(clamping: -1), -1)
|
|
expectEqual(Int128(clamping: Int8.min), -0x80)
|
|
expectEqual(Int128(clamping: Int8.max), 0x7f)
|
|
expectEqual(Int128(clamping: UInt8.max), 0xff)
|
|
expectEqual(Int128(clamping: Int64.min), -0x8000000000000000)
|
|
expectEqual(Int128(clamping: Int64.max), 0x7fffffffffffffff)
|
|
expectEqual(Int128(clamping: UInt64.max), 0xffffffffffffffff)
|
|
|
|
expectEqual(UInt128(truncatingIfNeeded: -1), 0xffffffffffffffff_ffffffffffffffff)
|
|
expectEqual(UInt128(truncatingIfNeeded: Int8.min), 0xffffffffffffffff_ffffffffffffff80)
|
|
expectEqual(UInt128(truncatingIfNeeded: Int8.max), 0x0000000000000000_000000000000007f)
|
|
expectEqual(UInt128(truncatingIfNeeded: UInt8.max),0x0000000000000000_00000000000000ff)
|
|
expectEqual(UInt128(truncatingIfNeeded: Int64.min), 0xffffffffffffffff_8000000000000000)
|
|
expectEqual(UInt128(truncatingIfNeeded: Int64.max), 0x0000000000000000_7fffffffffffffff)
|
|
expectEqual(UInt128(truncatingIfNeeded: UInt64.max), 0x0000000000000000_ffffffffffffffff)
|
|
|
|
expectEqual(UInt128(exactly: -1), nil)
|
|
expectEqual(UInt128(exactly: Int8.min), nil)
|
|
expectEqual(UInt128(exactly: Int8.max), 0x7f)
|
|
expectEqual(UInt128(exactly: UInt8.max), 0xff)
|
|
expectEqual(UInt128(exactly: Int64.min), nil)
|
|
expectEqual(UInt128(exactly: Int64.max), 0x7fffffffffffffff)
|
|
expectEqual(UInt128(exactly: UInt64.max), 0xffffffffffffffff)
|
|
|
|
expectEqual(UInt128(clamping: -1), 0)
|
|
expectEqual(UInt128(clamping: Int8.min), 0)
|
|
expectEqual(UInt128(clamping: Int8.max), 0x7f)
|
|
expectEqual(UInt128(clamping: UInt8.max),0xff)
|
|
expectEqual(UInt128(clamping: Int64.min), 0)
|
|
expectEqual(UInt128(clamping: Int64.max), 0x7fffffffffffffff)
|
|
expectEqual(UInt128(clamping: UInt64.max), 0xffffffffffffffff)
|
|
}
|
|
}
|
|
|
|
Int128Tests.test("Bytes and words") {
|
|
if #available(SwiftStdlib 6.0, *) {
|
|
let ascending: Int128 = 0x0f0e0d0c0b0a09080706050403020100
|
|
let descending: Int128 = 0x000102030405060708090a0b0c0d0e0f
|
|
expectEqual(ascending.byteSwapped, descending)
|
|
#if _endian(little)
|
|
expectEqual(ascending.littleEndian, ascending)
|
|
expectEqual(ascending.bigEndian, descending)
|
|
#else
|
|
expectEqual(ascending.littleEndian, descending)
|
|
expectEqual(ascending.bigEndian, ascending)
|
|
#endif
|
|
#if _pointerBitWidth(_32)
|
|
expectEqual(ascending.words[0], 0x03020100)
|
|
expectEqual(ascending.words[3], 0x0f0e0d0c)
|
|
#else
|
|
expectEqual(ascending.words[0], 0x0706050403020100)
|
|
expectEqual(ascending.words[1], 0x0f0e0d0c0b0a0908)
|
|
#endif
|
|
}
|
|
}
|
|
|
|
Int128Tests.test("Bitwise operations") {
|
|
if #available(SwiftStdlib 6.0, *) {
|
|
let a: UInt128 = 0xffff0000ffff0000_ffff0000ffff0000
|
|
let b: UInt128 = 0xf0e0d0c0b0a09080_7060504030201000
|
|
expectEqual(~a, 0x0000ffff0000ffff_0000ffff0000ffff)
|
|
expectEqual(~b, 0x0f1f2f3f4f5f6f7f_8f9fafbfcfdfefff)
|
|
expectEqual(a & b, 0xf0e00000b0a00000_7060000030200000)
|
|
expectEqual(a | b, 0xffffd0c0ffff9080_ffff5040ffff1000)
|
|
expectEqual(a ^ b, 0x0f1fd0c04f5f9080_8f9f5040cfdf1000)
|
|
|
|
expectEqual(a &>> 0, a)
|
|
expectEqual(a &>> 1, 0x7fff80007fff8000_7fff80007fff8000)
|
|
expectEqual(a &>> 2, 0x3fffc0003fffc000_3fffc0003fffc000)
|
|
expectEqual(a &>> 3, 0x1fffe0001fffe000_1fffe0001fffe000)
|
|
expectEqual(a &>> 4, 0x0ffff0000ffff000_0ffff0000ffff000)
|
|
expectEqual(b &>> 8, 0x00f0e0d0c0b0a090_8070605040302010)
|
|
expectEqual(b &>> 16, 0x0000f0e0d0c0b0a0_9080706050403020)
|
|
expectEqual(b &>> 32, 0x00000000f0e0d0c0_b0a0908070605040)
|
|
expectEqual(b &>> 64, 0x0000000000000000_f0e0d0c0b0a09080)
|
|
expectEqual(b &>> 127, 0x0000000000000000_0000000000000001)
|
|
expectEqual(b &>> 128, b)
|
|
|
|
expectEqual(a &<< 0, a)
|
|
expectEqual(a &<< 1, 0xfffe0001fffe0001_fffe0001fffe0000)
|
|
expectEqual(a &<< 2, 0xfffc0003fffc0003_fffc0003fffc0000)
|
|
expectEqual(a &<< 3, 0xfff80007fff80007_fff80007fff80000)
|
|
expectEqual(a &<< 4, 0xfff0000ffff0000f_fff0000ffff00000)
|
|
expectEqual(b &<< 8, 0xe0d0c0b0a0908070_6050403020100000)
|
|
expectEqual(b &<< 16, 0xd0c0b0a090807060_5040302010000000)
|
|
expectEqual(b &<< 32, 0xb0a0908070605040_3020100000000000)
|
|
expectEqual(b &<< 64, 0x7060504030201000_0000000000000000)
|
|
expectEqual(b &<< 127, 0x0000000000000000_0000000000000000)
|
|
expectEqual(b &<< 128, b)
|
|
|
|
expectEqual(a.nonzeroBitCount, 64)
|
|
expectEqual(b.nonzeroBitCount, 32)
|
|
for i in 0 ..< 128 {
|
|
expectEqual((a >> i).leadingZeroBitCount, i)
|
|
expectEqual((~a << i).trailingZeroBitCount, i)
|
|
}
|
|
}
|
|
}
|
|
|
|
Int128Tests.test("Addition and subtraction") {
|
|
if #available(SwiftStdlib 6.0, *) {
|
|
func testCase(
|
|
_ a: UInt128,
|
|
_ b: UInt128,
|
|
_ r: UInt128,
|
|
_ c: Bool,
|
|
line: UInt = #line
|
|
) {
|
|
|
|
expectEqual(a.addingReportingOverflow(b), (r, c), line: line)
|
|
expectEqual(r.subtractingReportingOverflow(b), (a, c), line: line)
|
|
expectEqual(a &+ b, r, line: line)
|
|
expectEqual(r &- b, a, line: line)
|
|
if !c {
|
|
expectEqual(a + b, r, line: line)
|
|
expectEqual(r - b, a, line: line)
|
|
}
|
|
|
|
let sa = Int128(bitPattern: a)
|
|
let sb = Int128(bitPattern: b)
|
|
let sr = Int128(bitPattern: r)
|
|
let o = (sr < sa) != (sb < 0)
|
|
|
|
expectEqual(sa.addingReportingOverflow(sb), (sr, o), line: line)
|
|
expectEqual(sr.subtractingReportingOverflow(sb), (sa, o), line: line)
|
|
expectEqual(sa &+ sb, sr, line: line)
|
|
expectEqual(sr &- sb, sa, line: line)
|
|
if !o {
|
|
expectEqual(sa + sb, sr, line: line)
|
|
expectEqual(sr - sb, sa, line: line)
|
|
}
|
|
}
|
|
|
|
testCase(0x22cece8fc3a992208da8556f20cd17b4, 0x5bf62486bf4d907e675fa524340e9d5a, 0x7ec4f31682f7229ef507fa9354dbb50e, false)
|
|
testCase(0xe9584e473c12b6939c5082bc1a6fefb8, 0xff05d7ed3e790d90d5ef9ebcb73d9069, 0xe85e26347a8bc42472402178d1ad8021, true)
|
|
testCase(0x7a798c5a2be3c25d535afa5034515452, 0x0d0ace9628ab60f1daf587b6b67c955c, 0x87845af0548f234f2e508206eacde9ae, false)
|
|
testCase(0xc705e6d4914456f1f2d06da52636e43f, 0xbbe6d539ab4547db2ad744ed53397a35, 0x82ecbc0e3c899ecd1da7b29279705e74, true)
|
|
testCase(0xf430bcb091f4ef9a4d85491e20ba04f8, 0x926a7b2ac49990b5199158bad743b159, 0x869b37db568e804f6716a1d8f7fdb651, true)
|
|
testCase(0xb60e3a058cd6e09533e5e033531cfd51, 0xdb158676610e7781644a11bbbaad0d4b, 0x9123c07bede55816982ff1ef0dca0a9c, true)
|
|
testCase(0xfa89a0decc7cd118ac1d6dc1c2a5551e, 0x4c7b749f2026fb70073991476ae8b14b, 0x4705157deca3cc88b356ff092d8e0669, true)
|
|
testCase(0x28cf1805ce5619540dc3865f3333a1c7, 0x4540a2f2904597acb76aad187dd2bd8c, 0x6e0fbaf85e9bb100c52e3377b1065f53, false)
|
|
testCase(0xfdcdfed4461bb6b5a2f9e820c942a23e, 0x56dbb5736acdf88a7ec689411190b1ee, 0x54a9b447b0e9af4021c07161dad3542c, true)
|
|
testCase(0x7bbaa57afd5f00ab23217777a34a1aeb, 0xc4e44711b56b4225de042bfca852ce05, 0x409eec8cb2ca42d10125a3744b9ce8f0, true)
|
|
testCase(0x1b7c7c6a905f48c0a75bf01a4dba2b15, 0x939db97340982bf994095590073c0273, 0xaf1a35ddd0f774ba3b6545aa54f62d88, false)
|
|
testCase(0xdedff2c264dfccd2911a30751905e0f1, 0x251cb12e47c0e6549816bc8f56a7de47, 0x03fca3f0aca0b3272930ed046fadbf38, true)
|
|
testCase(0x9f6673d7eb5c5d20be751255bfd8aab6, 0x03063926cb83f35999f2b84fec4c75a6, 0xa26cacfeb6e0507a5867caa5ac25205c, false)
|
|
testCase(0x64946c1e78af2b998861717ca84635a7, 0x41a8c07dd680babe0dc1cc2895f8743d, 0xa63d2c9c4f2fe65796233da53e3ea9e4, false)
|
|
testCase(0x1b6a36a075037a69d0801fc3370f7d0c, 0x243d24a92779ca04e96bebe55f4cf489, 0x3fa75b499c7d446eb9ec0ba8965c7195, false)
|
|
testCase(0xbd30fd9f09cc20a80b6bd90d4d56a816, 0x1767f07efe015f0f848325a5efe2ccb0, 0xd498ee1e07cd7fb78feefeb33d3974c6, false)
|
|
}
|
|
}
|
|
|
|
Int128Tests.test("Wide multiplication and division") {
|
|
if #available(SwiftStdlib 6.0, *) {
|
|
func testCase(
|
|
_ a: UInt128,
|
|
_ b: UInt128,
|
|
_ h: UInt128,
|
|
_ l: UInt128,
|
|
line: UInt = #line
|
|
) {
|
|
expectEqual(a.multipliedFullWidth(by: b), (h, l), line: line)
|
|
expectEqual(a &* b, l, line: line)
|
|
expectEqual(a.dividingFullWidth((high: h, low: l)), (b, 0), line: line)
|
|
let (l1, c) = l.addingReportingOverflow(a &- 1)
|
|
let h1 = h &+ (c ? 1 : 0)
|
|
expectEqual(a.dividingFullWidth((high: h1, low: l1)), (b, a &- 1), line: line)
|
|
let sa = Int128(bitPattern: a)
|
|
let sb = Int128(bitPattern: b)
|
|
let sh = Int128(bitPattern: h) &- (sa < 0 ? sb : 0) &- (sb < 0 ? sa : 0)
|
|
expectEqual(sa.multipliedFullWidth(by: sb), (sh, l), line: line)
|
|
expectEqual(sa &* sb, Int128(bitPattern: l), line: line)
|
|
expectEqual(sa.dividingFullWidth((high: sh, low: l)), (sb, 0), line: line)
|
|
let rem = sa.magnitude &- 1
|
|
if sh < 0 {
|
|
let (l1, c) = l.subtractingReportingOverflow(rem)
|
|
let h1 = sh &- (c ? 1 : 0)
|
|
expectEqual(sa.dividingFullWidth((high: h1, low: l1)), (sb, -Int128(rem)), line: line)
|
|
} else {
|
|
let (l1, c) = l.addingReportingOverflow(rem)
|
|
let h1 = sh &+ (c ? 1 : 0)
|
|
expectEqual(sa.dividingFullWidth((high: h1, low: l1)), (sb, Int128(rem)), line: line)
|
|
}
|
|
}
|
|
|
|
testCase(0x14f6c7bb051951bc8f36082753d0ad15, 0xdba081b2a9cde4e20c6778833e3795dd, 0x11fc41b8ce63bc91660b4e6b14214280, 0xc0c6e5ba6909c6bdaf80e33b1565a421)
|
|
testCase(0x4e0d20760a881de82733cea44f83b686, 0xff6f66e9e75392e824ff2eca4b114ad4, 0x4de10a6733150dc755f9f237e920c12d, 0x2d3e5a1b8508cace5d0b97024cbbe2f8)
|
|
testCase(0x2e79ffe8593c337e6711ce338d24e68e, 0x0865ae2d496547bef886cbd8cd01a507, 0x018645c05e2a2bfc986d97269c67548c, 0x2d7cc7781078868df9e718f64129d3e2)
|
|
testCase(0xb87ba0a48cef1ec31e29e9fdcfe2df98, 0x9562e44cdf7d2b477a13fab32c518a8a, 0x6ba73858c5d9434d32fe784903ab229f, 0x1f3fad1dd5d313f4760981613bec77f0)
|
|
testCase(0x9e592a6a645a5a122f2d8d91f0fd4a41, 0xe47f8b71ee5f8d6dcd106a0a948cd06c, 0x8d564e43aefdbe7ee9c60f4be7a313fd, 0x7ff590f409e22d36b114575ba6bc236c)
|
|
testCase(0x9b729e658174948344571ef72b076a27, 0x6974e6724777c407350cee21ff34c571, 0x4008fed5c6d6b87d6f8fe810feb01738, 0xbeb752f23799535430d2f07c1be1de37)
|
|
testCase(0xba8a7af31e765b55d6c25fe76afa6e07, 0x0be8692c259620beb17be8b4841dfda6, 0x08ad4d6ad640f33caf27840505980f1d, 0x7618d3e7bfedd9a16b5ad8ceefeb438a)
|
|
testCase(0xe5cd79731d8679e5e42ec8202a94d8dc, 0xa6ce214fa3403650c9e18694a06cda68, 0x95bc45ff5962bf0a20cb37f6e1f43e74, 0xc994fba22acbcb3eee8836d909f37160)
|
|
testCase(0xeb220b552e8fe3f9b132220667a22feb, 0x0becf5688f15a28f25a35c735a84dec7, 0x0af41b46b9a01f0b0d307b1f8fdd81ce, 0xa11503513c983a2753eb6fe387cd09ad)
|
|
testCase(0x5d169627de62266ddbc59265a154a308, 0x42ca365c49a2c5e15014254b2152a827, 0x18495a4d155bc7a7f7e315f7c6bdaa0d, 0x43ba59ef45fee3ccdd8180d35f721638)
|
|
testCase(0x74c28baa7abcef0ea57e0c83cc235eeb, 0xc2cd3db0b1fda551418574c229518cf8, 0x58d909c3fabd4d2348cc26c441ee3ee9, 0x8108c4836103e2ca0740decbc58777a8)
|
|
testCase(0x9fc1c89a4461a31e84eb3efe62d99eb8, 0x82c936fe8a96d4875ffb2b24b3994035, 0x519df95690eb6f4aac34ff7f7962ce45, 0x8a1753bb4bf2aade34461b4b62b3dc18)
|
|
testCase(0xa98fd77674c6933fd8092428742d1365, 0x7dc38f365a41e190913d42048216dce3, 0x534cc3a14fbabc0c6bde9041864620cf, 0xa324e403eec48789556c0b02b550fe8f)
|
|
testCase(0x970ec5575cbe7d2ce36963a03c8c9b67, 0x4bcad32daf8b4d550ee233b364ca5c48, 0x2cb9021470effa54bb93f9e9ecdafef2, 0x8fdbf661c079405b35bc7c7f6aaab8f8)
|
|
testCase(0x7600cffa32b6e9cf26b67a223ef199f0, 0x81dde6c0a4c20f27f46bee142b5d1d3b, 0x3bdcb1de25f4b1c5f4a752037488e46d, 0x3b388b97a7358b645634a0661c4eaa50)
|
|
testCase(0x66bf68e43bb06f1518298f5b3f44dfd2, 0x2aae55e5a54ca26fb9065285487add11, 0x11215fc8765040c025ded1c61f6bf4e2, 0xce48257020acb07866315c8d62df26f2)
|
|
}
|
|
}
|
|
|
|
Int128Tests.test("Narrow multiplication and division") {
|
|
if #available(SwiftStdlib 6.0, *) {
|
|
func testCase(
|
|
_ a: UInt128,
|
|
_ b: UInt128,
|
|
_ q: UInt128,
|
|
_ r: UInt128,
|
|
line: UInt = #line
|
|
) {
|
|
expectEqual(a, b*q + r, line: line)
|
|
expectEqual(a, b&*q &+ r, line: line)
|
|
expectEqual(q, a/b, line: line)
|
|
expectEqual(r, a%b, line: line)
|
|
expectEqual((q,r), a.quotientAndRemainder(dividingBy: b), line: line)
|
|
for sgn in 0 ..< 4 {
|
|
let sa = (sgn & 1 == 0 ? 1 : -1) * Int128(bitPattern: a)
|
|
let sb = (sgn & 2 == 0 ? 1 : -1) * Int128(bitPattern: b)
|
|
let sq = (sgn == 0 || sgn == 3 ? 1 : -1) * Int128(bitPattern: q)
|
|
let sr = (sgn & 1 == 0 ? 1 : -1) * Int128(bitPattern: r)
|
|
expectEqual(sa, sb*sq + sr, line: line)
|
|
expectEqual(sa, sb&*sq &+ sr, line: line)
|
|
expectEqual(sq, sa/sb, line: line)
|
|
expectEqual(sr, sa%sb, line: line)
|
|
expectEqual((sq,sr), sa.quotientAndRemainder(dividingBy: sb), line: line)
|
|
}
|
|
}
|
|
testCase(0x2d, 0x1, 0x2d, 0x0)
|
|
testCase(0x809b, 0x3f, 0x20a, 0x25)
|
|
testCase(0x1ffe1f, 0xb73df, 0x2, 0x91661)
|
|
testCase(0x6b324345, 0x2ff256, 0x23c, 0x10cb1d)
|
|
testCase(0x8b1339b357, 0x31e, 0x2c9d960a, 0x2b)
|
|
testCase(0x2517b04df6ce, 0x23abc4a, 0x10a33c, 0x6b776)
|
|
testCase(0x21e7e8fa820294, 0x880fb, 0x3fcb4bafa, 0x1af76)
|
|
testCase(0xde4770ddf9e0f3d3, 0x65af7, 0x22f9a7842600, 0x449d3)
|
|
testCase(0x33f29c91b6bc266b83, 0xc7, 0x42d3c2fbc5c50466, 0x39)
|
|
testCase(0xc5b6d1764958768637e9, 0x1a, 0x79ab94978f98e679fb0, 0x9)
|
|
testCase(0x45b7f2f79a6d80e6c51aca, 0x16322b389a60ca4, 0x3241b89a, 0x8e20ef8227a022)
|
|
testCase(0x917f58ede4323d3ba84bd18d, 0x604e0, 0x182c40337c3375ba4a05, 0x4f92d)
|
|
testCase(0x82f81933bff7f5eac96a153a7d, 0x5dfd04eff918d9c8e73bc217, 0x164, 0x443e560991670f67dafb5281)
|
|
testCase(0x1c2f66fc69f41900b99513223c17, 0x958363a31680f9c30, 0x3042609f065, 0x844cb780cc4dc9d27)
|
|
testCase(0x35fd60b643a620e916d79ed68f6456, 0x7ecdc2aa76f2b195896e3a0d, 0x6cff88, 0x442240b30e2e91c88ab19a6e)
|
|
testCase(0x4e1d078976ed907b2b06ec3ab6c09750, 0x17, 0x3656fa1cd84c37fca37f4028d82ceed, 0x5)
|
|
}
|
|
}
|
|
|
|
Int128Tests.test("String roundtrip") {
|
|
if #available(SwiftStdlib 6.0, *) {
|
|
let values: [UInt128] = [
|
|
0x8000ffff0000ffff_0000ffff0000ffff,
|
|
0x80f0e0d0c0b0a090_8070605040302010,
|
|
0x0000000000000000_ffffffffffffffff,
|
|
0xffffffffffffffff_ffffffffffffffff
|
|
]
|
|
for a in values {
|
|
expectEqual(a, UInt128(String(a)))
|
|
}
|
|
for a in values.map(Int128.init(bitPattern:)) {
|
|
expectEqual(a, Int128(String(a)))
|
|
}
|
|
}
|
|
}
|