// RUN: %target-run-simple-swift // REQUIRES: executable_test import StdlibUnittest var dwTests = TestSuite("DoubleWidth") typealias UInt128 = DoubleWidth typealias UInt256 = DoubleWidth typealias UInt512 = DoubleWidth typealias UInt1024 = DoubleWidth typealias Int128 = DoubleWidth typealias Int256 = DoubleWidth typealias Int512 = DoubleWidth typealias Int1024 = DoubleWidth func checkSignedIntegerConformance(_ x: T) {} func checkUnsignedIntegerConformance(_ x: T) {} dwTests.test("Literals") { let w: DoubleWidth = 100 expectTrue(w == 100 as Int) let x: DoubleWidth = 1000 expectTrue(x == 1000 as Int) let y: DoubleWidth = 1000 expectTrue(y == 1000 as Int) let z: DoubleWidth = -1000 expectTrue(z == -1000 as Int) expectCrashLater() _ = -1 as DoubleWidth } 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 = 1000 let y: DoubleWidth = 1111 expectEqual(x + 1, 1001) expectEqual(x + x, 2000) expectEqual(x - (1 as DoubleWidth), 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 = 1000 let y: DoubleWidth = -1111 expectEqual(x + 1, 1001) expectEqual(x + x, 2000) expectEqual(x - (1 as DoubleWidth), 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 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 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>> typealias DWI64 = DoubleWidth>> func f(_ 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 typealias DWU16 = DoubleWidth 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).words, [0]) expectEqualSequence((1 as DoubleWidth).words, [1]) expectEqualSequence((-1 as DoubleWidth).words, [UInt.max]) expectEqualSequence((256 as DoubleWidth).words, [256]) expectEqualSequence((-256 as DoubleWidth).words, [UInt.max - 255]) expectEqualSequence(DoubleWidth.max.words, [32767]) expectEqualSequence(DoubleWidth.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()