diff --git a/Tests/ANKFullWidthKitTests/192+Addition.swift b/Tests/ANKFullWidthKitTests/192+Addition.swift index 2f80f902..7dbd7ab9 100644 --- a/Tests/ANKFullWidthKitTests/192+Addition.swift +++ b/Tests/ANKFullWidthKitTests/192+Addition.swift @@ -72,11 +72,11 @@ final class Int192TestsOnAddition: XCTestCase { } func testAddingReportingOverflow() { - XCTAssert(T.min.addingReportingOverflow(T( 1)) == (T.min + 1, false) as (T, Bool)) - XCTAssert(T.max.addingReportingOverflow(T( 1)) == (T.min, true ) as (T, Bool)) + XCTAssert(T.min.addingReportingOverflow(T( 1)) == (T.min + T(1), false) as (T, Bool)) + XCTAssert(T.max.addingReportingOverflow(T( 1)) == (T.min, true ) as (T, Bool)) - XCTAssert(T.min.addingReportingOverflow(T(-1)) == (T.max, true ) as (T, Bool)) - XCTAssert(T.max.addingReportingOverflow(T(-1)) == (T.max - 1, false) as (T, Bool)) + XCTAssert(T.min.addingReportingOverflow(T(-1)) == (T.max, true ) as (T, Bool)) + XCTAssert(T.max.addingReportingOverflow(T(-1)) == (T.max - T(1), false) as (T, Bool)) } //=------------------------------------------------------------------------= @@ -109,19 +109,19 @@ final class Int192TestsOnAddition: XCTestCase { } func testAddingDigitWrappingAround() { - XCTAssertEqual(T.min &+ Int( 1), T.min + T(1)) + XCTAssertEqual(T.min &+ Int( 1), T.min + Int(1)) XCTAssertEqual(T.max &+ Int( 1), T.min) XCTAssertEqual(T.min &+ Int(-1), T.max) - XCTAssertEqual(T.max &+ Int(-1), T.max - T(1)) + XCTAssertEqual(T.max &+ Int(-1), T.max - Int(1)) } func testAddingDigitReportingOverflow() { - XCTAssert(T.min.addingReportingOverflow(Int( 1)) == (T.min + 1, false) as (T, Bool)) - XCTAssert(T.max.addingReportingOverflow(Int( 1)) == (T.min, true ) as (T, Bool)) + XCTAssert(T.min.addingReportingOverflow(Int( 1)) == (T.min + Int(1), false) as (T, Bool)) + XCTAssert(T.max.addingReportingOverflow(Int( 1)) == (T.min, true ) as (T, Bool)) - XCTAssert(T.min.addingReportingOverflow(Int(-1)) == (T.max, true ) as (T, Bool)) - XCTAssert(T.max.addingReportingOverflow(Int(-1)) == (T.max - 1, false) as (T, Bool)) + XCTAssert(T.min.addingReportingOverflow(Int(-1)) == (T.max, true ) as (T, Bool)) + XCTAssert(T.max.addingReportingOverflow(Int(-1)) == (T.max - Int(1), false) as (T, Bool)) } //=------------------------------------------------------------------------= @@ -173,8 +173,8 @@ final class UInt192TestsOnAddition: XCTestCase { } func testAddingReportingOverflow() { - XCTAssert(T.min.addingReportingOverflow(T(1)) == (T.min + (1 as UInt), false) as (T, Bool)) - XCTAssert(T.max.addingReportingOverflow(T(1)) == (T.min, true ) as (T, Bool)) + XCTAssert(T.min.addingReportingOverflow(T(1)) == (T.min + T(1), false) as (T, Bool)) + XCTAssert(T.max.addingReportingOverflow(T(1)) == (T.min, true ) as (T, Bool)) } //=------------------------------------------------------------------------= @@ -196,13 +196,13 @@ final class UInt192TestsOnAddition: XCTestCase { } func testAddingDigitWrappingAround() { - XCTAssertEqual(T.min &+ UInt(1), T.min + T(1)) + XCTAssertEqual(T.min &+ UInt(1), T.min + UInt(1)) XCTAssertEqual(T.max &+ UInt(1), T.min) } func testAddingDigitReportingOverflow() { - XCTAssert(T.min.addingReportingOverflow(UInt(1)) == (T.min + (1 as UInt), false) as (T, Bool)) - XCTAssert(T.max.addingReportingOverflow(UInt(1)) == (T.min, true ) as (T, Bool)) + XCTAssert(T.min.addingReportingOverflow(UInt(1)) == (T.min + UInt(1), false) as (T, Bool)) + XCTAssert(T.max.addingReportingOverflow(UInt(1)) == (T.min, true ) as (T, Bool)) } //=------------------------------------------------------------------------= diff --git a/Tests/ANKFullWidthKitTests/192+Endianness.swift b/Tests/ANKFullWidthKitTests/192+Endianness.swift index c1574ffd..a8359dd9 100644 --- a/Tests/ANKFullWidthKitTests/192+Endianness.swift +++ b/Tests/ANKFullWidthKitTests/192+Endianness.swift @@ -40,17 +40,19 @@ final class Int192TestsOnEndianness: XCTestCase { //=------------------------------------------------------------------------= func testBigEndian() { - let base = T(x64: X(1, 2, 3)) - let baseBigEndian = T(x64: X(b3, b2, b1)) - XCTAssertEqual(base.bigEndian, baseBigEndian) - XCTAssertEqual(T(bigEndian: baseBigEndian), base) + XCTAssertEqual(T(x64: X(01 ,02, 03)).bigEndian, T(x64: X(b3, b2, b1))) + XCTAssertEqual(T(x64: X(b3, b2, b1)).bigEndian, T(x64: X(01, 02, 03))) + + XCTAssertEqual(T(bigEndian: T(x64: X(01, 02, 03))), T(x64: X(b3, b2, b1))) + XCTAssertEqual(T(bigEndian: T(x64: X(b3, b2, b1))), T(x64: X(01, 02, 03))) } func testLittleEndian() { - let base = T(x64: X(1, 2, 3)) - let baseLittleEndian = T(x64: X(l1, l2, l3)) - XCTAssertEqual(base.littleEndian, baseLittleEndian) - XCTAssertEqual(T(littleEndian: baseLittleEndian), base) + XCTAssertEqual(T(x64: X(01, 02, 03)).littleEndian, T(x64: X(l1, l2, l3))) + XCTAssertEqual(T(x64: X(l1, l2, l3)).littleEndian, T(x64: X(01, 02, 03))) + + XCTAssertEqual(T(littleEndian: T(x64: X(01, 02, 03))), T(x64: X(l1, l2, l3))) + XCTAssertEqual(T(littleEndian: T(x64: X(l1, l2, l3))), T(x64: X(01, 02, 03))) } } @@ -79,17 +81,19 @@ final class UInt192TestsOnEndianness: XCTestCase { //=------------------------------------------------------------------------= func testBigEndian() { - let base = T(x64: X(1, 2, 3)) - let baseBigEndian = T(x64: X(b3, b2, b1)) - XCTAssertEqual(base.bigEndian, baseBigEndian) - XCTAssertEqual(T(bigEndian: baseBigEndian), base) + XCTAssertEqual(T(x64: X(01 ,02, 03)).bigEndian, T(x64: X(b3, b2, b1))) + XCTAssertEqual(T(x64: X(b3, b2, b1)).bigEndian, T(x64: X(01, 02, 03))) + + XCTAssertEqual(T(bigEndian: T(x64: X(01, 02, 03))), T(x64: X(b3, b2, b1))) + XCTAssertEqual(T(bigEndian: T(x64: X(b3, b2, b1))), T(x64: X(01, 02, 03))) } func testLittleEndian() { - let base = T(x64: X(1, 2, 3)) - let baseLittleEndian = T(x64: X(l1, l2, l3)) - XCTAssertEqual(base.littleEndian, baseLittleEndian) - XCTAssertEqual(T(littleEndian: baseLittleEndian), base) + XCTAssertEqual(T(x64: X(01, 02, 03)).littleEndian, T(x64: X(l1, l2, l3))) + XCTAssertEqual(T(x64: X(l1, l2, l3)).littleEndian, T(x64: X(01, 02, 03))) + + XCTAssertEqual(T(littleEndian: T(x64: X(01, 02, 03))), T(x64: X(l1, l2, l3))) + XCTAssertEqual(T(littleEndian: T(x64: X(l1, l2, l3))), T(x64: X(01, 02, 03))) } } diff --git a/Tests/ANKFullWidthKitTests/192+Negation.swift b/Tests/ANKFullWidthKitTests/192+Negation.swift index 26560ce6..8857532a 100644 --- a/Tests/ANKFullWidthKitTests/192+Negation.swift +++ b/Tests/ANKFullWidthKitTests/192+Negation.swift @@ -34,8 +34,8 @@ final class Int192TestsOnNegation: XCTestCase { } func testNegatedReportingOverflow() { - XCTAssert(T.min.negatedReportingOverflow() == (T(x64: X(0, 0, ~0 << 63)), true ) as (T, Bool)) - XCTAssert(T.max.negatedReportingOverflow() == (T(x64: X(1, 0, ~0 << 63)), false) as (T, Bool)) + XCTAssert(T.min.negatedReportingOverflow() == (T.min, true ) as (T, Bool)) + XCTAssert(T.max.negatedReportingOverflow() == (T.min + T(1), false) as (T, Bool)) } } diff --git a/Tests/ANKFullWidthKitTests/192+Shifts.swift b/Tests/ANKFullWidthKitTests/192+Shifts.swift index 8eb916f4..9db2d6ea 100644 --- a/Tests/ANKFullWidthKitTests/192+Shifts.swift +++ b/Tests/ANKFullWidthKitTests/192+Shifts.swift @@ -27,62 +27,99 @@ final class Int192TestsOnShifts: XCTestCase { // MARK: Tests x L //=------------------------------------------------------------------------= + func testBitshiftingLeftByBits() { + XCTAssertEqual(T(x64: X(1, 2, 3)) << ( 0), T(x64: X( 1, 2, 3))) + XCTAssertEqual(T(x64: X(1, 2, 3)) << ( 1), T(x64: X( 2, 4, 6))) + XCTAssertEqual(T(x64: X(1, 2, 3)) << ( 2), T(x64: X( 4, 8, 12))) + XCTAssertEqual(T(x64: X(1, 2, 3)) << ( 3), T(x64: X( 8, 16, 24))) + } + func testBitshiftingLeftByWords() { - XCTAssertEqual(T(x64: X(~0, ~0, ~0)) << (64 * 0), T(x64: X(~0, ~0, ~0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0)) << (64 * 1), T(x64: X( 0, ~0, ~0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0)) << (64 * 2), T(x64: X( 0, 0, ~0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0)) << (64 * 3), T(x64: X( 0, 0, 0))) - - XCTAssertEqual(T(x64: X(~0, ~0, ~0)) >> -(64 * 0), T(x64: X(~0, ~0, ~0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0)) >> -(64 * 1), T(x64: X( 0, ~0, ~0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0)) >> -(64 * 2), T(x64: X( 0, 0, ~0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0)) >> -(64 * 3), T(x64: X( 0, 0, 0))) + XCTAssertEqual(T(x64: X(1, 2, 3)) << ( 0), T(x64: X( 1, 2, 3))) + XCTAssertEqual(T(x64: X(1, 2, 3)) << ( 64), T(x64: X( 0, 1, 2))) + XCTAssertEqual(T(x64: X(1, 2, 3)) << (128), T(x64: X( 0, 0, 1))) + XCTAssertEqual(T(x64: X(1, 2, 3)) << (192), T(x64: X( 0, 0, 0))) } - func testBitshiftingLeftByBits() { - XCTAssertEqual(T(x64: X(1, 2, 3)) << 0, T(x64: X(1, 2, 3))) - XCTAssertEqual(T(x64: X(1, 2, 3)) << 1, T(x64: X(2, 4, 6))) - XCTAssertEqual(T(x64: X(1, 2, 3)) << 2, T(x64: X(4, 8, 12))) - - XCTAssertEqual(T(x64: X(~0 << 48, ~0 >> 16, 0)) << 16, T(x64: X(0, ~0, 0))) - XCTAssertEqual(T(x64: X(~0 << 32, ~0 >> 32, 0)) << 32, T(x64: X(0, ~0, 0))) - XCTAssertEqual(T(x64: X(~0 << 16, ~0 >> 48, 0)) << 48, T(x64: X(0, ~0, 0))) + func testBitshiftingLeftByWordsAndBits() { + XCTAssertEqual(T(x64: X(1, 2, 3)) << ( 3), T(x64: X( 8, 16, 24))) + XCTAssertEqual(T(x64: X(1, 2, 3)) << ( 67), T(x64: X( 0, 8, 16))) + XCTAssertEqual(T(x64: X(1, 2, 3)) << (131), T(x64: X( 0, 0, 8))) + XCTAssertEqual(T(x64: X(1, 2, 3)) << (195), T(x64: X( 0, 0, 0))) + } + + func testBitshiftingLeftSuchThatWordsSplit() { + XCTAssertEqual(T(x64: X(~0, 0, 0)) << 1, T(x64: X(~1, 1, 0))) + XCTAssertEqual(T(x64: X( 0, ~0, 0)) << 1, T(x64: X( 0, ~1, 1))) + XCTAssertEqual(T(x64: X( 0, 0, ~0)) << 1, T(x64: X( 0, 0, ~1))) } //=------------------------------------------------------------------------= // MARK: Tests x R //=------------------------------------------------------------------------= - + + func testBitshiftingRightByBits() { + XCTAssertEqual(T(x64: X(8, 16, 24)) >> ( 0), T(x64: X( 8, 16, 24))) + XCTAssertEqual(T(x64: X(8, 16, 24)) >> ( 1), T(x64: X( 4, 8, 12))) + XCTAssertEqual(T(x64: X(8, 16, 24)) >> ( 2), T(x64: X( 2, 4, 6))) + XCTAssertEqual(T(x64: X(8, 16, 24)) >> ( 3), T(x64: X( 1, 2, 3))) + } + func testBitshiftingRightByWords() { - XCTAssertEqual(T(x64: X( 0, 0, ~0)) >> (64 * 0), T(x64: X( 0, 0, ~0))) - XCTAssertEqual(T(x64: X( 0, 0, ~0)) >> (64 * 1), T(x64: X( 0, ~0, ~0))) - XCTAssertEqual(T(x64: X( 0, 0, ~0)) >> (64 * 2), T(x64: X(~0, ~0, ~0))) - XCTAssertEqual(T(x64: X( 0, 0, ~0)) >> (64 * 3), T(x64: X(~0, ~0, ~0))) - - XCTAssertEqual(T(x64: X( 0, 0, ~0)) << -(64 * 0), T(x64: X( 0, 0, ~0))) - XCTAssertEqual(T(x64: X( 0, 0, ~0)) << -(64 * 1), T(x64: X( 0, ~0, ~0))) - XCTAssertEqual(T(x64: X( 0, 0, ~0)) << -(64 * 2), T(x64: X(~0, ~0, ~0))) - XCTAssertEqual(T(x64: X( 0, 0, ~0)) << -(64 * 3), T(x64: X(~0, ~0, ~0))) - - XCTAssertEqual(T(x64: X(~0, ~0, 0)) >> (64 * 0), T(x64: X(~0, ~0, 0))) - XCTAssertEqual(T(x64: X(~0, ~0, 0)) >> (64 * 1), T(x64: X(~0, 0, 0))) - XCTAssertEqual(T(x64: X(~0, ~0, 0)) >> (64 * 2), T(x64: X( 0, 0, 0))) - XCTAssertEqual(T(x64: X(~0, ~0, 0)) >> (64 * 3), T(x64: X( 0, 0, 0))) - - XCTAssertEqual(T(x64: X(~0, ~0, 0)) << -(64 * 0), T(x64: X(~0, ~0, 0))) - XCTAssertEqual(T(x64: X(~0, ~0, 0)) << -(64 * 1), T(x64: X(~0, 0, 0))) - XCTAssertEqual(T(x64: X(~0, ~0, 0)) << -(64 * 2), T(x64: X( 0, 0, 0))) - XCTAssertEqual(T(x64: X(~0, ~0, 0)) << -(64 * 3), T(x64: X( 0, 0, 0))) + XCTAssertEqual(T(x64: X(8, 16, 24)) >> ( 0), T(x64: X( 8, 16, 24))) + XCTAssertEqual(T(x64: X(8, 16, 24)) >> ( 64), T(x64: X(16, 24, 0))) + XCTAssertEqual(T(x64: X(8, 16, 24)) >> (128), T(x64: X(24, 0, 0))) + XCTAssertEqual(T(x64: X(8, 16, 24)) >> (192), T(x64: X( 0, 0, 0))) } - func testBitshiftingRightByBits() { - XCTAssertEqual(T(x64: X(4, 8, 12)) >> 0, T(x64: X(4, 8, 12))) - XCTAssertEqual(T(x64: X(4, 8, 12)) >> 1, T(x64: X(2, 4, 6))) - XCTAssertEqual(T(x64: X(4, 8, 12)) >> 2, T(x64: X(1, 2, 3))) - - XCTAssertEqual(T(x64: X(0, ~0 << 16, ~0 >> 48)) >> 16, T(x64: X(0, ~0, 0))) - XCTAssertEqual(T(x64: X(0, ~0 << 32, ~0 >> 32)) >> 32, T(x64: X(0, ~0, 0))) - XCTAssertEqual(T(x64: X(0, ~0 << 48, ~0 >> 16)) >> 48, T(x64: X(0, ~0, 0))) + func testBitshiftingRightByWordsAndBits() { + XCTAssertEqual(T(x64: X(8, 16, 24)) >> ( 3), T(x64: X( 1, 2, 3))) + XCTAssertEqual(T(x64: X(8, 16, 24)) >> ( 67), T(x64: X( 2, 3, 0))) + XCTAssertEqual(T(x64: X(8, 16, 24)) >> (131), T(x64: X( 3, 0, 0))) + XCTAssertEqual(T(x64: X(8, 16, 24)) >> (195), T(x64: X( 0, 0, 0))) + } + + func testBitshiftingRightSuchThatWordsSplit() { + XCTAssertEqual(T(x64: X(0, 0, 7)) >> ( 1), T(x64: X( 0, 1 << 63, 3))) + XCTAssertEqual(T(x64: X(0, 7, 0)) >> ( 1), T(x64: X( 1 << 63, 3, 0))) + XCTAssertEqual(T(x64: X(7, 0, 0)) >> ( 1), T(x64: X( 3, 0, 0))) + } + + func testBitshiftingRightIsSigned() { + XCTAssertEqual(T(x64: X(0, 0, 1 << 63)) >> ( 0), T(x64: X( 0, 0, 1 << 63))) + XCTAssertEqual(T(x64: X(0, 0, 1 << 63)) >> ( 64), T(x64: X( 0, 1 << 63, ~0))) + XCTAssertEqual(T(x64: X(0, 0, 1 << 63)) >> (128), T(x64: X( 1 << 63, ~0, ~0))) + XCTAssertEqual(T(x64: X(0, 0, 1 << 63)) >> (192), T(x64: X(~0, ~0, ~0))) + } + + //=------------------------------------------------------------------------= + // MARK: Tests x Miscellaneous + //=------------------------------------------------------------------------= + + func testBitshiftingIsSmart() { + for _ in 0 ..< 100 { + let x0 = UInt64.random(in: 0 ..< UInt64.max) + let x1 = UInt64.random(in: 0 ..< UInt64.max) + let x2 = UInt64.random(in: 0 ..< UInt64.max) + let shift = Int.random(in: 0 ..< T.bitWidth) + let value = T(x64:(x0, x1, x2)) + + XCTAssertEqual(value << shift, value >> (-shift)) + XCTAssertEqual(value >> shift, value << (-shift)) + } + } + + func testBitshiftingByMaskingIsEquivalentToBitshiftingModuloBitWidth() { + for _ in 0 ..< 100 { + let x0 = UInt64.random(in: 0 ..< UInt64.max) + let x1 = UInt64.random(in: 0 ..< UInt64.max) + let x2 = UInt64.random(in: 0 ..< UInt64.max) + let shift = Int.random(in: 0 ..< Int.max) + let value = T(x64:(x0, x1, x2)) + + XCTAssertEqual(value &<< shift, value << abs(shift % T.bitWidth)) + XCTAssertEqual(value &>> shift, value >> abs(shift % T.bitWidth)) + } } } @@ -98,62 +135,99 @@ final class UInt192TestsOnShifts: XCTestCase { // MARK: Tests x L //=------------------------------------------------------------------------= + func testBitshiftingLeftByBits() { + XCTAssertEqual(T(x64: X(1, 2, 3)) << ( 0), T(x64: X( 1, 2, 3))) + XCTAssertEqual(T(x64: X(1, 2, 3)) << ( 1), T(x64: X( 2, 4, 6))) + XCTAssertEqual(T(x64: X(1, 2, 3)) << ( 2), T(x64: X( 4, 8, 12))) + XCTAssertEqual(T(x64: X(1, 2, 3)) << ( 3), T(x64: X( 8, 16, 24))) + } + func testBitshiftingLeftByWords() { - XCTAssertEqual(T(x64: X(~0, ~0, ~0)) << (64 * 0), T(x64: X(~0, ~0, ~0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0)) << (64 * 1), T(x64: X( 0, ~0, ~0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0)) << (64 * 2), T(x64: X( 0, 0, ~0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0)) << (64 * 3), T(x64: X( 0, 0, 0))) - - XCTAssertEqual(T(x64: X(~0, ~0, ~0)) >> -(64 * 0), T(x64: X(~0, ~0, ~0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0)) >> -(64 * 1), T(x64: X( 0, ~0, ~0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0)) >> -(64 * 2), T(x64: X( 0, 0, ~0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0)) >> -(64 * 3), T(x64: X( 0, 0, 0))) + XCTAssertEqual(T(x64: X(1, 2, 3)) << ( 0), T(x64: X( 1, 2, 3))) + XCTAssertEqual(T(x64: X(1, 2, 3)) << ( 64), T(x64: X( 0, 1, 2))) + XCTAssertEqual(T(x64: X(1, 2, 3)) << (128), T(x64: X( 0, 0, 1))) + XCTAssertEqual(T(x64: X(1, 2, 3)) << (192), T(x64: X( 0, 0, 0))) } - - func testBitshiftingLeftByBits() { - XCTAssertEqual(T(x64: X(1, 2, 3)) << 0, T(x64: X(1, 2, 3))) - XCTAssertEqual(T(x64: X(1, 2, 3)) << 1, T(x64: X(2, 4, 6))) - XCTAssertEqual(T(x64: X(1, 2, 3)) << 2, T(x64: X(4, 8, 12))) - - XCTAssertEqual(T(x64: X(~0 << 48, ~0 >> 16, 0)) << 16, T(x64: X(0, ~0, 0))) - XCTAssertEqual(T(x64: X(~0 << 32, ~0 >> 32, 0)) << 32, T(x64: X(0, ~0, 0))) - XCTAssertEqual(T(x64: X(~0 << 16, ~0 >> 48, 0)) << 48, T(x64: X(0, ~0, 0))) + + func testBitshiftingLeftByWordsAndBits() { + XCTAssertEqual(T(x64: X(1, 2, 3)) << ( 3), T(x64: X( 8, 16, 24))) + XCTAssertEqual(T(x64: X(1, 2, 3)) << ( 67), T(x64: X( 0, 8, 16))) + XCTAssertEqual(T(x64: X(1, 2, 3)) << (131), T(x64: X( 0, 0, 8))) + XCTAssertEqual(T(x64: X(1, 2, 3)) << (195), T(x64: X( 0, 0, 0))) + } + + func testBitshiftingLeftSuchThatWordsSplit() { + XCTAssertEqual(T(x64: X(~0, 0, 0)) << 1, T(x64: X(~1, 1, 0))) + XCTAssertEqual(T(x64: X( 0, ~0, 0)) << 1, T(x64: X( 0, ~1, 1))) + XCTAssertEqual(T(x64: X( 0, 0, ~0)) << 1, T(x64: X( 0, 0, ~1))) } //=------------------------------------------------------------------------= // MARK: Tests x R //=------------------------------------------------------------------------= + func testBitshiftingRightByBits() { + XCTAssertEqual(T(x64: X(8, 16, 24)) >> ( 0), T(x64: X( 8, 16, 24))) + XCTAssertEqual(T(x64: X(8, 16, 24)) >> ( 1), T(x64: X( 4, 8, 12))) + XCTAssertEqual(T(x64: X(8, 16, 24)) >> ( 2), T(x64: X( 2, 4, 6))) + XCTAssertEqual(T(x64: X(8, 16, 24)) >> ( 3), T(x64: X( 1, 2, 3))) + } + func testBitshiftingRightByWords() { - XCTAssertEqual(T(x64: X( 0, 0, ~0)) >> (64 * 0), T(x64: X( 0, 0, ~0))) - XCTAssertEqual(T(x64: X( 0, 0, ~0)) >> (64 * 1), T(x64: X( 0, ~0, 0))) - XCTAssertEqual(T(x64: X( 0, 0, ~0)) >> (64 * 2), T(x64: X(~0, 0, 0))) - XCTAssertEqual(T(x64: X( 0, 0, ~0)) >> (64 * 3), T(x64: X( 0, 0, 0))) - - XCTAssertEqual(T(x64: X( 0, 0, ~0)) << -(64 * 0), T(x64: X( 0, 0, ~0))) - XCTAssertEqual(T(x64: X( 0, 0, ~0)) << -(64 * 1), T(x64: X( 0, ~0, 0))) - XCTAssertEqual(T(x64: X( 0, 0, ~0)) << -(64 * 2), T(x64: X(~0, 0, 0))) - XCTAssertEqual(T(x64: X( 0, 0, ~0)) << -(64 * 3), T(x64: X( 0, 0, 0))) - - XCTAssertEqual(T(x64: X(~0, ~0, 0)) >> (64 * 0), T(x64: X(~0, ~0, 0))) - XCTAssertEqual(T(x64: X(~0, ~0, 0)) >> (64 * 1), T(x64: X(~0, 0, 0))) - XCTAssertEqual(T(x64: X(~0, ~0, 0)) >> (64 * 2), T(x64: X( 0, 0, 0))) - XCTAssertEqual(T(x64: X(~0, ~0, 0)) >> (64 * 3), T(x64: X( 0, 0, 0))) - - XCTAssertEqual(T(x64: X(~0, ~0, 0)) << -(64 * 0), T(x64: X(~0, ~0, 0))) - XCTAssertEqual(T(x64: X(~0, ~0, 0)) << -(64 * 1), T(x64: X(~0, 0, 0))) - XCTAssertEqual(T(x64: X(~0, ~0, 0)) << -(64 * 2), T(x64: X( 0, 0, 0))) - XCTAssertEqual(T(x64: X(~0, ~0, 0)) << -(64 * 3), T(x64: X( 0, 0, 0))) + XCTAssertEqual(T(x64: X(8, 16, 24)) >> ( 0), T(x64: X( 8, 16, 24))) + XCTAssertEqual(T(x64: X(8, 16, 24)) >> ( 64), T(x64: X(16, 24, 0))) + XCTAssertEqual(T(x64: X(8, 16, 24)) >> (128), T(x64: X(24, 0, 0))) + XCTAssertEqual(T(x64: X(8, 16, 24)) >> (192), T(x64: X( 0, 0, 0))) } - - func testBitshiftingRightByBits() { - XCTAssertEqual(T(x64: X(4, 8, 12)) >> 0, T(x64: X(4, 8, 12))) - XCTAssertEqual(T(x64: X(4, 8, 12)) >> 1, T(x64: X(2, 4, 6))) - XCTAssertEqual(T(x64: X(4, 8, 12)) >> 2, T(x64: X(1, 2, 3))) - - XCTAssertEqual(T(x64: X(0, ~0 << 16, ~0 >> 48)) >> 16, T(x64: X(0, ~0, 0))) - XCTAssertEqual(T(x64: X(0, ~0 << 32, ~0 >> 32)) >> 32, T(x64: X(0, ~0, 0))) - XCTAssertEqual(T(x64: X(0, ~0 << 48, ~0 >> 16)) >> 48, T(x64: X(0, ~0, 0))) + + func testBitshiftingRightByWordsAndBits() { + XCTAssertEqual(T(x64: X(8, 16, 24)) >> ( 3), T(x64: X( 1, 2, 3))) + XCTAssertEqual(T(x64: X(8, 16, 24)) >> ( 67), T(x64: X( 2, 3, 0))) + XCTAssertEqual(T(x64: X(8, 16, 24)) >> (131), T(x64: X( 3, 0, 0))) + XCTAssertEqual(T(x64: X(8, 16, 24)) >> (195), T(x64: X( 0, 0, 0))) + } + + func testBitshiftingRightSuchThatWordsSplit() { + XCTAssertEqual(T(x64: X(0, 0, 7)) >> ( 1), T(x64: X( 0, 1 << 63, 3))) + XCTAssertEqual(T(x64: X(0, 7, 0)) >> ( 1), T(x64: X( 1 << 63, 3, 0))) + XCTAssertEqual(T(x64: X(7, 0, 0)) >> ( 1), T(x64: X( 3, 0, 0))) + } + + func testBitshiftingRightIsUnsigned() { + XCTAssertEqual(T(x64: X(0, 0, 1 << 63)) >> ( 0), T(x64: X(0, 0, 1 << 63))) + XCTAssertEqual(T(x64: X(0, 0, 1 << 63)) >> ( 64), T(x64: X(0, 1 << 63, 0))) + XCTAssertEqual(T(x64: X(0, 0, 1 << 63)) >> (128), T(x64: X(1 << 63, 0, 0))) + XCTAssertEqual(T(x64: X(0, 0, 1 << 63)) >> (192), T(x64: X(0, 0, 0))) + } + + //=------------------------------------------------------------------------= + // MARK: Tests x Miscellaneous + //=------------------------------------------------------------------------= + + func testBitshiftingIsSmart() { + for _ in 0 ..< 100 { + let x0 = UInt64.random(in: 0 ..< UInt64.max) + let x1 = UInt64.random(in: 0 ..< UInt64.max) + let x2 = UInt64.random(in: 0 ..< UInt64.max) + let shift = Int.random(in: 0 ..< T.bitWidth) + let value = T(x64:(x0, x1, x2)) + + XCTAssertEqual(value << shift, value >> (-shift)) + XCTAssertEqual(value >> shift, value << (-shift)) + } + } + + func testBitshiftingByMaskingIsEquivalentToBitshiftingModuloBitWidth() { + for _ in 0 ..< 100 { + let x0 = UInt64.random(in: 0 ..< UInt64.max) + let x1 = UInt64.random(in: 0 ..< UInt64.max) + let x2 = UInt64.random(in: 0 ..< UInt64.max) + let shift = Int.random(in: 0 ..< Int.max) + let value = T(x64:(x0, x1, x2)) + + XCTAssertEqual(value &<< shift, value << abs(shift % T.bitWidth)) + XCTAssertEqual(value &>> shift, value >> abs(shift % T.bitWidth)) + } } } diff --git a/Tests/ANKFullWidthKitTests/256+Addition.swift b/Tests/ANKFullWidthKitTests/256+Addition.swift index 1cafac98..96d000a8 100644 --- a/Tests/ANKFullWidthKitTests/256+Addition.swift +++ b/Tests/ANKFullWidthKitTests/256+Addition.swift @@ -76,11 +76,11 @@ final class Int256TestsOnAddition: XCTestCase { } func testAddingReportingOverflow() { - XCTAssert(T.min.addingReportingOverflow(T( 1)) == (T.min + 1, false) as (T, Bool)) - XCTAssert(T.max.addingReportingOverflow(T( 1)) == (T.min, true ) as (T, Bool)) + XCTAssert(T.min.addingReportingOverflow(T( 1)) == (T.min + T(1), false) as (T, Bool)) + XCTAssert(T.max.addingReportingOverflow(T( 1)) == (T.min, true ) as (T, Bool)) - XCTAssert(T.min.addingReportingOverflow(T(-1)) == (T.max, true ) as (T, Bool)) - XCTAssert(T.max.addingReportingOverflow(T(-1)) == (T.max - 1, false) as (T, Bool)) + XCTAssert(T.min.addingReportingOverflow(T(-1)) == (T.max, true ) as (T, Bool)) + XCTAssert(T.max.addingReportingOverflow(T(-1)) == (T.max - T(1), false) as (T, Bool)) } //=------------------------------------------------------------------------= @@ -113,19 +113,19 @@ final class Int256TestsOnAddition: XCTestCase { } func testAddingDigitWrappingAround() { - XCTAssertEqual(T.min &+ Int( 1), T.min + T(1)) + XCTAssertEqual(T.min &+ Int( 1), T.min + Int(1)) XCTAssertEqual(T.max &+ Int( 1), T.min) XCTAssertEqual(T.min &+ Int(-1), T.max) - XCTAssertEqual(T.max &+ Int(-1), T.max - T(1)) + XCTAssertEqual(T.max &+ Int(-1), T.max - Int(1)) } func testAddingDigitReportingOverflow() { - XCTAssert(T.min.addingReportingOverflow(Int( 1)) == (T.min + 1, false) as (T, Bool)) - XCTAssert(T.max.addingReportingOverflow(Int( 1)) == (T.min, true ) as (T, Bool)) + XCTAssert(T.min.addingReportingOverflow(Int( 1)) == (T.min + Int(1), false) as (T, Bool)) + XCTAssert(T.max.addingReportingOverflow(Int( 1)) == (T.min, true ) as (T, Bool)) - XCTAssert(T.min.addingReportingOverflow(Int(-1)) == (T.max, true ) as (T, Bool)) - XCTAssert(T.max.addingReportingOverflow(Int(-1)) == (T.max - 1, false) as (T, Bool)) + XCTAssert(T.min.addingReportingOverflow(Int(-1)) == (T.max, true ) as (T, Bool)) + XCTAssert(T.max.addingReportingOverflow(Int(-1)) == (T.max - Int(1), false) as (T, Bool)) } //=------------------------------------------------------------------------= @@ -178,8 +178,8 @@ final class UInt256TestsOnAddition: XCTestCase { } func testAddingReportingOverflow() { - XCTAssert(T.min.addingReportingOverflow(T(1)) == (T.min + (1 as UInt), false) as (T, Bool)) - XCTAssert(T.max.addingReportingOverflow(T(1)) == (T.min, true ) as (T, Bool)) + XCTAssert(T.min.addingReportingOverflow(T(1)) == (T.min + T(1), false) as (T, Bool)) + XCTAssert(T.max.addingReportingOverflow(T(1)) == (T.min, true ) as (T, Bool)) } //=------------------------------------------------------------------------= @@ -202,13 +202,13 @@ final class UInt256TestsOnAddition: XCTestCase { } func testAddingDigitWrappingAround() { - XCTAssertEqual(T.min &+ UInt(1), T.min + T(1)) + XCTAssertEqual(T.min &+ UInt(1), T.min + UInt(1)) XCTAssertEqual(T.max &+ UInt(1), T.min) } func testAddingDigitReportingOverflow() { - XCTAssert(T.min.addingReportingOverflow(UInt(1)) == (T.min + (1 as UInt), false) as (T, Bool)) - XCTAssert(T.max.addingReportingOverflow(UInt(1)) == (T.min, true ) as (T, Bool)) + XCTAssert(T.min.addingReportingOverflow(UInt(1)) == (T.min + UInt(1), false) as (T, Bool)) + XCTAssert(T.max.addingReportingOverflow(UInt(1)) == (T.min, true ) as (T, Bool)) } //=------------------------------------------------------------------------= diff --git a/Tests/ANKFullWidthKitTests/256+Endianness.swift b/Tests/ANKFullWidthKitTests/256+Endianness.swift index 00e164b0..309dd8e8 100644 --- a/Tests/ANKFullWidthKitTests/256+Endianness.swift +++ b/Tests/ANKFullWidthKitTests/256+Endianness.swift @@ -42,17 +42,19 @@ final class Int256TestsOnEndianness: XCTestCase { //=------------------------------------------------------------------------= func testBigEndian() { - let base = T(x64: X(1, 2, 3, 4)) - let baseBigEndian = T(x64: X(b4, b3, b2, b1)) - XCTAssertEqual(base.bigEndian, baseBigEndian) - XCTAssertEqual(T(bigEndian: baseBigEndian), base) + XCTAssertEqual(T(x64: X(01 ,02, 03, 04)).bigEndian, T(x64: X(b4, b3, b2, b1))) + XCTAssertEqual(T(x64: X(b4, b3, b2, b1)).bigEndian, T(x64: X(01, 02, 03, 04))) + + XCTAssertEqual(T(bigEndian: T(x64: X(01, 02, 03, 04))), T(x64: X(b4, b3, b2, b1))) + XCTAssertEqual(T(bigEndian: T(x64: X(b4, b3, b2, b1))), T(x64: X(01, 02, 03, 04))) } func testLittleEndian() { - let base = T(x64: X(1, 2, 3, 4)) - let baseLittleEndian = T(x64: X(l1, l2, l3, l4)) - XCTAssertEqual(base.littleEndian, baseLittleEndian) - XCTAssertEqual(T(littleEndian: baseLittleEndian), base) + XCTAssertEqual(T(x64: X(01, 02, 03, 04)).littleEndian, T(x64: X(l1, l2, l3, l4))) + XCTAssertEqual(T(x64: X(l1, l2, l3, l4)).littleEndian, T(x64: X(01, 02, 03, 04))) + + XCTAssertEqual(T(littleEndian: T(x64: X(01, 02, 03, 04))), T(x64: X(l1, l2, l3, l4))) + XCTAssertEqual(T(littleEndian: T(x64: X(l1, l2, l3, l4))), T(x64: X(01, 02, 03, 04))) } } @@ -83,17 +85,19 @@ final class UInt256TestsOnEndianness: XCTestCase { //=------------------------------------------------------------------------= func testBigEndian() { - let base = T(x64: X(1, 2, 3, 4)) - let baseBigEndian = T(x64: X(b4, b3, b2, b1)) - XCTAssertEqual(base.bigEndian, baseBigEndian) - XCTAssertEqual(T(bigEndian: baseBigEndian), base) + XCTAssertEqual(T(x64: X(01 ,02, 03, 04)).bigEndian, T(x64: X(b4, b3, b2, b1))) + XCTAssertEqual(T(x64: X(b4, b3, b2, b1)).bigEndian, T(x64: X(01, 02, 03, 04))) + + XCTAssertEqual(T(bigEndian: T(x64: X(01, 02, 03, 04))), T(x64: X(b4, b3, b2, b1))) + XCTAssertEqual(T(bigEndian: T(x64: X(b4, b3, b2, b1))), T(x64: X(01, 02, 03, 04))) } func testLittleEndian() { - let base = T(x64: X(1, 2, 3, 4)) - let baseLittleEndian = T(x64: X(l1, l2, l3, l4)) - XCTAssertEqual(base.littleEndian, baseLittleEndian) - XCTAssertEqual(T(littleEndian: baseLittleEndian), base) + XCTAssertEqual(T(x64: X(01, 02, 03, 04)).littleEndian, T(x64: X(l1, l2, l3, l4))) + XCTAssertEqual(T(x64: X(l1, l2, l3, l4)).littleEndian, T(x64: X(01, 02, 03, 04))) + + XCTAssertEqual(T(littleEndian: T(x64: X(01, 02, 03, 04))), T(x64: X(l1, l2, l3, l4))) + XCTAssertEqual(T(littleEndian: T(x64: X(l1, l2, l3, l4))), T(x64: X(01, 02, 03, 04))) } } diff --git a/Tests/ANKFullWidthKitTests/256+Negation.swift b/Tests/ANKFullWidthKitTests/256+Negation.swift index e2ed2b9d..d127758b 100644 --- a/Tests/ANKFullWidthKitTests/256+Negation.swift +++ b/Tests/ANKFullWidthKitTests/256+Negation.swift @@ -34,8 +34,8 @@ final class Int256TestsOnNegation: XCTestCase { } func testNegatedReportingOverflow() { - XCTAssert(T.min.negatedReportingOverflow() == (T(x64: X(0, 0, 0, ~0 << 63)), true ) as (T, Bool)) - XCTAssert(T.max.negatedReportingOverflow() == (T(x64: X(1, 0, 0, ~0 << 63)), false) as (T, Bool)) + XCTAssert(T.min.negatedReportingOverflow() == (T.min, true ) as (T, Bool)) + XCTAssert(T.max.negatedReportingOverflow() == (T.min + T(1), false) as (T, Bool)) } } diff --git a/Tests/ANKFullWidthKitTests/256+Shifts.swift b/Tests/ANKFullWidthKitTests/256+Shifts.swift index ffb47787..4a6e5b12 100644 --- a/Tests/ANKFullWidthKitTests/256+Shifts.swift +++ b/Tests/ANKFullWidthKitTests/256+Shifts.swift @@ -27,68 +27,108 @@ final class Int256TestsOnShifts: XCTestCase { // MARK: Tests x L //=------------------------------------------------------------------------= + func testBitshiftingLeftByBits() { + XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << ( 0), T(x64: X( 1, 2, 3, 4))) + XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << ( 1), T(x64: X( 2, 4, 6, 8))) + XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << ( 2), T(x64: X( 4, 8, 12, 16))) + XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << ( 3), T(x64: X( 8, 16, 24, 32))) + } + func testBitshiftingLeftByWords() { - XCTAssertEqual(T(x64: X(~0, ~0, ~0, ~0)) << (64 * 0), T(x64: X(~0, ~0, ~0, ~0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, ~0)) << (64 * 1), T(x64: X( 0, ~0, ~0, ~0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, ~0)) << (64 * 2), T(x64: X( 0, 0, ~0, ~0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, ~0)) << (64 * 3), T(x64: X( 0, 0, 0, ~0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, ~0)) << (64 * 4), T(x64: X( 0, 0, 0, 0))) - - XCTAssertEqual(T(x64: X(~0, ~0, ~0, ~0)) >> -(64 * 0), T(x64: X(~0, ~0, ~0, ~0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, ~0)) >> -(64 * 1), T(x64: X( 0, ~0, ~0, ~0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, ~0)) >> -(64 * 2), T(x64: X( 0, 0, ~0, ~0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, ~0)) >> -(64 * 3), T(x64: X( 0, 0, 0, ~0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, ~0)) >> -(64 * 4), T(x64: X( 0, 0, 0, 0))) + XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << ( 0), T(x64: X( 1, 2, 3, 4))) + XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << ( 64), T(x64: X( 0, 1, 2, 3))) + XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << (128), T(x64: X( 0, 0, 1, 2))) + XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << (192), T(x64: X( 0, 0, 0, 1))) + XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << (256), T(x64: X( 0, 0, 0, 0))) } - func testBitshiftingLeftByBits() { - XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << 0, T(x64: X(1, 2, 3, 4))) - XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << 1, T(x64: X(2, 4, 6, 8))) - XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << 2, T(x64: X(4, 8, 12, 16))) - - XCTAssertEqual(T(x64: X(0, ~0 << 48, ~0 >> 16, 0)) << 16, T(x64: X(0, 0, ~0, 0))) - XCTAssertEqual(T(x64: X(0, ~0 << 32, ~0 >> 32, 0)) << 32, T(x64: X(0, 0, ~0, 0))) - XCTAssertEqual(T(x64: X(0, ~0 << 16, ~0 >> 48, 0)) << 48, T(x64: X(0, 0, ~0, 0))) + func testBitshiftingLeftByWordsAndBits() { + XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << ( 3), T(x64: X( 8, 16, 24, 32))) + XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << ( 67), T(x64: X( 0, 8, 16, 24))) + XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << (131), T(x64: X( 0, 0, 8, 16))) + XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << (195), T(x64: X( 0, 0, 0, 8))) + XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << (259), T(x64: X( 0, 0, 0, 0))) + } + + func testBitshiftingLeftSuchThatWordsSplit() { + XCTAssertEqual(T(x64: X(~0, 0, 0, 0)) << 1, T(x64: X(~1, 1, 0, 0))) + XCTAssertEqual(T(x64: X( 0, ~0, 0, 0)) << 1, T(x64: X( 0, ~1, 1, 0))) + XCTAssertEqual(T(x64: X( 0, 0, ~0, 0)) << 1, T(x64: X( 0, 0, ~1, 1))) + XCTAssertEqual(T(x64: X( 0, 0, 0, ~0)) << 1, T(x64: X( 0, 0, 0, ~1))) } //=------------------------------------------------------------------------= // MARK: Tests x R //=------------------------------------------------------------------------= + func testBitshiftingRightByBits() { + XCTAssertEqual(T(x64: X(8, 16, 24, 32)) >> ( 0), T(x64: X( 8, 16, 24, 32))) + XCTAssertEqual(T(x64: X(8, 16, 24, 32)) >> ( 1), T(x64: X( 4, 8, 12, 16))) + XCTAssertEqual(T(x64: X(8, 16, 24, 32)) >> ( 2), T(x64: X( 2, 4, 6, 8))) + XCTAssertEqual(T(x64: X(8, 16, 24, 32)) >> ( 3), T(x64: X( 1, 2, 3, 4))) + } + func testBitshiftingRightByWords() { - XCTAssertEqual(T(x64: X( 0, 0, 0, ~0)) >> (64 * 0), T(x64: X( 0, 0, 0, ~0))) - XCTAssertEqual(T(x64: X( 0, 0, 0, ~0)) >> (64 * 1), T(x64: X( 0, 0, ~0, ~0))) - XCTAssertEqual(T(x64: X( 0, 0, 0, ~0)) >> (64 * 2), T(x64: X( 0, ~0, ~0, ~0))) - XCTAssertEqual(T(x64: X( 0, 0, 0, ~0)) >> (64 * 3), T(x64: X(~0, ~0, ~0, ~0))) - XCTAssertEqual(T(x64: X( 0, 0, 0, ~0)) >> (64 * 4), T(x64: X(~0, ~0, ~0, ~0))) - - XCTAssertEqual(T(x64: X( 0, 0, 0, ~0)) << -(64 * 0), T(x64: X( 0, 0, 0, ~0))) - XCTAssertEqual(T(x64: X( 0, 0, 0, ~0)) << -(64 * 1), T(x64: X( 0, 0, ~0, ~0))) - XCTAssertEqual(T(x64: X( 0, 0, 0, ~0)) << -(64 * 2), T(x64: X( 0, ~0, ~0, ~0))) - XCTAssertEqual(T(x64: X( 0, 0, 0, ~0)) << -(64 * 3), T(x64: X(~0, ~0, ~0, ~0))) - XCTAssertEqual(T(x64: X( 0, 0, 0, ~0)) << -(64 * 4), T(x64: X(~0, ~0, ~0, ~0))) - - XCTAssertEqual(T(x64: X(~0, ~0, ~0, 0)) >> (64 * 0), T(x64: X(~0, ~0, ~0, 0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, 0)) >> (64 * 1), T(x64: X(~0, ~0, 0, 0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, 0)) >> (64 * 2), T(x64: X(~0, 0, 0, 0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, 0)) >> (64 * 3), T(x64: X( 0, 0, 0, 0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, 0)) >> (64 * 4), T(x64: X( 0, 0, 0, 0))) - - XCTAssertEqual(T(x64: X(~0, ~0, ~0, 0)) << -(64 * 0), T(x64: X(~0, ~0, ~0, 0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, 0)) << -(64 * 1), T(x64: X(~0, ~0, 0, 0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, 0)) << -(64 * 2), T(x64: X(~0, 0, 0, 0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, 0)) << -(64 * 3), T(x64: X( 0, 0, 0, 0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, 0)) << -(64 * 4), T(x64: X( 0, 0, 0, 0))) + XCTAssertEqual(T(x64: X(8, 16, 24, 32)) >> ( 0), T(x64: X( 8, 16, 24, 32))) + XCTAssertEqual(T(x64: X(8, 16, 24, 32)) >> ( 64), T(x64: X(16, 24, 32, 0))) + XCTAssertEqual(T(x64: X(8, 16, 24, 32)) >> (128), T(x64: X(24, 32, 0, 0))) + XCTAssertEqual(T(x64: X(8, 16, 24, 32)) >> (192), T(x64: X(32, 0, 0, 0))) + XCTAssertEqual(T(x64: X(8, 16, 24, 32)) >> (256), T(x64: X( 0, 0, 0, 0))) } - func testBitshiftingRightByBits() { - XCTAssertEqual(T(x64: X(4, 8, 12, 16)) >> 0, T(x64: X(4, 8, 12, 16))) - XCTAssertEqual(T(x64: X(4, 8, 12, 16)) >> 1, T(x64: X(2, 4, 6, 8))) - XCTAssertEqual(T(x64: X(4, 8, 12, 16)) >> 2, T(x64: X(1, 2, 3, 4))) - - XCTAssertEqual(T(x64: X(0, ~0 << 16, ~0 >> 48, 0)) >> 16, T(x64: X(0, ~0, 0, 0))) - XCTAssertEqual(T(x64: X(0, ~0 << 32, ~0 >> 32, 0)) >> 32, T(x64: X(0, ~0, 0, 0))) - XCTAssertEqual(T(x64: X(0, ~0 << 48, ~0 >> 16, 0)) >> 48, T(x64: X(0, ~0, 0, 0))) + func testBitshiftingRightByWordsAndBits() { + XCTAssertEqual(T(x64: X(8, 16, 24, 32)) >> ( 3), T(x64: X( 1, 2, 3, 4))) + XCTAssertEqual(T(x64: X(8, 16, 24, 32)) >> ( 67), T(x64: X( 2, 3, 4, 0))) + XCTAssertEqual(T(x64: X(8, 16, 24, 32)) >> (131), T(x64: X( 3, 4, 0, 0))) + XCTAssertEqual(T(x64: X(8, 16, 24, 32)) >> (195), T(x64: X( 4, 0, 0, 0))) + XCTAssertEqual(T(x64: X(8, 16, 24, 32)) >> (259), T(x64: X( 0, 0, 0, 0))) + } + + func testBitshiftingRightSuchThatWordsSplit() { + XCTAssertEqual(T(x64: X(0, 0, 0, 7)) >> ( 1), T(x64: X( 0, 0, 1 << 63, 3))) + XCTAssertEqual(T(x64: X(0, 0, 7, 0)) >> ( 1), T(x64: X( 0, 1 << 63, 3, 0))) + XCTAssertEqual(T(x64: X(0, 7, 0, 0)) >> ( 1), T(x64: X( 1 << 63, 3, 0, 0))) + XCTAssertEqual(T(x64: X(7, 0, 0, 0)) >> ( 1), T(x64: X( 3, 0, 0, 0))) + } + + func testBitshiftingRightIsSigned() { + XCTAssertEqual(T(x64: X(0, 0, 0, 1 << 63)) >> ( 0), T(x64: X( 0, 0, 0, 1 << 63))) + XCTAssertEqual(T(x64: X(0, 0, 0, 1 << 63)) >> ( 64), T(x64: X( 0, 0, 1 << 63, ~0))) + XCTAssertEqual(T(x64: X(0, 0, 0, 1 << 63)) >> (128), T(x64: X( 0, 1 << 63, ~0, ~0))) + XCTAssertEqual(T(x64: X(0, 0, 0, 1 << 63)) >> (192), T(x64: X( 1 << 63, ~0, ~0, ~0))) + XCTAssertEqual(T(x64: X(0, 0, 0, 1 << 63)) >> (256), T(x64: X(~0, ~0, ~0, ~0))) + } + + //=------------------------------------------------------------------------= + // MARK: Tests x Miscellaneous + //=------------------------------------------------------------------------= + + func testBitshiftingIsSmart() { + for _ in 0 ..< 100 { + let x0 = UInt64.random(in: 0 ..< UInt64.max) + let x1 = UInt64.random(in: 0 ..< UInt64.max) + let x2 = UInt64.random(in: 0 ..< UInt64.max) + let x3 = UInt64.random(in: 0 ..< UInt64.max) + let shift = Int.random(in: 0 ..< T.bitWidth) + let value = T(x64:(x0, x1, x2, x3)) + + XCTAssertEqual(value << shift, value >> (-shift)) + XCTAssertEqual(value >> shift, value << (-shift)) + } + } + + func testBitshiftingByMaskingIsEquivalentToBitshiftingModuloBitWidth() { + for _ in 0 ..< 100 { + let x0 = UInt64.random(in: 0 ..< UInt64.max) + let x1 = UInt64.random(in: 0 ..< UInt64.max) + let x2 = UInt64.random(in: 0 ..< UInt64.max) + let x3 = UInt64.random(in: 0 ..< UInt64.max) + let shift = Int.random(in: 0 ..< Int.max) + let value = T(x64:(x0, x1, x2, x3)) + + XCTAssertEqual(value &<< shift, value << abs(shift % T.bitWidth)) + XCTAssertEqual(value &>> shift, value >> abs(shift % T.bitWidth)) + } } } @@ -104,68 +144,108 @@ final class UInt256TestsOnShifts: XCTestCase { // MARK: Tests x L //=------------------------------------------------------------------------= + func testBitshiftingLeftByBits() { + XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << ( 0), T(x64: X( 1, 2, 3, 4))) + XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << ( 1), T(x64: X( 2, 4, 6, 8))) + XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << ( 2), T(x64: X( 4, 8, 12, 16))) + XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << ( 3), T(x64: X( 8, 16, 24, 32))) + } + func testBitshiftingLeftByWords() { - XCTAssertEqual(T(x64: X(~0, ~0, ~0, ~0)) << (64 * 0), T(x64: X(~0, ~0, ~0, ~0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, ~0)) << (64 * 1), T(x64: X( 0, ~0, ~0, ~0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, ~0)) << (64 * 2), T(x64: X( 0, 0, ~0, ~0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, ~0)) << (64 * 3), T(x64: X( 0, 0, 0, ~0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, ~0)) << (64 * 4), T(x64: X( 0, 0, 0, 0))) - - XCTAssertEqual(T(x64: X(~0, ~0, ~0, ~0)) >> -(64 * 0), T(x64: X(~0, ~0, ~0, ~0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, ~0)) >> -(64 * 1), T(x64: X( 0, ~0, ~0, ~0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, ~0)) >> -(64 * 2), T(x64: X( 0, 0, ~0, ~0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, ~0)) >> -(64 * 3), T(x64: X( 0, 0, 0, ~0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, ~0)) >> -(64 * 4), T(x64: X( 0, 0, 0, 0))) + XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << ( 0), T(x64: X( 1, 2, 3, 4))) + XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << ( 64), T(x64: X( 0, 1, 2, 3))) + XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << (128), T(x64: X( 0, 0, 1, 2))) + XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << (192), T(x64: X( 0, 0, 0, 1))) + XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << (256), T(x64: X( 0, 0, 0, 0))) } - - func testBitshiftingLeftByBits() { - XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << 0, T(x64: X(1, 2, 3, 4))) - XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << 1, T(x64: X(2, 4, 6, 8))) - XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << 2, T(x64: X(4, 8, 12, 16))) - - XCTAssertEqual(T(x64: X(0, ~0 << 48, ~0 >> 16, 0)) << 16, T(x64: X(0, 0, ~0, 0))) - XCTAssertEqual(T(x64: X(0, ~0 << 32, ~0 >> 32, 0)) << 32, T(x64: X(0, 0, ~0, 0))) - XCTAssertEqual(T(x64: X(0, ~0 << 16, ~0 >> 48, 0)) << 48, T(x64: X(0, 0, ~0, 0))) + + func testBitshiftingLeftByWordsAndBits() { + XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << ( 3), T(x64: X( 8, 16, 24, 32))) + XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << ( 67), T(x64: X( 0, 8, 16, 24))) + XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << (131), T(x64: X( 0, 0, 8, 16))) + XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << (195), T(x64: X( 0, 0, 0, 8))) + XCTAssertEqual(T(x64: X(1, 2, 3, 4)) << (259), T(x64: X( 0, 0, 0, 0))) + } + + func testBitshiftingLeftSuchThatWordsSplit() { + XCTAssertEqual(T(x64: X(~0, 0, 0, 0)) << 1, T(x64: X(~1, 1, 0, 0))) + XCTAssertEqual(T(x64: X( 0, ~0, 0, 0)) << 1, T(x64: X( 0, ~1, 1, 0))) + XCTAssertEqual(T(x64: X( 0, 0, ~0, 0)) << 1, T(x64: X( 0, 0, ~1, 1))) + XCTAssertEqual(T(x64: X( 0, 0, 0, ~0)) << 1, T(x64: X( 0, 0, 0, ~1))) } //=------------------------------------------------------------------------= // MARK: Tests x R //=------------------------------------------------------------------------= + func testBitshiftingRightByBits() { + XCTAssertEqual(T(x64: X(8, 16, 24, 32)) >> ( 0), T(x64: X( 8, 16, 24, 32))) + XCTAssertEqual(T(x64: X(8, 16, 24, 32)) >> ( 1), T(x64: X( 4, 8, 12, 16))) + XCTAssertEqual(T(x64: X(8, 16, 24, 32)) >> ( 2), T(x64: X( 2, 4, 6, 8))) + XCTAssertEqual(T(x64: X(8, 16, 24, 32)) >> ( 3), T(x64: X( 1, 2, 3, 4))) + } + func testBitshiftingRightByWords() { - XCTAssertEqual(T(x64: X( 0, 0, 0, ~0)) >> (64 * 0), T(x64: X( 0, 0, 0, ~0))) - XCTAssertEqual(T(x64: X( 0, 0, 0, ~0)) >> (64 * 1), T(x64: X( 0, 0, ~0, 0))) - XCTAssertEqual(T(x64: X( 0, 0, 0, ~0)) >> (64 * 2), T(x64: X( 0, ~0, 0, 0))) - XCTAssertEqual(T(x64: X( 0, 0, 0, ~0)) >> (64 * 3), T(x64: X(~0, 0, 0, 0))) - XCTAssertEqual(T(x64: X( 0, 0, 0, ~0)) >> (64 * 4), T(x64: X( 0, 0, 0, 0))) - - XCTAssertEqual(T(x64: X( 0, 0, 0, ~0)) << -(64 * 0), T(x64: X( 0, 0, 0, ~0))) - XCTAssertEqual(T(x64: X( 0, 0, 0, ~0)) << -(64 * 1), T(x64: X( 0, 0, ~0, 0))) - XCTAssertEqual(T(x64: X( 0, 0, 0, ~0)) << -(64 * 2), T(x64: X( 0, ~0, 0, 0))) - XCTAssertEqual(T(x64: X( 0, 0, 0, ~0)) << -(64 * 3), T(x64: X(~0, 0, 0, 0))) - XCTAssertEqual(T(x64: X( 0, 0, 0, ~0)) << -(64 * 4), T(x64: X( 0, 0, 0, 0))) - - XCTAssertEqual(T(x64: X(~0, ~0, ~0, 0)) >> (64 * 0), T(x64: X(~0, ~0, ~0, 0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, 0)) >> (64 * 1), T(x64: X(~0, ~0, 0, 0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, 0)) >> (64 * 2), T(x64: X(~0, 0, 0, 0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, 0)) >> (64 * 3), T(x64: X( 0, 0, 0, 0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, 0)) >> (64 * 4), T(x64: X( 0, 0, 0, 0))) - - XCTAssertEqual(T(x64: X(~0, ~0, ~0, 0)) << -(64 * 0), T(x64: X(~0, ~0, ~0, 0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, 0)) << -(64 * 1), T(x64: X(~0, ~0, 0, 0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, 0)) << -(64 * 2), T(x64: X(~0, 0, 0, 0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, 0)) << -(64 * 3), T(x64: X( 0, 0, 0, 0))) - XCTAssertEqual(T(x64: X(~0, ~0, ~0, 0)) << -(64 * 4), T(x64: X( 0, 0, 0, 0))) + XCTAssertEqual(T(x64: X(8, 16, 24, 32)) >> ( 0), T(x64: X( 8, 16, 24, 32))) + XCTAssertEqual(T(x64: X(8, 16, 24, 32)) >> ( 64), T(x64: X(16, 24, 32, 0))) + XCTAssertEqual(T(x64: X(8, 16, 24, 32)) >> (128), T(x64: X(24, 32, 0, 0))) + XCTAssertEqual(T(x64: X(8, 16, 24, 32)) >> (192), T(x64: X(32, 0, 0, 0))) + XCTAssertEqual(T(x64: X(8, 16, 24, 32)) >> (256), T(x64: X( 0, 0, 0, 0))) } - - func testBitshiftingRightByBits() { - XCTAssertEqual(T(x64: X(4, 8, 12, 16)) >> 0, T(x64: X(4, 8, 12, 16))) - XCTAssertEqual(T(x64: X(4, 8, 12, 16)) >> 1, T(x64: X(2, 4, 6, 8))) - XCTAssertEqual(T(x64: X(4, 8, 12, 16)) >> 2, T(x64: X(1, 2, 3, 4))) - - XCTAssertEqual(T(x64: X(0, ~0 << 16, ~0 >> 48, 0)) >> 16, T(x64: X(0, ~0, 0, 0))) - XCTAssertEqual(T(x64: X(0, ~0 << 32, ~0 >> 32, 0)) >> 32, T(x64: X(0, ~0, 0, 0))) - XCTAssertEqual(T(x64: X(0, ~0 << 48, ~0 >> 16, 0)) >> 48, T(x64: X(0, ~0, 0, 0))) + + func testBitshiftingRightByWordsAndBits() { + XCTAssertEqual(T(x64: X(8, 16, 24, 32)) >> ( 3), T(x64: X( 1, 2, 3, 4))) + XCTAssertEqual(T(x64: X(8, 16, 24, 32)) >> ( 67), T(x64: X( 2, 3, 4, 0))) + XCTAssertEqual(T(x64: X(8, 16, 24, 32)) >> (131), T(x64: X( 3, 4, 0, 0))) + XCTAssertEqual(T(x64: X(8, 16, 24, 32)) >> (195), T(x64: X( 4, 0, 0, 0))) + XCTAssertEqual(T(x64: X(8, 16, 24, 32)) >> (259), T(x64: X( 0, 0, 0, 0))) + } + + func testBitshiftingRightSuchThatWordsSplit() { + XCTAssertEqual(T(x64: X(0, 0, 0, 7)) >> ( 1), T(x64: X( 0, 0, 1 << 63, 3))) + XCTAssertEqual(T(x64: X(0, 0, 7, 0)) >> ( 1), T(x64: X( 0, 1 << 63, 3, 0))) + XCTAssertEqual(T(x64: X(0, 7, 0, 0)) >> ( 1), T(x64: X( 1 << 63, 3, 0, 0))) + XCTAssertEqual(T(x64: X(7, 0, 0, 0)) >> ( 1), T(x64: X( 3, 0, 0, 0))) + } + + func testBitshiftingRightIsUnsigned() { + XCTAssertEqual(T(x64: X(0, 0, 0, 1 << 63)) >> ( 0), T(x64: X(0, 0, 0, 1 << 63))) + XCTAssertEqual(T(x64: X(0, 0, 0, 1 << 63)) >> ( 64), T(x64: X(0, 0, 1 << 63, 0))) + XCTAssertEqual(T(x64: X(0, 0, 0, 1 << 63)) >> (128), T(x64: X(0, 1 << 63, 0, 0))) + XCTAssertEqual(T(x64: X(0, 0, 0, 1 << 63)) >> (192), T(x64: X(1 << 63, 0, 0, 0))) + XCTAssertEqual(T(x64: X(0, 0, 0, 1 << 63)) >> (256), T(x64: X(0, 0, 0, 0))) + } + + //=------------------------------------------------------------------------= + // MARK: Tests x Miscellaneous + //=------------------------------------------------------------------------= + + func testBitshiftingIsSmart() { + for _ in 0 ..< 100 { + let x0 = UInt64.random(in: 0 ..< UInt64.max) + let x1 = UInt64.random(in: 0 ..< UInt64.max) + let x2 = UInt64.random(in: 0 ..< UInt64.max) + let x3 = UInt64.random(in: 0 ..< UInt64.max) + let shift = Int.random(in: 0 ..< T.bitWidth) + let value = T(x64:(x0, x1, x2, x3)) + + XCTAssertEqual(value << shift, value >> (-shift)) + XCTAssertEqual(value >> shift, value << (-shift)) + } + } + + func testBitshiftingByMaskingIsEquivalentToBitshiftingModuloBitWidth() { + for _ in 0 ..< 100 { + let x0 = UInt64.random(in: 0 ..< UInt64.max) + let x1 = UInt64.random(in: 0 ..< UInt64.max) + let x2 = UInt64.random(in: 0 ..< UInt64.max) + let x3 = UInt64.random(in: 0 ..< UInt64.max) + let shift = Int.random(in: 0 ..< Int.max) + let value = T(x64:(x0, x1, x2, x3)) + + XCTAssertEqual(value &<< shift, value << abs(shift % T.bitWidth)) + XCTAssertEqual(value &>> shift, value >> abs(shift % T.bitWidth)) + } } }