blob: d6d874e1ffcbc4bbb4ea6d05c36bbc1f6cdb708f [file] [log] [blame]
// 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()