//=----------------------------------------------------------------------------= // This source file is part of the AwesomeNumbersKit open source project. // // Copyright (c) 2022 Oscar Byström Ericsson // Licensed under Apache License, Version 2.0 // // See http://www.apache.org/licenses/LICENSE-2.0 for license information. //=----------------------------------------------------------------------------= //*============================================================================* // MARK: * ANK x Fixed-Width Integer //*============================================================================* /// An integer type with a fixed bit width for every instance. /// /// ### Two's Complement /// /// Like `BinaryInteger`, it has [two's complement][2s] semantics. /// /// ``` /// The two's complement representation of 0 is an infinite sequence of 0s. /// The two's complement representation of -1 is an infinite sequence of 1s. /// ``` /// /// [2s]: https://en.wikipedia.org/wiki/Two%27s_complement /// public protocol ANKFixedWidthInteger: ANKBinaryInteger, ANKBitPatternConvertible, FixedWidthInteger where Digit: ANKFixedWidthInteger, Magnitude: ANKFixedWidthInteger, Magnitude.BitPattern == BitPattern { //=------------------------------------------------------------------------= // MARK: Details x Bits //=------------------------------------------------------------------------= /// Creates a new instance repeating the given bit. /// /// ``` /// ┌────── → ─────────────────────────┐ /// │ bit │ self │ /// ├────── → ────────── = ────────────┤ /// │ false │ Int256( 0) │ 0.......... │ /// │ true │ Int256(-1) │ 1.......... │ /// └────── → ────────── = ────────────┘ /// ``` /// /// - Note: This member has two's complement semantics. /// @inlinable init(repeating bit: Bool) /// Returns the most significant bit (`MSB`). /// /// ``` /// ┌───────────────────────── → ──────┐ /// │ self │ MSB │ /// ├─────────── = ─────────── → ──────┤ /// │ Int256( 3) │ 0........11 │ false │ /// │ Int256( 2) │ 0........10 │ false │ /// │ Int256( 1) │ 0.........1 │ false │ /// │ Int256( 0) │ 0.......... │ false │ /// │ Int256(-1) │ 1.......... │ true │ /// │ Int256(-2) │ 1.........0 │ true │ /// │ Int256(-3) │ 1........01 │ true │ /// │ Int256(-4) │ 1........00 │ true │ /// └─────────── = ─────────── → ──────┘ /// ``` /// /// - Note: This member has two's complement semantics. /// @inlinable var mostSignificantBit: Bool { get } //=------------------------------------------------------------------------= // MARK: Details x Complements //=------------------------------------------------------------------------= /// Forms the two's complement subsequence of `self` and `carry`, and returns an `overflow` indicator. /// /// The subsequence is equal to the two's complement when the `carry` bit is set: /// /// ```swift /// formTwosComplementSubsequence(true ) // two's complement /// formTwosComplementSubsequence(false) // one's complement /// ``` /// /// The following example shows a two's complement formation of a composite integer: /// /// ```swift /// var carry = true /// carry = low .formTwosComplementSubsequence(carry) /// carry = high.formTwosComplementSubsequence(carry) /// ``` /// @inlinable mutating func formTwosComplementSubsequence(_ carry: Bool) -> Bool /// Returns the two's complement subsequence of `self` and `carry`, along with an `overflow` indicator. /// /// The subsequence is equal to the two's complement when the `carry` bit is set: /// /// ```swift /// twosComplementSubsequence(true ) // two's complement /// twosComplementSubsequence(false) // one's complement /// ``` /// /// The following example shows a two's complement formation of a composite integer: /// /// ```swift /// var carry = true /// (low, carry) = low .twosComplementSubsequence(carry) /// (high, carry) = high.twosComplementSubsequence(carry) /// ``` /// @inlinable func twosComplementSubsequence(_ carry: Bool) -> PVO //=------------------------------------------------------------------------= // MARK: Details x Addition //=------------------------------------------------------------------------= /// Forms the `sum` of `self` and `other`, and returns an `overflow` indicator. /// /// ``` /// ┌────────────┬─────────── → ───────────┬──────────┐ /// │ self │ other │ sum │ overflow │ /// ├────────────┼─────────── → ───────────┼──────────┤ /// │ Int256( 1) │ Int256( 4) │ Int256( 5) │ false │ /// │ Int256( 2) │ Int256(-3) │ Int256(-1) │ false │ /// │ Int256(-3) │ Int256( 2) │ Int256(-1) │ false │ /// │ Int256(-4) │ Int256(-1) │ Int256(-5) │ false │ /// │────────────┤─────────── → ───────────┤──────────┤ /// │ Int256.max │ Int256( 1) │ Int256.min │ true │ /// │ Int256.min │ Int256(-1) │ Int256.max │ true │ /// └────────────┴─────────── → ───────────┴──────────┘ /// ``` /// /// - Note: In the case of `overflow`, the result is truncated. /// @inlinable mutating func addReportingOverflow(_ other: Self) -> Bool /// Forms the `sum` of `self` and `other`, and returns an `overflow` indicator. /// /// ``` /// ┌────────────┬─────────── → ───────────┬──────────┐ /// │ self │ other │ sum │ overflow │ /// ├────────────┼─────────── → ───────────┼──────────┤ /// │ Int256( 1) │ Int( 4) │ Int256( 5) │ false │ /// │ Int256( 2) │ Int( -3) │ Int256(-1) │ false │ /// │ Int256(-3) │ Int( 2) │ Int256(-1) │ false │ /// │ Int256(-4) │ Int( -1) │ Int256(-5) │ false │ /// │────────────┤─────────── → ───────────┤──────────┤ /// │ Int256.max │ Int( 1) │ Int256.min │ true │ /// │ Int256.min │ Int( -1) │ Int256.max │ true │ /// └────────────┴─────────── → ───────────┴──────────┘ /// ``` /// /// - Note: In the case of `overflow`, the result is truncated. /// @_disfavoredOverload @inlinable mutating func addReportingOverflow(_ other: Digit) -> Bool /// Returns the `sum` of `self` and `other`, along with an `overflow` indicator. /// /// ``` /// ┌────────────┬─────────── → ───────────┬──────────┐ /// │ self │ other │ sum │ overflow │ /// ├────────────┼─────────── → ───────────┼──────────┤ /// │ Int256( 1) │ Int256( 4) │ Int256( 5) │ false │ /// │ Int256( 2) │ Int256(-3) │ Int256(-1) │ false │ /// │ Int256(-3) │ Int256( 2) │ Int256(-1) │ false │ /// │ Int256(-4) │ Int256(-1) │ Int256(-5) │ false │ /// │────────────┤─────────── → ───────────┤──────────┤ /// │ Int256.max │ Int256( 1) │ Int256.min │ true │ /// │ Int256.min │ Int256(-1) │ Int256.max │ true │ /// └────────────┴─────────── → ───────────┴──────────┘ /// ``` /// /// - Note: In the case of `overflow`, the result is truncated. /// @inlinable func addingReportingOverflow(_ other: Self) -> PVO /// Returns the `sum` of `self` and `other`, along with an `overflow` indicator. /// /// ``` /// ┌────────────┬─────────── → ───────────┬──────────┐ /// │ self │ other │ sum │ overflow │ /// ├────────────┼─────────── → ───────────┼──────────┤ /// │ Int256( 1) │ Int( 4) │ Int256( 5) │ false │ /// │ Int256( 2) │ Int( -3) │ Int256(-1) │ false │ /// │ Int256(-3) │ Int( 2) │ Int256(-1) │ false │ /// │ Int256(-4) │ Int( -1) │ Int256(-5) │ false │ /// │────────────┤─────────── → ───────────┤──────────┤ /// │ Int256.max │ Int( 1) │ Int256.min │ true │ /// │ Int256.min │ Int( -1) │ Int256.max │ true │ /// └────────────┴─────────── → ───────────┴──────────┘ /// ``` /// /// - Note: In the case of `overflow`, the result is truncated. /// @_disfavoredOverload @inlinable func addingReportingOverflow(_ other: Digit) -> PVO /// Forms the `difference` of `self` and `other`, and returns an `overflow` indicator. /// /// ``` /// ┌────────────┬─────────── → ───────────┬──────────┐ /// │ self │ other │ difference │ overflow │ /// ├────────────┼─────────── → ───────────┤──────────┤ /// │ Int256( 1) │ Int256( 4) │ Int256(-3) │ false │ /// │ Int256( 2) │ Int256(-3) │ Int256( 5) │ false │ /// │ Int256(-3) │ Int256( 2) │ Int256(-5) │ false │ /// │ Int256(-4) │ Int256(-1) │ Int256(-3) │ false │ /// │────────────┤─────────── → ───────────┤──────────┤ /// │ Int256.max │ Int256(-1) │ Int256.min │ true │ /// │ Int256.min │ Int256( 1) │ Int256.max │ true │ /// └────────────┴─────────── → ───────────┴──────────┘ /// ``` /// /// - Note: In the case of `overflow`, the result is truncated. /// @inlinable mutating func subtractReportingOverflow(_ other: Self) -> Bool /// Forms the `difference` of `self` and `other`, and returns an `overflow` indicator. /// /// ``` /// ┌────────────┬─────────── → ───────────┬──────────┐ /// │ self │ other │ difference │ overflow │ /// ├────────────┼─────────── → ───────────┤──────────┤ /// │ Int256( 1) │ Int( 4) │ Int256(-3) │ false │ /// │ Int256( 2) │ Int( -3) │ Int256( 5) │ false │ /// │ Int256(-3) │ Int( 2) │ Int256(-5) │ false │ /// │ Int256(-4) │ Int( -1) │ Int256(-3) │ false │ /// │────────────┤─────────── → ───────────┤──────────┤ /// │ Int256.max │ Int( -1) │ Int256.min │ true │ /// │ Int256.min │ Int( 1) │ Int256.max │ true │ /// └────────────┴─────────── → ───────────┴──────────┘ /// ``` /// /// - Note: In the case of `overflow`, the result is truncated. /// @_disfavoredOverload @inlinable mutating func subtractReportingOverflow(_ other: Digit) -> Bool /// Returns the `difference` of `self` and `other`, along with an `overflow` indicator. /// /// ``` /// ┌────────────┬─────────── → ───────────┬──────────┐ /// │ self │ other │ difference │ overflow │ /// ├────────────┼─────────── → ───────────┤──────────┤ /// │ Int256( 1) │ Int256( 4) │ Int256(-3) │ false │ /// │ Int256( 2) │ Int256(-3) │ Int256( 5) │ false │ /// │ Int256(-3) │ Int256( 2) │ Int256(-5) │ false │ /// │ Int256(-4) │ Int256(-1) │ Int256(-3) │ false │ /// │────────────┤─────────── → ───────────┤──────────┤ /// │ Int256.max │ Int256(-1) │ Int256.min │ true │ /// │ Int256.min │ Int256( 1) │ Int256.max │ true │ /// └────────────┴─────────── → ───────────┴──────────┘ /// ``` /// /// - Note: In the case of `overflow`, the result is truncated. /// @inlinable func subtractingReportingOverflow(_ other: Self) -> PVO /// Returns the `difference` of `self` and `other`, along with an `overflow` indicator. /// /// ``` /// ┌────────────┬─────────── → ───────────┬──────────┐ /// │ self │ other │ difference │ overflow │ /// ├────────────┼─────────── → ───────────┤──────────┤ /// │ Int256( 1) │ Int( 4) │ Int256(-3) │ false │ /// │ Int256( 2) │ Int( -3) │ Int256( 5) │ false │ /// │ Int256(-3) │ Int( 2) │ Int256(-5) │ false │ /// │ Int256(-4) │ Int( -1) │ Int256(-3) │ false │ /// │────────────┤─────────── → ───────────┤──────────┤ /// │ Int256.max │ Int( -1) │ Int256.min │ true │ /// │ Int256.min │ Int( 1) │ Int256.max │ true │ /// └────────────┴─────────── → ───────────┴──────────┘ /// ``` /// /// - Note: In the case of `overflow`, the result is truncated. /// @_disfavoredOverload @inlinable func subtractingReportingOverflow(_ other: Digit) -> PVO //=------------------------------------------------------------------------= // MARK: Details x Multiplication //=------------------------------------------------------------------------= /// Forms the `low` product of `self` and `other`, and returns an `overflow` indicator. /// /// ``` /// ┌────────────┬─────────── → ───────────┬────────────┬──────────┐ /// │ self │ other │ high │ low │ overflow │ /// ├────────────┼─────────── → ───────────┤────────────┤──────────┤ /// │ Int256( 1) │ Int256( 4) │ Int256( 0) │ Int256( 4) │ false │ /// │ Int256( 2) │ Int256(-3) │ Int256(-1) │ Int256(-6) │ false │ /// │ Int256(-3) │ Int256( 2) │ Int256(-1) │ Int256(-6) │ false │ /// │ Int256(-4) │ Int256(-1) │ Int256( 0) │ Int256( 4) │ false │ /// │────────────┤─────────── → ───────────┤────────────┤──────────┤ /// │ Int256.max │ Int256( 2) │ Int256( 0) │ Int256(-2) │ true │ /// │ Int256.min │ Int256( 2) │ Int256(-1) │ Int256( 0) │ true │ /// └────────────┴─────────── → ───────────┴────────────┴──────────┘ /// ``` /// /// - Note: In the case of `overflow`, the result is truncated. /// @inlinable mutating func multiplyReportingOverflow(by other: Self) -> Bool /// Forms the `low` product of `self` and `other`, and returns an `overflow` indicator. /// /// ``` /// ┌────────────┬─────────── → ───────────┬────────────┬──────────┐ /// │ self │ other │ high │ low │ overflow │ /// ├────────────┼─────────── → ───────────┤────────────┤──────────┤ /// │ Int256( 1) │ Int( 4) │ Int( 0) │ Int256( 4) │ false │ /// │ Int256( 2) │ Int( -3) │ Int( -1) │ Int256(-6) │ false │ /// │ Int256(-3) │ Int( 2) │ Int( -1) │ Int256(-6) │ false │ /// │ Int256(-4) │ Int( -1) │ Int( 0) │ Int256( 4) │ false │ /// │────────────┤─────────── → ───────────┤────────────┤──────────┤ /// │ Int256.max │ Int( 2) │ Int( 0) │ Int256(-2) │ true │ /// │ Int256.min │ Int( 2) │ Int( -1) │ Int256( 0) │ true │ /// └────────────┴─────────── → ───────────┴────────────┴──────────┘ /// ``` /// /// - Note: In the case of `overflow`, the result is truncated. /// @_disfavoredOverload @inlinable mutating func multiplyReportingOverflow(by other: Digit) -> Bool /// Returns the `low` product of `self` and `other`, along with an `overflow` indicator. /// /// ``` /// ┌────────────┬─────────── → ───────────┬────────────┬──────────┐ /// │ self │ other │ high │ low │ overflow │ /// ├────────────┼─────────── → ───────────┤────────────┤──────────┤ /// │ Int256( 1) │ Int256( 4) │ Int256( 0) │ Int256( 4) │ false │ /// │ Int256( 2) │ Int256(-3) │ Int256(-1) │ Int256(-6) │ false │ /// │ Int256(-3) │ Int256( 2) │ Int256(-1) │ Int256(-6) │ false │ /// │ Int256(-4) │ Int256(-1) │ Int256( 0) │ Int256( 4) │ false │ /// │────────────┤─────────── → ───────────┤────────────┤──────────┤ /// │ Int256.max │ Int256( 2) │ Int256( 0) │ Int256(-2) │ true │ /// │ Int256.min │ Int256( 2) │ Int256(-1) │ Int256( 0) │ true │ /// └────────────┴─────────── → ───────────┴────────────┴──────────┘ /// ``` /// /// - Note: In the case of `overflow`, the result is truncated. /// @inlinable func multipliedReportingOverflow(by other: Self) -> PVO /// Returns the `low` product of `self` and `other`, along with an `overflow` indicator. /// /// ``` /// ┌────────────┬─────────── → ───────────┬────────────┬──────────┐ /// │ self │ other │ high │ low │ overflow │ /// ├────────────┼─────────── → ───────────┤────────────┤──────────┤ /// │ Int256( 1) │ Int( 4) │ Int( 0) │ Int256( 4) │ false │ /// │ Int256( 2) │ Int( -3) │ Int( -1) │ Int256(-6) │ false │ /// │ Int256(-3) │ Int( 2) │ Int( -1) │ Int256(-6) │ false │ /// │ Int256(-4) │ Int( -1) │ Int( 0) │ Int256( 4) │ false │ /// │────────────┤─────────── → ───────────┤────────────┤──────────┤ /// │ Int256.max │ Int( 2) │ Int( 0) │ Int256(-2) │ true │ /// │ Int256.min │ Int( 2) │ Int( -1) │ Int256( 0) │ true │ /// └────────────┴─────────── → ───────────┴────────────┴──────────┘ /// ``` /// /// - Note: In the case of `overflow`, the result is truncated. /// @_disfavoredOverload @inlinable func multipliedReportingOverflow(by other: Digit) -> PVO /// Forms the `low` product of `self` and `other`, and returns the `high`. /// /// ``` /// ┌────────────┬─────────── → ───────────┬────────────┬──────────┐ /// │ self │ other │ high │ low │ overflow │ /// ├────────────┼─────────── → ───────────┤────────────┤──────────┤ /// │ Int256( 1) │ Int256( 4) │ Int256( 0) │ Int256( 4) │ false │ /// │ Int256( 2) │ Int256(-3) │ Int256(-1) │ Int256(-6) │ false │ /// │ Int256(-3) │ Int256( 2) │ Int256(-1) │ Int256(-6) │ false │ /// │ Int256(-4) │ Int256(-1) │ Int256( 0) │ Int256( 4) │ false │ /// │────────────┤─────────── → ───────────┤────────────┤──────────┤ /// │ Int256.max │ Int256( 2) │ Int256( 0) │ Int256(-2) │ true │ /// │ Int256.min │ Int256( 2) │ Int256(-1) │ Int256( 0) │ true │ /// └────────────┴─────────── → ───────────┴────────────┴──────────┘ /// ``` /// /// - Note: The `high` and `low` product contain the entire `overflow` from `low` to `high`. /// @inlinable mutating func multiplyFullWidth(by other: Self) -> Self /// Forms the `low` product of `self` and `other`, and returns the `high`. /// /// ``` /// ┌────────────┬─────────── → ───────────┬────────────┬──────────┐ /// │ self │ other │ high │ low │ overflow │ /// ├────────────┼─────────── → ───────────┤────────────┤──────────┤ /// │ Int256( 1) │ Int( 4) │ Int( 0) │ Int256( 4) │ false │ /// │ Int256( 2) │ Int( -3) │ Int( -1) │ Int256(-6) │ false │ /// │ Int256(-3) │ Int( 2) │ Int( -1) │ Int256(-6) │ false │ /// │ Int256(-4) │ Int( -1) │ Int( 0) │ Int256( 4) │ false │ /// │────────────┤─────────── → ───────────┤────────────┤──────────┤ /// │ Int256.max │ Int( 2) │ Int( 0) │ Int256(-2) │ true │ /// │ Int256.min │ Int( 2) │ Int( -1) │ Int256( 0) │ true │ /// └────────────┴─────────── → ───────────┴────────────┴──────────┘ /// ``` /// /// - Note: The `high` and `low` product contain the entire `overflow` from `low` to `high`. /// @_disfavoredOverload @inlinable mutating func multiplyFullWidth(by other: Digit) -> Digit /// Returns the `high` and `low` product of `self` and `other`. /// /// ``` /// ┌────────────┬─────────── → ───────────┬────────────┬──────────┐ /// │ self │ other │ high │ low │ overflow │ /// ├────────────┼─────────── → ───────────┤────────────┤──────────┤ /// │ Int256( 1) │ Int256( 4) │ Int256( 0) │ Int256( 4) │ false │ /// │ Int256( 2) │ Int256(-3) │ Int256(-1) │ Int256(-6) │ false │ /// │ Int256(-3) │ Int256( 2) │ Int256(-1) │ Int256(-6) │ false │ /// │ Int256(-4) │ Int256(-1) │ Int256( 0) │ Int256( 4) │ false │ /// │────────────┤─────────── → ───────────┤────────────┤──────────┤ /// │ Int256.max │ Int256( 2) │ Int256( 0) │ Int256(-2) │ true │ /// │ Int256.min │ Int256( 2) │ Int256(-1) │ Int256( 0) │ true │ /// └────────────┴─────────── → ───────────┴────────────┴──────────┘ /// ``` /// /// - Note: The `high` and `low` product contain the entire `overflow` from `low` to `high`. /// @inlinable func multipliedFullWidth(by other: Self) -> HL /// Returns the `high` and `low` product of `self` and `other`. /// /// ``` /// ┌────────────┬─────────── → ───────────┬────────────┬──────────┐ /// │ self │ other │ high │ low │ overflow │ /// ├────────────┼─────────── → ───────────┤────────────┤──────────┤ /// │ Int256( 1) │ Int( 4) │ Int( 0) │ Int256( 4) │ false │ /// │ Int256( 2) │ Int( -3) │ Int( -1) │ Int256(-6) │ false │ /// │ Int256(-3) │ Int( 2) │ Int( -1) │ Int256(-6) │ false │ /// │ Int256(-4) │ Int( -1) │ Int( 0) │ Int256( 4) │ false │ /// │────────────┤─────────── → ───────────┤────────────┤──────────┤ /// │ Int256.max │ Int( 2) │ Int( 0) │ Int256(-2) │ true │ /// │ Int256.min │ Int( 2) │ Int( -1) │ Int256( 0) │ true │ /// └────────────┴─────────── → ───────────┴────────────┴──────────┘ /// ``` /// /// - Note: The `high` and `low` product contain the entire `overflow` from `low` to `high`. /// @_disfavoredOverload @inlinable func multipliedFullWidth(by other: Digit) -> HL //=------------------------------------------------------------------------= // MARK: Details x Division //=------------------------------------------------------------------------= /// Returns the `quotient` and `remainder` of dividing `other` by `self`. /// /// ``` /// ┌────────────┬──────────────────────────────────────── → ───────────┬────────────────┬──────────┐ /// │ self │ other │ quotient | remainder │ overflow │ /// ├────────────┼──────────────────────────────────────── → ───────────┤────────────────┤──────────┤ /// │ Int256.max │ Int256( 1), UInt256( 2) │ Int256( 2) │ Int256( 4) │ false │ /// │ Int256.min │ Int256( 1), UInt256( 2) │ Int256(-2) │ Int256( 2) │ false │ /// │ Int256.max │ Int256.max / 2 + 0, UInt256.max / 2 + 0 │ Int256.max │ Int256.max - 1 │ false │ /// │ Int256.min │ Int256.max / 2 + 1, UInt256.max / 2 + 0 │ Int256.min │ Int256.max - 1 │ false │ /// │────────────┤──────────────────────────────────────── → ───────────┤────────────────┤──────────┤ /// │ Int256( 0) │ Int256( 1), UInt256( 2) │ Int256( 2) │ Int256( 2) │ true │ /// │ Int256.max │ Int256.max / 2 + 0, UInt256.max / 2 + 1 │ Int256.min │ Int256( 0) │ true │ /// │ Int256.min │ Int256.max / 2 + 1, UInt256.max / 2 + 1 │ Int256.max │ Int256( 0) │ true │ /// └────────────┴──────────────────────────────────────── → ───────────┴────────────────┴──────────┘ /// ``` /// /// - Note: In the case of `overflow`, a runtime error may occur. /// @inlinable func dividingFullWidth(_ other: HL) -> QR /// Returns the `quotient` and `remainder` of dividing `other` by `self`, along with an `overflow` indicator. /// /// ``` /// ┌────────────┬──────────────────────────────────────── → ───────────┬────────────────┬──────────┐ /// │ self │ other │ quotient | remainder │ overflow │ /// ├────────────┼──────────────────────────────────────── → ───────────┤────────────────┤──────────┤ /// │ Int256.max │ Int256( 1), UInt256( 2) │ Int256( 2) │ Int256( 4) │ false │ /// │ Int256.min │ Int256( 1), UInt256( 2) │ Int256( 2) │ Int256( 4) │ false │ /// │ Int256.max │ Int256.max / 2 + 0, UInt256.max / 2 + 0 │ Int256.max │ Int256.max - 1 │ false │ /// │ Int256.min │ Int256.max / 2 + 1, UInt256.max / 2 + 0 │ Int256.min │ Int256.max - 1 │ false │ /// │────────────┤──────────────────────────────────────── → ───────────┤────────────────┤──────────┤ /// │ Int256( 0) │ Int256( 1), UInt256( 2) │ Int256( 2) │ Int256( 2) │ true │ /// │ Int256.max │ Int256.max / 2 + 0, UInt256.max / 2 + 1 │ Int256.min │ Int256( 0) │ true │ /// │ Int256.min │ Int256.max / 2 + 1, UInt256.max / 2 + 1 │ Int256.max │ Int256( 0) │ true │ /// └────────────┴──────────────────────────────────────── → ───────────┴────────────────┴──────────┘ /// ``` /// /// - Note: In the case of `overflow`, the result is truncated or, if undefined, `other` and `other`. /// @inlinable func dividingFullWidthReportingOverflow(_ other: HL) -> PVO> //=------------------------------------------------------------------------= // MARK: Details x Shifts //=------------------------------------------------------------------------= // see: https://github.com/oscbyspro/AwesomeNumbersKit/issues/135 //=------------------------------------------------------------------------= /// Forms the result of performing a masking left shift on `lhs` by `rhs`. @inlinable static func &<<=(lhs: inout Self, rhs: some BinaryInteger) /// Returns the result of performing a masking left shift on `lhs` by `rhs`. @inlinable static func &<<(lhs: Self, rhs: some BinaryInteger) -> Self /// Forms the result of performing a masking right shift on `lhs` by `rhs`. @inlinable static func &>>=(lhs: inout Self, rhs: some BinaryInteger) /// Returns the result of performing a masking right shift on `lhs` by `rhs`. @inlinable static func &>>(lhs: Self, rhs: some BinaryInteger) -> Self } //=----------------------------------------------------------------------------= // MARK: + Details //=----------------------------------------------------------------------------= extension ANKFixedWidthInteger { //=------------------------------------------------------------------------= // MARK: Details x Bits //=------------------------------------------------------------------------= @inlinable public init(bit: Bool) { self = bit ? (1 as Self) : (0 as Self) } @inlinable public init(repeating bit: Bool) { self = bit ? ~(0 as Self) : (0 as Self) } @inlinable public var mostSignificantBit: Bool { self & ((1 as Self) &<< (Self.bitWidth &- 1)) != (0 as Self) } @inlinable public var leastSignificantBit: Bool { self & ((1 as Self)) != (0 as Self) } //=------------------------------------------------------------------------= // MARK: Details x Comparisons //=------------------------------------------------------------------------= @inlinable public var isZero: Bool { self == (0 as Self) } @inlinable public var isLessThanZero: Bool { Self.isSigned && self < (0 as Self) } @inlinable public var isMoreThanZero: Bool { self > (0 as Self) } @inlinable public var isPowerOf2: Bool { !self.isLessThanZero && self.nonzeroBitCount == 1 } @inlinable public func compared(to other: Self) -> Int { (self < other) ? -1 : (self == other) ? 0 : 1 } //=------------------------------------------------------------------------= // MARK: Details x Complements //=------------------------------------------------------------------------= @inlinable public mutating func formTwosComplement() { _ = self.formTwosComplementSubsequence(true) } @inlinable public func twosComplement() -> Self { self.twosComplementSubsequence(true).partialValue } //=------------------------------------------------------------------------= // MARK: Details x Addition //=------------------------------------------------------------------------= @inlinable public static func +=(lhs: inout Self, rhs: Self) { let overflow: Bool = lhs.addReportingOverflow(rhs) precondition(!overflow, ANK.callsiteOverflowInfo()) } @_disfavoredOverload @inlinable public static func +=(lhs: inout Self, rhs: Digit) { let overflow: Bool = lhs.addReportingOverflow(rhs) precondition(!overflow, ANK.callsiteOverflowInfo()) } @inlinable public static func +(lhs: Self, rhs: Self) -> Self { let pvo: PVO = lhs.addingReportingOverflow(rhs) precondition(!pvo.overflow, ANK.callsiteOverflowInfo()) return pvo.partialValue as Self } @_disfavoredOverload @inlinable public static func +(lhs: Self, rhs: Digit) -> Self { let pvo: PVO = lhs.addingReportingOverflow(rhs) precondition(!pvo.overflow, ANK.callsiteOverflowInfo()) return pvo.partialValue as Self } @inlinable public static func &+=(lhs: inout Self, rhs: Self) { _ = lhs.addReportingOverflow(rhs) } @_disfavoredOverload @inlinable public static func &+=(lhs: inout Self, rhs: Digit) { _ = lhs.addReportingOverflow(rhs) } @inlinable public static func &+(lhs: Self, rhs: Self) -> Self { lhs.addingReportingOverflow(rhs).partialValue } @_disfavoredOverload @inlinable public static func &+(lhs: Self, rhs: Digit) -> Self { lhs.addingReportingOverflow(rhs).partialValue } @inlinable public static func -=(lhs: inout Self, rhs: Self) { let overflow: Bool = lhs.subtractReportingOverflow(rhs) precondition(!overflow, ANK.callsiteOverflowInfo()) } @_disfavoredOverload @inlinable public static func -=(lhs: inout Self, rhs: Digit) { let overflow: Bool = lhs.subtractReportingOverflow(rhs) precondition(!overflow, ANK.callsiteOverflowInfo()) } @inlinable public static func -(lhs: Self, rhs: Self) -> Self { let pvo: PVO = lhs.subtractingReportingOverflow(rhs) precondition(!pvo.overflow, ANK.callsiteOverflowInfo()) return pvo.partialValue as Self } @_disfavoredOverload @inlinable public static func -(lhs: Self, rhs: Digit) -> Self { let pvo: PVO = lhs.subtractingReportingOverflow(rhs) precondition(!pvo.overflow, ANK.callsiteOverflowInfo()) return pvo.partialValue as Self } @inlinable public static func &-=(lhs: inout Self, rhs: Self) { _ = lhs.subtractReportingOverflow(rhs) } @_disfavoredOverload @inlinable public static func &-=(lhs: inout Self, rhs: Digit) { _ = lhs.subtractReportingOverflow(rhs) } @inlinable public static func &-(lhs: Self, rhs: Self) -> Self { lhs.subtractingReportingOverflow(rhs).partialValue } @_disfavoredOverload @inlinable public static func &-(lhs: Self, rhs: Digit) -> Self { lhs.subtractingReportingOverflow(rhs).partialValue } //=------------------------------------------------------------------------= // MARK: Details x Multiplication //=------------------------------------------------------------------------= @inlinable public static func *=(lhs: inout Self, rhs: Self) { let overflow: Bool = lhs.multiplyReportingOverflow(by: rhs) precondition(!overflow, ANK.callsiteOverflowInfo()) } @_disfavoredOverload @inlinable public static func *=(lhs: inout Self, rhs: Digit) { let overflow: Bool = lhs.multiplyReportingOverflow(by: rhs) precondition(!overflow, ANK.callsiteOverflowInfo()) } @inlinable public static func *(lhs: Self, rhs: Self) -> Self { let pvo: PVO = lhs.multipliedReportingOverflow(by: rhs) precondition(!pvo.overflow, ANK.callsiteOverflowInfo()) return pvo.partialValue as Self } @_disfavoredOverload @inlinable public static func *(lhs: Self, rhs: Digit) -> Self { let pvo: PVO = lhs.multipliedReportingOverflow(by: rhs) precondition(!pvo.overflow, ANK.callsiteOverflowInfo()) return pvo.partialValue as Self } @inlinable public static func &*=(lhs: inout Self, rhs: Self) { _ = lhs.multiplyReportingOverflow(by: rhs) } @_disfavoredOverload @inlinable public static func &*=(lhs: inout Self, rhs: Digit) { _ = lhs.multiplyReportingOverflow(by: rhs) } @inlinable public static func &*(lhs: Self, rhs: Self) -> Self { lhs.multipliedReportingOverflow(by: rhs).partialValue } @_disfavoredOverload @inlinable public static func &*(lhs: Self, rhs: Digit) -> Self { lhs.multipliedReportingOverflow(by: rhs).partialValue } } //=----------------------------------------------------------------------------= // MARK: + Details x Signed //=----------------------------------------------------------------------------= extension ANKFixedWidthInteger where Self: ANKSignedInteger { //=------------------------------------------------------------------------= // MARK: Transformations //=------------------------------------------------------------------------= @inlinable public mutating func negateReportingOverflow() -> Bool { self.formTwosComplementSubsequence(true) } @inlinable public func negatedReportingOverflow() -> PVO { self.twosComplementSubsequence(true) } } //=------------------------------------------------------------------------= // MARK: + Details x Sign & Magnitude //=------------------------------------------------------------------------= extension ANKFixedWidthInteger { //=------------------------------------------------------------------------= // MARK: Initializers //=------------------------------------------------------------------------= /// Tries to create a representable value equal to the given `sign` and `magnitude`. /// /// If the `sign` and `magnitude` are is not representable, the result is nil. /// /// ``` /// ┌───────┬───────────────────── → ───────────┐ /// │ sign │ magnitude │ self │ /// │───────┤───────────────────── → ───────────┤ /// │ plus │ UInt256( 1) │ Int256( 1) │ /// │ minus │ UInt256( 1) │ Int256(-1) │ /// │───────┤───────────────────── → ───────────┤ /// │ plus │ Int256.max.magnitude │ Int256.max │ /// │ minus │ Int256.min.magnitude │ Int256.min │ /// │───────┤───────────────────── → ───────────┤ /// │ plus │ UInt256.max │ nil │ /// │ minus │ UInt256.max │ nil │ /// └───────┴───────────────────── → ───────────┘ /// ``` /// /// - Note: The `sign` and `magnitude` pair (minus, zero) is represented as zero. /// @inlinable public static func exactly(sign: FloatingPointSign, magnitude: Magnitude) -> Self? { var bitPattern = magnitude as Magnitude var isLessThanZero = (sign == FloatingPointSign.minus) if isLessThanZero { isLessThanZero = !bitPattern.formTwosComplementSubsequence(true) } let value = Self(bitPattern: bitPattern) return value.isLessThanZero == isLessThanZero ? value : nil } /// Creates the representable value closest to the given `sign` and `magnitude`. /// /// If the `sign` and `magnitude` are greater than the maximum representable value, /// the result is this type’s largest value. If the `sign` and `magnitude` are less /// than the smallest representable value, the result is this type’s smallest value. /// /// ``` /// ┌───────┬───────────────────── → ───────────┐ /// │ sign │ magnitude │ self │ /// │───────┤───────────────────── → ───────────┤ /// │ plus │ UInt256( 1) │ Int256( 1) │ /// │ minus │ UInt256( 1) │ Int256(-1) │ /// │───────┤───────────────────── → ───────────┤ /// │ plus │ Int256.max.magnitude │ Int256.max │ /// │ minus │ Int256.min.magnitude │ Int256.min │ /// │───────┤───────────────────── → ───────────┤ /// │ plus │ UInt256.max │ Int256.max │ /// │ minus │ UInt256.max │ Int256.min │ /// └───────┴───────────────────── → ───────────┘ /// ``` /// @inlinable public static func clamping(sign: FloatingPointSign, magnitude: Magnitude) -> Self { self.exactly(sign: sign, magnitude: magnitude) ?? (sign == FloatingPointSign.minus ? Self.min : Self.max) } }