From a99f1b9417aa8c1b9767fa9f8095a59b030731de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oscar=20Bystr=C3=B6m=20Ericsson?= Date: Thu, 26 Oct 2023 18:00:58 +0200 Subject: [PATCH] [NBKCoreKit] Proper binary integer namespace (#85). --- Sources/NBKCoreKit/Private/NBK.swift | 21 +++++++++++ ...BinaryInteger+GreatestCommonDivisor.swift} | 35 ++++++++++++------- .../Private/NBKProperBinaryInteger.swift | 28 +++++++++++++++ ...BinaryInteger+GreatestCommonDivisor.swift} | 16 +++++---- 4 files changed, 81 insertions(+), 19 deletions(-) rename Sources/NBKCoreKit/Private/{NBK+GreatestCommonDivisor.swift => NBKProperBinaryInteger+GreatestCommonDivisor.swift} (64%) create mode 100644 Sources/NBKCoreKit/Private/NBKProperBinaryInteger.swift rename Tests/NBKCoreKitTests/Private/{NBK+GreatestCommonDivisor.swift => NBKProperBinaryInteger+GreatestCommonDivisor.swift} (90%) diff --git a/Sources/NBKCoreKit/Private/NBK.swift b/Sources/NBKCoreKit/Private/NBK.swift index 02d8219a..b2fa607a 100644 --- a/Sources/NBKCoreKit/Private/NBK.swift +++ b/Sources/NBKCoreKit/Private/NBK.swift @@ -50,6 +50,27 @@ // MARK: Namespaces x Binary Integer //=------------------------------------------------------------------------= + /// A namespace for `Numberick` development. + /// + /// - Warning: Do not use this namespace outside of `Numberick` development. + /// + public typealias PBI = NBK.ProperBinaryInteger + where Integer: NBKBinaryInteger + + /// A namespace for `Numberick` development. + /// + /// - Warning: Do not use this namespace outside of `Numberick` development. + /// + public typealias PSI = NBK.ProperBinaryInteger + where Integer: NBKBinaryInteger & NBKSignedInteger + + /// A namespace for `Numberick` development. + /// + /// - Warning: Do not use this namespace outside of `Numberick` development. + /// + public typealias PUI = NBK.ProperBinaryInteger + where Integer: NBKBinaryInteger & NBKUnsignedInteger + /// A namespace for `Numberick` development. /// /// - Warning: Do not use this namespace outside of `Numberick` development. diff --git a/Sources/NBKCoreKit/Private/NBK+GreatestCommonDivisor.swift b/Sources/NBKCoreKit/Private/NBKProperBinaryInteger+GreatestCommonDivisor.swift similarity index 64% rename from Sources/NBKCoreKit/Private/NBK+GreatestCommonDivisor.swift rename to Sources/NBKCoreKit/Private/NBKProperBinaryInteger+GreatestCommonDivisor.swift index 82c7c6d5..8fead2b1 100644 --- a/Sources/NBKCoreKit/Private/NBK+GreatestCommonDivisor.swift +++ b/Sources/NBKCoreKit/Private/NBKProperBinaryInteger+GreatestCommonDivisor.swift @@ -8,10 +8,10 @@ //=----------------------------------------------------------------------------= //*============================================================================* -// MARK: * NBK x Greatest Common Divisor +// MARK: * NBK x Proper Binary Integer x Greatest Common Divisor //*============================================================================* -extension NBK { +extension NBK.ProperBinaryInteger { //=------------------------------------------------------------------------= // MARK: Utilities @@ -21,28 +21,39 @@ extension NBK { /// /// [algorithm]: https://en.wikipedia.org/wiki/binary_GCD_algorithm /// - @inlinable public static func greatestCommonDivisorByBinaryAlgorithm( - of lhs: T, and rhs: T) -> T.Magnitude where T: NBKBinaryInteger { - self.greatestCommonDivisorByBinaryAlgorithm(of: lhs.magnitude, and: rhs.magnitude) + @inlinable public static func greatestCommonDivisorByBinaryAlgorithm( + of lhs: Integer, and rhs: Integer) -> Integer.Magnitude { + NBK.PUI.greatestCommonDivisorByBinaryAlgorithm(of: lhs.magnitude, and: rhs.magnitude) } +} + +//*============================================================================* +// MARK: * NBK x Proper Binary Integer x Greatest Common Divisor x Unsigned +//*============================================================================* + +extension NBK.ProperBinaryInteger where Integer: NBKUnsignedInteger { + //=------------------------------------------------------------------------= + // MARK: Utilities + //=------------------------------------------------------------------------= + /// Finds the GCD of `lhs` and `rhs` by using [this binary algorithm][algorithm]. /// /// [algorithm]: https://en.wikipedia.org/wiki/binary_GCD_algorithm /// /// - TODO: Use `bitShift(...)` methods if/when NBKBinaryInteger... /// - @inlinable public static func greatestCommonDivisorByBinaryAlgorithm( - of lhs: T, and rhs: T) -> T where T: NBKUnsignedInteger { + @inlinable public static func greatestCommonDivisorByBinaryAlgorithm( + of lhs: Integer, and rhs: Integer) -> Integer { //=--------------------------------------= if rhs.isZero { return lhs } if lhs.isZero { return rhs } //=--------------------------------------= - let lhsShift: Int = lhs.trailingZeroBitCount - let rhsShift: Int = rhs.trailingZeroBitCount + let lhsShift = lhs.trailingZeroBitCount as Int + let rhsShift = rhs.trailingZeroBitCount as Int //=--------------------------------------= - var lhs: T = lhs >> lhsShift - var rhs: T = rhs >> rhsShift + var lhs: Integer = lhs >> lhsShift + var rhs: Integer = rhs >> rhsShift while lhs != rhs { if lhs < rhs { @@ -55,6 +66,6 @@ extension NBK { } lhs <<= Swift.min(lhsShift, rhsShift) - return lhs as T.Magnitude + return lhs as Integer.Magnitude } } diff --git a/Sources/NBKCoreKit/Private/NBKProperBinaryInteger.swift b/Sources/NBKCoreKit/Private/NBKProperBinaryInteger.swift new file mode 100644 index 00000000..47196ece --- /dev/null +++ b/Sources/NBKCoreKit/Private/NBKProperBinaryInteger.swift @@ -0,0 +1,28 @@ +//=----------------------------------------------------------------------------= +// This source file is part of the Numberick open source project. +// +// Copyright (c) 2023 Oscar Byström Ericsson +// Licensed under Apache License, Version 2.0 +// +// See http://www.apache.org/licenses/LICENSE-2.0 for license information. +//=----------------------------------------------------------------------------= + +//*============================================================================* +// MARK: * NBK x Proper Binary Integer +//*============================================================================* + +extension NBK { + + /// A namespace for proper binary integer algorithms. + /// + /// - Note: Proper binary integer models conform to ``NBKBinaryInteger``. + /// + @frozen public enum ProperBinaryInteger where Integer: NBKBinaryInteger { + + //*====================================================================* + // MARK: * Magnitude + //*====================================================================* + + public typealias Magnitude = ProperBinaryInteger + } +} diff --git a/Tests/NBKCoreKitTests/Private/NBK+GreatestCommonDivisor.swift b/Tests/NBKCoreKitTests/Private/NBKProperBinaryInteger+GreatestCommonDivisor.swift similarity index 90% rename from Tests/NBKCoreKitTests/Private/NBK+GreatestCommonDivisor.swift rename to Tests/NBKCoreKitTests/Private/NBKProperBinaryInteger+GreatestCommonDivisor.swift index 69dbfa40..7f05b99a 100644 --- a/Tests/NBKCoreKitTests/Private/NBK+GreatestCommonDivisor.swift +++ b/Tests/NBKCoreKitTests/Private/NBKProperBinaryInteger+GreatestCommonDivisor.swift @@ -13,10 +13,10 @@ import NBKCoreKit import XCTest //*============================================================================* -// MARK: * NBK x Greatest Common Divisor +// MARK: * NBK x Proper Binary Integer x Greatest Common Divisor //*============================================================================* -final class NBKTestsOnGreatestCommonDivisor: XCTestCase { +final class NBKProperBinaryIntegerTestsOnGreatestCommonDivisor: XCTestCase { //=------------------------------------------------------------------------= // MARK: Tests @@ -84,20 +84,22 @@ final class NBKTestsOnGreatestCommonDivisor: XCTestCase { } //*============================================================================* -// MARK: * NBK x Greatest Common Divisor x Assertions +// MARK: * NBK x Proper Binary Integer x Greatest Common Divisor x Assertions //*============================================================================* private func NBKAssertGreatestCommonDivisor( _ lhs: T, _ rhs: T, _ gcd: T.Magnitude, file: StaticString = #file, line: UInt = #line) { + //=------------------------------------------= + let binary = NBK.ProperBinaryInteger.greatestCommonDivisorByBinaryAlgorithm(of:and:) //=------------------------------------------= func with(_ lhs: T, _ rhs: T, _ gcd: T.Magnitude) { brr: do { - XCTAssertEqual(NBK.greatestCommonDivisorByBinaryAlgorithm(of: 0 + lhs, and: 0 + rhs), gcd, file: file, line: line) + XCTAssertEqual(binary(0 + lhs, 0 + rhs), gcd, file: file, line: line) }; if T.isSigned { - XCTAssertEqual(NBK.greatestCommonDivisorByBinaryAlgorithm(of: 0 + lhs, and: 0 - rhs), gcd, file: file, line: line) - XCTAssertEqual(NBK.greatestCommonDivisorByBinaryAlgorithm(of: 0 - lhs, and: 0 + rhs), gcd, file: file, line: line) - XCTAssertEqual(NBK.greatestCommonDivisorByBinaryAlgorithm(of: 0 - lhs, and: 0 - rhs), gcd, file: file, line: line) + XCTAssertEqual(binary(0 + lhs, 0 - rhs), gcd, file: file, line: line) + XCTAssertEqual(binary(0 - lhs, 0 + rhs), gcd, file: file, line: line) + XCTAssertEqual(binary(0 - lhs, 0 - rhs), gcd, file: file, line: line) } } //=------------------------------------------=