mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
357 lines
9.9 KiB
Swift
357 lines
9.9 KiB
Swift
// RUN: %target-run-simple-swift
|
|
// REQUIRES: executable_test
|
|
|
|
import StdlibUnittest
|
|
|
|
var dwTests = TestSuite("DoubleWidth")
|
|
|
|
typealias UInt128 = DoubleWidth<UInt64>
|
|
typealias UInt256 = DoubleWidth<UInt128>
|
|
typealias UInt512 = DoubleWidth<UInt256>
|
|
typealias UInt1024 = DoubleWidth<UInt512>
|
|
|
|
typealias Int128 = DoubleWidth<Int64>
|
|
typealias Int256 = DoubleWidth<Int128>
|
|
typealias Int512 = DoubleWidth<Int256>
|
|
typealias Int1024 = DoubleWidth<Int512>
|
|
|
|
func checkSignedIntegerConformance<T: SignedInteger>(_ x: T) {}
|
|
func checkUnsignedIntegerConformance<T: UnsignedInteger>(_ x: T) {}
|
|
|
|
dwTests.test("Literals") {
|
|
let w: DoubleWidth<UInt8> = 100
|
|
expectTrue(w == 100 as Int)
|
|
|
|
let x: DoubleWidth<UInt8> = 1000
|
|
expectTrue(x == 1000 as Int)
|
|
|
|
let y: DoubleWidth<Int8> = 1000
|
|
expectTrue(y == 1000 as Int)
|
|
|
|
let z: DoubleWidth<Int8> = -1000
|
|
expectTrue(z == -1000 as Int)
|
|
|
|
expectCrashLater()
|
|
_ = -1 as DoubleWidth<UInt8>
|
|
}
|
|
|
|
dwTests.test("Literals/Large/Signed") {
|
|
let a: Int256 =
|
|
0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
|
let b: Int256 =
|
|
-0x8000000000000000000000000000000000000000000000000000000000000000
|
|
expectEqual(a, Int256.max)
|
|
expectEqual(b, Int256.min)
|
|
expectCrashLater()
|
|
_ = -0x8000000000000000000000000000000000000000000000000000000000000001
|
|
as Int256
|
|
}
|
|
|
|
dwTests.test("Literals/Large/SignedOverflow") {
|
|
expectCrashLater()
|
|
_ = 0x8000000000000000000000000000000000000000000000000000000000000000
|
|
as Int256
|
|
}
|
|
|
|
dwTests.test("Literals/Large/Unsigned") {
|
|
let a: UInt256 =
|
|
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
|
let b: UInt256 = 0
|
|
expectEqual(a, UInt256.max)
|
|
expectEqual(b, UInt256.min)
|
|
expectCrashLater()
|
|
_ = -1 as UInt256
|
|
}
|
|
|
|
dwTests.test("Literals/Large/UnsignedOverflow") {
|
|
expectCrashLater()
|
|
_ = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0
|
|
as UInt256
|
|
}
|
|
|
|
dwTests.test("Arithmetic/unsigned") {
|
|
let x: DoubleWidth<UInt8> = 1000
|
|
let y: DoubleWidth<UInt8> = 1111
|
|
expectEqual(x + 1, 1001)
|
|
expectEqual(x + x, 2000)
|
|
expectEqual(x - (1 as DoubleWidth<UInt8>), 999)
|
|
expectEqual(x - x, 0)
|
|
expectEqual(y - x, 111)
|
|
|
|
expectEqual(x * 7, 7000)
|
|
expectEqual(y * 7, 7777)
|
|
|
|
expectEqual(x / 3, 333)
|
|
expectEqual(x / x, 1)
|
|
expectEqual(x / y, 0)
|
|
expectEqual(y / x, 1)
|
|
|
|
expectEqual(x % 3, 1)
|
|
expectEqual(x % y, x)
|
|
}
|
|
|
|
dwTests.test("Arithmetic/signed") {
|
|
let x: DoubleWidth<Int8> = 1000
|
|
let y: DoubleWidth<Int8> = -1111
|
|
expectEqual(x + 1, 1001)
|
|
expectEqual(x + x, 2000)
|
|
expectEqual(x - (1 as DoubleWidth<Int8>), 999)
|
|
expectEqual(x - x, 0)
|
|
expectEqual(0 - x, -1000)
|
|
expectEqual(x + y, -111)
|
|
expectEqual(x - y, 2111)
|
|
|
|
expectEqual(x * 7, 7000)
|
|
expectEqual(y * 7, -7777)
|
|
expectEqual(x * -7, -7000)
|
|
expectEqual(y * -7, 7777)
|
|
|
|
expectEqual(x / 3, 333)
|
|
expectEqual(x / -3, -333)
|
|
expectEqual(x / x, 1)
|
|
expectEqual(x / y, 0)
|
|
expectEqual(y / x, -1)
|
|
expectEqual(y / y, 1)
|
|
|
|
expectEqual(x % 3, 1)
|
|
expectEqual(x % -3, 1)
|
|
expectEqual(y % 3, -1)
|
|
expectEqual(y % -3, -1)
|
|
|
|
expectEqual(-y, 1111)
|
|
expectEqual(-x, -1000)
|
|
}
|
|
|
|
dwTests.test("Nested") {
|
|
do {
|
|
let x = UInt1024.max
|
|
let (y, o) = x.addingReportingOverflow(1)
|
|
expectEqual(y, 0)
|
|
expectTrue(y == (0 as Int))
|
|
expectTrue(o)
|
|
}
|
|
|
|
do {
|
|
let x = Int1024.max
|
|
let (y, o) = x.addingReportingOverflow(1)
|
|
expectEqual(y, Int1024.min)
|
|
expectLT(y, 0)
|
|
expectTrue(y < (0 as Int))
|
|
expectTrue(y < (0 as UInt))
|
|
expectTrue(o)
|
|
}
|
|
|
|
expectFalse(UInt1024.isSigned)
|
|
expectEqual(UInt1024.bitWidth, 1024)
|
|
expectTrue(Int1024.isSigned)
|
|
expectEqual(Int1024.bitWidth, 1024)
|
|
|
|
expectEqualSequence(
|
|
UInt1024.max.words, repeatElement(UInt.max, count: 1024 / UInt.bitWidth))
|
|
}
|
|
|
|
dwTests.test("inits") {
|
|
typealias DWU16 = DoubleWidth<UInt8>
|
|
|
|
expectTrue(DWU16(UInt16.max) == UInt16.max)
|
|
expectNil(DWU16(exactly: UInt32.max))
|
|
expectEqual(DWU16(truncatingIfNeeded: UInt64.max), DWU16.max)
|
|
|
|
expectCrashLater()
|
|
_ = DWU16(UInt32.max)
|
|
}
|
|
|
|
dwTests.test("TwoWords") {
|
|
typealias DW = DoubleWidth<Int>
|
|
|
|
expectEqual(-1 as DW, DW(truncatingIfNeeded: -1 as Int8))
|
|
|
|
expectNil(Int(exactly: DW(Int.min) - 1))
|
|
expectNil(Int(exactly: DW(Int.max) + 1))
|
|
|
|
expectTrue(DW(Int.min) - 1 < Int.min)
|
|
expectTrue(DW(Int.max) + 1 > Int.max)
|
|
}
|
|
|
|
dwTests.test("Bitshifts") {
|
|
typealias DWU64 = DoubleWidth<DoubleWidth<DoubleWidth<UInt8>>>
|
|
typealias DWI64 = DoubleWidth<DoubleWidth<DoubleWidth<Int8>>>
|
|
|
|
func f<T: FixedWidthInteger, U: FixedWidthInteger>(_ x: T, type: U.Type) {
|
|
let y = U(x)
|
|
expectEqual(T.bitWidth, U.bitWidth)
|
|
for i in -(T.bitWidth + 1)...(T.bitWidth + 1) {
|
|
expectTrue(x << i == y << i)
|
|
expectTrue(x >> i == y >> i)
|
|
|
|
expectTrue(x &<< i == y &<< i)
|
|
expectTrue(x &>> i == y &>> i)
|
|
}
|
|
}
|
|
|
|
f(1 as UInt64, type: DWU64.self)
|
|
f(~(~0 as UInt64 >> 1), type: DWU64.self)
|
|
f(UInt64.max, type: DWU64.self)
|
|
// 0b01010101_10100101_11110000_10100101_11110000_10100101_11110000_10100101
|
|
f(17340530535757639845 as UInt64, type: DWU64.self)
|
|
|
|
f(1 as Int64, type: DWI64.self)
|
|
f(Int64.min, type: DWI64.self)
|
|
f(Int64.max, type: DWI64.self)
|
|
// 0b01010101_10100101_11110000_10100101_11110000_10100101_11110000_10100101
|
|
f(6171603459878809765 as Int64, type: DWI64.self)
|
|
}
|
|
|
|
dwTests.test("Remainder/DividingBy0") {
|
|
func f(_ x: Int1024, _ y: Int1024) -> Int1024 {
|
|
return x % y
|
|
}
|
|
expectCrashLater()
|
|
_ = f(42, 0)
|
|
}
|
|
|
|
dwTests.test("Division/By0") {
|
|
func f(_ x: Int1024, _ y: Int1024) -> Int1024 {
|
|
return x / y
|
|
}
|
|
expectCrashLater()
|
|
_ = f(42, 0)
|
|
}
|
|
|
|
dwTests.test("DivideMinByMinusOne") {
|
|
func f(_ x: Int1024) -> Int1024 {
|
|
return x / -1
|
|
}
|
|
expectCrashLater()
|
|
_ = f(Int1024.min)
|
|
}
|
|
|
|
dwTests.test("MultiplyMinByMinusOne") {
|
|
func f(_ x: Int1024) -> Int1024 {
|
|
return x * -1
|
|
}
|
|
expectCrashLater()
|
|
_ = f(Int1024.min)
|
|
}
|
|
|
|
typealias DWI16 = DoubleWidth<Int8>
|
|
typealias DWU16 = DoubleWidth<UInt8>
|
|
|
|
dwTests.test("Conversions") {
|
|
expectTrue(DWI16(1 << 15 - 1) == Int(1 << 15 - 1))
|
|
expectTrue(DWI16(-1 << 15) == Int(-1 << 15))
|
|
expectTrue(DWU16(1 << 16 - 1) == Int(1 << 16 - 1))
|
|
expectTrue(DWU16(0) == Int(0))
|
|
|
|
expectTrue(DWI16(Double(1 << 15 - 1)) == Int(1 << 15 - 1))
|
|
expectTrue(DWI16(Double(-1 << 15)) == Int(-1 << 15))
|
|
expectTrue(DWU16(Double(1 << 16 - 1)) == Int(1 << 16 - 1))
|
|
expectTrue(DWU16(Double(0)) == Int(0))
|
|
|
|
expectTrue(DWI16(Double(1 << 15 - 1) + 0.9) == Int(1 << 15 - 1))
|
|
expectTrue(DWI16(Double(-1 << 15) - 0.9) == Int(-1 << 15))
|
|
expectTrue(DWU16(Double(1 << 16 - 1) + 0.9) == Int(1 << 16 - 1))
|
|
expectTrue(DWU16(Double(0) - 0.9) == Int(0))
|
|
|
|
expectEqual(DWI16(0.00001), 0)
|
|
expectEqual(DWU16(0.00001), 0)
|
|
}
|
|
|
|
dwTests.test("Exact Conversions") {
|
|
expectEqual(DWI16(Double(1 << 15 - 1)), DWI16(exactly: Double(1 << 15 - 1))!)
|
|
expectEqual(DWI16(Double(-1 << 15)), DWI16(exactly: Double(-1 << 15))!)
|
|
expectEqual(DWU16(Double(1 << 16 - 1)), DWU16(exactly: Double(1 << 16 - 1))!)
|
|
expectEqual(DWU16(Double(0)), DWU16(exactly: Double(0))!)
|
|
|
|
expectNil(DWI16(exactly: Double(1 << 15 - 1) + 0.9))
|
|
expectNil(DWI16(exactly: Double(-1 << 15) - 0.9))
|
|
expectNil(DWU16(exactly: Double(1 << 16 - 1) + 0.9))
|
|
expectNil(DWU16(exactly: Double(0) - 0.9))
|
|
|
|
expectNil(DWI16(exactly: Double(1 << 15)))
|
|
expectNil(DWI16(exactly: Double(-1 << 15) - 1))
|
|
expectNil(DWU16(exactly: Double(1 << 16)))
|
|
expectNil(DWU16(exactly: Double(-1)))
|
|
|
|
expectNil(DWI16(exactly: 0.00001))
|
|
expectNil(DWU16(exactly: 0.00001))
|
|
|
|
expectNil(DWU16(exactly: Double.nan))
|
|
expectNil(DWU16(exactly: Float.nan))
|
|
expectNil(DWU16(exactly: Double.infinity))
|
|
expectNil(DWU16(exactly: Float.infinity))
|
|
}
|
|
|
|
dwTests.test("Conversions/SignedMax+1") {
|
|
expectCrashLater()
|
|
_ = DWI16(1 << 15)
|
|
}
|
|
|
|
dwTests.test("Conversions/SignedMin-1") {
|
|
expectCrashLater()
|
|
_ = DWI16(-1 << 15 - 1)
|
|
}
|
|
|
|
dwTests.test("Conversions/UnsignedMax+1") {
|
|
expectCrashLater()
|
|
_ = DWU16(1 << 16)
|
|
}
|
|
|
|
dwTests.test("Conversions/Unsigned-1") {
|
|
expectCrashLater()
|
|
_ = DWU16(-1)
|
|
}
|
|
|
|
dwTests.test("Conversions/String") {
|
|
expectEqual(String(Int256.max, radix: 16),
|
|
"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")
|
|
expectEqual(String(Int256.min, radix: 16),
|
|
"-8000000000000000000000000000000000000000000000000000000000000000")
|
|
|
|
expectEqual(String(Int256.max, radix: 2), """
|
|
1111111111111111111111111111111111111111111111111111111111111111\
|
|
1111111111111111111111111111111111111111111111111111111111111111\
|
|
1111111111111111111111111111111111111111111111111111111111111111\
|
|
111111111111111111111111111111111111111111111111111111111111111
|
|
""")
|
|
expectEqual(String(Int256.min, radix: 2), """
|
|
-100000000000000000000000000000000000000000000000000000000000000\
|
|
0000000000000000000000000000000000000000000000000000000000000000\
|
|
0000000000000000000000000000000000000000000000000000000000000000\
|
|
00000000000000000000000000000000000000000000000000000000000000000
|
|
""")
|
|
|
|
expectEqual(String(Int128.max, radix: 10),
|
|
"170141183460469231731687303715884105727")
|
|
expectEqual(String(Int128.min, radix: 10),
|
|
"-170141183460469231731687303715884105728")
|
|
}
|
|
|
|
dwTests.test("Words") {
|
|
expectEqualSequence((0 as DoubleWidth<Int8>).words, [0])
|
|
expectEqualSequence((1 as DoubleWidth<Int8>).words, [1])
|
|
expectEqualSequence((-1 as DoubleWidth<Int8>).words, [UInt.max])
|
|
expectEqualSequence((256 as DoubleWidth<Int8>).words, [256])
|
|
expectEqualSequence((-256 as DoubleWidth<Int8>).words, [UInt.max - 255])
|
|
expectEqualSequence(DoubleWidth<Int8>.max.words, [32767])
|
|
expectEqualSequence(DoubleWidth<Int8>.min.words, [UInt.max - 32767])
|
|
|
|
expectEqualSequence((0 as Int1024).words,
|
|
repeatElement(0 as UInt, count: 1024 / UInt.bitWidth))
|
|
expectEqualSequence((-1 as Int1024).words,
|
|
repeatElement(UInt.max, count: 1024 / UInt.bitWidth))
|
|
expectEqualSequence((1 as Int1024).words,
|
|
[1] + Array(repeating: 0, count: 1024 / UInt.bitWidth - 1))
|
|
}
|
|
|
|
dwTests.test("Conditional Conformance") {
|
|
checkSignedIntegerConformance(0 as Int128)
|
|
checkSignedIntegerConformance(0 as Int1024)
|
|
|
|
checkUnsignedIntegerConformance(0 as UInt128)
|
|
checkUnsignedIntegerConformance(0 as UInt1024)
|
|
}
|
|
|
|
runAllTests()
|
|
|