Skip to content

Commit

Permalink
Req. static binary integer one (#106).
Browse files Browse the repository at this point in the history
  • Loading branch information
oscbyspro committed Nov 3, 2023
1 parent 806ee2e commit 56acf68
Show file tree
Hide file tree
Showing 8 changed files with 315 additions and 30 deletions.
30 changes: 29 additions & 1 deletion Sources/NBKCoreKit/NBKBinaryInteger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,28 @@ where Magnitude: NBKUnsignedInteger, Words: Sendable {
// MARK: Details x Numbers
//=------------------------------------------------------------------------=

/// An instance equal to zero.
///
/// Zero is the identity element for addition.
///
/// ```swift
/// precondition(x + .one == x) // for each x
/// precondition(.one + x == x) // for each x
/// ```
///
@inlinable static var zero: Self { get }

/// An instance equal to one.
///
/// One is the identity element for multiplication.
///
/// ```swift
/// precondition(x * .one == x) // for each x
/// precondition(.one * x == x) // for each x
/// ```
///
@inlinable static var one: Self { get }

/// Creates a new instance from the given digit.
///
/// ```
Expand Down Expand Up @@ -1354,9 +1376,15 @@ where Magnitude: NBKUnsignedInteger, Words: Sendable {
extension NBKBinaryInteger {

//=------------------------------------------------------------------------=
// MARK: Initializers
// MARK: Details x Numbers
//=------------------------------------------------------------------------=
// NOTE: Zero is already provided by Swift.AdditiveArithmetic.
//=------------------------------------------------------------------------=

@inlinable public static var one: Self {
1
}

@inlinable public init(digit: Digit) where Digit == Self {
self = digit
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/NBKCoreKit/NBKFixedWidthInteger.swift
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,7 @@ extension NBKFixedWidthInteger where Self: NBKSignedInteger {
extension NBKFixedWidthInteger {

//=------------------------------------------------------------------------=
// MARK: Initializers
// MARK: Details x Numbers
//=------------------------------------------------------------------------=

@inlinable public init?(magnitude: Magnitude) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,13 @@ extension NBK.ProperBinaryInteger where Integer: NBKUnsignedInteger {
///
@inlinable public static func modularMultiplicativeInverse(sign: NBK.Sign, magnitude: Integer, modulo modulus: Integer) -> Integer? {
//=--------------------------------------=
switch modulus.compared(to: 1 as Integer.Digit) {
case 1: break;
case 0: return Integer.zero
switch modulus.compared(to: Integer.Digit.one) {
case 01: break;
case 00: return Integer.zero
default: return nil }
//=--------------------------------------=
let extended = self.greatestCommonDivisorByEuclideanAlgorithm10(of: magnitude, and: modulus)
//=--------------------------------------=
guard extended.result.compared(to: 1 as Integer.Digit).isZero else {
return nil // the arguments must be coprime
}
if !extended.result.compared(to: Integer.Digit.one).isZero { return nil } // must be coprime
//=--------------------------------------=
Swift.assert(extended.lhsCoefficient.isMoreThanZero)
return (sign == .minus) == extended.iteration.isEven ? modulus - extended.lhsCoefficient : extended.lhsCoefficient
Expand Down
89 changes: 89 additions & 0 deletions Tests/NBKCoreKitBenchmarks/NBKCoreInteger+Numbers.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
//=----------------------------------------------------------------------------=
// 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.
//=----------------------------------------------------------------------------=

#if !DEBUG

import NBKCoreKit
import XCTest

//*============================================================================*
// MARK: * NBK x Core Integer x Numbers x Int
//*============================================================================*

final class NBKCoreIntegerBenchmarksOnNumbersAsInt: XCTestCase {

typealias T = Int

//=------------------------------------------------------------------------=
// MARK: Tests x Constants
//=------------------------------------------------------------------------=

func testZero() {
for _ in 0 ..< 5_000_000 {
NBK.blackHole(T.zero)
}
}

func testOne() {
for _ in 0 ..< 5_000_000 {
NBK.blackHole(T.one)
}
}

func testMin() {
for _ in 0 ..< 5_000_000 {
NBK.blackHole(T.min)
}
}

func testMax() {
for _ in 0 ..< 5_000_000 {
NBK.blackHole(T.max)
}
}
}

//*============================================================================*
// MARK: * NBK x Core Integer x Numbers x UInt
//*============================================================================*

final class NBKCoreIntegerBenchmarksOnNumbersAsUInt: XCTestCase {

typealias T = UInt

//=------------------------------------------------------------------------=
// MARK: Tests x Constants
//=------------------------------------------------------------------------=

func testZero() {
for _ in 0 ..< 5_000_000 {
NBK.blackHole(T.zero)
}
}

func testOne() {
for _ in 0 ..< 5_000_000 {
NBK.blackHole(T.one)
}
}

func testMin() {
for _ in 0 ..< 5_000_000 {
NBK.blackHole(T.min)
}
}

func testMax() {
for _ in 0 ..< 5_000_000 {
NBK.blackHole(T.max)
}
}
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ private typealias Y = [UInt32]
//*============================================================================*

final class NBKProperBinaryIntegerBenchmarksOnModularMultiplicativeInverse: XCTestCase {

typealias T = NBK.PBI

//=------------------------------------------------------------------------=
Expand Down
83 changes: 82 additions & 1 deletion Tests/NBKCoreKitTests/NBKCoreInteger+Numbers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,88 @@ final class NBKCoreIntegerTestsOnNumbers: XCTestCase {
let types: [T] = NBKCoreIntegerTests.types

//=------------------------------------------------------------------------=
// MARK: Tests
// MARK: Tests x Constants
//=------------------------------------------------------------------------=

func testZero() {
func whereIs<T>(_ type: T.Type) where T: NBKCoreInteger {
XCTAssertEqual(T.zero, 000)

for x in Int8.min ... Int8.max {
let x = T(truncatingIfNeeded: x)

XCTAssertEqual(x + T.zero, x)
XCTAssertEqual(T.zero + x, x)

XCTAssertEqual(x - x, T.zero)
XCTAssertEqual(x - T.zero, x)
}
}

for type: T in types {
whereIs(type)
}
}

func testOne() {
func whereIs<T>(_ type: T.Type) where T: NBKCoreInteger {
XCTAssertEqual(T.one, 0001)

for x in Int8.min ... Int8.max {
let x = T(truncatingIfNeeded: x)

XCTAssertEqual(x * T.one, x)
XCTAssertEqual(T.one * x, x)

XCTAssertEqual(x / T.one, x)
XCTAssertEqual(x % T.one, T.zero)

if !x.isZero {
XCTAssertEqual(x / x, T.one )
XCTAssertEqual(x % x, T.zero)
}
}
}

for type: T in types {
whereIs(type)
}
}

func testMin() {
func whereIsSigned<T>(_ type: T.Type) where T: NBKCoreInteger {
XCTAssertEqual( T.min, T.one << (T.bitWidth - 1))
XCTAssertEqual(~T.max, T.one << (T.bitWidth - 1))
}

func whereIsUnsigned<T>(_ type: T.Type) where T: NBKCoreInteger {
XCTAssertEqual( T.min, T(repeating: false))
XCTAssertEqual(~T.max, T(repeating: false))
}

for type: T in types {
type.isSigned ? whereIsSigned(type) : whereIsUnsigned(type)
}
}

func testMax() {
func whereIsSigned<T>(_ type: T.Type) where T: NBKCoreInteger {
XCTAssertEqual( T.max, ~(T.one << (T.bitWidth - 1)))
XCTAssertEqual(~T.min, ~(T.one << (T.bitWidth - 1)))
}

func whereIsUnsigned<T>(_ type: T.Type) where T: NBKCoreInteger {
XCTAssertEqual( T.max, T(repeating: true))
XCTAssertEqual(~T.min, T(repeating: true))
}

for type: T in types {
type.isSigned ? whereIsSigned(type) : whereIsUnsigned(type)
}
}

//=------------------------------------------------------------------------=
// MARK: Tests x Integers
//=------------------------------------------------------------------------=

func testFromDigit() {
Expand Down
42 changes: 31 additions & 11 deletions Tests/NBKDoubleWidthKitBenchmarks/NBKDoubleWidth+Numbers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,29 @@ final class NBKDoubleWidthBenchmarksOnNumbersAsInt256: XCTestCase {
typealias M = UInt256

//=------------------------------------------------------------------------=
// MARK: Tests
// MARK: Tests x Constants
//=------------------------------------------------------------------------=

func testZero() {
for _ in 0 ..< 1_000_000 {
NBK.blackHole(T())
for _ in 0 ..< 5_000_000 {
NBK.blackHole(T.zero)
}
}

func testEdges() {
for _ in 0 ..< 1_000_000 {
func testOne() {
for _ in 0 ..< 5_000_000 {
NBK.blackHole(T.one)
}
}

func testMin() {
for _ in 0 ..< 5_000_000 {
NBK.blackHole(T.min)
}
}

func testMax() {
for _ in 0 ..< 5_000_000 {
NBK.blackHole(T.max)
}
}
Expand Down Expand Up @@ -436,23 +446,33 @@ final class NBKDoubleWidthBenchmarksOnNumbersAsUInt256: XCTestCase {
typealias M = UInt256

//=------------------------------------------------------------------------=
// MARK: Tests
// MARK: Tests x Constants
//=------------------------------------------------------------------------=

func testZero() {
for _ in 0 ..< 1_000_000 {
NBK.blackHole(T())
for _ in 0 ..< 5_000_000 {
NBK.blackHole(T.zero)
}
}

func testEdges() {
for _ in 0 ..< 1_000_000 {
func testOne() {
for _ in 0 ..< 5_000_000 {
NBK.blackHole(T.one)
}
}

func testMin() {
for _ in 0 ..< 5_000_000 {
NBK.blackHole(T.min)
}
}

func testMax() {
for _ in 0 ..< 5_000_000 {
NBK.blackHole(T.max)
}
}

//=------------------------------------------------------------------------=
// MARK: Tests x Integers
//=------------------------------------------------------------------------=
Expand Down
Loading

0 comments on commit 56acf68

Please sign in to comment.