# protocol-oriented integers (take 2)

**URL:** <https://forums.swift.org/t/protocol-oriented-integers-take-2/4884>\
**Category:** Discussion\
**Created:** [January 13, 2017, 8:47pm UTC](https://forums.swift.org/t/protocol-oriented-integers-take-2/4884 "2017-01-13T20:47:34Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![moiseev](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/moiseev/32/281_2.png) [@moiseev](https://forums.swift.org/u/moiseev)\
**Post date:** [January 13, 2017, 8:47pm UTC](https://forums.swift.org/t/protocol-oriented-integers-take-2/4884/1 "2017-01-13T20:47:34Z")

</div>

Hi everyone,

Back in June 2016 we discussed the new design of the integer types for the standard library. It even resulted in acceptance of SE-0104 \<[https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md&gt](https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md&gt); for Swift 3. Unfortunately we were not able to implement it in time for the release.

But it was not forgotten, although, as time went by, a few changes needed to be made in order to reflect the current state of the language.  
Without further introduction, please welcome the refined proposal to make integers in Swift more suitable for generic programming.

Available in this gist [Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c) and also inlined below.

Max

Protocol-oriented integers (take 2)

Proposal: SE-NNNN \<[https://gist.github.com/moiseev/0000-even-more-improved-integers.md&gt](https://gist.github.com/moiseev/0000-even-more-improved-integers.md&gt);  
Authors: Dave Abrahams \<[https://github.com/dabrahams&gt;](https://github.com/dabrahams&gt;), Maxim Moiseev \<[https://github.com/moiseev&gt](https://github.com/moiseev&gt);  
Review Manager: TBD  
Status: Awaiting review  
Bug: SR-3196 \<[Issues · apple/swift-issues · GitHub](https://bugs.swift.org/browse/SR-3196&gt);  
Previous Proposal: SE-0104 \<[https://gist.github.com/moiseev/0104-improved-integers.md&gt](https://gist.github.com/moiseev/0104-improved-integers.md&gt);  
\<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#introduction&gt;Introduction)

This proposal is an evolution of SE-0104 \<[https://gist.github.com/moiseev/0104-improved-integers.md&gt;\](https://gist.github.com/moiseev/0104-improved-integers.md&gt;%5C). The goal is still to clean up Swifts integer APIs and make them more useful for generic programming.

The language has evolved in ways that affect integers APIs since the time the original proposal was approved for Swift 3. We also attempted to implement the proposed model in the standard library and found that some essential APIs were missing, whereas others could be safely removed.

Major changes to the APIs introduced by this proposal (as compared to SE-0104 \<[https://gist.github.com/moiseev/0104-improved-integers.md&gt;\](https://gist.github.com/moiseev/0104-improved-integers.md&gt;%5C)) are listed in a dedicated section \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#whats-new-since-se-0104&gt;%5C).

\<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#motivation&gt;Motivation)

Swift's integer protocols don't currently provide a suitable basis for generic programming. See this blog post \<[http://blog.krzyzanowskim.com/2015/03/01/swift\_madness\_of\_generic\_integer/&gt](http://blog.krzyzanowskim.com/2015/03/01/swift_madness_of_generic_integer/&gt); for an example of an attempt to implement a generic algorithm over integers.

The way the Arithmetic protocol is defined, it does not generalize to floating point numbers and also slows down compilation by requiring every concrete type to provide an implementation of arithmetic operators, thus polluting the overload set.

Converting from one integer type to another is performed using the concept of the 'maximum width integer' (see MaxInt), which is an artificial limitation. The very existence of MaxInt makes it unclear what to do should someone implement Int256, for example.

Another annoying problem is the inability to use integers of different types in comparison and bit-shift operations. For example, the following snippets won't compile:

var x: Int8 = 42  
let y = 1  
let z = 0

x \<\<= y // error: binary operator '\<\<=' cannot be applied to operands of type 'Int8' and 'Int'  
if x \> z { ... } // error: binary operator '\>' cannot be applied to operands of type 'Int8' and 'Int'  
Currently, bit-shifting a negative number of (or too many) bits causes a trap on some platforms, which makes low-level bit manipulations needlessly dangerous and unpredictable.

Finally, the current design predates many of the improvements that came since Swift 1, and hasn't been revised since then.

\<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#proposed-solution&gt;Proposed) solution

We propose a new model that does not have above mentioned problems and is more easily extensible.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+--------------+ +-------------+  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+------\>+ Arithmetic | | Comparable |  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \> (+,-,\*,/) | | (==,\<,\>,...)|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> +-------------++ +---+---------+  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> ^ ^  
+-------+------------+ | |

> SignedArithmetic | +-+-------+-----------+  
> &nbsp;&nbsp;&nbsp;&nbsp;(unary -) | | BinaryInteger |

+------+-------------+ |(words,%,bitwise,...)|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^ ++---+-----+----------+  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> +-----------^ ^ ^---------------+  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \> \> \>  
+------+---------++ +---------+---------------+ +--+----------------+

> SignedInteger | | FixedWidthInteger | | UnsignedInteger |  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \>(endianness,overflow,...)| | |

+---------------+-+ +-+--------------------+--+ +-+-----------------+  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^ ^ ^ ^  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \> \> \>  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \> \> \>  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++--------+-+ +-+-------+-+  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\>Int family |-+ |UInt family|-+  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+-----------+ | +-----------+ |  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+-----------+ +-----------+  
There are several benefits provided by this model over the old one:

It allows mixing integer types in generic functions.

The possibility to initialize instances of any concrete integer type with values of any other concrete integer type enables writing functions that operate on more than one type conforming to BinaryInteger, such as heterogeneous comparisons or bit shifts, described later.

It removes the overload resolution overhead.

Arithmetic and bitwise operations can now be defined as generic operators on protocols. This approach significantly reduces the number of overloads for those operations, which used to be defined for every single concrete integer type.

It enables protocol sharing between integer and floating point types.

Note the exclusion of the % operation from Arithmetic. Its behavior for floating point numbers is sufficiently different from the one for integers that using it in generic context would lead to confusion. The FloatingPoint protocol introduced by SE-0067 \<[https://gist.github.com/moiseev/0067-floating-point-protocols.md&gt](https://gist.github.com/moiseev/0067-floating-point-protocols.md&gt); should now refine SignedArithmetic.

It makes future extensions possible.

The proposed model eliminates the 'largest integer type' concept previously used to interoperate between integer types (see toIntMax in the current model) and instead provides access to machine words. It also introduces thedoubleWidthMultiply, doubleWidthDivide, and quotientAndRemainder methods. Together these changes can be used to provide an efficient implementation of bignums that would be hard to achieve otherwise.

The implementation of proposed model in the standard library is available in the new-integer-protocols branch \<[https://github.com/apple/swift/tree/new-integer-protocols&gt;\](https://github.com/apple/swift/tree/new-integer-protocols&gt;%5C).

\<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#a-note-on-bit-shifts&gt;A) note on bit shifts

This proposal introduces the concepts of smart shifts and masking shifts.

The semantics of shift operations are often undefined \<[LLVM Language Reference Manual — LLVM 18.0.0git documentation](http://llvm.org/docs/LangRef.html#bitwise-binary-operations&gt); in under- or over-shift cases. Smart shifts, implemented by \>\> and \<\<, are designed to address this problem and always behave in a well defined way, as shown in the examples below:

x \<\< -2 is equivalent to x \>\> 2

(1 as UInt8) \>\> 42) will evaluate to 0

(-128 as Int8) \>\> 42) will evaluate to 0xff or -1

In most scenarios, the right hand operand is a literal constant, and branches for handling under- and over-shift cases can be optimized away. For other cases, this proposal provides masking shifts, implemented by &\>\> and &\<\<. A masking shift logically preprocesses the right hand operand by masking its bits to produce a value in the range 0...(x-1) where x is the number of bits in the left hand operand. On most architectures this masking is already performed by the CPU's shift instructions and has no cost. Both kinds of shift avoid undefined behavior and produce uniform semantics across architectures.

\<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#detailed-design&gt;Detailed) design

\<[https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#whats-new-since-se-0104&gt;What&#39;s](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#whats-new-since-se-0104&gt;What&#39;s) new since SE-0104

SE-0091 \<[https://gist.github.com/moiseev/0091-improving-operators-in-protocols.md&gt](https://gist.github.com/moiseev/0091-improving-operators-in-protocols.md&gt); removed the necessity to dispatch generic operators through special methods.

All operators are now declared by protocols as static funcs.

Standard Library no longer provides + and - operators for Strideable types.

They were problematic, as one could have written mixed-type code like let x: Int64 = 42; x += (1 as Int), which would compile, but shouldn't. Besides, since the Stride of an unsigned type is signed, Standard Library had to implement a hack to make code like let x: UInt = 42; x += (1 as Int) ambiguous. These operators were only necessary because they made advancing collection indices convenient, which is no longer the case since the introduction of the new indexing model \<[https://gist.github.com/moiseev/0065-collections-move-indices.md&gt](https://gist.github.com/moiseev/0065-collections-move-indices.md&gt); in Swift 3.

Shifts and other bitwise operations were moved from FixedWidthInteger to BinaryInteger.

Left shift operation on an unbounded integer should infinitely extend the number, and never drop set bits when they reach the most significant position in the underlying representation.

BitwiseOperations protocol was deprecated.

We believe there are no useful entities that support bitwise operations, but at the same time are not binary integers.

minimumSignedRepresentationBitWidth property was removed.

trailingZeros property was added to the BinaryInteger protocol.

leadingZeros and popcount properties are still defined by the FixedWidthInteger protocol.

Endian-converting initializers and properties were added to the FixedWidthInteger protocol.

Standard library introduces the new type DoubleWidth\<T\>.

See this section \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#doublewidth&gt); for more details.

\<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#protocols&gt;Protocols)

\<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#arithmetic&gt;Arithmetic)

The Arithmetic protocol declares binary arithmetic operators – such as +, -, and \* — and their mutating counterparts.

It provides a suitable basis for arithmetic on scalars such as integers and floating point numbers.

Both mutating and non-mutating operations are declared in the protocol, however only the mutating ones are required, as default implementations of the non-mutating ones are provided by a protocol extension.

The Magnitude associated type is able to hold the absolute value of any possible value of Self. Concrete types do not have to provide a type alias for it, as it can be inferred from the magnitude property. This property can be useful in operations that are simpler to implement in terms of unsigned values, for example, printing a value of an integer, which is just printing a '-' character in front of an absolute value.

Please note that for ordinary work, the magnitude property should not be preferred to the abs(\_) function, whose return value is of the same type as its argument.

public protocol Arithmetic : Equatable, ExpressibleByIntegerLiteral {  
&nbsp;&nbsp;/// Creates a new instance from the given integer, if it can be represented  
&nbsp;&nbsp;/// exactly.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// If the value passed as `source` is not representable exactly, the result  
&nbsp;&nbsp;/// is `nil`. In the following example, the constant `x` is successfully  
&nbsp;&nbsp;/// created from a value of `100`, while the attempt to initialize the  
&nbsp;&nbsp;/// constant `y` from `1_000` fails because the `Int8` type can represent  
&nbsp;&nbsp;/// `127` at maximum:  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let x = Int8(exactly: 100)  
&nbsp;&nbsp;/// // x == Optional(100)  
&nbsp;&nbsp;/// let y = Int8(exactly: 1\_000)  
&nbsp;&nbsp;/// // y == nil  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - Parameter source: A floating-point value to convert to an integer.  
&nbsp;&nbsp;init?\<T : BinaryInteger\>(exactly source: T)

&nbsp;&nbsp;/// A type that can represent the absolute value of any possible value of the  
&nbsp;&nbsp;/// conforming type.  
&nbsp;&nbsp;associatedtype Magnitude : Equatable, ExpressibleByIntegerLiteral

&nbsp;&nbsp;/// The magnitude of this value.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// For any numeric value `x`, `x.magnitude` is the absolute value of `x`.  
&nbsp;&nbsp;/// You can use the `magnitude` property in operations that are simpler to  
&nbsp;&nbsp;/// implement in terms of unsigned values, such as printing the value of an  
&nbsp;&nbsp;/// integer, which is just printing a '-' character in front of an absolute  
&nbsp;&nbsp;/// value.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let x = -200  
&nbsp;&nbsp;/// // x.magnitude == 200  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// The global `abs(_:)` function provides more familiar syntax when you need  
&nbsp;&nbsp;/// to find an absolute value. In addition, because `abs(_:)` always returns  
&nbsp;&nbsp;/// a value of the same type, even in a generic context, using the function  
&nbsp;&nbsp;/// instead of the `magnitude` property is encouraged.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - SeeAlso: `abs(_:)`  
&nbsp;&nbsp;var magnitude: Magnitude { get }

&nbsp;&nbsp;/// Returns the sum of the two given values.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// The sum of `lhs` and `rhs` must be representable in the same type. In the  
&nbsp;&nbsp;/// following example, the result of `100 + 200` is greater than the maximum  
&nbsp;&nbsp;/// representable `Int8` value:  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let x: Int8 = 10 + 21  
&nbsp;&nbsp;/// // x == 31  
&nbsp;&nbsp;/// let y: Int8 = 100 + 121  
&nbsp;&nbsp;/// // Overflow error  
&nbsp;&nbsp;static func +(\_ lhs: Self, \_ rhs: Self) -\> Self

&nbsp;&nbsp;/// Adds the given value to this value in place.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// For example:  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// var x = 15  
&nbsp;&nbsp;/// y += 7  
&nbsp;&nbsp;/// // y == 22  
&nbsp;&nbsp;static func +=(\_ lhs: inout Self, rhs: Self)

&nbsp;&nbsp;/// Returns the difference of the two given values.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// The difference of `lhs` and `rhs` must be representable in the same type.  
&nbsp;&nbsp;/// In the following example, the result of `10 - 21` is less than zero, the  
&nbsp;&nbsp;/// minimum representable `UInt` value:  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let x: UInt = 21 - 10  
&nbsp;&nbsp;/// // x == 11  
&nbsp;&nbsp;/// let y: UInt = 10 - 21  
&nbsp;&nbsp;/// // Overflow error  
&nbsp;&nbsp;static func -(\_ lhs: Self, \_ rhs: Self) -\> Self

&nbsp;&nbsp;/// Subtracts the given value from this value in place.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// For example:  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// var x = 15  
&nbsp;&nbsp;/// y -= 7  
&nbsp;&nbsp;/// // y == 8  
&nbsp;&nbsp;static func -=(\_ lhs: inout Self, rhs: Self)

&nbsp;&nbsp;/// Returns the product of the two given values.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// The product of `lhs` and `rhs` must be representable in the same type. In  
&nbsp;&nbsp;/// the following example, the result of `10 * 50` is greater than the  
&nbsp;&nbsp;/// maximum representable `Int8` value.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let x: Int8 = 10 \* 5  
&nbsp;&nbsp;/// // x == 50  
&nbsp;&nbsp;/// let y: Int8 = 10 \* 50  
&nbsp;&nbsp;/// // Overflow error  
&nbsp;&nbsp;static func \*(\_ lhs: Self, \_ rhs: Self) -\> Self

&nbsp;&nbsp;/// Multiples this value by the given value in place.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// For example:  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// var x = 15  
&nbsp;&nbsp;/// y \*= 7  
&nbsp;&nbsp;/// // y == 105  
&nbsp;&nbsp;static func \*=(\_ lhs: inout Self, rhs: Self)

&nbsp;&nbsp;/// Returns the quotient of dividing the first value by the second.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// For integer types, any remainder of the division is discarded.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let x = 21 / 5  
&nbsp;&nbsp;/// // x == 4  
&nbsp;&nbsp;static func /(\_ lhs: Self, \_ rhs: Self) -\> Self

&nbsp;&nbsp;/// Divides this value by the given value in place.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// For example:  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// var x = 15  
&nbsp;&nbsp;/// y /= 7  
&nbsp;&nbsp;/// // y == 2  
&nbsp;&nbsp;static func /=(\_ lhs: inout Self, rhs: Self)  
}

extension Arithmetic {  
&nbsp;&nbsp;public init() { self = 0 }

&nbsp;&nbsp;public static prefix func + (x: Self) -\> Self {  
&nbsp;&nbsp;&nbsp;&nbsp;return x  
&nbsp;&nbsp;}  
}  
\<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#signedarithmetic&gt;SignedArithmetic)

The SignedArithmetic protocol is for numbers that can be negated.

public protocol SignedArithmetic : Arithmetic {  
&nbsp;&nbsp;/// Returns the additive inverse of this value.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let x = 21  
&nbsp;&nbsp;/// let y = -x  
&nbsp;&nbsp;/// // y == -21  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - Returns: The additive inverse of this value.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - SeeAlso: `negate()`  
&nbsp;&nbsp;static prefix func - (\_ operand: Self) -\> Self

&nbsp;&nbsp;/// Replaces this value with its additive inverse.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// The following example uses the `negate()` method to negate the value of  
&nbsp;&nbsp;/// an integer `x`:  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// var x = 21  
&nbsp;&nbsp;/// x.negate()  
&nbsp;&nbsp;/// // x == -21  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - SeeAlso: The unary minus operator (`-`).  
&nbsp;&nbsp;mutating func negate()  
}

extension SignedArithmetic {  
&nbsp;&nbsp;public static prefix func - (\_ operand: Self) -\> Self {  
&nbsp;&nbsp;&nbsp;&nbsp;var result = operand  
&nbsp;&nbsp;&nbsp;&nbsp;result.negate()  
&nbsp;&nbsp;&nbsp;&nbsp;return result  
&nbsp;&nbsp;}

&nbsp;&nbsp;public mutating func negate() {  
&nbsp;&nbsp;&nbsp;&nbsp;self = Self() - self  
&nbsp;&nbsp;}  
}  
\<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#binaryinteger&gt;BinaryInteger)

The BinaryInteger protocol is the basis for all the integer types provided by the standard library.

This protocol adds a few new initializers. Two of them allow to create integers from floating point numbers, others support construction from instances of any type conforming to BinaryInteger, using different strategies:

Initialize Self with the value, provided that the value is representable. The precondition should be satisfied by the caller.

Extend or truncate the value to fit into Self

Clamp the value to the representable range of Self

BinaryInteger also declares bitwise and shift operators.

public protocol BinaryInteger :  
&nbsp;&nbsp;Comparable, Hashable, Arithmetic, CustomStringConvertible, Strideable {

&nbsp;&nbsp;/// A Boolean value indicating whether this type is a signed integer type.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// \*Signed\* integer types can represent both positive and negative values.  
&nbsp;&nbsp;/// \*Unsigned\* integer types can represent only nonnegative values.  
&nbsp;&nbsp;static var isSigned: Bool { get }

&nbsp;&nbsp;/// Creates an integer from the given floating-point value, if it can be  
&nbsp;&nbsp;/// represented exactly.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// If the value passed as `source` is not representable exactly, the result  
&nbsp;&nbsp;/// is `nil`. In the following example, the constant `x` is successfully  
&nbsp;&nbsp;/// created from a value of `21.0`, while the attempt to initialize the  
&nbsp;&nbsp;/// constant `y` from `21.5` fails:  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let x = Int(exactly: 21.0)  
&nbsp;&nbsp;/// // x == Optional(21)  
&nbsp;&nbsp;/// let y = Int(exactly: 21.5)  
&nbsp;&nbsp;/// // y == nil  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - Parameter source: A floating-point value to convert to an integer.  
&nbsp;&nbsp;init?\<T : FloatingPoint\>(exactly source: T)

&nbsp;&nbsp;/// Creates an integer from the given floating-point value, truncating any  
&nbsp;&nbsp;/// fractional part.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// Truncating the fractional part of `source` is equivalent to rounding  
&nbsp;&nbsp;/// toward zero.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let x = Int(21.5)  
&nbsp;&nbsp;/// // x == 21  
&nbsp;&nbsp;/// let y = Int(-21.5)  
&nbsp;&nbsp;/// // y == -21  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// If `source` is outside the bounds of this type after truncation, a  
&nbsp;&nbsp;/// runtime error may occur.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let z = UInt(-21.5)  
&nbsp;&nbsp;/// // Error: ...the result would be less than UInt.min  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - Parameter source: A floating-point value to convert to an integer.  
&nbsp;&nbsp;/// `source` must be representable in this type after truncation.  
&nbsp;&nbsp;init\<T : FloatingPoint\>(\_ source: T)

&nbsp;&nbsp;/// Creates an new instance from the given integer.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// If the value passed as `source` is not representable in this type, a  
&nbsp;&nbsp;/// runtime error may occur.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let x = -500 as Int  
&nbsp;&nbsp;/// let y = Int32(x)  
&nbsp;&nbsp;/// // y == -500  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// // -500 is not representable as a 'UInt32' instance  
&nbsp;&nbsp;/// let z = UInt32(x)  
&nbsp;&nbsp;/// // Error  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - Parameter source: An integer to convert. `source` must be representable  
&nbsp;&nbsp;/// in this type.  
&nbsp;&nbsp;init\<T : BinaryInteger\>(\_ source: T)

&nbsp;&nbsp;/// Creates a new instance from the bit pattern of the given instance by  
&nbsp;&nbsp;/// sign-extending or truncating to fit this type.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// When the bit width of `T` (the type of `source`) is equal to or greater  
&nbsp;&nbsp;/// than this type's bit width, the result is the truncated  
&nbsp;&nbsp;/// least-significant bits of `source`. For example, when converting a  
&nbsp;&nbsp;/// 16-bit value to an 8-bit type, only the lower 8 bits of `source` are  
&nbsp;&nbsp;/// used.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let p: Int16 = -500  
&nbsp;&nbsp;/// // 'p' has a binary representation of 11111110\_00001100  
&nbsp;&nbsp;/// let q = Int8(extendingOrTruncating: p)  
&nbsp;&nbsp;/// // q == 12  
&nbsp;&nbsp;/// // 'q' has a binary representation of 00001100  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// When the bit width of `T` is less than this type's bit width, the result  
&nbsp;&nbsp;/// is \*sign-extended\* to fill the remaining bits. That is, if `source` is  
&nbsp;&nbsp;/// negative, the result is padded with ones; otherwise, the result is  
&nbsp;&nbsp;/// padded with zeros.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let u: Int8 = 21  
&nbsp;&nbsp;/// // 'u' has a binary representation of 00010101  
&nbsp;&nbsp;/// let v = Int16(extendingOrTruncating: u)  
&nbsp;&nbsp;/// // v == 21  
&nbsp;&nbsp;/// // 'v' has a binary representation of 00000000\_00010101  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let w: Int8 = -21  
&nbsp;&nbsp;/// // 'w' has a binary representation of 11101011  
&nbsp;&nbsp;/// let x = Int16(extendingOrTruncating: w)  
&nbsp;&nbsp;/// // x == -21  
&nbsp;&nbsp;/// // 'x' has a binary representation of 11111111\_11101011  
&nbsp;&nbsp;/// let y = UInt16(extendingOrTruncating: w)  
&nbsp;&nbsp;/// // y == 65515  
&nbsp;&nbsp;/// // 'y' has a binary representation of 11111111\_11101011  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - Parameter source: An integer to convert to this type.  
&nbsp;&nbsp;init\<T : BinaryInteger\>(extendingOrTruncating source: T)

&nbsp;&nbsp;/// Creates a new instance with the representable value that's closest to the  
&nbsp;&nbsp;/// given integer.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// If the value passed as `source` is greater than the maximum representable  
&nbsp;&nbsp;/// value in this type, the result is the type's `max` value. If `source` is  
&nbsp;&nbsp;/// less than the smallest representable value in this type, the result is  
&nbsp;&nbsp;/// the type's `min` value.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// In this example, `x` is initialized as an `Int8` instance by clamping  
&nbsp;&nbsp;/// `500` to the range `-128...127`, and `y` is initialized as a `UInt`  
&nbsp;&nbsp;/// instance by clamping `-500` to the range `0...UInt.max`.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let x = Int8(clamping: 500)  
&nbsp;&nbsp;/// // x == 127  
&nbsp;&nbsp;/// // x == Int8.max  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let y = UInt(clamping: -500)  
&nbsp;&nbsp;/// // y == 0  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - Parameter source: An integer to convert to this type.  
&nbsp;&nbsp;init\<T : BinaryInteger\>(clamping source: T)

&nbsp;&nbsp;/// Returns the n-th word, counting from the least significant to most  
&nbsp;&nbsp;/// significant, of this value's binary representation.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// The `word(at:)` method returns negative values in two's complement  
&nbsp;&nbsp;/// representation, regardless of a type's underlying implementation. If `n`  
&nbsp;&nbsp;/// is greater than the number of words in this value's current  
&nbsp;&nbsp;/// representation, the result is `0` for positive numbers and `~0` for  
&nbsp;&nbsp;/// negative numbers.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - Parameter n: The word to return, counting from the least significant to  
&nbsp;&nbsp;/// most significant. `n` must be greater than or equal to zero.  
&nbsp;&nbsp;/// - Returns: An word-sized, unsigned integer with the bit pattern of the  
&nbsp;&nbsp;/// n-th word of this value.  
&nbsp;&nbsp;func word(at n: Int) -\> UInt

&nbsp;&nbsp;/// The number of bits in the current binary representation of this value.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// This property is a constant for instances of fixed-width integer  
&nbsp;&nbsp;/// types.  
&nbsp;&nbsp;var bitWidth : Int { get }

&nbsp;&nbsp;/// The number of trailing zeros in this value's binary representation.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// For example, in a fixed-width integer type with a `bitWidth` value of 8,  
&nbsp;&nbsp;/// the number -8 has three trailing zeros.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let x = Int8(bitPattern: 0b1111\_1000)  
&nbsp;&nbsp;/// // x == -8  
&nbsp;&nbsp;/// // x.trailingZeros == 3  
&nbsp;&nbsp;var trailingZeros: Int { get }

&nbsp;&nbsp;/// Returns the remainder of dividing the first value by the second.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// The result has the same sign as `lhs` and is less than `rhs.magnitude`.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let x = 22 % 5  
&nbsp;&nbsp;/// // x == 2  
&nbsp;&nbsp;/// let y = 22 % -5  
&nbsp;&nbsp;/// // y == 2  
&nbsp;&nbsp;/// let z = -22 % -5  
&nbsp;&nbsp;/// // z == -2  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - Parameters:  
&nbsp;&nbsp;/// - lhs: The value to divide.  
&nbsp;&nbsp;/// - rhs: The value to divide `lhs` by. `rhs` must not be zero.  
&nbsp;&nbsp;static func %(\_ lhs: Self, \_ rhs: Self) -\> Self

&nbsp;&nbsp;/// Replaces this value with the remainder of itself divided by the given  
&nbsp;&nbsp;/// value. For example:  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// var x = 15  
&nbsp;&nbsp;/// x %= 7  
&nbsp;&nbsp;/// // x == 1  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - Parameter rhs: The value to divide this value by. `rhs` must not be  
&nbsp;&nbsp;/// zero.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - SeeAlso: `remainder(dividingBy:)`  
&nbsp;&nbsp;static func %=(\_ lhs: inout Self, \_ rhs: Self)

&nbsp;&nbsp;/// Returns the inverse of the bits set in the argument.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// The bitwise NOT operator (`~`) is a prefix operator that returns a value  
&nbsp;&nbsp;/// in which all the bits of its argument are flipped: Bits that are `1` in  
&nbsp;&nbsp;/// the argument are `0` in the result, and bits that are `0` in the argument  
&nbsp;&nbsp;/// are `1` in the result. This is equivalent to the inverse of a set. For  
&nbsp;&nbsp;/// example:  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let x: UInt8 = 5 // 0b00000101  
&nbsp;&nbsp;/// let notX = ~x // 0b11111010  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// Performing a bitwise NOT operation on 0 returns a value with every bit  
&nbsp;&nbsp;/// set to `1`.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let allOnes = ~UInt8.min // 0b11111111  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - Complexity: O(1).  
&nbsp;&nbsp;static prefix func ~ (\_ x: Self) -\> Self

&nbsp;&nbsp;/// Returns the result of performing a bitwise AND operation on this value  
&nbsp;&nbsp;/// and the given value.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// A bitwise AND operation results in a value that has each bit set to `1`  
&nbsp;&nbsp;/// where \*both\* of its arguments have that bit set to `1`. For example:  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let x: UInt8 = 5 // 0b00000101  
&nbsp;&nbsp;/// let y: UInt8 = 14 // 0b00001110  
&nbsp;&nbsp;/// let z = x & y // 0b00000100  
&nbsp;&nbsp;static func &(\_ lhs: Self, \_ rhs: Self) -\> Self  
&nbsp;&nbsp;static func &=(\_ lhs: inout Self, \_ rhs: Self)

&nbsp;&nbsp;/// Returns the result of performing a bitwise OR operation on this value and  
&nbsp;&nbsp;/// the given value.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// A bitwise OR operation results in a value that has each bit set to `1`  
&nbsp;&nbsp;/// where \*one or both\* of its arguments have that bit set to `1`. For  
&nbsp;&nbsp;/// example:  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let x: UInt8 = 5 // 0b00000101  
&nbsp;&nbsp;/// let y: UInt8 = 14 // 0b00001110  
&nbsp;&nbsp;/// let z = x | y // 0b00001111  
&nbsp;&nbsp;static func |(\_ lhs: Self, \_ rhs: Self) -\> Self  
&nbsp;&nbsp;static func |=(\_ lhs: inout Self, \_ rhs: Self)

&nbsp;&nbsp;/// Returns the result of performing a bitwise XOR operation on this value  
&nbsp;&nbsp;/// and the given value.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// A bitwise XOR operation, also known as an exclusive OR operation, results  
&nbsp;&nbsp;/// in a value that has each bit set to `1` where \*one or the other but not  
&nbsp;&nbsp;/// both\* of its arguments had that bit set to `1`. For example:  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let x: UInt8 = 5 // 0b00000101  
&nbsp;&nbsp;/// let y: UInt8 = 14 // 0b00001110  
&nbsp;&nbsp;/// let z = x ^ y // 0b00001011  
&nbsp;&nbsp;static func ^(\_ lhs: Self, \_ rhs: Self) -\> Self  
&nbsp;&nbsp;static func ^=(\_ lhs: inout Self, \_ rhs: Self)

&nbsp;&nbsp;/// Returns the result of shifting this value's binary representation the  
&nbsp;&nbsp;/// specified number of digits to the right.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// In a \*masking shift\*, the bit pattern of the value passed as `rhs` is  
&nbsp;&nbsp;/// masked to produce a value between zero and the bit width of `lhs`. The  
&nbsp;&nbsp;/// shift is performed using this masked value. Masking shifts require more  
&nbsp;&nbsp;/// care to use correctly than a traditional bit shift, but are likely to be  
&nbsp;&nbsp;/// more efficient when used with shift amounts that are not compile-time  
&nbsp;&nbsp;/// constants. On most architectures, a masking shift compiles down to a  
&nbsp;&nbsp;/// single instruction.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// For example, if you shift an 8-bit, unsigned integer by 2, the shift  
&nbsp;&nbsp;/// amount requires no masking.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let x: UInt8 = 30 // 0b00011110  
&nbsp;&nbsp;/// let y = x &\>\> 2  
&nbsp;&nbsp;/// // y == 7 // 0b00000111  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// However, if you shift it by 11, it first bitmasks `rhs` to `3`, and then  
&nbsp;&nbsp;/// uses that masked value as the number of bits to shift `x`.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let z = x &\>\> 11  
&nbsp;&nbsp;/// // z == 3 // 0b00000011  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// Relationship to the Right Shift Operator  
&nbsp;&nbsp;/// ----------------------------------------  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// The masking right shift operator handles attempted overshifts and  
&nbsp;&nbsp;/// undershifts differently from the right shift operator (`\>\>`). When the  
&nbsp;&nbsp;/// value passed as `rhs` in a masking shift is within the range  
&nbsp;&nbsp;/// `0...\<bitWidth`, the operation is equivalent to using the right shift  
&nbsp;&nbsp;/// operator.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let x: UInt8 = 30 // 0b00011110  
&nbsp;&nbsp;/// let y1 = x &\>\> 2  
&nbsp;&nbsp;/// // y1 == 7 // 0b00000111  
&nbsp;&nbsp;/// let y2 = x \>\> 2  
&nbsp;&nbsp;/// // y2 == 7 // 0b00000111  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// The right shift operator does not mask its right-hand-side argument, so  
&nbsp;&nbsp;/// passing `11` as `rhs` shifts all the bits of `x` to zero.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let z1 = x &\>\> 11  
&nbsp;&nbsp;/// // z1 == 240 // 0b00000011  
&nbsp;&nbsp;/// let z2 = x \>\> 11  
&nbsp;&nbsp;/// // z2 == 0 // 0b00000000  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - Parameter rhs: The number of bits to shift this value to the right. If  
&nbsp;&nbsp;/// `rhs` is outside the range `0..\<bitWidth`, it is masked to produce a  
&nbsp;&nbsp;/// value within that range.  
&nbsp;&nbsp;/// - Returns: The result of shifting this value by the masked `rhs` to the  
&nbsp;&nbsp;/// right.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - SeeAlso: `&\<\<`, `\>\>`  
&nbsp;&nbsp;static func &\>\>(\_ lhs: Self, \_ rhs: Self) -\> Self  
&nbsp;&nbsp;static func &\>\>=(\_ lhs: inout Self, \_ rhs: Self)

&nbsp;&nbsp;/// Returns the result of shifting this value's binary representation the  
&nbsp;&nbsp;/// specified number of digits to the left.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// In a \*masking shift\*, the bit pattern of the value passed as `rhs` is  
&nbsp;&nbsp;/// masked to produce a value between zero and the bit width of `lhs`. The  
&nbsp;&nbsp;/// shift is performed using this masked value. Masking shifts require more  
&nbsp;&nbsp;/// care to use correctly than a traditional bit shift, but are likely to be  
&nbsp;&nbsp;/// more efficient when used with shift amounts that are not compile-time  
&nbsp;&nbsp;/// constants. On most architectures, a masking shift compiles down to a  
&nbsp;&nbsp;/// single instruction.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// For example, if you shift an 8-bit, unsigned integer by 2, the shift  
&nbsp;&nbsp;/// amount requires no masking.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let x: UInt8 = 30 // 0b00011110  
&nbsp;&nbsp;/// let y = x &\>\> 2  
&nbsp;&nbsp;/// // y == 120 // 0b01111000  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// However, if you shift it by 11, it first bitmasks `rhs` to `3`, and then  
&nbsp;&nbsp;/// uses that masked value as the number of bits to shift `x`.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let z = x &\<\< 11  
&nbsp;&nbsp;/// // z == 240 // 0b11110000  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// Relationship to the Left Shift Operator  
&nbsp;&nbsp;/// ---------------------------------------  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// The masking left shift operator handles attempted overshifts and  
&nbsp;&nbsp;/// undershifts differently from the left shift operator (`\<\<`). When the  
&nbsp;&nbsp;/// value passed as `rhs` in a masking shift is within the range  
&nbsp;&nbsp;/// `0...\<bitWidth`, the operation is equivalent to using the left shift  
&nbsp;&nbsp;/// operator.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let x: UInt8 = 30 // 0b00011110  
&nbsp;&nbsp;/// let y1 = x &\<\< 2  
&nbsp;&nbsp;/// // y1 == 120 // 0b01111000  
&nbsp;&nbsp;/// let y2 = x \<\< 2  
&nbsp;&nbsp;/// // y2 == 120 // 0b01111000  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// The left shift operator does not mask its right-hand-side argument, so  
&nbsp;&nbsp;/// passing `11` as `rhs` shifts all the bits of `x` to zero.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let z1 = x &\<\< 11  
&nbsp;&nbsp;/// // z1 == 240 // 0b11110000  
&nbsp;&nbsp;/// let z2 = x \<\< 11  
&nbsp;&nbsp;/// // z2 == 0 // 0b00000000  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - Parameter rhs: The number of bits to shift this value to the left. If  
&nbsp;&nbsp;/// `rhs` is outside the range `0..\<bitWidth`, it is masked to produce a  
&nbsp;&nbsp;/// value within that range.  
&nbsp;&nbsp;/// - Returns: The result of shifting this value by the masked `rhs` to the  
&nbsp;&nbsp;/// left.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - SeeAlso: `&\>\>`, `\<\<`  
&nbsp;&nbsp;static func &\<\<(\_ lhs: Self, \_ rhs: Self) -\> Self  
&nbsp;&nbsp;static func &\<\<=(\_ lhs: inout Self, \_ rhs: Self)

&nbsp;&nbsp;/// Returns the quotient and remainder of this value divided by the given  
&nbsp;&nbsp;/// value.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// Use this method to calculate the quotient and remainder of a division at  
&nbsp;&nbsp;/// the same time.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let x = 1\_000\_000  
&nbsp;&nbsp;/// let (q, r) = x.quotientAndRemainder(dividingBy: 933)  
&nbsp;&nbsp;/// // q == 1071  
&nbsp;&nbsp;/// // r == 757  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - Parameter rhs: The value to divide this value by.  
&nbsp;&nbsp;/// - Returns: A tuple containing the quotient and remainder of this value  
&nbsp;&nbsp;/// divided by `rhs`.  
&nbsp;&nbsp;func quotientAndRemainder(dividingBy rhs: Self)  
&nbsp;&nbsp;&nbsp;&nbsp;-\> (quotient: Self, remainder: Self)

&nbsp;&nbsp;/// Returns `-1` if this value is negative and `1` if it's positive;  
&nbsp;&nbsp;/// otherwise, `0`.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - Returns: The sign of this number, expressed as an integer of the same  
&nbsp;&nbsp;/// type.  
&nbsp;&nbsp;func signum() -\> Self  
}  
\<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#fixedwidthinteger&gt;FixedWidthInteger)

The FixedWidthInteger protocol adds the notion of endianness as well as static properties for type bounds and bit width.

The WithOverflow family of methods is used in default implementations of mutating arithmetic methods (see the Arithmetic protocol). Having these methods allows the library to provide both bounds-checked and masking implementations of arithmetic operations, without duplicating code.

The doubleWidthMultiply and doubleWidthDivide methods are necessary building blocks to implement support for integer types of a greater width such as arbitrary-precision integers.

public protocol FixedWidthInteger : BinaryInteger {  
&nbsp;&nbsp;/// The number of bits used for the underlying binary representation of  
&nbsp;&nbsp;/// values of this type.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// An unsigned, fixed-width integer type can represent values from 0 through  
&nbsp;&nbsp;/// `(2 **bitWidth) - 1`, where `**` is exponentiation. A signed,  
&nbsp;&nbsp;/// fixed-width integer type can represent values from  
&nbsp;&nbsp;/// `-(2 **bitWidth - 1)` through `(2** bitWidth - 1) - 1`. For example,  
&nbsp;&nbsp;/// the `Int8` type has a `bitWidth` value of 8 and can store any integer in  
&nbsp;&nbsp;/// the range `-128...127`.  
&nbsp;&nbsp;static var bitWidth : Int { get }

&nbsp;&nbsp;/// The maximum representable integer in this type.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// For unsigned integer types, this value is `(2 ** bitWidth) - 1`, where  
&nbsp;&nbsp;/// `**` is exponentiation. For signed integer types, this value is  
&nbsp;&nbsp;/// `(2 ** bitWidth - 1) - 1`.  
&nbsp;&nbsp;static var max: Self { get }

&nbsp;&nbsp;/// The minimum representable value.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// For unsigned integer types, this value is always `0`. For signed integer  
&nbsp;&nbsp;/// types, this value is `-(2 **bitWidth - 1)`, where `**` is  
&nbsp;&nbsp;/// exponentiation.  
&nbsp;&nbsp;static var min: Self { get }

&nbsp;&nbsp;/// Returns the sum of this value and the given value along with a flag  
&nbsp;&nbsp;/// indicating whether overflow occurred in the operation.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - Parameter other: The value to add to this value.  
&nbsp;&nbsp;/// - Returns: A tuple containing the result of the addition along with a  
&nbsp;&nbsp;/// flag indicating whether overflow occurred. If the `overflow` component  
&nbsp;&nbsp;/// is `.none`, the `partialValue` component contains the entire sum. If  
&nbsp;&nbsp;/// the `overflow` component is `.overflow`, an overflow occurred and the  
&nbsp;&nbsp;/// `partialValue` component contains the truncated sum of this value and  
&nbsp;&nbsp;/// `other`.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - SeeAlso: `+`  
&nbsp;&nbsp;func addingWithOverflow(\_ other: Self)  
&nbsp;&nbsp;&nbsp;&nbsp;-\> (partialValue: Self, overflow: ArithmeticOverflow)

&nbsp;&nbsp;/// Returns the difference of this value and the given value along with a  
&nbsp;&nbsp;/// flag indicating whether overflow occurred in the operation.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - Parameter other: The value to subtract from this value.  
&nbsp;&nbsp;/// - Returns: A tuple containing the result of the subtraction along with a  
&nbsp;&nbsp;/// flag indicating whether overflow occurred. If the `overflow` component  
&nbsp;&nbsp;/// is `.none`, the `partialValue` component contains the entire  
&nbsp;&nbsp;/// difference. If the `overflow` component is `.overflow`, an overflow  
&nbsp;&nbsp;/// occurred and the `partialValue` component contains the truncated  
&nbsp;&nbsp;/// result of `other` subtracted from this value.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - SeeAlso: `-`  
&nbsp;&nbsp;func subtractingWithOverflow(\_ other: Self)  
&nbsp;&nbsp;&nbsp;&nbsp;-\> (partialValue: Self, overflow: ArithmeticOverflow)

&nbsp;&nbsp;/// Returns the product of this value and the given value along with a flag  
&nbsp;&nbsp;/// indicating whether overflow occurred in the operation.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - Parameter other: The value to multiply by this value.  
&nbsp;&nbsp;/// - Returns: A tuple containing the result of the multiplication along with  
&nbsp;&nbsp;/// a flag indicating whether overflow occurred. If the `overflow`  
&nbsp;&nbsp;/// component is `.none`, the `partialValue` component contains the entire  
&nbsp;&nbsp;/// product. If the `overflow` component is `.overflow`, an overflow  
&nbsp;&nbsp;/// occurred and the `partialValue` component contains the truncated  
&nbsp;&nbsp;/// product of this value and `other`.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - SeeAlso: `*`, `doubleWidthMultiply(_:_:)`  
&nbsp;&nbsp;func multipliedWithOverflow(by other: Self)  
&nbsp;&nbsp;&nbsp;&nbsp;-\> (partialValue: Self, overflow: ArithmeticOverflow)

&nbsp;&nbsp;/// Returns the quotient of dividing this value by the given value along with  
&nbsp;&nbsp;/// a flag indicating whether overflow occurred in the operation.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// For a value `x`, if zero is passed as `other`, the result is  
&nbsp;&nbsp;/// `(x, .overflow)`.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - Parameter other: The value to divide this value by.  
&nbsp;&nbsp;/// - Returns: A tuple containing the result of the division along with a  
&nbsp;&nbsp;/// flag indicating whether overflow occurred. If the `overflow` component  
&nbsp;&nbsp;/// is `.none`, the `partialValue` component contains the entire quotient.  
&nbsp;&nbsp;/// If the `overflow` component is `.overflow`, an overflow occurred and  
&nbsp;&nbsp;/// the `partialValue` component contains the truncated quotient.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - SeeAlso: `/`, `doubleWidthDivide(_:_:)`  
&nbsp;&nbsp;func dividedWithOverflow(by other: Self)  
&nbsp;&nbsp;&nbsp;&nbsp;-\> (partialValue: Self, overflow: ArithmeticOverflow)

&nbsp;&nbsp;/// Returns a tuple containing the high and low parts of the result of  
&nbsp;&nbsp;/// multiplying its arguments.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// Use this method to calculate the full result of a product that would  
&nbsp;&nbsp;/// otherwise overflow. Unlike traditional truncating multiplication, the  
&nbsp;&nbsp;/// `doubleWidthMultiply(_:_:)` method returns both the `high` and `low`  
&nbsp;&nbsp;/// parts of the product of `lhs` and `rhs`. The following example uses this  
&nbsp;&nbsp;/// method to multiply two `UInt8` values that normally overflow when  
&nbsp;&nbsp;/// multiplied:  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let x: UInt8 = 100  
&nbsp;&nbsp;/// let y: UInt8 = 20  
&nbsp;&nbsp;/// let result = UInt8.doubleWidthMultiply(100, 20)  
&nbsp;&nbsp;/// // result.high == 0b00000111  
&nbsp;&nbsp;/// // result.low == 0b11010000  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// The product of `x` and `y` is 2000, which is too large to represent in a  
&nbsp;&nbsp;/// `UInt8` instance. The `high` and `low` components of the `result` tuple  
&nbsp;&nbsp;/// represent 2000 when concatenated to form a double-width integer; that  
&nbsp;&nbsp;/// is, using `result.high` as the high byte and `result.low` as the low byte  
&nbsp;&nbsp;/// of a `UInt16` instance.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let z = UInt16(result.high) \<\< 8 | UInt16(result.low)  
&nbsp;&nbsp;/// // z == 2000  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - Parameters:  
&nbsp;&nbsp;/// - lhs: A value to multiply.  
&nbsp;&nbsp;/// - rhs: Another value to multiply.  
&nbsp;&nbsp;/// - Returns: A tuple containing the high and low parts of the result of  
&nbsp;&nbsp;/// multiplying `lhs` and `rhs`.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - SeeAlso: `multipliedWithOverflow(by:)`  
&nbsp;&nbsp;static func doubleWidthMultiply(\_ lhs: Self, \_ rhs: Self)  
&nbsp;&nbsp;&nbsp;&nbsp;-\> (high: Self, low: Magnitude)

&nbsp;&nbsp;/// Returns a tuple containing the quotient and remainder of dividing the  
&nbsp;&nbsp;/// first argument by the second.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// The resulting quotient must be representable within the bounds of the  
&nbsp;&nbsp;/// type. If the quotient of dividing `lhs` by `rhs` is too large to  
&nbsp;&nbsp;/// represent in the type, a runtime error may occur.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - Parameters:  
&nbsp;&nbsp;/// - lhs: A tuple containing the high and low parts of a double-width  
&nbsp;&nbsp;/// integer. The `high` component of the tuple carries the sign, if the  
&nbsp;&nbsp;/// type is signed.  
&nbsp;&nbsp;/// - rhs: The integer to divide into `lhs`.  
&nbsp;&nbsp;/// - Returns: A tuple containing the quotient and remainder of `lhs` divided  
&nbsp;&nbsp;/// by `rhs`.  
&nbsp;&nbsp;static func doubleWidthDivide(  
&nbsp;&nbsp;&nbsp;&nbsp;\_ lhs: (high: Self, low: Magnitude), \_ rhs: Self)  
&nbsp;&nbsp;&nbsp;&nbsp;-\> (quotient: Self, remainder: Self)

&nbsp;&nbsp;/// The number of bits equal to 1 in this value's binary representation.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// For example, in a fixed-width integer type with a `bitWidth` value of 8,  
&nbsp;&nbsp;/// the number 31 has five bits equal to 1.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let x: Int8 = 0b0001\_1111  
&nbsp;&nbsp;/// // x == 31  
&nbsp;&nbsp;/// // x.popcount == 5  
&nbsp;&nbsp;var popcount: Int { get }

&nbsp;&nbsp;/// The number of leading zeros in this value's binary representation.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// For example, in a fixed-width integer type with a `bitWidth` value of 8,  
&nbsp;&nbsp;/// the number 31 has three leading zeros.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// let x: Int8 = 0b0001\_1111  
&nbsp;&nbsp;/// // x == 31  
&nbsp;&nbsp;/// // x.leadingZeros == 3  
&nbsp;&nbsp;/// - SeeAlso: `BinaryInteger.trailingZeros`  
&nbsp;&nbsp;var leadingZeros: Int { get }

&nbsp;&nbsp;/// Creates an integer from its big-endian representation, changing the  
&nbsp;&nbsp;/// byte order if necessary.  
&nbsp;&nbsp;init(bigEndian value: Self)

&nbsp;&nbsp;/// Creates an integer from its little-endian representation, changing the  
&nbsp;&nbsp;/// byte order if necessary.  
&nbsp;&nbsp;init(littleEndian value: Self)

&nbsp;&nbsp;/// The big-endian representation of this integer.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// If necessary, the byte order of this value is reversed from the typical  
&nbsp;&nbsp;/// byte order of this integer type. On a big-endian platform, for any  
&nbsp;&nbsp;/// integer `x`, `x == x.bigEndian`.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - SeeAlso: `littleEndian`  
&nbsp;&nbsp;var bigEndian: Self { get }

&nbsp;&nbsp;/// The little-endian representation of this integer.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// If necessary, the byte order of this value is reversed from the typical  
&nbsp;&nbsp;/// byte order of this integer type. On a little-endian platform, for any  
&nbsp;&nbsp;/// integer `x`, `x == x.littleEndian`.  
&nbsp;&nbsp;///  
&nbsp;&nbsp;/// - SeeAlso: `bigEndian`  
&nbsp;&nbsp;var littleEndian: Self { get }

&nbsp;&nbsp;/// A representation of this integer with the byte order swapped.  
&nbsp;&nbsp;var byteSwapped: Self { get }  
}  
\<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#auxiliary-protocols&gt;Auxiliary) protocols

public protocol UnsignedInteger : BinaryInteger {  
&nbsp;&nbsp;associatedtype Magnitude : BinaryInteger  
}  
public protocol SignedInteger : BinaryInteger, SignedArithmetic {  
&nbsp;&nbsp;associatedtype Magnitude : BinaryInteger  
}  
\<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#doublewidth&gt;DoubleWidth)

The DoubleWidth\<T\> type allows to create wider fixed-width integer types from the ones available in the standard library.

Standard library currently provides fixed-width integer types of up to 64 bits. A value of DoubleWidth\<Int64\> will double the range of the underlying type and implement all the FixedWidthInteger requirements. Please note though that the implementation will not necessarily be the most efficient one, so it would not be a good idea to use DoubleWidth\<Int32\>instead of a built-in Int64.

\<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#extra-operators&gt;Extra) operators

In addition to the operators described in the protocols section \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#protocols&gt;), we also provide a few extensions that are not protocol requirements:

\<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#heterogeneous-shifts&gt;Heterogeneous) shifts

extension BinaryInteger {  
&nbsp;&nbsp;// Masking shifts  
&nbsp;&nbsp;static func &\>\> \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self  
&nbsp;&nbsp;static func &\>\>= \<Other : BinaryInteger\>(lhs: inout Self, rhs: Other)  
&nbsp;&nbsp;static func &\<\< \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self  
&nbsp;&nbsp;static func &\<\<= \<Other : BinaryInteger\>(lhs: inout Self, rhs: Other)

&nbsp;&nbsp;// 'Smart' shifts  
&nbsp;&nbsp;static func \>\> \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self  
&nbsp;&nbsp;static func \>\>= \<Other : BinaryInteger\>(lhs: inout Self, rhs: Other)  
&nbsp;&nbsp;static func \<\< \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self  
&nbsp;&nbsp;static func \<\<= \<Other : BinaryInteger\>(lhs: inout Self, rhs: Other)  
}  
\<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#heterogeneous-equality-and-comparison&gt;Heterogeneous) equality and comparison

extension BinaryInteger {  
&nbsp;&nbsp;// Equality  
&nbsp;&nbsp;static func == \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool  
&nbsp;&nbsp;static func != \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool

&nbsp;&nbsp;// Comparison  
&nbsp;&nbsp;static func \< \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool  
&nbsp;&nbsp;static func \<= \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool  
&nbsp;&nbsp;static func \> \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool  
&nbsp;&nbsp;static func \>= \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool  
}  
\<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#masking-arithmetic&gt;Masking) arithmetic

public func &\* \<T: FixedWidthInteger\>(lhs: T, rhs: T) -\> T  
public func &- \<T: FixedWidthInteger\>(lhs: T, rhs: T) -\> T  
public func &+ \<T: FixedWidthInteger\>(lhs: T, rhs: T) -\> T  
\<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#non-goals&gt;Non%5C-goals)

This proposal:

DOES NOT solve the integer promotion problem, which would allow mixed-type arithmetic. However, we believe that it is an important step in the right direction.

DOES NOT include the implementation of a BigInt type, but allows it to be implemented in the future.

\<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#source-compatibility&gt;Source) compatibility

The proposed change is designed to be as non-breaking as possible, and it has been proven that it does not break code on concrete integer types. However, there are still a few API breaking changes in the realm of generic code:

Integer protocols in Swift up to and including version 3 were not particularly useful for generic programming, but were rather a means of sharing implementation between conforming types. Therefore we believe the amount of code that relied on these protocols is relatively small. The breakage can be further reduced by introducing proper aliases for the removed protocols with deprecation warnings.

Deprecation of the BitwiseOperations protocol. We find it hard to imagine a type that conforms to this protocol, but is not a binary integer type.

Addition of 'smart' shifts will change the behavior of existing code. It will still compile, but will be potentially less performant due to extra logic involved. In a case, where this becomes a problem, newly introduced masking shift operators can be used instead. Unfortunately, performance characteristics of the code cannot be statically checked, and thus migration cannot be provided.

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [January 13, 2017, 10:14pm UTC](https://forums.swift.org/t/protocol-oriented-integers-take-2/4884/2 "2017-01-13T22:14:13Z")

</div>

[Resending to list with original message removed for length.]

This is fantastic. Glad to see it take shape. Very neat and insightful to  
have trailingZeros on BinaryInteger but leadingZeros on FixedWidthInteger.  
A couple of questions on smart shifts: What is the performance penalty as  
compared to the existing operators? Beyond performance, what are the  
implications for migrating existing bit twiddling algorithms written in  
Swift 3?

---

<div class="post-metadata">

**Author:** ![Charles\_Srstka](https://avatars.discourse-cdn.com/v4/letter/c/0ea827/32.png) [@Charles\_Srstka](https://forums.swift.org/u/Charles_Srstka)\
**Post date:** [January 13, 2017, 11:06pm UTC](https://forums.swift.org/t/protocol-oriented-integers-take-2/4884/3 "2017-01-13T23:06:18Z")

</div>

How could anyone ever argue against this?

+1.

Charles

> **···**
>
> > On Jan 13, 2017, at 2:47 PM, Max Moiseev via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > Hi everyone,
> > 
> > Back in June 2016 we discussed the new design of the integer types for the standard library. It even resulted in acceptance of SE-0104 \<[https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md&gt](https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md&gt); for Swift 3. Unfortunately we were not able to implement it in time for the release.
> > 
> > But it was not forgotten, although, as time went by, a few changes needed to be made in order to reflect the current state of the language.  
> > Without further introduction, please welcome the refined proposal to make integers in Swift more suitable for generic programming.
> > 
> > Available in this gist [Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c) and also inlined below.
> > 
> > Max
> > 
> > Protocol-oriented integers (take 2)
> > 
> > Proposal: SE-NNNN \<[https://gist.github.com/moiseev/0000-even-more-improved-integers.md&gt](https://gist.github.com/moiseev/0000-even-more-improved-integers.md&gt);  
> > Authors: Dave Abrahams \<[https://github.com/dabrahams&gt;](https://github.com/dabrahams&gt;), Maxim Moiseev \<[https://github.com/moiseev&gt](https://github.com/moiseev&gt);  
> > Review Manager: TBD  
> > Status: Awaiting review  
> > Bug: SR-3196 \<[Issues · apple/swift-issues · GitHub](https://bugs.swift.org/browse/SR-3196&gt);  
> > Previous Proposal: SE-0104 \<[https://gist.github.com/moiseev/0104-improved-integers.md&gt](https://gist.github.com/moiseev/0104-improved-integers.md&gt);  
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#introduction&gt;Introduction)
> > 
> > This proposal is an evolution of SE-0104 \<[https://gist.github.com/moiseev/0104-improved-integers.md&gt;\](https://gist.github.com/moiseev/0104-improved-integers.md&gt;%5C). The goal is still to clean up Swifts integer APIs and make them more useful for generic programming.
> > 
> > The language has evolved in ways that affect integers APIs since the time the original proposal was approved for Swift 3. We also attempted to implement the proposed model in the standard library and found that some essential APIs were missing, whereas others could be safely removed.
> > 
> > Major changes to the APIs introduced by this proposal (as compared to SE-0104 \<[https://gist.github.com/moiseev/0104-improved-integers.md&gt;\](https://gist.github.com/moiseev/0104-improved-integers.md&gt;%5C)) are listed in a dedicated section \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#whats-new-since-se-0104&gt;%5C).
> > 
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#motivation&gt;Motivation)
> > 
> > Swift's integer protocols don't currently provide a suitable basis for generic programming. See this blog post \<[http://blog.krzyzanowskim.com/2015/03/01/swift\_madness\_of\_generic\_integer/&gt](http://blog.krzyzanowskim.com/2015/03/01/swift_madness_of_generic_integer/&gt); for an example of an attempt to implement a generic algorithm over integers.
> > 
> > The way the Arithmetic protocol is defined, it does not generalize to floating point numbers and also slows down compilation by requiring every concrete type to provide an implementation of arithmetic operators, thus polluting the overload set.
> > 
> > Converting from one integer type to another is performed using the concept of the 'maximum width integer' (see MaxInt), which is an artificial limitation. The very existence of MaxInt makes it unclear what to do should someone implement Int256, for example.
> > 
> > Another annoying problem is the inability to use integers of different types in comparison and bit-shift operations. For example, the following snippets won't compile:
> > 
> > var x: Int8 = 42  
> > let y = 1  
> > let z = 0
> > 
> > x \<\<= y // error: binary operator '\<\<=' cannot be applied to operands of type 'Int8' and 'Int'  
> > if x \> z { ... } // error: binary operator '\>' cannot be applied to operands of type 'Int8' and 'Int'  
> > Currently, bit-shifting a negative number of (or too many) bits causes a trap on some platforms, which makes low-level bit manipulations needlessly dangerous and unpredictable.
> > 
> > Finally, the current design predates many of the improvements that came since Swift 1, and hasn't been revised since then.
> > 
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#proposed-solution&gt;Proposed) solution
> > 
> > We propose a new model that does not have above mentioned problems and is more easily extensible.
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+--------------+ +-------------+  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+------\>+ Arithmetic | | Comparable |  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \> (+,-,\*,/) | | (==,\<,\>,...)|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> +-------------++ +---+---------+  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> ^ ^  
> > +-------+------------+ | |  
> > \> SignedArithmetic | +-+-------+-----------+  
> > \> (unary -) | | BinaryInteger |  
> > +------+-------------+ |(words,%,bitwise,...)|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^ ++---+-----+----------+  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> +-----------^ ^ ^---------------+  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \> \> \>  
> > +------+---------++ +---------+---------------+ +--+----------------+  
> > \> SignedInteger | | FixedWidthInteger | | UnsignedInteger |  
> > \> \> \>(endianness,overflow,...)| | |  
> > +---------------+-+ +-+--------------------+--+ +-+-----------------+  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^ ^ ^ ^  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \> \> \>  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \> \> \>  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++--------+-+ +-+-------+-+  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\>Int family |-+ |UInt family|-+  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+-----------+ | +-----------+ |  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+-----------+ +-----------+  
> > There are several benefits provided by this model over the old one:
> > 
> > It allows mixing integer types in generic functions.
> > 
> > The possibility to initialize instances of any concrete integer type with values of any other concrete integer type enables writing functions that operate on more than one type conforming to BinaryInteger, such as heterogeneous comparisons or bit shifts, described later.
> > 
> > It removes the overload resolution overhead.
> > 
> > Arithmetic and bitwise operations can now be defined as generic operators on protocols. This approach significantly reduces the number of overloads for those operations, which used to be defined for every single concrete integer type.
> > 
> > It enables protocol sharing between integer and floating point types.
> > 
> > Note the exclusion of the % operation from Arithmetic. Its behavior for floating point numbers is sufficiently different from the one for integers that using it in generic context would lead to confusion. The FloatingPoint protocol introduced by SE-0067 \<[https://gist.github.com/moiseev/0067-floating-point-protocols.md&gt](https://gist.github.com/moiseev/0067-floating-point-protocols.md&gt); should now refine SignedArithmetic.
> > 
> > It makes future extensions possible.
> > 
> > The proposed model eliminates the 'largest integer type' concept previously used to interoperate between integer types (see toIntMax in the current model) and instead provides access to machine words. It also introduces thedoubleWidthMultiply, doubleWidthDivide, and quotientAndRemainder methods. Together these changes can be used to provide an efficient implementation of bignums that would be hard to achieve otherwise.
> > 
> > The implementation of proposed model in the standard library is available in the new-integer-protocols branch \<[https://github.com/apple/swift/tree/new-integer-protocols&gt;\](https://github.com/apple/swift/tree/new-integer-protocols&gt;%5C).
> > 
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#a-note-on-bit-shifts&gt;A) note on bit shifts
> > 
> > This proposal introduces the concepts of smart shifts and masking shifts.
> > 
> > The semantics of shift operations are often undefined \<[LLVM Language Reference Manual — LLVM 18.0.0git documentation](http://llvm.org/docs/LangRef.html#bitwise-binary-operations&gt); in under- or over-shift cases. Smart shifts, implemented by \>\> and \<\<, are designed to address this problem and always behave in a well defined way, as shown in the examples below:
> > 
> > x \<\< -2 is equivalent to x \>\> 2
> > 
> > (1 as UInt8) \>\> 42) will evaluate to 0
> > 
> > (-128 as Int8) \>\> 42) will evaluate to 0xff or -1
> > 
> > In most scenarios, the right hand operand is a literal constant, and branches for handling under- and over-shift cases can be optimized away. For other cases, this proposal provides masking shifts, implemented by &\>\> and &\<\<. A masking shift logically preprocesses the right hand operand by masking its bits to produce a value in the range 0...(x-1) where x is the number of bits in the left hand operand. On most architectures this masking is already performed by the CPU's shift instructions and has no cost. Both kinds of shift avoid undefined behavior and produce uniform semantics across architectures.
> > 
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#detailed-design&gt;Detailed) design
> > 
> > \<[https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#whats-new-since-se-0104&gt;What&#39;s](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#whats-new-since-se-0104&gt;What&#39;s) new since SE-0104
> > 
> > SE-0091 \<[https://gist.github.com/moiseev/0091-improving-operators-in-protocols.md&gt](https://gist.github.com/moiseev/0091-improving-operators-in-protocols.md&gt); removed the necessity to dispatch generic operators through special methods.
> > 
> > All operators are now declared by protocols as static funcs.
> > 
> > Standard Library no longer provides + and - operators for Strideable types.
> > 
> > They were problematic, as one could have written mixed-type code like let x: Int64 = 42; x += (1 as Int), which would compile, but shouldn't. Besides, since the Stride of an unsigned type is signed, Standard Library had to implement a hack to make code like let x: UInt = 42; x += (1 as Int) ambiguous. These operators were only necessary because they made advancing collection indices convenient, which is no longer the case since the introduction of the new indexing model \<[https://gist.github.com/moiseev/0065-collections-move-indices.md&gt](https://gist.github.com/moiseev/0065-collections-move-indices.md&gt); in Swift 3.
> > 
> > Shifts and other bitwise operations were moved from FixedWidthInteger to BinaryInteger.
> > 
> > Left shift operation on an unbounded integer should infinitely extend the number, and never drop set bits when they reach the most significant position in the underlying representation.
> > 
> > BitwiseOperations protocol was deprecated.
> > 
> > We believe there are no useful entities that support bitwise operations, but at the same time are not binary integers.
> > 
> > minimumSignedRepresentationBitWidth property was removed.
> > 
> > trailingZeros property was added to the BinaryInteger protocol.
> > 
> > leadingZeros and popcount properties are still defined by the FixedWidthInteger protocol.
> > 
> > Endian-converting initializers and properties were added to the FixedWidthInteger protocol.
> > 
> > Standard library introduces the new type DoubleWidth\<T\>.
> > 
> > See this section \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#doublewidth&gt); for more details.
> > 
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#protocols&gt;Protocols)
> > 
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#arithmetic&gt;Arithmetic)
> > 
> > The Arithmetic protocol declares binary arithmetic operators – such as +, -, and \* — and their mutating counterparts.
> > 
> > It provides a suitable basis for arithmetic on scalars such as integers and floating point numbers.
> > 
> > Both mutating and non-mutating operations are declared in the protocol, however only the mutating ones are required, as default implementations of the non-mutating ones are provided by a protocol extension.
> > 
> > The Magnitude associated type is able to hold the absolute value of any possible value of Self. Concrete types do not have to provide a type alias for it, as it can be inferred from the magnitude property. This property can be useful in operations that are simpler to implement in terms of unsigned values, for example, printing a value of an integer, which is just printing a '-' character in front of an absolute value.
> > 
> > Please note that for ordinary work, the magnitude property should not be preferred to the abs(\_) function, whose return value is of the same type as its argument.
> > 
> > public protocol Arithmetic : Equatable, ExpressibleByIntegerLiteral {  
> > &nbsp;&nbsp;/// Creates a new instance from the given integer, if it can be represented  
> > &nbsp;&nbsp;/// exactly.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// If the value passed as `source` is not representable exactly, the result  
> > &nbsp;&nbsp;/// is `nil`. In the following example, the constant `x` is successfully  
> > &nbsp;&nbsp;/// created from a value of `100`, while the attempt to initialize the  
> > &nbsp;&nbsp;/// constant `y` from `1_000` fails because the `Int8` type can represent  
> > &nbsp;&nbsp;/// `127` at maximum:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = Int8(exactly: 100)  
> > &nbsp;&nbsp;/// // x == Optional(100)  
> > &nbsp;&nbsp;/// let y = Int8(exactly: 1\_000)  
> > &nbsp;&nbsp;/// // y == nil  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter source: A floating-point value to convert to an integer.  
> > &nbsp;&nbsp;init?\<T : BinaryInteger\>(exactly source: T)
> > 
> > &nbsp;&nbsp;/// A type that can represent the absolute value of any possible value of the  
> > &nbsp;&nbsp;/// conforming type.  
> > &nbsp;&nbsp;associatedtype Magnitude : Equatable, ExpressibleByIntegerLiteral
> > 
> > &nbsp;&nbsp;/// The magnitude of this value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For any numeric value `x`, `x.magnitude` is the absolute value of `x`.  
> > &nbsp;&nbsp;/// You can use the `magnitude` property in operations that are simpler to  
> > &nbsp;&nbsp;/// implement in terms of unsigned values, such as printing the value of an  
> > &nbsp;&nbsp;/// integer, which is just printing a '-' character in front of an absolute  
> > &nbsp;&nbsp;/// value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = -200  
> > &nbsp;&nbsp;/// // x.magnitude == 200  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The global `abs(_:)` function provides more familiar syntax when you need  
> > &nbsp;&nbsp;/// to find an absolute value. In addition, because `abs(_:)` always returns  
> > &nbsp;&nbsp;/// a value of the same type, even in a generic context, using the function  
> > &nbsp;&nbsp;/// instead of the `magnitude` property is encouraged.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `abs(_:)`  
> > &nbsp;&nbsp;var magnitude: Magnitude { get }
> > 
> > &nbsp;&nbsp;/// Returns the sum of the two given values.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The sum of `lhs` and `rhs` must be representable in the same type. In the  
> > &nbsp;&nbsp;/// following example, the result of `100 + 200` is greater than the maximum  
> > &nbsp;&nbsp;/// representable `Int8` value:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: Int8 = 10 + 21  
> > &nbsp;&nbsp;/// // x == 31  
> > &nbsp;&nbsp;/// let y: Int8 = 100 + 121  
> > &nbsp;&nbsp;/// // Overflow error  
> > &nbsp;&nbsp;static func +(\_ lhs: Self, \_ rhs: Self) -\> Self
> > 
> > &nbsp;&nbsp;/// Adds the given value to this value in place.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For example:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// var x = 15  
> > &nbsp;&nbsp;/// y += 7  
> > &nbsp;&nbsp;/// // y == 22  
> > &nbsp;&nbsp;static func +=(\_ lhs: inout Self, rhs: Self)
> > 
> > &nbsp;&nbsp;/// Returns the difference of the two given values.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The difference of `lhs` and `rhs` must be representable in the same type.  
> > &nbsp;&nbsp;/// In the following example, the result of `10 - 21` is less than zero, the  
> > &nbsp;&nbsp;/// minimum representable `UInt` value:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt = 21 - 10  
> > &nbsp;&nbsp;/// // x == 11  
> > &nbsp;&nbsp;/// let y: UInt = 10 - 21  
> > &nbsp;&nbsp;/// // Overflow error  
> > &nbsp;&nbsp;static func -(\_ lhs: Self, \_ rhs: Self) -\> Self
> > 
> > &nbsp;&nbsp;/// Subtracts the given value from this value in place.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For example:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// var x = 15  
> > &nbsp;&nbsp;/// y -= 7  
> > &nbsp;&nbsp;/// // y == 8  
> > &nbsp;&nbsp;static func -=(\_ lhs: inout Self, rhs: Self)
> > 
> > &nbsp;&nbsp;/// Returns the product of the two given values.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The product of `lhs` and `rhs` must be representable in the same type. In  
> > &nbsp;&nbsp;/// the following example, the result of `10 * 50` is greater than the  
> > &nbsp;&nbsp;/// maximum representable `Int8` value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: Int8 = 10 \* 5  
> > &nbsp;&nbsp;/// // x == 50  
> > &nbsp;&nbsp;/// let y: Int8 = 10 \* 50  
> > &nbsp;&nbsp;/// // Overflow error  
> > &nbsp;&nbsp;static func \*(\_ lhs: Self, \_ rhs: Self) -\> Self
> > 
> > &nbsp;&nbsp;/// Multiples this value by the given value in place.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For example:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// var x = 15  
> > &nbsp;&nbsp;/// y \*= 7  
> > &nbsp;&nbsp;/// // y == 105  
> > &nbsp;&nbsp;static func \*=(\_ lhs: inout Self, rhs: Self)
> > 
> > &nbsp;&nbsp;/// Returns the quotient of dividing the first value by the second.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For integer types, any remainder of the division is discarded.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = 21 / 5  
> > &nbsp;&nbsp;/// // x == 4  
> > &nbsp;&nbsp;static func /(\_ lhs: Self, \_ rhs: Self) -\> Self
> > 
> > &nbsp;&nbsp;/// Divides this value by the given value in place.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For example:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// var x = 15  
> > &nbsp;&nbsp;/// y /= 7  
> > &nbsp;&nbsp;/// // y == 2  
> > &nbsp;&nbsp;static func /=(\_ lhs: inout Self, rhs: Self)  
> > }
> > 
> > extension Arithmetic {  
> > &nbsp;&nbsp;public init() { self = 0 }
> > 
> > &nbsp;&nbsp;public static prefix func + (x: Self) -\> Self {  
> > &nbsp;&nbsp;&nbsp;&nbsp;return x  
> > &nbsp;&nbsp;}  
> > }  
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#signedarithmetic&gt;SignedArithmetic)
> > 
> > The SignedArithmetic protocol is for numbers that can be negated.
> > 
> > public protocol SignedArithmetic : Arithmetic {  
> > &nbsp;&nbsp;/// Returns the additive inverse of this value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = 21  
> > &nbsp;&nbsp;/// let y = -x  
> > &nbsp;&nbsp;/// // y == -21  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Returns: The additive inverse of this value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `negate()`  
> > &nbsp;&nbsp;static prefix func - (\_ operand: Self) -\> Self
> > 
> > &nbsp;&nbsp;/// Replaces this value with its additive inverse.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The following example uses the `negate()` method to negate the value of  
> > &nbsp;&nbsp;/// an integer `x`:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// var x = 21  
> > &nbsp;&nbsp;/// x.negate()  
> > &nbsp;&nbsp;/// // x == -21  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: The unary minus operator (`-`).  
> > &nbsp;&nbsp;mutating func negate()  
> > }
> > 
> > extension SignedArithmetic {  
> > &nbsp;&nbsp;public static prefix func - (\_ operand: Self) -\> Self {  
> > &nbsp;&nbsp;&nbsp;&nbsp;var result = operand  
> > &nbsp;&nbsp;&nbsp;&nbsp;result.negate()  
> > &nbsp;&nbsp;&nbsp;&nbsp;return result  
> > &nbsp;&nbsp;}
> > 
> > &nbsp;&nbsp;public mutating func negate() {  
> > &nbsp;&nbsp;&nbsp;&nbsp;self = Self() - self  
> > &nbsp;&nbsp;}  
> > }  
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#binaryinteger&gt;BinaryInteger)
> > 
> > The BinaryInteger protocol is the basis for all the integer types provided by the standard library.
> > 
> > This protocol adds a few new initializers. Two of them allow to create integers from floating point numbers, others support construction from instances of any type conforming to BinaryInteger, using different strategies:
> > 
> > Initialize Self with the value, provided that the value is representable. The precondition should be satisfied by the caller.
> > 
> > Extend or truncate the value to fit into Self
> > 
> > Clamp the value to the representable range of Self
> > 
> > BinaryInteger also declares bitwise and shift operators.
> > 
> > public protocol BinaryInteger :  
> > &nbsp;&nbsp;Comparable, Hashable, Arithmetic, CustomStringConvertible, Strideable {
> > 
> > &nbsp;&nbsp;/// A Boolean value indicating whether this type is a signed integer type.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// \*Signed\* integer types can represent both positive and negative values.  
> > &nbsp;&nbsp;/// \*Unsigned\* integer types can represent only nonnegative values.  
> > &nbsp;&nbsp;static var isSigned: Bool { get }
> > 
> > &nbsp;&nbsp;/// Creates an integer from the given floating-point value, if it can be  
> > &nbsp;&nbsp;/// represented exactly.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// If the value passed as `source` is not representable exactly, the result  
> > &nbsp;&nbsp;/// is `nil`. In the following example, the constant `x` is successfully  
> > &nbsp;&nbsp;/// created from a value of `21.0`, while the attempt to initialize the  
> > &nbsp;&nbsp;/// constant `y` from `21.5` fails:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = Int(exactly: 21.0)  
> > &nbsp;&nbsp;/// // x == Optional(21)  
> > &nbsp;&nbsp;/// let y = Int(exactly: 21.5)  
> > &nbsp;&nbsp;/// // y == nil  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter source: A floating-point value to convert to an integer.  
> > &nbsp;&nbsp;init?\<T : FloatingPoint\>(exactly source: T)
> > 
> > &nbsp;&nbsp;/// Creates an integer from the given floating-point value, truncating any  
> > &nbsp;&nbsp;/// fractional part.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// Truncating the fractional part of `source` is equivalent to rounding  
> > &nbsp;&nbsp;/// toward zero.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = Int(21.5)  
> > &nbsp;&nbsp;/// // x == 21  
> > &nbsp;&nbsp;/// let y = Int(-21.5)  
> > &nbsp;&nbsp;/// // y == -21  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// If `source` is outside the bounds of this type after truncation, a  
> > &nbsp;&nbsp;/// runtime error may occur.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let z = UInt(-21.5)  
> > &nbsp;&nbsp;/// // Error: ...the result would be less than UInt.min  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter source: A floating-point value to convert to an integer.  
> > &nbsp;&nbsp;/// `source` must be representable in this type after truncation.  
> > &nbsp;&nbsp;init\<T : FloatingPoint\>(\_ source: T)
> > 
> > &nbsp;&nbsp;/// Creates an new instance from the given integer.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// If the value passed as `source` is not representable in this type, a  
> > &nbsp;&nbsp;/// runtime error may occur.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = -500 as Int  
> > &nbsp;&nbsp;/// let y = Int32(x)  
> > &nbsp;&nbsp;/// // y == -500  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// // -500 is not representable as a 'UInt32' instance  
> > &nbsp;&nbsp;/// let z = UInt32(x)  
> > &nbsp;&nbsp;/// // Error  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter source: An integer to convert. `source` must be representable  
> > &nbsp;&nbsp;/// in this type.  
> > &nbsp;&nbsp;init\<T : BinaryInteger\>(\_ source: T)
> > 
> > &nbsp;&nbsp;/// Creates a new instance from the bit pattern of the given instance by  
> > &nbsp;&nbsp;/// sign-extending or truncating to fit this type.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// When the bit width of `T` (the type of `source`) is equal to or greater  
> > &nbsp;&nbsp;/// than this type's bit width, the result is the truncated  
> > &nbsp;&nbsp;/// least-significant bits of `source`. For example, when converting a  
> > &nbsp;&nbsp;/// 16-bit value to an 8-bit type, only the lower 8 bits of `source` are  
> > &nbsp;&nbsp;/// used.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let p: Int16 = -500  
> > &nbsp;&nbsp;/// // 'p' has a binary representation of 11111110\_00001100  
> > &nbsp;&nbsp;/// let q = Int8(extendingOrTruncating: p)  
> > &nbsp;&nbsp;/// // q == 12  
> > &nbsp;&nbsp;/// // 'q' has a binary representation of 00001100  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// When the bit width of `T` is less than this type's bit width, the result  
> > &nbsp;&nbsp;/// is \*sign-extended\* to fill the remaining bits. That is, if `source` is  
> > &nbsp;&nbsp;/// negative, the result is padded with ones; otherwise, the result is  
> > &nbsp;&nbsp;/// padded with zeros.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let u: Int8 = 21  
> > &nbsp;&nbsp;/// // 'u' has a binary representation of 00010101  
> > &nbsp;&nbsp;/// let v = Int16(extendingOrTruncating: u)  
> > &nbsp;&nbsp;/// // v == 21  
> > &nbsp;&nbsp;/// // 'v' has a binary representation of 00000000\_00010101  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let w: Int8 = -21  
> > &nbsp;&nbsp;/// // 'w' has a binary representation of 11101011  
> > &nbsp;&nbsp;/// let x = Int16(extendingOrTruncating: w)  
> > &nbsp;&nbsp;/// // x == -21  
> > &nbsp;&nbsp;/// // 'x' has a binary representation of 11111111\_11101011  
> > &nbsp;&nbsp;/// let y = UInt16(extendingOrTruncating: w)  
> > &nbsp;&nbsp;/// // y == 65515  
> > &nbsp;&nbsp;/// // 'y' has a binary representation of 11111111\_11101011  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter source: An integer to convert to this type.  
> > &nbsp;&nbsp;init\<T : BinaryInteger\>(extendingOrTruncating source: T)
> > 
> > &nbsp;&nbsp;/// Creates a new instance with the representable value that's closest to the  
> > &nbsp;&nbsp;/// given integer.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// If the value passed as `source` is greater than the maximum representable  
> > &nbsp;&nbsp;/// value in this type, the result is the type's `max` value. If `source` is  
> > &nbsp;&nbsp;/// less than the smallest representable value in this type, the result is  
> > &nbsp;&nbsp;/// the type's `min` value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// In this example, `x` is initialized as an `Int8` instance by clamping  
> > &nbsp;&nbsp;/// `500` to the range `-128...127`, and `y` is initialized as a `UInt`  
> > &nbsp;&nbsp;/// instance by clamping `-500` to the range `0...UInt.max`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = Int8(clamping: 500)  
> > &nbsp;&nbsp;/// // x == 127  
> > &nbsp;&nbsp;/// // x == Int8.max  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let y = UInt(clamping: -500)  
> > &nbsp;&nbsp;/// // y == 0  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter source: An integer to convert to this type.  
> > &nbsp;&nbsp;init\<T : BinaryInteger\>(clamping source: T)
> > 
> > &nbsp;&nbsp;/// Returns the n-th word, counting from the least significant to most  
> > &nbsp;&nbsp;/// significant, of this value's binary representation.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The `word(at:)` method returns negative values in two's complement  
> > &nbsp;&nbsp;/// representation, regardless of a type's underlying implementation. If `n`  
> > &nbsp;&nbsp;/// is greater than the number of words in this value's current  
> > &nbsp;&nbsp;/// representation, the result is `0` for positive numbers and `~0` for  
> > &nbsp;&nbsp;/// negative numbers.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter n: The word to return, counting from the least significant to  
> > &nbsp;&nbsp;/// most significant. `n` must be greater than or equal to zero.  
> > &nbsp;&nbsp;/// - Returns: An word-sized, unsigned integer with the bit pattern of the  
> > &nbsp;&nbsp;/// n-th word of this value.  
> > &nbsp;&nbsp;func word(at n: Int) -\> UInt
> > 
> > &nbsp;&nbsp;/// The number of bits in the current binary representation of this value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// This property is a constant for instances of fixed-width integer  
> > &nbsp;&nbsp;/// types.  
> > &nbsp;&nbsp;var bitWidth : Int { get }
> > 
> > &nbsp;&nbsp;/// The number of trailing zeros in this value's binary representation.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For example, in a fixed-width integer type with a `bitWidth` value of 8,  
> > &nbsp;&nbsp;/// the number -8 has three trailing zeros.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = Int8(bitPattern: 0b1111\_1000)  
> > &nbsp;&nbsp;/// // x == -8  
> > &nbsp;&nbsp;/// // x.trailingZeros == 3  
> > &nbsp;&nbsp;var trailingZeros: Int { get }
> > 
> > &nbsp;&nbsp;/// Returns the remainder of dividing the first value by the second.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The result has the same sign as `lhs` and is less than `rhs.magnitude`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = 22 % 5  
> > &nbsp;&nbsp;/// // x == 2  
> > &nbsp;&nbsp;/// let y = 22 % -5  
> > &nbsp;&nbsp;/// // y == 2  
> > &nbsp;&nbsp;/// let z = -22 % -5  
> > &nbsp;&nbsp;/// // z == -2  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameters:  
> > &nbsp;&nbsp;/// - lhs: The value to divide.  
> > &nbsp;&nbsp;/// - rhs: The value to divide `lhs` by. `rhs` must not be zero.  
> > &nbsp;&nbsp;static func %(\_ lhs: Self, \_ rhs: Self) -\> Self
> > 
> > &nbsp;&nbsp;/// Replaces this value with the remainder of itself divided by the given  
> > &nbsp;&nbsp;/// value. For example:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// var x = 15  
> > &nbsp;&nbsp;/// x %= 7  
> > &nbsp;&nbsp;/// // x == 1  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter rhs: The value to divide this value by. `rhs` must not be  
> > &nbsp;&nbsp;/// zero.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `remainder(dividingBy:)`  
> > &nbsp;&nbsp;static func %=(\_ lhs: inout Self, \_ rhs: Self)
> > 
> > &nbsp;&nbsp;/// Returns the inverse of the bits set in the argument.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The bitwise NOT operator (`~`) is a prefix operator that returns a value  
> > &nbsp;&nbsp;/// in which all the bits of its argument are flipped: Bits that are `1` in  
> > &nbsp;&nbsp;/// the argument are `0` in the result, and bits that are `0` in the argument  
> > &nbsp;&nbsp;/// are `1` in the result. This is equivalent to the inverse of a set. For  
> > &nbsp;&nbsp;/// example:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt8 = 5 // 0b00000101  
> > &nbsp;&nbsp;/// let notX = ~x // 0b11111010  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// Performing a bitwise NOT operation on 0 returns a value with every bit  
> > &nbsp;&nbsp;/// set to `1`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let allOnes = ~UInt8.min // 0b11111111  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Complexity: O(1).  
> > &nbsp;&nbsp;static prefix func ~ (\_ x: Self) -\> Self
> > 
> > &nbsp;&nbsp;/// Returns the result of performing a bitwise AND operation on this value  
> > &nbsp;&nbsp;/// and the given value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// A bitwise AND operation results in a value that has each bit set to `1`  
> > &nbsp;&nbsp;/// where \*both\* of its arguments have that bit set to `1`. For example:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt8 = 5 // 0b00000101  
> > &nbsp;&nbsp;/// let y: UInt8 = 14 // 0b00001110  
> > &nbsp;&nbsp;/// let z = x & y // 0b00000100  
> > &nbsp;&nbsp;static func &(\_ lhs: Self, \_ rhs: Self) -\> Self  
> > &nbsp;&nbsp;static func &=(\_ lhs: inout Self, \_ rhs: Self)
> > 
> > &nbsp;&nbsp;/// Returns the result of performing a bitwise OR operation on this value and  
> > &nbsp;&nbsp;/// the given value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// A bitwise OR operation results in a value that has each bit set to `1`  
> > &nbsp;&nbsp;/// where \*one or both\* of its arguments have that bit set to `1`. For  
> > &nbsp;&nbsp;/// example:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt8 = 5 // 0b00000101  
> > &nbsp;&nbsp;/// let y: UInt8 = 14 // 0b00001110  
> > &nbsp;&nbsp;/// let z = x | y // 0b00001111  
> > &nbsp;&nbsp;static func |(\_ lhs: Self, \_ rhs: Self) -\> Self  
> > &nbsp;&nbsp;static func |=(\_ lhs: inout Self, \_ rhs: Self)
> > 
> > &nbsp;&nbsp;/// Returns the result of performing a bitwise XOR operation on this value  
> > &nbsp;&nbsp;/// and the given value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// A bitwise XOR operation, also known as an exclusive OR operation, results  
> > &nbsp;&nbsp;/// in a value that has each bit set to `1` where \*one or the other but not  
> > &nbsp;&nbsp;/// both\* of its arguments had that bit set to `1`. For example:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt8 = 5 // 0b00000101  
> > &nbsp;&nbsp;/// let y: UInt8 = 14 // 0b00001110  
> > &nbsp;&nbsp;/// let z = x ^ y // 0b00001011  
> > &nbsp;&nbsp;static func ^(\_ lhs: Self, \_ rhs: Self) -\> Self  
> > &nbsp;&nbsp;static func ^=(\_ lhs: inout Self, \_ rhs: Self)
> > 
> > &nbsp;&nbsp;/// Returns the result of shifting this value's binary representation the  
> > &nbsp;&nbsp;/// specified number of digits to the right.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// In a \*masking shift\*, the bit pattern of the value passed as `rhs` is  
> > &nbsp;&nbsp;/// masked to produce a value between zero and the bit width of `lhs`. The  
> > &nbsp;&nbsp;/// shift is performed using this masked value. Masking shifts require more  
> > &nbsp;&nbsp;/// care to use correctly than a traditional bit shift, but are likely to be  
> > &nbsp;&nbsp;/// more efficient when used with shift amounts that are not compile-time  
> > &nbsp;&nbsp;/// constants. On most architectures, a masking shift compiles down to a  
> > &nbsp;&nbsp;/// single instruction.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For example, if you shift an 8-bit, unsigned integer by 2, the shift  
> > &nbsp;&nbsp;/// amount requires no masking.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt8 = 30 // 0b00011110  
> > &nbsp;&nbsp;/// let y = x &\>\> 2  
> > &nbsp;&nbsp;/// // y == 7 // 0b00000111  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// However, if you shift it by 11, it first bitmasks `rhs` to `3`, and then  
> > &nbsp;&nbsp;/// uses that masked value as the number of bits to shift `x`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let z = x &\>\> 11  
> > &nbsp;&nbsp;/// // z == 3 // 0b00000011  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// Relationship to the Right Shift Operator  
> > &nbsp;&nbsp;/// ----------------------------------------  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The masking right shift operator handles attempted overshifts and  
> > &nbsp;&nbsp;/// undershifts differently from the right shift operator (`\>\>`). When the  
> > &nbsp;&nbsp;/// value passed as `rhs` in a masking shift is within the range  
> > &nbsp;&nbsp;/// `0...\<bitWidth`, the operation is equivalent to using the right shift  
> > &nbsp;&nbsp;/// operator.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt8 = 30 // 0b00011110  
> > &nbsp;&nbsp;/// let y1 = x &\>\> 2  
> > &nbsp;&nbsp;/// // y1 == 7 // 0b00000111  
> > &nbsp;&nbsp;/// let y2 = x \>\> 2  
> > &nbsp;&nbsp;/// // y2 == 7 // 0b00000111  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The right shift operator does not mask its right-hand-side argument, so  
> > &nbsp;&nbsp;/// passing `11` as `rhs` shifts all the bits of `x` to zero.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let z1 = x &\>\> 11  
> > &nbsp;&nbsp;/// // z1 == 240 // 0b00000011  
> > &nbsp;&nbsp;/// let z2 = x \>\> 11  
> > &nbsp;&nbsp;/// // z2 == 0 // 0b00000000  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter rhs: The number of bits to shift this value to the right. If  
> > &nbsp;&nbsp;/// `rhs` is outside the range `0..\<bitWidth`, it is masked to produce a  
> > &nbsp;&nbsp;/// value within that range.  
> > &nbsp;&nbsp;/// - Returns: The result of shifting this value by the masked `rhs` to the  
> > &nbsp;&nbsp;/// right.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `&\<\<`, `\>\>`  
> > &nbsp;&nbsp;static func &\>\>(\_ lhs: Self, \_ rhs: Self) -\> Self  
> > &nbsp;&nbsp;static func &\>\>=(\_ lhs: inout Self, \_ rhs: Self)
> > 
> > &nbsp;&nbsp;/// Returns the result of shifting this value's binary representation the  
> > &nbsp;&nbsp;/// specified number of digits to the left.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// In a \*masking shift\*, the bit pattern of the value passed as `rhs` is  
> > &nbsp;&nbsp;/// masked to produce a value between zero and the bit width of `lhs`. The  
> > &nbsp;&nbsp;/// shift is performed using this masked value. Masking shifts require more  
> > &nbsp;&nbsp;/// care to use correctly than a traditional bit shift, but are likely to be  
> > &nbsp;&nbsp;/// more efficient when used with shift amounts that are not compile-time  
> > &nbsp;&nbsp;/// constants. On most architectures, a masking shift compiles down to a  
> > &nbsp;&nbsp;/// single instruction.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For example, if you shift an 8-bit, unsigned integer by 2, the shift  
> > &nbsp;&nbsp;/// amount requires no masking.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt8 = 30 // 0b00011110  
> > &nbsp;&nbsp;/// let y = x &\>\> 2  
> > &nbsp;&nbsp;/// // y == 120 // 0b01111000  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// However, if you shift it by 11, it first bitmasks `rhs` to `3`, and then  
> > &nbsp;&nbsp;/// uses that masked value as the number of bits to shift `x`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let z = x &\<\< 11  
> > &nbsp;&nbsp;/// // z == 240 // 0b11110000  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// Relationship to the Left Shift Operator  
> > &nbsp;&nbsp;/// ---------------------------------------  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The masking left shift operator handles attempted overshifts and  
> > &nbsp;&nbsp;/// undershifts differently from the left shift operator (`\<\<`). When the  
> > &nbsp;&nbsp;/// value passed as `rhs` in a masking shift is within the range  
> > &nbsp;&nbsp;/// `0...\<bitWidth`, the operation is equivalent to using the left shift  
> > &nbsp;&nbsp;/// operator.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt8 = 30 // 0b00011110  
> > &nbsp;&nbsp;/// let y1 = x &\<\< 2  
> > &nbsp;&nbsp;/// // y1 == 120 // 0b01111000  
> > &nbsp;&nbsp;/// let y2 = x \<\< 2  
> > &nbsp;&nbsp;/// // y2 == 120 // 0b01111000  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The left shift operator does not mask its right-hand-side argument, so  
> > &nbsp;&nbsp;/// passing `11` as `rhs` shifts all the bits of `x` to zero.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let z1 = x &\<\< 11  
> > &nbsp;&nbsp;/// // z1 == 240 // 0b11110000  
> > &nbsp;&nbsp;/// let z2 = x \<\< 11  
> > &nbsp;&nbsp;/// // z2 == 0 // 0b00000000  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter rhs: The number of bits to shift this value to the left. If  
> > &nbsp;&nbsp;/// `rhs` is outside the range `0..\<bitWidth`, it is masked to produce a  
> > &nbsp;&nbsp;/// value within that range.  
> > &nbsp;&nbsp;/// - Returns: The result of shifting this value by the masked `rhs` to the  
> > &nbsp;&nbsp;/// left.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `&\>\>`, `\<\<`  
> > &nbsp;&nbsp;static func &\<\<(\_ lhs: Self, \_ rhs: Self) -\> Self  
> > &nbsp;&nbsp;static func &\<\<=(\_ lhs: inout Self, \_ rhs: Self)
> > 
> > &nbsp;&nbsp;/// Returns the quotient and remainder of this value divided by the given  
> > &nbsp;&nbsp;/// value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// Use this method to calculate the quotient and remainder of a division at  
> > &nbsp;&nbsp;/// the same time.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = 1\_000\_000  
> > &nbsp;&nbsp;/// let (q, r) = x.quotientAndRemainder(dividingBy: 933)  
> > &nbsp;&nbsp;/// // q == 1071  
> > &nbsp;&nbsp;/// // r == 757  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter rhs: The value to divide this value by.  
> > &nbsp;&nbsp;/// - Returns: A tuple containing the quotient and remainder of this value  
> > &nbsp;&nbsp;/// divided by `rhs`.  
> > &nbsp;&nbsp;func quotientAndRemainder(dividingBy rhs: Self)  
> > &nbsp;&nbsp;&nbsp;&nbsp;-\> (quotient: Self, remainder: Self)
> > 
> > &nbsp;&nbsp;/// Returns `-1` if this value is negative and `1` if it's positive;  
> > &nbsp;&nbsp;/// otherwise, `0`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Returns: The sign of this number, expressed as an integer of the same  
> > &nbsp;&nbsp;/// type.  
> > &nbsp;&nbsp;func signum() -\> Self  
> > }  
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#fixedwidthinteger&gt;FixedWidthInteger)
> > 
> > The FixedWidthInteger protocol adds the notion of endianness as well as static properties for type bounds and bit width.
> > 
> > The WithOverflow family of methods is used in default implementations of mutating arithmetic methods (see the Arithmetic protocol). Having these methods allows the library to provide both bounds-checked and masking implementations of arithmetic operations, without duplicating code.
> > 
> > The doubleWidthMultiply and doubleWidthDivide methods are necessary building blocks to implement support for integer types of a greater width such as arbitrary-precision integers.
> > 
> > public protocol FixedWidthInteger : BinaryInteger {  
> > &nbsp;&nbsp;/// The number of bits used for the underlying binary representation of  
> > &nbsp;&nbsp;/// values of this type.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// An unsigned, fixed-width integer type can represent values from 0 through  
> > &nbsp;&nbsp;/// `(2 **bitWidth) - 1`, where `**` is exponentiation. A signed,  
> > &nbsp;&nbsp;/// fixed-width integer type can represent values from  
> > &nbsp;&nbsp;/// `-(2 **bitWidth - 1)` through `(2** bitWidth - 1) - 1`. For example,  
> > &nbsp;&nbsp;/// the `Int8` type has a `bitWidth` value of 8 and can store any integer in  
> > &nbsp;&nbsp;/// the range `-128...127`.  
> > &nbsp;&nbsp;static var bitWidth : Int { get }
> > 
> > &nbsp;&nbsp;/// The maximum representable integer in this type.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For unsigned integer types, this value is `(2 ** bitWidth) - 1`, where  
> > &nbsp;&nbsp;/// `**` is exponentiation. For signed integer types, this value is  
> > &nbsp;&nbsp;/// `(2 ** bitWidth - 1) - 1`.  
> > &nbsp;&nbsp;static var max: Self { get }
> > 
> > &nbsp;&nbsp;/// The minimum representable value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For unsigned integer types, this value is always `0`. For signed integer  
> > &nbsp;&nbsp;/// types, this value is `-(2 **bitWidth - 1)`, where `**` is  
> > &nbsp;&nbsp;/// exponentiation.  
> > &nbsp;&nbsp;static var min: Self { get }
> > 
> > &nbsp;&nbsp;/// Returns the sum of this value and the given value along with a flag  
> > &nbsp;&nbsp;/// indicating whether overflow occurred in the operation.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter other: The value to add to this value.  
> > &nbsp;&nbsp;/// - Returns: A tuple containing the result of the addition along with a  
> > &nbsp;&nbsp;/// flag indicating whether overflow occurred. If the `overflow` component  
> > &nbsp;&nbsp;/// is `.none`, the `partialValue` component contains the entire sum. If  
> > &nbsp;&nbsp;/// the `overflow` component is `.overflow`, an overflow occurred and the  
> > &nbsp;&nbsp;/// `partialValue` component contains the truncated sum of this value and  
> > &nbsp;&nbsp;/// `other`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `+`  
> > &nbsp;&nbsp;func addingWithOverflow(\_ other: Self)  
> > &nbsp;&nbsp;&nbsp;&nbsp;-\> (partialValue: Self, overflow: ArithmeticOverflow)
> > 
> > &nbsp;&nbsp;/// Returns the difference of this value and the given value along with a  
> > &nbsp;&nbsp;/// flag indicating whether overflow occurred in the operation.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter other: The value to subtract from this value.  
> > &nbsp;&nbsp;/// - Returns: A tuple containing the result of the subtraction along with a  
> > &nbsp;&nbsp;/// flag indicating whether overflow occurred. If the `overflow` component  
> > &nbsp;&nbsp;/// is `.none`, the `partialValue` component contains the entire  
> > &nbsp;&nbsp;/// difference. If the `overflow` component is `.overflow`, an overflow  
> > &nbsp;&nbsp;/// occurred and the `partialValue` component contains the truncated  
> > &nbsp;&nbsp;/// result of `other` subtracted from this value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `-`  
> > &nbsp;&nbsp;func subtractingWithOverflow(\_ other: Self)  
> > &nbsp;&nbsp;&nbsp;&nbsp;-\> (partialValue: Self, overflow: ArithmeticOverflow)
> > 
> > &nbsp;&nbsp;/// Returns the product of this value and the given value along with a flag  
> > &nbsp;&nbsp;/// indicating whether overflow occurred in the operation.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter other: The value to multiply by this value.  
> > &nbsp;&nbsp;/// - Returns: A tuple containing the result of the multiplication along with  
> > &nbsp;&nbsp;/// a flag indicating whether overflow occurred. If the `overflow`  
> > &nbsp;&nbsp;/// component is `.none`, the `partialValue` component contains the entire  
> > &nbsp;&nbsp;/// product. If the `overflow` component is `.overflow`, an overflow  
> > &nbsp;&nbsp;/// occurred and the `partialValue` component contains the truncated  
> > &nbsp;&nbsp;/// product of this value and `other`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `*`, `doubleWidthMultiply(_:_:)`  
> > &nbsp;&nbsp;func multipliedWithOverflow(by other: Self)  
> > &nbsp;&nbsp;&nbsp;&nbsp;-\> (partialValue: Self, overflow: ArithmeticOverflow)
> > 
> > &nbsp;&nbsp;/// Returns the quotient of dividing this value by the given value along with  
> > &nbsp;&nbsp;/// a flag indicating whether overflow occurred in the operation.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For a value `x`, if zero is passed as `other`, the result is  
> > &nbsp;&nbsp;/// `(x, .overflow)`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter other: The value to divide this value by.  
> > &nbsp;&nbsp;/// - Returns: A tuple containing the result of the division along with a  
> > &nbsp;&nbsp;/// flag indicating whether overflow occurred. If the `overflow` component  
> > &nbsp;&nbsp;/// is `.none`, the `partialValue` component contains the entire quotient.  
> > &nbsp;&nbsp;/// If the `overflow` component is `.overflow`, an overflow occurred and  
> > &nbsp;&nbsp;/// the `partialValue` component contains the truncated quotient.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `/`, `doubleWidthDivide(_:_:)`  
> > &nbsp;&nbsp;func dividedWithOverflow(by other: Self)  
> > &nbsp;&nbsp;&nbsp;&nbsp;-\> (partialValue: Self, overflow: ArithmeticOverflow)
> > 
> > &nbsp;&nbsp;/// Returns a tuple containing the high and low parts of the result of  
> > &nbsp;&nbsp;/// multiplying its arguments.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// Use this method to calculate the full result of a product that would  
> > &nbsp;&nbsp;/// otherwise overflow. Unlike traditional truncating multiplication, the  
> > &nbsp;&nbsp;/// `doubleWidthMultiply(_:_:)` method returns both the `high` and `low`  
> > &nbsp;&nbsp;/// parts of the product of `lhs` and `rhs`. The following example uses this  
> > &nbsp;&nbsp;/// method to multiply two `UInt8` values that normally overflow when  
> > &nbsp;&nbsp;/// multiplied:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt8 = 100  
> > &nbsp;&nbsp;/// let y: UInt8 = 20  
> > &nbsp;&nbsp;/// let result = UInt8.doubleWidthMultiply(100, 20)  
> > &nbsp;&nbsp;/// // result.high == 0b00000111  
> > &nbsp;&nbsp;/// // result.low == 0b11010000  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The product of `x` and `y` is 2000, which is too large to represent in a  
> > &nbsp;&nbsp;/// `UInt8` instance. The `high` and `low` components of the `result` tuple  
> > &nbsp;&nbsp;/// represent 2000 when concatenated to form a double-width integer; that  
> > &nbsp;&nbsp;/// is, using `result.high` as the high byte and `result.low` as the low byte  
> > &nbsp;&nbsp;/// of a `UInt16` instance.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let z = UInt16(result.high) \<\< 8 | UInt16(result.low)  
> > &nbsp;&nbsp;/// // z == 2000  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameters:  
> > &nbsp;&nbsp;/// - lhs: A value to multiply.  
> > &nbsp;&nbsp;/// - rhs: Another value to multiply.  
> > &nbsp;&nbsp;/// - Returns: A tuple containing the high and low parts of the result of  
> > &nbsp;&nbsp;/// multiplying `lhs` and `rhs`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `multipliedWithOverflow(by:)`  
> > &nbsp;&nbsp;static func doubleWidthMultiply(\_ lhs: Self, \_ rhs: Self)  
> > &nbsp;&nbsp;&nbsp;&nbsp;-\> (high: Self, low: Magnitude)
> > 
> > &nbsp;&nbsp;/// Returns a tuple containing the quotient and remainder of dividing the  
> > &nbsp;&nbsp;/// first argument by the second.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The resulting quotient must be representable within the bounds of the  
> > &nbsp;&nbsp;/// type. If the quotient of dividing `lhs` by `rhs` is too large to  
> > &nbsp;&nbsp;/// represent in the type, a runtime error may occur.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameters:  
> > &nbsp;&nbsp;/// - lhs: A tuple containing the high and low parts of a double-width  
> > &nbsp;&nbsp;/// integer. The `high` component of the tuple carries the sign, if the  
> > &nbsp;&nbsp;/// type is signed.  
> > &nbsp;&nbsp;/// - rhs: The integer to divide into `lhs`.  
> > &nbsp;&nbsp;/// - Returns: A tuple containing the quotient and remainder of `lhs` divided  
> > &nbsp;&nbsp;/// by `rhs`.  
> > &nbsp;&nbsp;static func doubleWidthDivide(  
> > &nbsp;&nbsp;&nbsp;&nbsp;\_ lhs: (high: Self, low: Magnitude), \_ rhs: Self)  
> > &nbsp;&nbsp;&nbsp;&nbsp;-\> (quotient: Self, remainder: Self)
> > 
> > &nbsp;&nbsp;/// The number of bits equal to 1 in this value's binary representation.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For example, in a fixed-width integer type with a `bitWidth` value of 8,  
> > &nbsp;&nbsp;/// the number 31 has five bits equal to 1.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: Int8 = 0b0001\_1111  
> > &nbsp;&nbsp;/// // x == 31  
> > &nbsp;&nbsp;/// // x.popcount == 5  
> > &nbsp;&nbsp;var popcount: Int { get }
> > 
> > &nbsp;&nbsp;/// The number of leading zeros in this value's binary representation.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For example, in a fixed-width integer type with a `bitWidth` value of 8,  
> > &nbsp;&nbsp;/// the number 31 has three leading zeros.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: Int8 = 0b0001\_1111  
> > &nbsp;&nbsp;/// // x == 31  
> > &nbsp;&nbsp;/// // x.leadingZeros == 3  
> > &nbsp;&nbsp;/// - SeeAlso: `BinaryInteger.trailingZeros`  
> > &nbsp;&nbsp;var leadingZeros: Int { get }
> > 
> > &nbsp;&nbsp;/// Creates an integer from its big-endian representation, changing the  
> > &nbsp;&nbsp;/// byte order if necessary.  
> > &nbsp;&nbsp;init(bigEndian value: Self)
> > 
> > &nbsp;&nbsp;/// Creates an integer from its little-endian representation, changing the  
> > &nbsp;&nbsp;/// byte order if necessary.  
> > &nbsp;&nbsp;init(littleEndian value: Self)
> > 
> > &nbsp;&nbsp;/// The big-endian representation of this integer.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// If necessary, the byte order of this value is reversed from the typical  
> > &nbsp;&nbsp;/// byte order of this integer type. On a big-endian platform, for any  
> > &nbsp;&nbsp;/// integer `x`, `x == x.bigEndian`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `littleEndian`  
> > &nbsp;&nbsp;var bigEndian: Self { get }
> > 
> > &nbsp;&nbsp;/// The little-endian representation of this integer.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// If necessary, the byte order of this value is reversed from the typical  
> > &nbsp;&nbsp;/// byte order of this integer type. On a little-endian platform, for any  
> > &nbsp;&nbsp;/// integer `x`, `x == x.littleEndian`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `bigEndian`  
> > &nbsp;&nbsp;var littleEndian: Self { get }
> > 
> > &nbsp;&nbsp;/// A representation of this integer with the byte order swapped.  
> > &nbsp;&nbsp;var byteSwapped: Self { get }  
> > }  
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#auxiliary-protocols&gt;Auxiliary) protocols
> > 
> > public protocol UnsignedInteger : BinaryInteger {  
> > &nbsp;&nbsp;associatedtype Magnitude : BinaryInteger  
> > }  
> > public protocol SignedInteger : BinaryInteger, SignedArithmetic {  
> > &nbsp;&nbsp;associatedtype Magnitude : BinaryInteger  
> > }  
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#doublewidth&gt;DoubleWidth)
> > 
> > The DoubleWidth\<T\> type allows to create wider fixed-width integer types from the ones available in the standard library.
> > 
> > Standard library currently provides fixed-width integer types of up to 64 bits. A value of DoubleWidth\<Int64\> will double the range of the underlying type and implement all the FixedWidthInteger requirements. Please note though that the implementation will not necessarily be the most efficient one, so it would not be a good idea to use DoubleWidth\<Int32\>instead of a built-in Int64.
> > 
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#extra-operators&gt;Extra) operators
> > 
> > In addition to the operators described in the protocols section \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#protocols&gt;), we also provide a few extensions that are not protocol requirements:
> > 
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#heterogeneous-shifts&gt;Heterogeneous) shifts
> > 
> > extension BinaryInteger {  
> > &nbsp;&nbsp;// Masking shifts  
> > &nbsp;&nbsp;static func &\>\> \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self  
> > &nbsp;&nbsp;static func &\>\>= \<Other : BinaryInteger\>(lhs: inout Self, rhs: Other)  
> > &nbsp;&nbsp;static func &\<\< \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self  
> > &nbsp;&nbsp;static func &\<\<= \<Other : BinaryInteger\>(lhs: inout Self, rhs: Other)
> > 
> > &nbsp;&nbsp;// 'Smart' shifts  
> > &nbsp;&nbsp;static func \>\> \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self  
> > &nbsp;&nbsp;static func \>\>= \<Other : BinaryInteger\>(lhs: inout Self, rhs: Other)  
> > &nbsp;&nbsp;static func \<\< \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self  
> > &nbsp;&nbsp;static func \<\<= \<Other : BinaryInteger\>(lhs: inout Self, rhs: Other)  
> > }  
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#heterogeneous-equality-and-comparison&gt;Heterogeneous) equality and comparison
> > 
> > extension BinaryInteger {  
> > &nbsp;&nbsp;// Equality  
> > &nbsp;&nbsp;static func == \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool  
> > &nbsp;&nbsp;static func != \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool
> > 
> > &nbsp;&nbsp;// Comparison  
> > &nbsp;&nbsp;static func \< \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool  
> > &nbsp;&nbsp;static func \<= \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool  
> > &nbsp;&nbsp;static func \> \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool  
> > &nbsp;&nbsp;static func \>= \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool  
> > }  
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#masking-arithmetic&gt;Masking) arithmetic
> > 
> > public func &\* \<T: FixedWidthInteger\>(lhs: T, rhs: T) -\> T  
> > public func &- \<T: FixedWidthInteger\>(lhs: T, rhs: T) -\> T  
> > public func &+ \<T: FixedWidthInteger\>(lhs: T, rhs: T) -\> T  
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#non-goals&gt;Non%5C-goals)
> > 
> > This proposal:
> > 
> > DOES NOT solve the integer promotion problem, which would allow mixed-type arithmetic. However, we believe that it is an important step in the right direction.
> > 
> > DOES NOT include the implementation of a BigInt type, but allows it to be implemented in the future.
> > 
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#source-compatibility&gt;Source) compatibility
> > 
> > The proposed change is designed to be as non-breaking as possible, and it has been proven that it does not break code on concrete integer types. However, there are still a few API breaking changes in the realm of generic code:
> > 
> > Integer protocols in Swift up to and including version 3 were not particularly useful for generic programming, but were rather a means of sharing implementation between conforming types. Therefore we believe the amount of code that relied on these protocols is relatively small. The breakage can be further reduced by introducing proper aliases for the removed protocols with deprecation warnings.
> > 
> > Deprecation of the BitwiseOperations protocol. We find it hard to imagine a type that conforms to this protocol, but is not a binary integer type.
> > 
> > Addition of 'smart' shifts will change the behavior of existing code. It will still compile, but will be potentially less performant due to extra logic involved. In a case, where this becomes a problem, newly introduced masking shift operators can be used instead. Unfortunately, performance characteristics of the code cannot be statically checked, and thus migration cannot be provided.
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![jtbandes](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jtbandes/32/463_2.png) [@jtbandes](https://forums.swift.org/u/jtbandes)\
**Post date:** [January 14, 2017, 7:32am UTC](https://forums.swift.org/t/protocol-oriented-integers-take-2/4884/4 "2017-01-14T07:32:03Z")

</div>

Great work, all. I'm not sure I ever commented on SE-0104, so I've read  
through this one more carefully. Here are some things that came to mind:

\*## Arithmetic\*

Why are ExpressibleByIntegerLiteral and init?\<T:BinaryInteger\>(exactly:)  
required? I could understand needing access to 0, but this could be  
provided by a static property or nullary initializer. It doesn't seem like  
all types supporting arithmetic operations would necessarily be convertible  
from an arbitrary binary integer.

I tried to evaluate the Arithmetic protocol by considering what it means  
for higher-dimensional types such as CGPoint and CGVector. My use case was  
a linear interpolation function:

&nbsp;&nbsp;&nbsp;&nbsp;func lerp\<T: Arithmetic\>(from a: T, to b: T, by ratio: T) -\> T {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return a + (b - a) \* ratio  
&nbsp;&nbsp;&nbsp;&nbsp;}

If I've read the proposal correctly, this definition works for integer and  
floating-point values. But we can't make it work properly for CGVector (or,  
perhaps less mathematically correct but more familiar, CGPoint). It's okay  
to define +(CGVector, CGVector) and -(CGVector, CGVector), but \*(CGVector,  
CGVector) and /(CGVector, CGVector) don't make much sense. What we really  
want is \*(CGVector, \*CGFloat\*) and /(CGVector, \*CGFloat\*).

After consulting a mathematician, I believe what the lerp function really  
wants is for its generic param to be an affine space  
\<[https://en.wikipedia.org/wiki/Affine\_space&gt;\](https://en.wikipedia.org/wiki/Affine_space&gt;%5C). I explored this a bit here:  
[https://gist.github.com/jtbandes/93eeb7d5eee8e1a7245387c660d](https://gist.github.com/jtbandes/93eeb7d5eee8e1a7245387c660d)  
53b03#file-affine-swift-L16-L18

This approach is less restrictive and more composable than the proposed  
Arithmetic protocol, which can be viewed as a special case with the  
following definitions:

&nbsp;&nbsp;&nbsp;&nbsp;extension Arithmetic: AffineSpace, VectorSpace { // not actually  
allowed in Swift  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typealias Displacement = Self  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typealias Scalar = Self  
&nbsp;&nbsp;&nbsp;&nbsp;}

It'd be great to be able to define a lerp() which works for all  
floating-point and integer numbers, as well as points and vectors (assuming  
a glorious future where CGPoint and CGVector have built-in arithmetic  
operations). But maybe the complexity of these extra protocols isn't worth  
it for the stdlib...

\*## BinaryInteger\*

I'm a little confused by the presence of init(extendingOrTruncating:) for  
\*all\* binary integers. Why does it make sense to be able to write  
UInt16(extendingOrTruncating: (-21 as Int8)) ? In my mind, sign-extension  
only has meaning when the source and destination types are both signed.

Although I would not be against a clamp() function in the standard library,  
"init(clamping:)" sounds strange to me. What about calling it  
"init(nearestTo:)"? One could also define a FloatingPoint version of  
init(nearestTo:), i.e. lround(). For maximum annoyance and explicitness,  
you could even rename the existing init(\_:) to init(truncating:) to make it  
clear that truncation, not regular rounding, occurs when converting from  
floating-point.

\*... masking shifts\*

The example claims that "(30 as UInt8) &\>\> 11" produces 3, because it  
right-shifts 30 by 3. But isn't the bitWidth of UInt8 always 8 since it's a  
fixed-width type? Why should 11 get masked to 3 before the shift? (Also, it  
might be a good idea to choose examples with numbers whose base-ten  
representations don't look like valid binary. 😉) What use cases are there  
for masking shifts? I was under the impression that "smart shifts" were  
pretty much how the usual shift instructions already behaved.

(Minor: were the smart shift operators supposed to be included as  
BinaryInteger protocol requirements? I only see them in the "heterogeneous  
shifts" extension.)

\*... init\<T: BinaryInteger\>(\_ source: T)\*

Now a thought experiment: suppose you wanted to write an  
arbitrary-precision BigInt, or any binary integer such as Int256. The  
BinaryInteger protocol requires you to provide init\<T:BinaryInteger\>(\_  
source: T). Given the source of type T, how do you access its bits? Is  
repeated use of word(at:) the recommended way? If so, it might be nice to  
include a "wordCount" returning the number of available words; otherwise I  
suppose the user has to use something like bitWidth/(8\*MemoryLayout\<Int\>.size),  
which is pretty ugly.

\*## FixedWidthInteger\*

Why is popcount restricted to FixedWidthInteger? It seems like it could  
theoretically apply to any UnsignedInteger.

\*## Heterogenous shifts, equality, and comparison\*

These look great. How will the default implementations be provided?  
(Equivalent question: how would a user define their own heterogeneous  
operators?) I suppose this works:

&nbsp;&nbsp;&nbsp;&nbsp;static func &\>\> \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// delegate to the protocol requirement &\>\>(Self, Self)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return self &\>\> Self(extendingOrTruncating: rhs)  
&nbsp;&nbsp;&nbsp;&nbsp;}

But for operations you can't delegate so easily... I'm imagining trying to  
implement heterogeneous comparison (i.e. \< ) and the best I can come up  
with uses signum() and word(at:)...

Also, should these be protocol requirements so user-defined types can  
specialize them?

\*## Masking arithmetic\*

Do &\* and &+ and &- need their operands to have the same type, or could  
these be heterogeneous too (at least &+ and &-)?

Jacob

> **···**
>
> On Fri, Jan 13, 2017 at 12:47 PM, Max Moiseev via swift-evolution \< swift-evolution@swift.org\> wrote:
> 
> > Hi everyone,
> > 
> > Back in June 2016 we discussed the new design of the integer types for the  
> > standard library. It even resulted in acceptance of SE-0104  
> > \<[https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md&gt](https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md&gt); for  
> > Swift 3. Unfortunately we were not able to implement it in time for the  
> > release.
> > 
> > But it was not forgotten, although, as time went by, a few changes needed  
> > to be made in order to reflect the current state of the language.  
> > Without further introduction, please welcome the refined proposal to make  
> > integers in Swift more suitable for generic programming.
> > 
> > Available in this gist [m’s gists · GitHub](https://gist.github.com/m)  
> > oiseev/62ffe3c91b66866fdebf6f3fcc7cad8c and also inlined below.
> > 
> > Max

---

<div class="post-metadata">

**Author:** ![Rien](https://avatars.discourse-cdn.com/v4/letter/r/0ea827/32.png) [@Rien](https://forums.swift.org/u/Rien)\
**Post date:** [January 14, 2017, 8:00am UTC](https://forums.swift.org/t/protocol-oriented-integers-take-2/4884/5 "2017-01-14T08:00:06Z")

</div>

+1

Any change of including “ranged integers”?  
I.e. an integer with a value that must fit in a predefined range?

Regards,  
Rien

Site: [http://balancingrock.nl](http://balancingrock.nl)  
Blog: [http://swiftrien.blogspot.com](http://swiftrien.blogspot.com)  
Github: [Swiftrien (Rien) · GitHub](http://github.com/Swiftrien)  
Project: [http://swiftfire.nl](http://swiftfire.nl)

> **···**
>
> > On 13 Jan 2017, at 21:47, Max Moiseev via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > Hi everyone,
> > 
> > Back in June 2016 we discussed the new design of the integer types for the standard library. It even resulted in acceptance of SE-0104 for Swift 3. Unfortunately we were not able to implement it in time for the release.
> > 
> > But it was not forgotten, although, as time went by, a few changes needed to be made in order to reflect the current state of the language.  
> > Without further introduction, please welcome the refined proposal to make integers in Swift more suitable for generic programming.
> > 
> > Available in this gist [Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c) and also inlined below.
> > 
> > Max
> > 
> > Protocol-oriented integers (take 2)
> > 
> > &nbsp;&nbsp;• Proposal: SE-NNNN  
> > &nbsp;&nbsp;• Authors: Dave Abrahams, Maxim Moiseev  
> > &nbsp;&nbsp;• Review Manager: TBD  
> > &nbsp;&nbsp;• Status: Awaiting review  
> > &nbsp;&nbsp;• Bug: SR-3196  
> > &nbsp;&nbsp;• Previous Proposal: SE-0104  
> > Introduction
> > 
> > This proposal is an evolution of SE-0104. The goal is still to clean up Swifts integer APIs and make them more useful for generic programming.
> > 
> > The language has evolved in ways that affect integers APIs since the time the original proposal was approved for Swift 3. We also attempted to implement the proposed model in the standard library and found that some essential APIs were missing, whereas others could be safely removed.
> > 
> > Major changes to the APIs introduced by this proposal (as compared to SE-0104) are listed in a dedicated section.
> > 
> > Motivation
> > 
> > Swift's integer protocols don't currently provide a suitable basis for generic programming. See this blog post for an example of an attempt to implement a generic algorithm over integers.
> > 
> > The way the Arithmetic protocol is defined, it does not generalize to floating point numbers and also slows down compilation by requiring every concrete type to provide an implementation of arithmetic operators, thus polluting the overload set.
> > 
> > Converting from one integer type to another is performed using the concept of the 'maximum width integer' (see MaxInt), which is an artificial limitation. The very existence of MaxInt makes it unclear what to do should someone implement Int256, for example.
> > 
> > Another annoying problem is the inability to use integers of different types in comparison and bit-shift operations. For example, the following snippets won't compile:
> > 
> > var x: Int8 = 42  
> > let y = 1  
> > let z = 0
> > 
> > x  
> > \<\<= y // error: binary operator '\<\<=' cannot be applied to operands of type 'Int8' and 'Int'  
> > if x \> z { ... } // error: binary operator '\>' cannot be applied to operands of type 'Int8' and 'Int'  
> > Currently, bit-shifting a negative number of (or too many) bits causes a trap on some platforms, which makes low-level bit manipulations needlessly dangerous and unpredictable.
> > 
> > Finally, the current design predates many of the improvements that came since Swift 1, and hasn't been revised since then.
> > 
> > Proposed solution
> > 
> > We propose a new model that does not have above mentioned problems and is more easily extensible.
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+--------------+ +-------------+  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+------\>+ Arithmetic | | Comparable |  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \> (+,-,\*,/) | | (==,\<,\>,...)|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> +-------------++ +---+---------+  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> ^ ^  
> > +-------+------------+ | |  
> > \> SignedArithmetic | +-+-------+-----------+  
> > \> (unary -) | | BinaryInteger |  
> > +------+-------------+ |(words,%,bitwise,...)|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^ ++---+-----+----------+  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> +-----------^ ^ ^---------------+  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \> \> \>  
> > +------+---------++ +---------+---------------+ +--+----------------+  
> > \> SignedInteger | | FixedWidthInteger | | UnsignedInteger |  
> > \> \> \>(endianness,overflow,...)| | |  
> > +---------------+-+ +-+--------------------+--+ +-+-----------------+  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^ ^ ^ ^  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \> \> \>  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \> \> \>  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++--------+-+ +-+-------+-+  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\>Int family |-+ |UInt family|-+  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+-----------+ | +-----------+ |  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+-----------+ +-----------+
> > 
> > There are several benefits provided by this model over the old one:
> > 
> > &nbsp;&nbsp;• It allows mixing integer types in generic functions.
> > 
> > The possibility to initialize instances of any concrete integer type with values of any other concrete integer type enables writing functions that operate on more than one type conforming to BinaryInteger, such as heterogeneous comparisons or bit shifts, described later.
> > 
> > &nbsp;&nbsp;• It removes the overload resolution overhead.
> > 
> > Arithmetic and bitwise operations can now be defined as generic operators on protocols. This approach significantly reduces the number of overloads for those operations, which used to be defined for every single concrete integer type.
> > 
> > &nbsp;&nbsp;• It enables protocol sharing between integer and floating point types.
> > 
> > Note the exclusion of the % operation from Arithmetic. Its behavior for floating point numbers is sufficiently different from the one for integers that using it in generic context would lead to confusion. The FloatingPoint protocol introduced by SE-0067 should now refine SignedArithmetic.
> > 
> > &nbsp;&nbsp;• It makes future extensions possible.
> > 
> > The proposed model eliminates the 'largest integer type' concept previously used to interoperate between integer types (see toIntMax in the current model) and instead provides access to machine words. It also introduces thedoubleWidthMultiply, doubleWidthDivide, and quotientAndRemainder methods. Together these changes can be used to provide an efficient implementation of bignums that would be hard to achieve otherwise.
> > 
> > The implementation of proposed model in the standard library is available in the new-integer-protocols branch.
> > 
> > A note on bit shifts
> > 
> > This proposal introduces the concepts of smart shifts and masking shifts.
> > 
> > The semantics of shift operations are often undefined in under- or over-shift cases. Smart shifts, implemented by \>\> and \<\<, are designed to address this problem and always behave in a well defined way, as shown in the examples below:
> > 
> > &nbsp;&nbsp;• x \<\< -2 is equivalent to x \>\> 2
> > 
> > &nbsp;&nbsp;• (1 as UInt8) \>\> 42) will evaluate to 0
> > 
> > &nbsp;&nbsp;• (-128 as Int8) \>\> 42) will evaluate to 0xff or -1
> > 
> > In most scenarios, the right hand operand is a literal constant, and branches for handling under- and over-shift cases can be optimized away. For other cases, this proposal provides masking shifts, implemented by &\>\> and &\<\<. A masking shift logically preprocesses the right hand operand by masking its bits to produce a value in the range 0...(x-1) where x is the number of bits in the left hand operand. On most architectures this masking is already performed by the CPU's shift instructions and has no cost. Both kinds of shift avoid undefined behavior and produce uniform semantics across architectures.
> > 
> > Detailed design
> > 
> > What's new since SE-0104
> > 
> > &nbsp;&nbsp;• SE-0091 removed the necessity to dispatch generic operators through special methods.
> > 
> > All operators are now declared by protocols as static funcs.
> > 
> > &nbsp;&nbsp;• Standard Library no longer provides + and - operators for Strideable types.
> > 
> > They were problematic, as one could have written mixed-type code like let x: Int64 = 42; x += (1 as Int), which would compile, but shouldn't. Besides, since the Stride of an unsigned type is signed, Standard Library had to implement a hack to make code like let x: UInt = 42; x += (1 as Int) ambiguous. These operators were only necessary because they made advancing collection indices convenient, which is no longer the case since the introduction of the new indexing model in Swift 3.
> > 
> > &nbsp;&nbsp;• Shifts and other bitwise operations were moved from FixedWidthInteger to BinaryInteger.
> > 
> > Left shift operation on an unbounded integer should infinitely extend the number, and never drop set bits when they reach the most significant position in the underlying representation.
> > 
> > &nbsp;&nbsp;• BitwiseOperations protocol was deprecated.
> > 
> > We believe there are no useful entities that support bitwise operations, but at the same time are not binary integers.
> > 
> > &nbsp;&nbsp;• minimumSignedRepresentationBitWidth property was removed.
> > 
> > &nbsp;&nbsp;• trailingZeros property was added to the BinaryInteger protocol.
> > 
> > leadingZeros and popcount properties are still defined by the FixedWidthInteger protocol.
> > 
> > &nbsp;&nbsp;• Endian-converting initializers and properties were added to the FixedWidthInteger protocol.
> > 
> > &nbsp;&nbsp;• Standard library introduces the new type DoubleWidth\<T\>.
> > 
> > See this section for more details.
> > 
> > Protocols
> > 
> > Arithmetic
> > 
> > The Arithmetic protocol declares binary arithmetic operators – such as +, -, and \* — and their mutating counterparts.
> > 
> > It provides a suitable basis for arithmetic on scalars such as integers and floating point numbers.
> > 
> > Both mutating and non-mutating operations are declared in the protocol, however only the mutating ones are required, as default implementations of the non-mutating ones are provided by a protocol extension.
> > 
> > The Magnitude associated type is able to hold the absolute value of any possible value of Self. Concrete types do not have to provide a type alias for it, as it can be inferred from the magnitude property. This property can be useful in operations that are simpler to implement in terms of unsigned values, for example, printing a value of an integer, which is just printing a '-' character in front of an absolute value.
> > 
> > Please note that for ordinary work, the magnitude property should not be preferred to the abs(\_) function, whose return value is of the same type as its argument.
> > 
> > public protocol Arithmetic : Equatable, ExpressibleByIntegerLiteral  
> > {  
> > &nbsp;&nbsp;  
> > /// Creates a new instance from the given integer, if it can be represented  
> > &nbsp;&nbsp;/// exactly.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// If the value passed as `source` is not representable exactly, the result  
> > &nbsp;&nbsp;/// is `nil`. In the following example, the constant `x` is successfully  
> > &nbsp;&nbsp;/// created from a value of `100`, while the attempt to initialize the  
> > &nbsp;&nbsp;/// constant `y` from `1_000` fails because the `Int8` type can represent  
> > &nbsp;&nbsp;/// `127` at maximum:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = Int8(exactly: 100)  
> > &nbsp;&nbsp;/// // x == Optional(100)  
> > &nbsp;&nbsp;/// let y = Int8(exactly: 1\_000)  
> > &nbsp;&nbsp;/// // y == nil  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter source: A floating-point value to convert to an integer.  
> > &nbsp;&nbsp;init?\<T : BinaryInteger\>(exactly source  
> > : T)
> > 
> > /// A type that can represent the absolute value of any possible value of the  
> > &nbsp;&nbsp;/// conforming type.  
> > &nbsp;&nbsp;associatedtype Magnitude : Equatable, ExpressibleByIntegerLiteral
> > 
> > /// The magnitude of this value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For any numeric value `x`, `x.magnitude` is the absolute value of `x`.  
> > &nbsp;&nbsp;/// You can use the `magnitude` property in operations that are simpler to  
> > &nbsp;&nbsp;/// implement in terms of unsigned values, such as printing the value of an  
> > &nbsp;&nbsp;/// integer, which is just printing a '-' character in front of an absolute  
> > &nbsp;&nbsp;/// value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = -200  
> > &nbsp;&nbsp;/// // x.magnitude == 200  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The global `abs(_:)` function provides more familiar syntax when you need  
> > &nbsp;&nbsp;/// to find an absolute value. In addition, because `abs(_:)` always returns  
> > &nbsp;&nbsp;/// a value of the same type, even in a generic context, using the function  
> > &nbsp;&nbsp;/// instead of the `magnitude` property is encouraged.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `abs(_:)`  
> > &nbsp;&nbsp;var magnitude: Magnitude { get  
> > }
> > 
> > /// Returns the sum of the two given values.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The sum of `lhs` and `rhs` must be representable in the same type. In the  
> > &nbsp;&nbsp;/// following example, the result of `100 + 200` is greater than the maximum  
> > &nbsp;&nbsp;/// representable `Int8` value:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: Int8 = 10 + 21  
> > &nbsp;&nbsp;/// // x == 31  
> > &nbsp;&nbsp;/// let y: Int8 = 100 + 121  
> > &nbsp;&nbsp;/// // Overflow error  
> > &nbsp;&nbsp;static func +(\_ lhs: Self, \_ rhs: Self) -\> Self
> > 
> > /// Adds the given value to this value in place.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For example:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// var x = 15  
> > &nbsp;&nbsp;/// y += 7  
> > &nbsp;&nbsp;/// // y == 22  
> > &nbsp;&nbsp;static func +=(\_ lhs: inout Self, rhs: Self  
> > )
> > 
> > /// Returns the difference of the two given values.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The difference of `lhs` and `rhs` must be representable in the same type.  
> > &nbsp;&nbsp;/// In the following example, the result of `10 - 21` is less than zero, the  
> > &nbsp;&nbsp;/// minimum representable `UInt` value:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt = 21 - 10  
> > &nbsp;&nbsp;/// // x == 11  
> > &nbsp;&nbsp;/// let y: UInt = 10 - 21  
> > &nbsp;&nbsp;/// // Overflow error  
> > &nbsp;&nbsp;static func -(\_ lhs: Self, \_ rhs: Self) -\> Self
> > 
> > /// Subtracts the given value from this value in place.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For example:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// var x = 15  
> > &nbsp;&nbsp;/// y -= 7  
> > &nbsp;&nbsp;/// // y == 8  
> > &nbsp;&nbsp;static func -=(\_ lhs: inout Self, rhs: Self  
> > )
> > 
> > /// Returns the product of the two given values.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The product of `lhs` and `rhs` must be representable in the same type. In  
> > &nbsp;&nbsp;/// the following example, the result of `10 * 50` is greater than the  
> > &nbsp;&nbsp;/// maximum representable `Int8` value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: Int8 = 10 \* 5  
> > &nbsp;&nbsp;/// // x == 50  
> > &nbsp;&nbsp;/// let y: Int8 = 10 \* 50  
> > &nbsp;&nbsp;/// // Overflow error  
> > &nbsp;&nbsp;static func \*(\_ lhs: Self, \_ rhs: Self) -\> Self
> > 
> > /// Multiples this value by the given value in place.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For example:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// var x = 15  
> > &nbsp;&nbsp;/// y \*= 7  
> > &nbsp;&nbsp;/// // y == 105  
> > &nbsp;&nbsp;static func \*=(\_ lhs: inout Self, rhs: Self  
> > )
> > 
> > /// Returns the quotient of dividing the first value by the second.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For integer types, any remainder of the division is discarded.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = 21 / 5  
> > &nbsp;&nbsp;/// // x == 4  
> > &nbsp;&nbsp;static func /(\_ lhs: Self, \_ rhs: Self) -\> Self
> > 
> > /// Divides this value by the given value in place.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For example:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// var x = 15  
> > &nbsp;&nbsp;/// y /= 7  
> > &nbsp;&nbsp;/// // y == 2  
> > &nbsp;&nbsp;static func /=(\_ lhs: inout Self, rhs: Self  
> > )  
> > }
> > 
> > extension Arithmetic  
> > {  
> > &nbsp;&nbsp;  
> > public init() { self = 0  
> > }
> > 
> > public static prefix func + (x: Self) -\> Self  
> > {  
> > &nbsp;&nbsp;&nbsp;&nbsp;  
> > return  
> > x  
> > &nbsp;&nbsp;}  
> > }
> > 
> > SignedArithmetic
> > 
> > The SignedArithmetic protocol is for numbers that can be negated.
> > 
> > public protocol SignedArithmetic : Arithmetic  
> > {  
> > &nbsp;&nbsp;  
> > /// Returns the additive inverse of this value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = 21  
> > &nbsp;&nbsp;/// let y = -x  
> > &nbsp;&nbsp;/// // y == -21  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Returns: The additive inverse of this value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `negate()`  
> > &nbsp;&nbsp;static prefix func - (\_ operand: Self) -\> Self
> > 
> > /// Replaces this value with its additive inverse.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The following example uses the `negate()` method to negate the value of  
> > &nbsp;&nbsp;/// an integer `x`:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// var x = 21  
> > &nbsp;&nbsp;/// x.negate()  
> > &nbsp;&nbsp;/// // x == -21  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: The unary minus operator (`-`).  
> > &nbsp;&nbsp;mutating func negate  
> > ()  
> > }
> > 
> > extension SignedArithmetic  
> > {  
> > &nbsp;&nbsp;  
> > public static prefix func - (\_ operand: Self) -\> Self  
> > {  
> > &nbsp;&nbsp;&nbsp;&nbsp;  
> > var result =  
> > operand  
> > &nbsp;&nbsp;&nbsp;&nbsp;result.  
> > negate  
> > ()  
> > &nbsp;&nbsp;&nbsp;&nbsp;  
> > return  
> > result  
> > &nbsp;&nbsp;}
> > 
> > public mutating func negate  
> > () {  
> > &nbsp;&nbsp;&nbsp;&nbsp;  
> > self = Self() - self
> > 
> > &nbsp;&nbsp;}  
> > }
> > 
> > BinaryInteger
> > 
> > The BinaryInteger protocol is the basis for all the integer types provided by the standard library.
> > 
> > This protocol adds a few new initializers. Two of them allow to create integers from floating point numbers, others support construction from instances of any type conforming to BinaryInteger, using different strategies:
> > 
> > &nbsp;&nbsp;• Initialize Self with the value, provided that the value is representable. The precondition should be satisfied by the caller.
> > 
> > &nbsp;&nbsp;• Extend or truncate the value to fit into Self
> > 
> > &nbsp;&nbsp;• Clamp the value to the representable range of Self
> > 
> > BinaryInteger also declares bitwise and shift operators.
> > 
> > public protocol BinaryInteger :  
> > &nbsp;&nbsp;Comparable, Hashable, Arithmetic, CustomStringConvertible, Strideable  
> > {
> > 
> > /// A Boolean value indicating whether this type is a signed integer type.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// \*Signed\* integer types can represent both positive and negative values.  
> > &nbsp;&nbsp;/// \*Unsigned\* integer types can represent only nonnegative values.  
> > &nbsp;&nbsp;static var isSigned: Bool { get  
> > }
> > 
> > /// Creates an integer from the given floating-point value, if it can be  
> > &nbsp;&nbsp;/// represented exactly.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// If the value passed as `source` is not representable exactly, the result  
> > &nbsp;&nbsp;/// is `nil`. In the following example, the constant `x` is successfully  
> > &nbsp;&nbsp;/// created from a value of `21.0`, while the attempt to initialize the  
> > &nbsp;&nbsp;/// constant `y` from `21.5` fails:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = Int(exactly: 21.0)  
> > &nbsp;&nbsp;/// // x == Optional(21)  
> > &nbsp;&nbsp;/// let y = Int(exactly: 21.5)  
> > &nbsp;&nbsp;/// // y == nil  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter source: A floating-point value to convert to an integer.  
> > &nbsp;&nbsp;init?\<T : FloatingPoint\>(exactly source  
> > : T)
> > 
> > /// Creates an integer from the given floating-point value, truncating any  
> > &nbsp;&nbsp;/// fractional part.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// Truncating the fractional part of `source` is equivalent to rounding  
> > &nbsp;&nbsp;/// toward zero.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = Int(21.5)  
> > &nbsp;&nbsp;/// // x == 21  
> > &nbsp;&nbsp;/// let y = Int(-21.5)  
> > &nbsp;&nbsp;/// // y == -21  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// If `source` is outside the bounds of this type after truncation, a  
> > &nbsp;&nbsp;/// runtime error may occur.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let z = UInt(-21.5)  
> > &nbsp;&nbsp;/// // Error: ...the result would be less than UInt.min  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter source: A floating-point value to convert to an integer.  
> > &nbsp;&nbsp;/// `source` must be representable in this type after truncation.  
> > &nbsp;&nbsp;init\<T : FloatingPoint\>(\_ source  
> > : T)
> > 
> > /// Creates an new instance from the given integer.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// If the value passed as `source` is not representable in this type, a  
> > &nbsp;&nbsp;/// runtime error may occur.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = -500 as Int  
> > &nbsp;&nbsp;/// let y = Int32(x)  
> > &nbsp;&nbsp;/// // y == -500  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// // -500 is not representable as a 'UInt32' instance  
> > &nbsp;&nbsp;/// let z = UInt32(x)  
> > &nbsp;&nbsp;/// // Error  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter source: An integer to convert. `source` must be representable  
> > &nbsp;&nbsp;/// in this type.  
> > &nbsp;&nbsp;init\<T : BinaryInteger\>(\_ source  
> > : T)
> > 
> > /// Creates a new instance from the bit pattern of the given instance by  
> > &nbsp;&nbsp;/// sign-extending or truncating to fit this type.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// When the bit width of `T` (the type of `source`) is equal to or greater  
> > &nbsp;&nbsp;/// than this type's bit width, the result is the truncated  
> > &nbsp;&nbsp;/// least-significant bits of `source`. For example, when converting a  
> > &nbsp;&nbsp;/// 16-bit value to an 8-bit type, only the lower 8 bits of `source` are  
> > &nbsp;&nbsp;/// used.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let p: Int16 = -500  
> > &nbsp;&nbsp;/// // 'p' has a binary representation of 11111110\_00001100  
> > &nbsp;&nbsp;/// let q = Int8(extendingOrTruncating: p)  
> > &nbsp;&nbsp;/// // q == 12  
> > &nbsp;&nbsp;/// // 'q' has a binary representation of 00001100  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// When the bit width of `T` is less than this type's bit width, the result  
> > &nbsp;&nbsp;/// is \*sign-extended\* to fill the remaining bits. That is, if `source` is  
> > &nbsp;&nbsp;/// negative, the result is padded with ones; otherwise, the result is  
> > &nbsp;&nbsp;/// padded with zeros.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let u: Int8 = 21  
> > &nbsp;&nbsp;/// // 'u' has a binary representation of 00010101  
> > &nbsp;&nbsp;/// let v = Int16(extendingOrTruncating: u)  
> > &nbsp;&nbsp;/// // v == 21  
> > &nbsp;&nbsp;/// // 'v' has a binary representation of 00000000\_00010101  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let w: Int8 = -21  
> > &nbsp;&nbsp;/// // 'w' has a binary representation of 11101011  
> > &nbsp;&nbsp;/// let x = Int16(extendingOrTruncating: w)  
> > &nbsp;&nbsp;/// // x == -21  
> > &nbsp;&nbsp;/// // 'x' has a binary representation of 11111111\_11101011  
> > &nbsp;&nbsp;/// let y = UInt16(extendingOrTruncating: w)  
> > &nbsp;&nbsp;/// // y == 65515  
> > &nbsp;&nbsp;/// // 'y' has a binary representation of 11111111\_11101011  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter source: An integer to convert to this type.  
> > &nbsp;&nbsp;init\<T : BinaryInteger\>(extendingOrTruncating source  
> > : T)
> > 
> > /// Creates a new instance with the representable value that's closest to the  
> > &nbsp;&nbsp;/// given integer.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// If the value passed as `source` is greater than the maximum representable  
> > &nbsp;&nbsp;/// value in this type, the result is the type's `max` value. If `source` is  
> > &nbsp;&nbsp;/// less than the smallest representable value in this type, the result is  
> > &nbsp;&nbsp;/// the type's `min` value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// In this example, `x` is initialized as an `Int8` instance by clamping  
> > &nbsp;&nbsp;/// `500` to the range `-128...127`, and `y` is initialized as a `UInt`  
> > &nbsp;&nbsp;/// instance by clamping `-500` to the range `0...UInt.max`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = Int8(clamping: 500)  
> > &nbsp;&nbsp;/// // x == 127  
> > &nbsp;&nbsp;/// // x == Int8.max  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let y = UInt(clamping: -500)  
> > &nbsp;&nbsp;/// // y == 0  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter source: An integer to convert to this type.  
> > &nbsp;&nbsp;init\<T : BinaryInteger\>(clamping source  
> > : T)
> > 
> > /// Returns the n-th word, counting from the least significant to most  
> > &nbsp;&nbsp;/// significant, of this value's binary representation.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The `word(at:)` method returns negative values in two's complement  
> > &nbsp;&nbsp;/// representation, regardless of a type's underlying implementation. If `n`  
> > &nbsp;&nbsp;/// is greater than the number of words in this value's current  
> > &nbsp;&nbsp;/// representation, the result is `0` for positive numbers and `~0` for  
> > &nbsp;&nbsp;/// negative numbers.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter n: The word to return, counting from the least significant to  
> > &nbsp;&nbsp;/// most significant. `n` must be greater than or equal to zero.  
> > &nbsp;&nbsp;/// - Returns: An word-sized, unsigned integer with the bit pattern of the  
> > &nbsp;&nbsp;/// n-th word of this value.  
> > &nbsp;&nbsp;func word(at n: Int) -\> UInt
> > 
> > /// The number of bits in the current binary representation of this value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// This property is a constant for instances of fixed-width integer  
> > &nbsp;&nbsp;/// types.  
> > &nbsp;&nbsp;var bitWidth : Int { get  
> > }
> > 
> > /// The number of trailing zeros in this value's binary representation.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For example, in a fixed-width integer type with a `bitWidth` value of 8,  
> > &nbsp;&nbsp;/// the number -8 has three trailing zeros.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = Int8(bitPattern: 0b1111\_1000)  
> > &nbsp;&nbsp;/// // x == -8  
> > &nbsp;&nbsp;/// // x.trailingZeros == 3  
> > &nbsp;&nbsp;var trailingZeros: Int { get  
> > }
> > 
> > /// Returns the remainder of dividing the first value by the second.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The result has the same sign as `lhs` and is less than `rhs.magnitude`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = 22 % 5  
> > &nbsp;&nbsp;/// // x == 2  
> > &nbsp;&nbsp;/// let y = 22 % -5  
> > &nbsp;&nbsp;/// // y == 2  
> > &nbsp;&nbsp;/// let z = -22 % -5  
> > &nbsp;&nbsp;/// // z == -2  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameters:  
> > &nbsp;&nbsp;/// - lhs: The value to divide.  
> > &nbsp;&nbsp;/// - rhs: The value to divide `lhs` by. `rhs` must not be zero.  
> > &nbsp;&nbsp;static func %(\_ lhs: Self, \_ rhs: Self) -\> Self
> > 
> > /// Replaces this value with the remainder of itself divided by the given  
> > &nbsp;&nbsp;/// value. For example:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// var x = 15  
> > &nbsp;&nbsp;/// x %= 7  
> > &nbsp;&nbsp;/// // x == 1  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter rhs: The value to divide this value by. `rhs` must not be  
> > &nbsp;&nbsp;/// zero.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `remainder(dividingBy:)`  
> > &nbsp;&nbsp;static func %=(\_ lhs: inout Self, \_ rhs: Self  
> > )
> > 
> > /// Returns the inverse of the bits set in the argument.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The bitwise NOT operator (`~`) is a prefix operator that returns a value  
> > &nbsp;&nbsp;/// in which all the bits of its argument are flipped: Bits that are `1` in  
> > &nbsp;&nbsp;/// the argument are `0` in the result, and bits that are `0` in the argument  
> > &nbsp;&nbsp;/// are `1` in the result. This is equivalent to the inverse of a set. For  
> > &nbsp;&nbsp;/// example:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt8 = 5 // 0b00000101  
> > &nbsp;&nbsp;/// let notX = ~x // 0b11111010  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// Performing a bitwise NOT operation on 0 returns a value with every bit  
> > &nbsp;&nbsp;/// set to `1`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let allOnes = ~UInt8.min // 0b11111111  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Complexity: O(1).  
> > &nbsp;&nbsp;static prefix func ~ (\_ x: Self) -\> Self
> > 
> > /// Returns the result of performing a bitwise AND operation on this value  
> > &nbsp;&nbsp;/// and the given value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// A bitwise AND operation results in a value that has each bit set to `1`  
> > &nbsp;&nbsp;/// where \*both\* of its arguments have that bit set to `1`. For example:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt8 = 5 // 0b00000101  
> > &nbsp;&nbsp;/// let y: UInt8 = 14 // 0b00001110  
> > &nbsp;&nbsp;/// let z = x & y // 0b00000100  
> > &nbsp;&nbsp;static func &(\_ lhs: Self, \_ rhs: Self) -\> Self
> > 
> > static func &=(\_ lhs: inout Self, \_ rhs: Self  
> > )
> > 
> > /// Returns the result of performing a bitwise OR operation on this value and  
> > &nbsp;&nbsp;/// the given value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// A bitwise OR operation results in a value that has each bit set to `1`  
> > &nbsp;&nbsp;/// where \*one or both\* of its arguments have that bit set to `1`. For  
> > &nbsp;&nbsp;/// example:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt8 = 5 // 0b00000101  
> > &nbsp;&nbsp;/// let y: UInt8 = 14 // 0b00001110  
> > &nbsp;&nbsp;/// let z = x | y // 0b00001111  
> > &nbsp;&nbsp;static func |(\_ lhs: Self, \_ rhs: Self) -\> Self
> > 
> > static func |=(\_ lhs: inout Self, \_ rhs: Self  
> > )
> > 
> > /// Returns the result of performing a bitwise XOR operation on this value  
> > &nbsp;&nbsp;/// and the given value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// A bitwise XOR operation, also known as an exclusive OR operation, results  
> > &nbsp;&nbsp;/// in a value that has each bit set to `1` where \*one or the other but not  
> > &nbsp;&nbsp;/// both\* of its arguments had that bit set to `1`. For example:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt8 = 5 // 0b00000101  
> > &nbsp;&nbsp;/// let y: UInt8 = 14 // 0b00001110  
> > &nbsp;&nbsp;/// let z = x ^ y // 0b00001011  
> > &nbsp;&nbsp;static func ^(\_ lhs: Self, \_ rhs: Self) -\> Self
> > 
> > static func ^=(\_ lhs: inout Self, \_ rhs: Self  
> > )
> > 
> > /// Returns the result of shifting this value's binary representation the  
> > &nbsp;&nbsp;/// specified number of digits to the right.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// In a \*masking shift\*, the bit pattern of the value passed as `rhs` is  
> > &nbsp;&nbsp;/// masked to produce a value between zero and the bit width of `lhs`. The  
> > &nbsp;&nbsp;/// shift is performed using this masked value. Masking shifts require more  
> > &nbsp;&nbsp;/// care to use correctly than a traditional bit shift, but are likely to be  
> > &nbsp;&nbsp;/// more efficient when used with shift amounts that are not compile-time  
> > &nbsp;&nbsp;/// constants. On most architectures, a masking shift compiles down to a  
> > &nbsp;&nbsp;/// single instruction.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For example, if you shift an 8-bit, unsigned integer by 2, the shift  
> > &nbsp;&nbsp;/// amount requires no masking.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt8 = 30 // 0b00011110  
> > &nbsp;&nbsp;/// let y = x &\>\> 2  
> > &nbsp;&nbsp;/// // y == 7 // 0b00000111  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// However, if you shift it by 11, it first bitmasks `rhs` to `3`, and then  
> > &nbsp;&nbsp;/// uses that masked value as the number of bits to shift `x`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let z = x &\>\> 11  
> > &nbsp;&nbsp;/// // z == 3 // 0b00000011  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// Relationship to the Right Shift Operator  
> > &nbsp;&nbsp;/// ----------------------------------------  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The masking right shift operator handles attempted overshifts and  
> > &nbsp;&nbsp;/// undershifts differently from the right shift operator (`\>\>`). When the  
> > &nbsp;&nbsp;/// value passed as `rhs` in a masking shift is within the range  
> > &nbsp;&nbsp;/// `0...\<bitWidth`, the operation is equivalent to using the right shift  
> > &nbsp;&nbsp;/// operator.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt8 = 30 // 0b00011110  
> > &nbsp;&nbsp;/// let y1 = x &\>\> 2  
> > &nbsp;&nbsp;/// // y1 == 7 // 0b00000111  
> > &nbsp;&nbsp;/// let y2 = x \>\> 2  
> > &nbsp;&nbsp;/// // y2 == 7 // 0b00000111  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The right shift operator does not mask its right-hand-side argument, so  
> > &nbsp;&nbsp;/// passing `11` as `rhs` shifts all the bits of `x` to zero.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let z1 = x &\>\> 11  
> > &nbsp;&nbsp;/// // z1 == 240 // 0b00000011  
> > &nbsp;&nbsp;/// let z2 = x \>\> 11  
> > &nbsp;&nbsp;/// // z2 == 0 // 0b00000000  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter rhs: The number of bits to shift this value to the right. If  
> > &nbsp;&nbsp;/// `rhs` is outside the range `0..\<bitWidth`, it is masked to produce a  
> > &nbsp;&nbsp;/// value within that range.  
> > &nbsp;&nbsp;/// - Returns: The result of shifting this value by the masked `rhs` to the  
> > &nbsp;&nbsp;/// right.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `&\<\<`, `\>\>`  
> > &nbsp;&nbsp;static func &\>\>(\_ lhs: Self, \_ rhs: Self) -\> Self
> > 
> > static func &\>\>=(\_ lhs: inout Self, \_ rhs: Self  
> > )
> > 
> > /// Returns the result of shifting this value's binary representation the  
> > &nbsp;&nbsp;/// specified number of digits to the left.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// In a \*masking shift\*, the bit pattern of the value passed as `rhs` is  
> > &nbsp;&nbsp;/// masked to produce a value between zero and the bit width of `lhs`. The  
> > &nbsp;&nbsp;/// shift is performed using this masked value. Masking shifts require more  
> > &nbsp;&nbsp;/// care to use correctly than a traditional bit shift, but are likely to be  
> > &nbsp;&nbsp;/// more efficient when used with shift amounts that are not compile-time  
> > &nbsp;&nbsp;/// constants. On most architectures, a masking shift compiles down to a  
> > &nbsp;&nbsp;/// single instruction.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For example, if you shift an 8-bit, unsigned integer by 2, the shift  
> > &nbsp;&nbsp;/// amount requires no masking.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt8 = 30 // 0b00011110  
> > &nbsp;&nbsp;/// let y = x &\>\> 2  
> > &nbsp;&nbsp;/// // y == 120 // 0b01111000  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// However, if you shift it by 11, it first bitmasks `rhs` to `3`, and then  
> > &nbsp;&nbsp;/// uses that masked value as the number of bits to shift `x`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let z = x &\<\< 11  
> > &nbsp;&nbsp;/// // z == 240 // 0b11110000  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// Relationship to the Left Shift Operator  
> > &nbsp;&nbsp;/// ---------------------------------------  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The masking left shift operator handles attempted overshifts and  
> > &nbsp;&nbsp;/// undershifts differently from the left shift operator (`\<\<`). When the  
> > &nbsp;&nbsp;/// value passed as `rhs` in a masking shift is within the range  
> > &nbsp;&nbsp;/// `0...\<bitWidth`, the operation is equivalent to using the left shift  
> > &nbsp;&nbsp;/// operator.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt8 = 30 // 0b00011110  
> > &nbsp;&nbsp;/// let y1 = x &\<\< 2  
> > &nbsp;&nbsp;/// // y1 == 120 // 0b01111000  
> > &nbsp;&nbsp;/// let y2 = x \<\< 2  
> > &nbsp;&nbsp;/// // y2 == 120 // 0b01111000  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The left shift operator does not mask its right-hand-side argument, so  
> > &nbsp;&nbsp;/// passing `11` as `rhs` shifts all the bits of `x` to zero.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let z1 = x &\<\< 11  
> > &nbsp;&nbsp;/// // z1 == 240 // 0b11110000  
> > &nbsp;&nbsp;/// let z2 = x \<\< 11  
> > &nbsp;&nbsp;/// // z2 == 0 // 0b00000000  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter rhs: The number of bits to shift this value to the left. If  
> > &nbsp;&nbsp;/// `rhs` is outside the range `0..\<bitWidth`, it is masked to produce a  
> > &nbsp;&nbsp;/// value within that range.  
> > &nbsp;&nbsp;/// - Returns: The result of shifting this value by the masked `rhs` to the  
> > &nbsp;&nbsp;/// left.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `&\>\>`, `\<\<`  
> > &nbsp;&nbsp;static func &\<\<(\_ lhs: Self, \_ rhs: Self) -\> Self
> > 
> > static func &\<\<=(\_ lhs: inout Self, \_ rhs: Self  
> > )
> > 
> > /// Returns the quotient and remainder of this value divided by the given  
> > &nbsp;&nbsp;/// value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// Use this method to calculate the quotient and remainder of a division at  
> > &nbsp;&nbsp;/// the same time.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = 1\_000\_000  
> > &nbsp;&nbsp;/// let (q, r) = x.quotientAndRemainder(dividingBy: 933)  
> > &nbsp;&nbsp;/// // q == 1071  
> > &nbsp;&nbsp;/// // r == 757  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter rhs: The value to divide this value by.  
> > &nbsp;&nbsp;/// - Returns: A tuple containing the quotient and remainder of this value  
> > &nbsp;&nbsp;/// divided by `rhs`.  
> > &nbsp;&nbsp;func quotientAndRemainder(dividingBy rhs: Self  
> > )  
> > &nbsp;&nbsp;&nbsp;&nbsp;  
> > -\> (quotient: Self, remainder: Self  
> > )
> > 
> > /// Returns `-1` if this value is negative and `1` if it's positive;  
> > &nbsp;&nbsp;/// otherwise, `0`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Returns: The sign of this number, expressed as an integer of the same  
> > &nbsp;&nbsp;/// type.  
> > &nbsp;&nbsp;func signum() -\> Self
> > 
> > }
> > 
> > FixedWidthInteger
> > 
> > The FixedWidthInteger protocol adds the notion of endianness as well as static properties for type bounds and bit width.
> > 
> > The WithOverflow family of methods is used in default implementations of mutating arithmetic methods (see the Arithmetic protocol). Having these methods allows the library to provide both bounds-checked and masking implementations of arithmetic operations, without duplicating code.
> > 
> > The doubleWidthMultiply and doubleWidthDivide methods are necessary building blocks to implement support for integer types of a greater width such as arbitrary-precision integers.
> > 
> > public protocol FixedWidthInteger : BinaryInteger  
> > {  
> > &nbsp;&nbsp;  
> > /// The number of bits used for the underlying binary representation of  
> > &nbsp;&nbsp;/// values of this type.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// An unsigned, fixed-width integer type can represent values from 0 through  
> > &nbsp;&nbsp;/// `(2 **bitWidth) - 1`, where `**` is exponentiation. A signed,  
> > &nbsp;&nbsp;/// fixed-width integer type can represent values from  
> > &nbsp;&nbsp;/// `-(2 **bitWidth - 1)` through `(2** bitWidth - 1) - 1`. For example,  
> > &nbsp;&nbsp;/// the `Int8` type has a `bitWidth` value of 8 and can store any integer in  
> > &nbsp;&nbsp;/// the range `-128...127`.  
> > &nbsp;&nbsp;static var bitWidth : Int { get  
> > }
> > 
> > /// The maximum representable integer in this type.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For unsigned integer types, this value is `(2 ** bitWidth) - 1`, where  
> > &nbsp;&nbsp;/// `**` is exponentiation. For signed integer types, this value is  
> > &nbsp;&nbsp;/// `(2 ** bitWidth - 1) - 1`.  
> > &nbsp;&nbsp;static var max: Self { get  
> > }
> > 
> > /// The minimum representable value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For unsigned integer types, this value is always `0`. For signed integer  
> > &nbsp;&nbsp;/// types, this value is `-(2 **bitWidth - 1)`, where `**` is  
> > &nbsp;&nbsp;/// exponentiation.  
> > &nbsp;&nbsp;static var min: Self { get  
> > }
> > 
> > /// Returns the sum of this value and the given value along with a flag  
> > &nbsp;&nbsp;/// indicating whether overflow occurred in the operation.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter other: The value to add to this value.  
> > &nbsp;&nbsp;/// - Returns: A tuple containing the result of the addition along with a  
> > &nbsp;&nbsp;/// flag indicating whether overflow occurred. If the `overflow` component  
> > &nbsp;&nbsp;/// is `.none`, the `partialValue` component contains the entire sum. If  
> > &nbsp;&nbsp;/// the `overflow` component is `.overflow`, an overflow occurred and the  
> > &nbsp;&nbsp;/// `partialValue` component contains the truncated sum of this value and  
> > &nbsp;&nbsp;/// `other`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `+`  
> > &nbsp;&nbsp;func addingWithOverflow(\_ other: Self  
> > )  
> > &nbsp;&nbsp;&nbsp;&nbsp;  
> > -\> (partialValue: Self, overflow  
> > : ArithmeticOverflow)
> > 
> > /// Returns the difference of this value and the given value along with a  
> > &nbsp;&nbsp;/// flag indicating whether overflow occurred in the operation.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter other: The value to subtract from this value.  
> > &nbsp;&nbsp;/// - Returns: A tuple containing the result of the subtraction along with a  
> > &nbsp;&nbsp;/// flag indicating whether overflow occurred. If the `overflow` component  
> > &nbsp;&nbsp;/// is `.none`, the `partialValue` component contains the entire  
> > &nbsp;&nbsp;/// difference. If the `overflow` component is `.overflow`, an overflow  
> > &nbsp;&nbsp;/// occurred and the `partialValue` component contains the truncated  
> > &nbsp;&nbsp;/// result of `other` subtracted from this value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `-`  
> > &nbsp;&nbsp;func subtractingWithOverflow(\_ other: Self  
> > )  
> > &nbsp;&nbsp;&nbsp;&nbsp;  
> > -\> (partialValue: Self, overflow  
> > : ArithmeticOverflow)
> > 
> > /// Returns the product of this value and the given value along with a flag  
> > &nbsp;&nbsp;/// indicating whether overflow occurred in the operation.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter other: The value to multiply by this value.  
> > &nbsp;&nbsp;/// - Returns: A tuple containing the result of the multiplication along with  
> > &nbsp;&nbsp;/// a flag indicating whether overflow occurred. If the `overflow`  
> > &nbsp;&nbsp;/// component is `.none`, the `partialValue` component contains the entire  
> > &nbsp;&nbsp;/// product. If the `overflow` component is `.overflow`, an overflow  
> > &nbsp;&nbsp;/// occurred and the `partialValue` component contains the truncated  
> > &nbsp;&nbsp;/// product of this value and `other`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `*`, `doubleWidthMultiply(_:_:)`  
> > &nbsp;&nbsp;func multipliedWithOverflow(by other: Self  
> > )  
> > &nbsp;&nbsp;&nbsp;&nbsp;  
> > -\> (partialValue: Self, overflow  
> > : ArithmeticOverflow)
> > 
> > /// Returns the quotient of dividing this value by the given value along with  
> > &nbsp;&nbsp;/// a flag indicating whether overflow occurred in the operation.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For a value `x`, if zero is passed as `other`, the result is  
> > &nbsp;&nbsp;/// `(x, .overflow)`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter other: The value to divide this value by.  
> > &nbsp;&nbsp;/// - Returns: A tuple containing the result of the division along with a  
> > &nbsp;&nbsp;/// flag indicating whether overflow occurred. If the `overflow` component  
> > &nbsp;&nbsp;/// is `.none`, the `partialValue` component contains the entire quotient.  
> > &nbsp;&nbsp;/// If the `overflow` component is `.overflow`, an overflow occurred and  
> > &nbsp;&nbsp;/// the `partialValue` component contains the truncated quotient.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `/`, `doubleWidthDivide(_:_:)`  
> > &nbsp;&nbsp;func dividedWithOverflow(by other: Self  
> > )  
> > &nbsp;&nbsp;&nbsp;&nbsp;  
> > -\> (partialValue: Self, overflow  
> > : ArithmeticOverflow)
> > 
> > /// Returns a tuple containing the high and low parts of the result of  
> > &nbsp;&nbsp;/// multiplying its arguments.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// Use this method to calculate the full result of a product that would  
> > &nbsp;&nbsp;/// otherwise overflow. Unlike traditional truncating multiplication, the  
> > &nbsp;&nbsp;/// `doubleWidthMultiply(_:_:)` method returns both the `high` and `low`  
> > &nbsp;&nbsp;/// parts of the product of `lhs` and `rhs`. The following example uses this  
> > &nbsp;&nbsp;/// method to multiply two `UInt8` values that normally overflow when  
> > &nbsp;&nbsp;/// multiplied:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt8 = 100  
> > &nbsp;&nbsp;/// let y: UInt8 = 20  
> > &nbsp;&nbsp;/// let result = UInt8.doubleWidthMultiply(100, 20)  
> > &nbsp;&nbsp;/// // result.high == 0b00000111  
> > &nbsp;&nbsp;/// // result.low == 0b11010000  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The product of `x` and `y` is 2000, which is too large to represent in a  
> > &nbsp;&nbsp;/// `UInt8` instance. The `high` and `low` components of the `result` tuple  
> > &nbsp;&nbsp;/// represent 2000 when concatenated to form a double-width integer; that  
> > &nbsp;&nbsp;/// is, using `result.high` as the high byte and `result.low` as the low byte  
> > &nbsp;&nbsp;/// of a `UInt16` instance.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let z = UInt16(result.high) \<\< 8 | UInt16(result.low)  
> > &nbsp;&nbsp;/// // z == 2000  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameters:  
> > &nbsp;&nbsp;/// - lhs: A value to multiply.  
> > &nbsp;&nbsp;/// - rhs: Another value to multiply.  
> > &nbsp;&nbsp;/// - Returns: A tuple containing the high and low parts of the result of  
> > &nbsp;&nbsp;/// multiplying `lhs` and `rhs`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `multipliedWithOverflow(by:)`  
> > &nbsp;&nbsp;static func doubleWidthMultiply(\_ lhs: Self, \_ rhs: Self  
> > )  
> > &nbsp;&nbsp;&nbsp;&nbsp;  
> > -\> (high: Self, low  
> > : Magnitude)
> > 
> > /// Returns a tuple containing the quotient and remainder of dividing the  
> > &nbsp;&nbsp;/// first argument by the second.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The resulting quotient must be representable within the bounds of the  
> > &nbsp;&nbsp;/// type. If the quotient of dividing `lhs` by `rhs` is too large to  
> > &nbsp;&nbsp;/// represent in the type, a runtime error may occur.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameters:  
> > &nbsp;&nbsp;/// - lhs: A tuple containing the high and low parts of a double-width  
> > &nbsp;&nbsp;/// integer. The `high` component of the tuple carries the sign, if the  
> > &nbsp;&nbsp;/// type is signed.  
> > &nbsp;&nbsp;/// - rhs: The integer to divide into `lhs`.  
> > &nbsp;&nbsp;/// - Returns: A tuple containing the quotient and remainder of `lhs` divided  
> > &nbsp;&nbsp;/// by `rhs`.  
> > &nbsp;&nbsp;static func doubleWidthDivide  
> > (  
> > &nbsp;&nbsp;&nbsp;&nbsp;  
> > \_ lhs: (high: Self, low: Magnitude), \_ rhs: Self  
> > )  
> > &nbsp;&nbsp;&nbsp;&nbsp;  
> > -\> (quotient: Self, remainder: Self  
> > )
> > 
> > /// The number of bits equal to 1 in this value's binary representation.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For example, in a fixed-width integer type with a `bitWidth` value of 8,  
> > &nbsp;&nbsp;/// the number 31 has five bits equal to 1.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: Int8 = 0b0001\_1111  
> > &nbsp;&nbsp;/// // x == 31  
> > &nbsp;&nbsp;/// // x.popcount == 5  
> > &nbsp;&nbsp;var popcount: Int { get  
> > }
> > 
> > /// The number of leading zeros in this value's binary representation.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For example, in a fixed-width integer type with a `bitWidth` value of 8,  
> > &nbsp;&nbsp;/// the number 31 has three leading zeros.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: Int8 = 0b0001\_1111  
> > &nbsp;&nbsp;/// // x == 31  
> > &nbsp;&nbsp;/// // x.leadingZeros == 3  
> > &nbsp;&nbsp;/// - SeeAlso: `BinaryInteger.trailingZeros`  
> > &nbsp;&nbsp;var leadingZeros: Int { get  
> > }
> > 
> > /// Creates an integer from its big-endian representation, changing the  
> > &nbsp;&nbsp;/// byte order if necessary.  
> > &nbsp;&nbsp;init(bigEndian value: Self  
> > )
> > 
> > /// Creates an integer from its little-endian representation, changing the  
> > &nbsp;&nbsp;/// byte order if necessary.  
> > &nbsp;&nbsp;init(littleEndian value: Self  
> > )
> > 
> > /// The big-endian representation of this integer.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// If necessary, the byte order of this value is reversed from the typical  
> > &nbsp;&nbsp;/// byte order of this integer type. On a big-endian platform, for any  
> > &nbsp;&nbsp;/// integer `x`, `x == x.bigEndian`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `littleEndian`  
> > &nbsp;&nbsp;var bigEndian: Self { get  
> > }
> > 
> > /// The little-endian representation of this integer.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// If necessary, the byte order of this value is reversed from the typical  
> > &nbsp;&nbsp;/// byte order of this integer type. On a little-endian platform, for any  
> > &nbsp;&nbsp;/// integer `x`, `x == x.littleEndian`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `bigEndian`  
> > &nbsp;&nbsp;var littleEndian: Self { get  
> > }
> > 
> > /// A representation of this integer with the byte order swapped.  
> > &nbsp;&nbsp;var byteSwapped: Self { get  
> > }  
> > }
> > 
> > Auxiliary protocols
> > 
> > public protocol UnsignedInteger : BinaryInteger  
> > {  
> > &nbsp;&nbsp;  
> > associatedtype Magnitude : BinaryInteger
> > 
> > }
> > 
> > public protocol SignedInteger : BinaryInteger, SignedArithmetic  
> > {  
> > &nbsp;&nbsp;  
> > associatedtype Magnitude : BinaryInteger
> > 
> > }
> > 
> > DoubleWidth
> > 
> > The DoubleWidth\<T\> type allows to create wider fixed-width integer types from the ones available in the standard library.
> > 
> > Standard library currently provides fixed-width integer types of up to 64 bits. A value of DoubleWidth\<Int64\> will double the range of the underlying type and implement all the FixedWidthInteger requirements. Please note though that the implementation will not necessarily be the most efficient one, so it would not be a good idea to use DoubleWidth\<Int32\>instead of a built-in Int64.
> > 
> > Extra operators
> > 
> > In addition to the operators described in the protocols section, we also provide a few extensions that are not protocol requirements:
> > 
> > Heterogeneous shifts
> > 
> > extension BinaryInteger  
> > {  
> > &nbsp;&nbsp;  
> > // Masking shifts  
> > &nbsp;&nbsp;static func &\>\> \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self
> > 
> > static func &\>\>= \<Other : BinaryInteger\>(lhs: inout Self, rhs  
> > : Other)  
> > &nbsp;&nbsp;  
> > static func &\<\< \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self
> > 
> > static func &\<\<= \<Other : BinaryInteger\>(lhs: inout Self, rhs  
> > : Other)
> > 
> > // 'Smart' shifts  
> > &nbsp;&nbsp;static func \>\> \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self
> > 
> > static func \>\>= \<Other : BinaryInteger\>(lhs: inout Self, rhs  
> > : Other)  
> > &nbsp;&nbsp;  
> > static func \<\< \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self
> > 
> > static func \<\<= \<Other : BinaryInteger\>(lhs: inout Self, rhs  
> > : Other)  
> > }
> > 
> > Heterogeneous equality and comparison
> > 
> > extension BinaryInteger  
> > {  
> > &nbsp;&nbsp;  
> > // Equality  
> > &nbsp;&nbsp;static func == \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool
> > 
> > static func != \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool
> > 
> > // Comparison  
> > &nbsp;&nbsp;static func \< \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool
> > 
> > static func \<= \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool
> > 
> > static func \> \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool
> > 
> > static func \>= \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool
> > 
> > }
> > 
> > Masking arithmetic
> > 
> > public func &\* \<T: FixedWidthInteger\>(lhs: T, rhs: T) -\>  
> > T
> > 
> > public func &- \<T: FixedWidthInteger\>(lhs: T, rhs: T) -\>  
> > T
> > 
> > public func &+ \<T: FixedWidthInteger\>(lhs: T, rhs: T) -\> T  
> > Non-goals
> > 
> > This proposal:
> > 
> > &nbsp;&nbsp;• DOES NOT solve the integer promotion problem, which would allow mixed-type arithmetic. However, we believe that it is an important step in the right direction.
> > 
> > &nbsp;&nbsp;• DOES NOT include the implementation of a BigInt type, but allows it to be implemented in the future.
> > 
> > Source compatibility
> > 
> > The proposed change is designed to be as non-breaking as possible, and it has been proven that it does not break code on concrete integer types. However, there are still a few API breaking changes in the realm of generic code:
> > 
> > &nbsp;&nbsp;• Integer protocols in Swift up to and including version 3 were not particularly useful for generic programming, but were rather a means of sharing implementation between conforming types. Therefore we believe the amount of code that relied on these protocols is relatively small. The breakage can be further reduced by introducing proper aliases for the removed protocols with deprecation warnings.
> > 
> > &nbsp;&nbsp;• Deprecation of the BitwiseOperations protocol. We find it hard to imagine a type that conforms to this protocol, but is not a binary integer type.
> > 
> > &nbsp;&nbsp;• Addition of 'smart' shifts will change the behavior of existing code. It will still compile, but will be potentially less performant due to extra logic involved. In a case, where this becomes a problem, newly introduced masking shift operators can be used instead. Unfortunately, performance characteristics of the code cannot be statically checked, and thus migration cannot be provided.
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![Karl](https://avatars.discourse-cdn.com/v4/letter/k/34f0e0/32.png) [@Karl](https://forums.swift.org/u/Karl)\
**Post date:** [January 16, 2017, 5:57pm UTC](https://forums.swift.org/t/protocol-oriented-integers-take-2/4884/6 "2017-01-16T17:57:40Z")

</div>

Really glad to see this coming back :)

I have a couple of questions:

1) How does Strideable relate to Arithmetic?

My understanding is that Strideable allows non-numeric types to express different-type addition and subtraction, and that Arithmetic is for numeric types only (derives from ExpressibleByIntegerLiteral) and allows then to express same-type operations. Is that correct? If so, it would be nice to add it to the proposal so people know when they should conform (or set their generic constraints) to one or the other.

2) Can SignedNumber get some operators now?

Strideable.Stride is bound to this weird protocol ‘SignedNumber’. You can create instances of it out of thin air via an integer literal, but you can’t accumulate Strides to find the overall distance between some adjacent Strideables.

Also, #1 is why I don’t like the Strideable operator deprecation being part of the proposal (and therefore part of the language specification). It doesn’t solve the underlying issue, which is that our integer literal protocols aren’t really good enough - they’re not useful enough outside the standard library (see: [https://bugs.swift.org/browse/SR-920\](https://bugs.swift.org/browse/SR-920%5C)), and evidently the compiler isn’t able to use them to infer types correctly. Perhaps fixing it is a low priority, and that’s fine, but what about if somebody else defines this operator in their library? They start of break lots of valid code because the compiler can’t do the right thing. Improved literal protocols may be the better way to resolve that problem.

- Karl

---

<div class="post-metadata">

**Author:** ![benrimmington](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/benrimmington/32/695_2.png) [@benrimmington](https://forums.swift.org/u/benrimmington)\
**Post date:** [January 17, 2017, 5:43pm UTC](https://forums.swift.org/t/protocol-oriented-integers-take-2/4884/7 "2017-01-17T17:43:01Z")

</div>

\<[https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c&gt](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c&gt);

&nbsp;&nbsp;public protocol Arithmetic {  
&nbsp;&nbsp;&nbsp;&nbsp;init?\<T : BinaryInteger\>(exactly source: T)  
&nbsp;&nbsp;}

&nbsp;&nbsp;public protocol BinaryInteger : Arithmetic {  
&nbsp;&nbsp;&nbsp;&nbsp;init?\<T : FloatingPoint\>(exactly source: T)  
&nbsp;&nbsp;}

Should the `init?(exactly:)` initializers belong to the same protocol?  
Would this allow generic conversions between integer and floating-point types?  
For example, a failable `numericCast` function.

-- Ben

---

<div class="post-metadata">

**Author:** ![antonvmironov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/antonvmironov/32/22862_2.png) [@antonvmironov](https://forums.swift.org/u/antonvmironov)\
**Post date:** [January 25, 2017, 3:59pm UTC](https://forums.swift.org/t/protocol-oriented-integers-take-2/4884/8 "2017-01-25T15:59:48Z")

</div>

Hi everyone,

I want to suggest a tiny extension to an Arithmetic protocol. It would be nice to have an additive identity and a multiplicative identity constants. Basically zero and one.

```swift
protocol Arithmetic {
  /* ... */
  static var zero: Self { get } // additive identity: (value + .zero) == value
  static var one: Self { get } // multiplicative identity: (value * .one) == value
}

```

These constants will ease implementation of math structures: vectors, matrices and etc.  
I’m sorry if I’m duplicating someone’s suggestion. It is really hard to search for something in a long thread.

Thanks,  
Anton Mironov

> **···**
>
> > On Jan 13, 2017, at 10:47 PM, Max Moiseev via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > Hi everyone,
> > 
> > Back in June 2016 we discussed the new design of the integer types for the standard library. It even resulted in acceptance of SE-0104 \<[https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md&gt](https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md&gt); for Swift 3. Unfortunately we were not able to implement it in time for the release.
> > 
> > But it was not forgotten, although, as time went by, a few changes needed to be made in order to reflect the current state of the language.  
> > Without further introduction, please welcome the refined proposal to make integers in Swift more suitable for generic programming.
> > 
> > Available in this gist [Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c) and also inlined below.
> > 
> > Max
> > 
> > Protocol-oriented integers (take 2)
> > 
> > Proposal: SE-NNNN \<[https://gist.github.com/moiseev/0000-even-more-improved-integers.md&gt](https://gist.github.com/moiseev/0000-even-more-improved-integers.md&gt);  
> > Authors: Dave Abrahams \<[https://github.com/dabrahams&gt;](https://github.com/dabrahams&gt;), Maxim Moiseev \<[https://github.com/moiseev&gt](https://github.com/moiseev&gt);  
> > Review Manager: TBD  
> > Status: Awaiting review  
> > Bug: SR-3196 \<[Issues · apple/swift-issues · GitHub](https://bugs.swift.org/browse/SR-3196&gt);  
> > Previous Proposal: SE-0104 \<[https://gist.github.com/moiseev/0104-improved-integers.md&gt](https://gist.github.com/moiseev/0104-improved-integers.md&gt);  
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#introduction&gt;Introduction)
> > 
> > This proposal is an evolution of SE-0104 \<[https://gist.github.com/moiseev/0104-improved-integers.md&gt;\](https://gist.github.com/moiseev/0104-improved-integers.md&gt;%5C). The goal is still to clean up Swifts integer APIs and make them more useful for generic programming.
> > 
> > The language has evolved in ways that affect integers APIs since the time the original proposal was approved for Swift 3. We also attempted to implement the proposed model in the standard library and found that some essential APIs were missing, whereas others could be safely removed.
> > 
> > Major changes to the APIs introduced by this proposal (as compared to SE-0104 \<[https://gist.github.com/moiseev/0104-improved-integers.md&gt;\](https://gist.github.com/moiseev/0104-improved-integers.md&gt;%5C)) are listed in a dedicated section \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#whats-new-since-se-0104&gt;%5C).
> > 
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#motivation&gt;Motivation)
> > 
> > Swift's integer protocols don't currently provide a suitable basis for generic programming. See this blog post \<[http://blog.krzyzanowskim.com/2015/03/01/swift\_madness\_of\_generic\_integer/&gt](http://blog.krzyzanowskim.com/2015/03/01/swift_madness_of_generic_integer/&gt); for an example of an attempt to implement a generic algorithm over integers.
> > 
> > The way the Arithmetic protocol is defined, it does not generalize to floating point numbers and also slows down compilation by requiring every concrete type to provide an implementation of arithmetic operators, thus polluting the overload set.
> > 
> > Converting from one integer type to another is performed using the concept of the 'maximum width integer' (see MaxInt), which is an artificial limitation. The very existence of MaxInt makes it unclear what to do should someone implement Int256, for example.
> > 
> > Another annoying problem is the inability to use integers of different types in comparison and bit-shift operations. For example, the following snippets won't compile:
> > 
> > var x: Int8 = 42  
> > let y = 1  
> > let z = 0
> > 
> > x \<\<= y // error: binary operator '\<\<=' cannot be applied to operands of type 'Int8' and 'Int'  
> > if x \> z { ... } // error: binary operator '\>' cannot be applied to operands of type 'Int8' and 'Int'  
> > Currently, bit-shifting a negative number of (or too many) bits causes a trap on some platforms, which makes low-level bit manipulations needlessly dangerous and unpredictable.
> > 
> > Finally, the current design predates many of the improvements that came since Swift 1, and hasn't been revised since then.
> > 
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#proposed-solution&gt;Proposed) solution
> > 
> > We propose a new model that does not have above mentioned problems and is more easily extensible.
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+--------------+ +-------------+  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+------\>+ Arithmetic | | Comparable |  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \> (+,-,\*,/) | | (==,\<,\>,...)|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> +-------------++ +---+---------+  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> ^ ^  
> > +-------+------------+ | |  
> > \> SignedArithmetic | +-+-------+-----------+  
> > \> (unary -) | | BinaryInteger |  
> > +------+-------------+ |(words,%,bitwise,...)|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^ ++---+-----+----------+  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> +-----------^ ^ ^---------------+  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \> \> \>  
> > +------+---------++ +---------+---------------+ +--+----------------+  
> > \> SignedInteger | | FixedWidthInteger | | UnsignedInteger |  
> > \> \> \>(endianness,overflow,...)| | |  
> > +---------------+-+ +-+--------------------+--+ +-+-----------------+  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^ ^ ^ ^  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \> \> \>  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \> \> \>  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++--------+-+ +-+-------+-+  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\>Int family |-+ |UInt family|-+  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+-----------+ | +-----------+ |  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+-----------+ +-----------+  
> > There are several benefits provided by this model over the old one:
> > 
> > It allows mixing integer types in generic functions.
> > 
> > The possibility to initialize instances of any concrete integer type with values of any other concrete integer type enables writing functions that operate on more than one type conforming to BinaryInteger, such as heterogeneous comparisons or bit shifts, described later.
> > 
> > It removes the overload resolution overhead.
> > 
> > Arithmetic and bitwise operations can now be defined as generic operators on protocols. This approach significantly reduces the number of overloads for those operations, which used to be defined for every single concrete integer type.
> > 
> > It enables protocol sharing between integer and floating point types.
> > 
> > Note the exclusion of the % operation from Arithmetic. Its behavior for floating point numbers is sufficiently different from the one for integers that using it in generic context would lead to confusion. The FloatingPoint protocol introduced by SE-0067 \<[https://gist.github.com/moiseev/0067-floating-point-protocols.md&gt](https://gist.github.com/moiseev/0067-floating-point-protocols.md&gt); should now refine SignedArithmetic.
> > 
> > It makes future extensions possible.
> > 
> > The proposed model eliminates the 'largest integer type' concept previously used to interoperate between integer types (see toIntMax in the current model) and instead provides access to machine words. It also introduces thedoubleWidthMultiply, doubleWidthDivide, and quotientAndRemainder methods. Together these changes can be used to provide an efficient implementation of bignums that would be hard to achieve otherwise.
> > 
> > The implementation of proposed model in the standard library is available in the new-integer-protocols branch \<[https://github.com/apple/swift/tree/new-integer-protocols&gt;\](https://github.com/apple/swift/tree/new-integer-protocols&gt;%5C).
> > 
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#a-note-on-bit-shifts&gt;A) note on bit shifts
> > 
> > This proposal introduces the concepts of smart shifts and masking shifts.
> > 
> > The semantics of shift operations are often undefined \<[LLVM Language Reference Manual — LLVM 18.0.0git documentation](http://llvm.org/docs/LangRef.html#bitwise-binary-operations&gt); in under- or over-shift cases. Smart shifts, implemented by \>\> and \<\<, are designed to address this problem and always behave in a well defined way, as shown in the examples below:
> > 
> > x \<\< -2 is equivalent to x \>\> 2
> > 
> > (1 as UInt8) \>\> 42) will evaluate to 0
> > 
> > (-128 as Int8) \>\> 42) will evaluate to 0xff or -1
> > 
> > In most scenarios, the right hand operand is a literal constant, and branches for handling under- and over-shift cases can be optimized away. For other cases, this proposal provides masking shifts, implemented by &\>\> and &\<\<. A masking shift logically preprocesses the right hand operand by masking its bits to produce a value in the range 0...(x-1) where x is the number of bits in the left hand operand. On most architectures this masking is already performed by the CPU's shift instructions and has no cost. Both kinds of shift avoid undefined behavior and produce uniform semantics across architectures.
> > 
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#detailed-design&gt;Detailed) design
> > 
> > \<[https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#whats-new-since-se-0104&gt;What&#39;s](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#whats-new-since-se-0104&gt;What&#39;s) new since SE-0104
> > 
> > SE-0091 \<[https://gist.github.com/moiseev/0091-improving-operators-in-protocols.md&gt](https://gist.github.com/moiseev/0091-improving-operators-in-protocols.md&gt); removed the necessity to dispatch generic operators through special methods.
> > 
> > All operators are now declared by protocols as static funcs.
> > 
> > Standard Library no longer provides + and - operators for Strideable types.
> > 
> > They were problematic, as one could have written mixed-type code like let x: Int64 = 42; x += (1 as Int), which would compile, but shouldn't. Besides, since the Stride of an unsigned type is signed, Standard Library had to implement a hack to make code like let x: UInt = 42; x += (1 as Int) ambiguous. These operators were only necessary because they made advancing collection indices convenient, which is no longer the case since the introduction of the new indexing model \<[https://gist.github.com/moiseev/0065-collections-move-indices.md&gt](https://gist.github.com/moiseev/0065-collections-move-indices.md&gt); in Swift 3.
> > 
> > Shifts and other bitwise operations were moved from FixedWidthInteger to BinaryInteger.
> > 
> > Left shift operation on an unbounded integer should infinitely extend the number, and never drop set bits when they reach the most significant position in the underlying representation.
> > 
> > BitwiseOperations protocol was deprecated.
> > 
> > We believe there are no useful entities that support bitwise operations, but at the same time are not binary integers.
> > 
> > minimumSignedRepresentationBitWidth property was removed.
> > 
> > trailingZeros property was added to the BinaryInteger protocol.
> > 
> > leadingZeros and popcount properties are still defined by the FixedWidthInteger protocol.
> > 
> > Endian-converting initializers and properties were added to the FixedWidthInteger protocol.
> > 
> > Standard library introduces the new type DoubleWidth\<T\>.
> > 
> > See this section \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#doublewidth&gt); for more details.
> > 
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#protocols&gt;Protocols)
> > 
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#arithmetic&gt;Arithmetic)
> > 
> > The Arithmetic protocol declares binary arithmetic operators – such as +, -, and \* — and their mutating counterparts.
> > 
> > It provides a suitable basis for arithmetic on scalars such as integers and floating point numbers.
> > 
> > Both mutating and non-mutating operations are declared in the protocol, however only the mutating ones are required, as default implementations of the non-mutating ones are provided by a protocol extension.
> > 
> > The Magnitude associated type is able to hold the absolute value of any possible value of Self. Concrete types do not have to provide a type alias for it, as it can be inferred from the magnitude property. This property can be useful in operations that are simpler to implement in terms of unsigned values, for example, printing a value of an integer, which is just printing a '-' character in front of an absolute value.
> > 
> > Please note that for ordinary work, the magnitude property should not be preferred to the abs(\_) function, whose return value is of the same type as its argument.
> > 
> > public protocol Arithmetic : Equatable, ExpressibleByIntegerLiteral {  
> > &nbsp;&nbsp;/// Creates a new instance from the given integer, if it can be represented  
> > &nbsp;&nbsp;/// exactly.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// If the value passed as `source` is not representable exactly, the result  
> > &nbsp;&nbsp;/// is `nil`. In the following example, the constant `x` is successfully  
> > &nbsp;&nbsp;/// created from a value of `100`, while the attempt to initialize the  
> > &nbsp;&nbsp;/// constant `y` from `1_000` fails because the `Int8` type can represent  
> > &nbsp;&nbsp;/// `127` at maximum:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = Int8(exactly: 100)  
> > &nbsp;&nbsp;/// // x == Optional(100)  
> > &nbsp;&nbsp;/// let y = Int8(exactly: 1\_000)  
> > &nbsp;&nbsp;/// // y == nil  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter source: A floating-point value to convert to an integer.  
> > &nbsp;&nbsp;init?\<T : BinaryInteger\>(exactly source: T)
> > 
> > &nbsp;&nbsp;/// A type that can represent the absolute value of any possible value of the  
> > &nbsp;&nbsp;/// conforming type.  
> > &nbsp;&nbsp;associatedtype Magnitude : Equatable, ExpressibleByIntegerLiteral
> > 
> > &nbsp;&nbsp;/// The magnitude of this value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For any numeric value `x`, `x.magnitude` is the absolute value of `x`.  
> > &nbsp;&nbsp;/// You can use the `magnitude` property in operations that are simpler to  
> > &nbsp;&nbsp;/// implement in terms of unsigned values, such as printing the value of an  
> > &nbsp;&nbsp;/// integer, which is just printing a '-' character in front of an absolute  
> > &nbsp;&nbsp;/// value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = -200  
> > &nbsp;&nbsp;/// // x.magnitude == 200  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The global `abs(_:)` function provides more familiar syntax when you need  
> > &nbsp;&nbsp;/// to find an absolute value. In addition, because `abs(_:)` always returns  
> > &nbsp;&nbsp;/// a value of the same type, even in a generic context, using the function  
> > &nbsp;&nbsp;/// instead of the `magnitude` property is encouraged.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `abs(_:)`  
> > &nbsp;&nbsp;var magnitude: Magnitude { get }
> > 
> > &nbsp;&nbsp;/// Returns the sum of the two given values.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The sum of `lhs` and `rhs` must be representable in the same type. In the  
> > &nbsp;&nbsp;/// following example, the result of `100 + 200` is greater than the maximum  
> > &nbsp;&nbsp;/// representable `Int8` value:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: Int8 = 10 + 21  
> > &nbsp;&nbsp;/// // x == 31  
> > &nbsp;&nbsp;/// let y: Int8 = 100 + 121  
> > &nbsp;&nbsp;/// // Overflow error  
> > &nbsp;&nbsp;static func +(\_ lhs: Self, \_ rhs: Self) -\> Self
> > 
> > &nbsp;&nbsp;/// Adds the given value to this value in place.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For example:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// var x = 15  
> > &nbsp;&nbsp;/// y += 7  
> > &nbsp;&nbsp;/// // y == 22  
> > &nbsp;&nbsp;static func +=(\_ lhs: inout Self, rhs: Self)
> > 
> > &nbsp;&nbsp;/// Returns the difference of the two given values.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The difference of `lhs` and `rhs` must be representable in the same type.  
> > &nbsp;&nbsp;/// In the following example, the result of `10 - 21` is less than zero, the  
> > &nbsp;&nbsp;/// minimum representable `UInt` value:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt = 21 - 10  
> > &nbsp;&nbsp;/// // x == 11  
> > &nbsp;&nbsp;/// let y: UInt = 10 - 21  
> > &nbsp;&nbsp;/// // Overflow error  
> > &nbsp;&nbsp;static func -(\_ lhs: Self, \_ rhs: Self) -\> Self
> > 
> > &nbsp;&nbsp;/// Subtracts the given value from this value in place.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For example:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// var x = 15  
> > &nbsp;&nbsp;/// y -= 7  
> > &nbsp;&nbsp;/// // y == 8  
> > &nbsp;&nbsp;static func -=(\_ lhs: inout Self, rhs: Self)
> > 
> > &nbsp;&nbsp;/// Returns the product of the two given values.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The product of `lhs` and `rhs` must be representable in the same type. In  
> > &nbsp;&nbsp;/// the following example, the result of `10 * 50` is greater than the  
> > &nbsp;&nbsp;/// maximum representable `Int8` value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: Int8 = 10 \* 5  
> > &nbsp;&nbsp;/// // x == 50  
> > &nbsp;&nbsp;/// let y: Int8 = 10 \* 50  
> > &nbsp;&nbsp;/// // Overflow error  
> > &nbsp;&nbsp;static func \*(\_ lhs: Self, \_ rhs: Self) -\> Self
> > 
> > &nbsp;&nbsp;/// Multiples this value by the given value in place.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For example:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// var x = 15  
> > &nbsp;&nbsp;/// y \*= 7  
> > &nbsp;&nbsp;/// // y == 105  
> > &nbsp;&nbsp;static func \*=(\_ lhs: inout Self, rhs: Self)
> > 
> > &nbsp;&nbsp;/// Returns the quotient of dividing the first value by the second.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For integer types, any remainder of the division is discarded.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = 21 / 5  
> > &nbsp;&nbsp;/// // x == 4  
> > &nbsp;&nbsp;static func /(\_ lhs: Self, \_ rhs: Self) -\> Self
> > 
> > &nbsp;&nbsp;/// Divides this value by the given value in place.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For example:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// var x = 15  
> > &nbsp;&nbsp;/// y /= 7  
> > &nbsp;&nbsp;/// // y == 2  
> > &nbsp;&nbsp;static func /=(\_ lhs: inout Self, rhs: Self)  
> > }
> > 
> > extension Arithmetic {  
> > &nbsp;&nbsp;public init() { self = 0 }
> > 
> > &nbsp;&nbsp;public static prefix func + (x: Self) -\> Self {  
> > &nbsp;&nbsp;&nbsp;&nbsp;return x  
> > &nbsp;&nbsp;}  
> > }  
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#signedarithmetic&gt;SignedArithmetic)
> > 
> > The SignedArithmetic protocol is for numbers that can be negated.
> > 
> > public protocol SignedArithmetic : Arithmetic {  
> > &nbsp;&nbsp;/// Returns the additive inverse of this value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = 21  
> > &nbsp;&nbsp;/// let y = -x  
> > &nbsp;&nbsp;/// // y == -21  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Returns: The additive inverse of this value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `negate()`  
> > &nbsp;&nbsp;static prefix func - (\_ operand: Self) -\> Self
> > 
> > &nbsp;&nbsp;/// Replaces this value with its additive inverse.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The following example uses the `negate()` method to negate the value of  
> > &nbsp;&nbsp;/// an integer `x`:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// var x = 21  
> > &nbsp;&nbsp;/// x.negate()  
> > &nbsp;&nbsp;/// // x == -21  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: The unary minus operator (`-`).  
> > &nbsp;&nbsp;mutating func negate()  
> > }
> > 
> > extension SignedArithmetic {  
> > &nbsp;&nbsp;public static prefix func - (\_ operand: Self) -\> Self {  
> > &nbsp;&nbsp;&nbsp;&nbsp;var result = operand  
> > &nbsp;&nbsp;&nbsp;&nbsp;result.negate()  
> > &nbsp;&nbsp;&nbsp;&nbsp;return result  
> > &nbsp;&nbsp;}
> > 
> > &nbsp;&nbsp;public mutating func negate() {  
> > &nbsp;&nbsp;&nbsp;&nbsp;self = Self() - self  
> > &nbsp;&nbsp;}  
> > }  
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#binaryinteger&gt;BinaryInteger)
> > 
> > The BinaryInteger protocol is the basis for all the integer types provided by the standard library.
> > 
> > This protocol adds a few new initializers. Two of them allow to create integers from floating point numbers, others support construction from instances of any type conforming to BinaryInteger, using different strategies:
> > 
> > Initialize Self with the value, provided that the value is representable. The precondition should be satisfied by the caller.
> > 
> > Extend or truncate the value to fit into Self
> > 
> > Clamp the value to the representable range of Self
> > 
> > BinaryInteger also declares bitwise and shift operators.
> > 
> > public protocol BinaryInteger :  
> > &nbsp;&nbsp;Comparable, Hashable, Arithmetic, CustomStringConvertible, Strideable {
> > 
> > &nbsp;&nbsp;/// A Boolean value indicating whether this type is a signed integer type.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// \*Signed\* integer types can represent both positive and negative values.  
> > &nbsp;&nbsp;/// \*Unsigned\* integer types can represent only nonnegative values.  
> > &nbsp;&nbsp;static var isSigned: Bool { get }
> > 
> > &nbsp;&nbsp;/// Creates an integer from the given floating-point value, if it can be  
> > &nbsp;&nbsp;/// represented exactly.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// If the value passed as `source` is not representable exactly, the result  
> > &nbsp;&nbsp;/// is `nil`. In the following example, the constant `x` is successfully  
> > &nbsp;&nbsp;/// created from a value of `21.0`, while the attempt to initialize the  
> > &nbsp;&nbsp;/// constant `y` from `21.5` fails:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = Int(exactly: 21.0)  
> > &nbsp;&nbsp;/// // x == Optional(21)  
> > &nbsp;&nbsp;/// let y = Int(exactly: 21.5)  
> > &nbsp;&nbsp;/// // y == nil  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter source: A floating-point value to convert to an integer.  
> > &nbsp;&nbsp;init?\<T : FloatingPoint\>(exactly source: T)
> > 
> > &nbsp;&nbsp;/// Creates an integer from the given floating-point value, truncating any  
> > &nbsp;&nbsp;/// fractional part.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// Truncating the fractional part of `source` is equivalent to rounding  
> > &nbsp;&nbsp;/// toward zero.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = Int(21.5)  
> > &nbsp;&nbsp;/// // x == 21  
> > &nbsp;&nbsp;/// let y = Int(-21.5)  
> > &nbsp;&nbsp;/// // y == -21  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// If `source` is outside the bounds of this type after truncation, a  
> > &nbsp;&nbsp;/// runtime error may occur.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let z = UInt(-21.5)  
> > &nbsp;&nbsp;/// // Error: ...the result would be less than UInt.min  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter source: A floating-point value to convert to an integer.  
> > &nbsp;&nbsp;/// `source` must be representable in this type after truncation.  
> > &nbsp;&nbsp;init\<T : FloatingPoint\>(\_ source: T)
> > 
> > &nbsp;&nbsp;/// Creates an new instance from the given integer.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// If the value passed as `source` is not representable in this type, a  
> > &nbsp;&nbsp;/// runtime error may occur.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = -500 as Int  
> > &nbsp;&nbsp;/// let y = Int32(x)  
> > &nbsp;&nbsp;/// // y == -500  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// // -500 is not representable as a 'UInt32' instance  
> > &nbsp;&nbsp;/// let z = UInt32(x)  
> > &nbsp;&nbsp;/// // Error  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter source: An integer to convert. `source` must be representable  
> > &nbsp;&nbsp;/// in this type.  
> > &nbsp;&nbsp;init\<T : BinaryInteger\>(\_ source: T)
> > 
> > &nbsp;&nbsp;/// Creates a new instance from the bit pattern of the given instance by  
> > &nbsp;&nbsp;/// sign-extending or truncating to fit this type.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// When the bit width of `T` (the type of `source`) is equal to or greater  
> > &nbsp;&nbsp;/// than this type's bit width, the result is the truncated  
> > &nbsp;&nbsp;/// least-significant bits of `source`. For example, when converting a  
> > &nbsp;&nbsp;/// 16-bit value to an 8-bit type, only the lower 8 bits of `source` are  
> > &nbsp;&nbsp;/// used.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let p: Int16 = -500  
> > &nbsp;&nbsp;/// // 'p' has a binary representation of 11111110\_00001100  
> > &nbsp;&nbsp;/// let q = Int8(extendingOrTruncating: p)  
> > &nbsp;&nbsp;/// // q == 12  
> > &nbsp;&nbsp;/// // 'q' has a binary representation of 00001100  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// When the bit width of `T` is less than this type's bit width, the result  
> > &nbsp;&nbsp;/// is \*sign-extended\* to fill the remaining bits. That is, if `source` is  
> > &nbsp;&nbsp;/// negative, the result is padded with ones; otherwise, the result is  
> > &nbsp;&nbsp;/// padded with zeros.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let u: Int8 = 21  
> > &nbsp;&nbsp;/// // 'u' has a binary representation of 00010101  
> > &nbsp;&nbsp;/// let v = Int16(extendingOrTruncating: u)  
> > &nbsp;&nbsp;/// // v == 21  
> > &nbsp;&nbsp;/// // 'v' has a binary representation of 00000000\_00010101  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let w: Int8 = -21  
> > &nbsp;&nbsp;/// // 'w' has a binary representation of 11101011  
> > &nbsp;&nbsp;/// let x = Int16(extendingOrTruncating: w)  
> > &nbsp;&nbsp;/// // x == -21  
> > &nbsp;&nbsp;/// // 'x' has a binary representation of 11111111\_11101011  
> > &nbsp;&nbsp;/// let y = UInt16(extendingOrTruncating: w)  
> > &nbsp;&nbsp;/// // y == 65515  
> > &nbsp;&nbsp;/// // 'y' has a binary representation of 11111111\_11101011  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter source: An integer to convert to this type.  
> > &nbsp;&nbsp;init\<T : BinaryInteger\>(extendingOrTruncating source: T)
> > 
> > &nbsp;&nbsp;/// Creates a new instance with the representable value that's closest to the  
> > &nbsp;&nbsp;/// given integer.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// If the value passed as `source` is greater than the maximum representable  
> > &nbsp;&nbsp;/// value in this type, the result is the type's `max` value. If `source` is  
> > &nbsp;&nbsp;/// less than the smallest representable value in this type, the result is  
> > &nbsp;&nbsp;/// the type's `min` value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// In this example, `x` is initialized as an `Int8` instance by clamping  
> > &nbsp;&nbsp;/// `500` to the range `-128...127`, and `y` is initialized as a `UInt`  
> > &nbsp;&nbsp;/// instance by clamping `-500` to the range `0...UInt.max`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = Int8(clamping: 500)  
> > &nbsp;&nbsp;/// // x == 127  
> > &nbsp;&nbsp;/// // x == Int8.max  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let y = UInt(clamping: -500)  
> > &nbsp;&nbsp;/// // y == 0  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter source: An integer to convert to this type.  
> > &nbsp;&nbsp;init\<T : BinaryInteger\>(clamping source: T)
> > 
> > &nbsp;&nbsp;/// Returns the n-th word, counting from the least significant to most  
> > &nbsp;&nbsp;/// significant, of this value's binary representation.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The `word(at:)` method returns negative values in two's complement  
> > &nbsp;&nbsp;/// representation, regardless of a type's underlying implementation. If `n`  
> > &nbsp;&nbsp;/// is greater than the number of words in this value's current  
> > &nbsp;&nbsp;/// representation, the result is `0` for positive numbers and `~0` for  
> > &nbsp;&nbsp;/// negative numbers.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter n: The word to return, counting from the least significant to  
> > &nbsp;&nbsp;/// most significant. `n` must be greater than or equal to zero.  
> > &nbsp;&nbsp;/// - Returns: An word-sized, unsigned integer with the bit pattern of the  
> > &nbsp;&nbsp;/// n-th word of this value.  
> > &nbsp;&nbsp;func word(at n: Int) -\> UInt
> > 
> > &nbsp;&nbsp;/// The number of bits in the current binary representation of this value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// This property is a constant for instances of fixed-width integer  
> > &nbsp;&nbsp;/// types.  
> > &nbsp;&nbsp;var bitWidth : Int { get }
> > 
> > &nbsp;&nbsp;/// The number of trailing zeros in this value's binary representation.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For example, in a fixed-width integer type with a `bitWidth` value of 8,  
> > &nbsp;&nbsp;/// the number -8 has three trailing zeros.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = Int8(bitPattern: 0b1111\_1000)  
> > &nbsp;&nbsp;/// // x == -8  
> > &nbsp;&nbsp;/// // x.trailingZeros == 3  
> > &nbsp;&nbsp;var trailingZeros: Int { get }
> > 
> > &nbsp;&nbsp;/// Returns the remainder of dividing the first value by the second.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The result has the same sign as `lhs` and is less than `rhs.magnitude`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = 22 % 5  
> > &nbsp;&nbsp;/// // x == 2  
> > &nbsp;&nbsp;/// let y = 22 % -5  
> > &nbsp;&nbsp;/// // y == 2  
> > &nbsp;&nbsp;/// let z = -22 % -5  
> > &nbsp;&nbsp;/// // z == -2  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameters:  
> > &nbsp;&nbsp;/// - lhs: The value to divide.  
> > &nbsp;&nbsp;/// - rhs: The value to divide `lhs` by. `rhs` must not be zero.  
> > &nbsp;&nbsp;static func %(\_ lhs: Self, \_ rhs: Self) -\> Self
> > 
> > &nbsp;&nbsp;/// Replaces this value with the remainder of itself divided by the given  
> > &nbsp;&nbsp;/// value. For example:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// var x = 15  
> > &nbsp;&nbsp;/// x %= 7  
> > &nbsp;&nbsp;/// // x == 1  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter rhs: The value to divide this value by. `rhs` must not be  
> > &nbsp;&nbsp;/// zero.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `remainder(dividingBy:)`  
> > &nbsp;&nbsp;static func %=(\_ lhs: inout Self, \_ rhs: Self)
> > 
> > &nbsp;&nbsp;/// Returns the inverse of the bits set in the argument.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The bitwise NOT operator (`~`) is a prefix operator that returns a value  
> > &nbsp;&nbsp;/// in which all the bits of its argument are flipped: Bits that are `1` in  
> > &nbsp;&nbsp;/// the argument are `0` in the result, and bits that are `0` in the argument  
> > &nbsp;&nbsp;/// are `1` in the result. This is equivalent to the inverse of a set. For  
> > &nbsp;&nbsp;/// example:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt8 = 5 // 0b00000101  
> > &nbsp;&nbsp;/// let notX = ~x // 0b11111010  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// Performing a bitwise NOT operation on 0 returns a value with every bit  
> > &nbsp;&nbsp;/// set to `1`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let allOnes = ~UInt8.min // 0b11111111  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Complexity: O(1).  
> > &nbsp;&nbsp;static prefix func ~ (\_ x: Self) -\> Self
> > 
> > &nbsp;&nbsp;/// Returns the result of performing a bitwise AND operation on this value  
> > &nbsp;&nbsp;/// and the given value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// A bitwise AND operation results in a value that has each bit set to `1`  
> > &nbsp;&nbsp;/// where \*both\* of its arguments have that bit set to `1`. For example:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt8 = 5 // 0b00000101  
> > &nbsp;&nbsp;/// let y: UInt8 = 14 // 0b00001110  
> > &nbsp;&nbsp;/// let z = x & y // 0b00000100  
> > &nbsp;&nbsp;static func &(\_ lhs: Self, \_ rhs: Self) -\> Self  
> > &nbsp;&nbsp;static func &=(\_ lhs: inout Self, \_ rhs: Self)
> > 
> > &nbsp;&nbsp;/// Returns the result of performing a bitwise OR operation on this value and  
> > &nbsp;&nbsp;/// the given value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// A bitwise OR operation results in a value that has each bit set to `1`  
> > &nbsp;&nbsp;/// where \*one or both\* of its arguments have that bit set to `1`. For  
> > &nbsp;&nbsp;/// example:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt8 = 5 // 0b00000101  
> > &nbsp;&nbsp;/// let y: UInt8 = 14 // 0b00001110  
> > &nbsp;&nbsp;/// let z = x | y // 0b00001111  
> > &nbsp;&nbsp;static func |(\_ lhs: Self, \_ rhs: Self) -\> Self  
> > &nbsp;&nbsp;static func |=(\_ lhs: inout Self, \_ rhs: Self)
> > 
> > &nbsp;&nbsp;/// Returns the result of performing a bitwise XOR operation on this value  
> > &nbsp;&nbsp;/// and the given value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// A bitwise XOR operation, also known as an exclusive OR operation, results  
> > &nbsp;&nbsp;/// in a value that has each bit set to `1` where \*one or the other but not  
> > &nbsp;&nbsp;/// both\* of its arguments had that bit set to `1`. For example:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt8 = 5 // 0b00000101  
> > &nbsp;&nbsp;/// let y: UInt8 = 14 // 0b00001110  
> > &nbsp;&nbsp;/// let z = x ^ y // 0b00001011  
> > &nbsp;&nbsp;static func ^(\_ lhs: Self, \_ rhs: Self) -\> Self  
> > &nbsp;&nbsp;static func ^=(\_ lhs: inout Self, \_ rhs: Self)
> > 
> > &nbsp;&nbsp;/// Returns the result of shifting this value's binary representation the  
> > &nbsp;&nbsp;/// specified number of digits to the right.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// In a \*masking shift\*, the bit pattern of the value passed as `rhs` is  
> > &nbsp;&nbsp;/// masked to produce a value between zero and the bit width of `lhs`. The  
> > &nbsp;&nbsp;/// shift is performed using this masked value. Masking shifts require more  
> > &nbsp;&nbsp;/// care to use correctly than a traditional bit shift, but are likely to be  
> > &nbsp;&nbsp;/// more efficient when used with shift amounts that are not compile-time  
> > &nbsp;&nbsp;/// constants. On most architectures, a masking shift compiles down to a  
> > &nbsp;&nbsp;/// single instruction.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For example, if you shift an 8-bit, unsigned integer by 2, the shift  
> > &nbsp;&nbsp;/// amount requires no masking.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt8 = 30 // 0b00011110  
> > &nbsp;&nbsp;/// let y = x &\>\> 2  
> > &nbsp;&nbsp;/// // y == 7 // 0b00000111  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// However, if you shift it by 11, it first bitmasks `rhs` to `3`, and then  
> > &nbsp;&nbsp;/// uses that masked value as the number of bits to shift `x`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let z = x &\>\> 11  
> > &nbsp;&nbsp;/// // z == 3 // 0b00000011  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// Relationship to the Right Shift Operator  
> > &nbsp;&nbsp;/// ----------------------------------------  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The masking right shift operator handles attempted overshifts and  
> > &nbsp;&nbsp;/// undershifts differently from the right shift operator (`\>\>`). When the  
> > &nbsp;&nbsp;/// value passed as `rhs` in a masking shift is within the range  
> > &nbsp;&nbsp;/// `0...\<bitWidth`, the operation is equivalent to using the right shift  
> > &nbsp;&nbsp;/// operator.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt8 = 30 // 0b00011110  
> > &nbsp;&nbsp;/// let y1 = x &\>\> 2  
> > &nbsp;&nbsp;/// // y1 == 7 // 0b00000111  
> > &nbsp;&nbsp;/// let y2 = x \>\> 2  
> > &nbsp;&nbsp;/// // y2 == 7 // 0b00000111  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The right shift operator does not mask its right-hand-side argument, so  
> > &nbsp;&nbsp;/// passing `11` as `rhs` shifts all the bits of `x` to zero.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let z1 = x &\>\> 11  
> > &nbsp;&nbsp;/// // z1 == 240 // 0b00000011  
> > &nbsp;&nbsp;/// let z2 = x \>\> 11  
> > &nbsp;&nbsp;/// // z2 == 0 // 0b00000000  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter rhs: The number of bits to shift this value to the right. If  
> > &nbsp;&nbsp;/// `rhs` is outside the range `0..\<bitWidth`, it is masked to produce a  
> > &nbsp;&nbsp;/// value within that range.  
> > &nbsp;&nbsp;/// - Returns: The result of shifting this value by the masked `rhs` to the  
> > &nbsp;&nbsp;/// right.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `&\<\<`, `\>\>`  
> > &nbsp;&nbsp;static func &\>\>(\_ lhs: Self, \_ rhs: Self) -\> Self  
> > &nbsp;&nbsp;static func &\>\>=(\_ lhs: inout Self, \_ rhs: Self)
> > 
> > &nbsp;&nbsp;/// Returns the result of shifting this value's binary representation the  
> > &nbsp;&nbsp;/// specified number of digits to the left.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// In a \*masking shift\*, the bit pattern of the value passed as `rhs` is  
> > &nbsp;&nbsp;/// masked to produce a value between zero and the bit width of `lhs`. The  
> > &nbsp;&nbsp;/// shift is performed using this masked value. Masking shifts require more  
> > &nbsp;&nbsp;/// care to use correctly than a traditional bit shift, but are likely to be  
> > &nbsp;&nbsp;/// more efficient when used with shift amounts that are not compile-time  
> > &nbsp;&nbsp;/// constants. On most architectures, a masking shift compiles down to a  
> > &nbsp;&nbsp;/// single instruction.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For example, if you shift an 8-bit, unsigned integer by 2, the shift  
> > &nbsp;&nbsp;/// amount requires no masking.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt8 = 30 // 0b00011110  
> > &nbsp;&nbsp;/// let y = x &\>\> 2  
> > &nbsp;&nbsp;/// // y == 120 // 0b01111000  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// However, if you shift it by 11, it first bitmasks `rhs` to `3`, and then  
> > &nbsp;&nbsp;/// uses that masked value as the number of bits to shift `x`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let z = x &\<\< 11  
> > &nbsp;&nbsp;/// // z == 240 // 0b11110000  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// Relationship to the Left Shift Operator  
> > &nbsp;&nbsp;/// ---------------------------------------  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The masking left shift operator handles attempted overshifts and  
> > &nbsp;&nbsp;/// undershifts differently from the left shift operator (`\<\<`). When the  
> > &nbsp;&nbsp;/// value passed as `rhs` in a masking shift is within the range  
> > &nbsp;&nbsp;/// `0...\<bitWidth`, the operation is equivalent to using the left shift  
> > &nbsp;&nbsp;/// operator.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt8 = 30 // 0b00011110  
> > &nbsp;&nbsp;/// let y1 = x &\<\< 2  
> > &nbsp;&nbsp;/// // y1 == 120 // 0b01111000  
> > &nbsp;&nbsp;/// let y2 = x \<\< 2  
> > &nbsp;&nbsp;/// // y2 == 120 // 0b01111000  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The left shift operator does not mask its right-hand-side argument, so  
> > &nbsp;&nbsp;/// passing `11` as `rhs` shifts all the bits of `x` to zero.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let z1 = x &\<\< 11  
> > &nbsp;&nbsp;/// // z1 == 240 // 0b11110000  
> > &nbsp;&nbsp;/// let z2 = x \<\< 11  
> > &nbsp;&nbsp;/// // z2 == 0 // 0b00000000  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter rhs: The number of bits to shift this value to the left. If  
> > &nbsp;&nbsp;/// `rhs` is outside the range `0..\<bitWidth`, it is masked to produce a  
> > &nbsp;&nbsp;/// value within that range.  
> > &nbsp;&nbsp;/// - Returns: The result of shifting this value by the masked `rhs` to the  
> > &nbsp;&nbsp;/// left.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `&\>\>`, `\<\<`  
> > &nbsp;&nbsp;static func &\<\<(\_ lhs: Self, \_ rhs: Self) -\> Self  
> > &nbsp;&nbsp;static func &\<\<=(\_ lhs: inout Self, \_ rhs: Self)
> > 
> > &nbsp;&nbsp;/// Returns the quotient and remainder of this value divided by the given  
> > &nbsp;&nbsp;/// value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// Use this method to calculate the quotient and remainder of a division at  
> > &nbsp;&nbsp;/// the same time.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x = 1\_000\_000  
> > &nbsp;&nbsp;/// let (q, r) = x.quotientAndRemainder(dividingBy: 933)  
> > &nbsp;&nbsp;/// // q == 1071  
> > &nbsp;&nbsp;/// // r == 757  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter rhs: The value to divide this value by.  
> > &nbsp;&nbsp;/// - Returns: A tuple containing the quotient and remainder of this value  
> > &nbsp;&nbsp;/// divided by `rhs`.  
> > &nbsp;&nbsp;func quotientAndRemainder(dividingBy rhs: Self)  
> > &nbsp;&nbsp;&nbsp;&nbsp;-\> (quotient: Self, remainder: Self)
> > 
> > &nbsp;&nbsp;/// Returns `-1` if this value is negative and `1` if it's positive;  
> > &nbsp;&nbsp;/// otherwise, `0`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Returns: The sign of this number, expressed as an integer of the same  
> > &nbsp;&nbsp;/// type.  
> > &nbsp;&nbsp;func signum() -\> Self  
> > }  
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#fixedwidthinteger&gt;FixedWidthInteger)
> > 
> > The FixedWidthInteger protocol adds the notion of endianness as well as static properties for type bounds and bit width.
> > 
> > The WithOverflow family of methods is used in default implementations of mutating arithmetic methods (see the Arithmetic protocol). Having these methods allows the library to provide both bounds-checked and masking implementations of arithmetic operations, without duplicating code.
> > 
> > The doubleWidthMultiply and doubleWidthDivide methods are necessary building blocks to implement support for integer types of a greater width such as arbitrary-precision integers.
> > 
> > public protocol FixedWidthInteger : BinaryInteger {  
> > &nbsp;&nbsp;/// The number of bits used for the underlying binary representation of  
> > &nbsp;&nbsp;/// values of this type.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// An unsigned, fixed-width integer type can represent values from 0 through  
> > &nbsp;&nbsp;/// `(2 **bitWidth) - 1`, where `**` is exponentiation. A signed,  
> > &nbsp;&nbsp;/// fixed-width integer type can represent values from  
> > &nbsp;&nbsp;/// `-(2 **bitWidth - 1)` through `(2** bitWidth - 1) - 1`. For example,  
> > &nbsp;&nbsp;/// the `Int8` type has a `bitWidth` value of 8 and can store any integer in  
> > &nbsp;&nbsp;/// the range `-128...127`.  
> > &nbsp;&nbsp;static var bitWidth : Int { get }
> > 
> > &nbsp;&nbsp;/// The maximum representable integer in this type.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For unsigned integer types, this value is `(2 ** bitWidth) - 1`, where  
> > &nbsp;&nbsp;/// `**` is exponentiation. For signed integer types, this value is  
> > &nbsp;&nbsp;/// `(2 ** bitWidth - 1) - 1`.  
> > &nbsp;&nbsp;static var max: Self { get }
> > 
> > &nbsp;&nbsp;/// The minimum representable value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For unsigned integer types, this value is always `0`. For signed integer  
> > &nbsp;&nbsp;/// types, this value is `-(2 **bitWidth - 1)`, where `**` is  
> > &nbsp;&nbsp;/// exponentiation.  
> > &nbsp;&nbsp;static var min: Self { get }
> > 
> > &nbsp;&nbsp;/// Returns the sum of this value and the given value along with a flag  
> > &nbsp;&nbsp;/// indicating whether overflow occurred in the operation.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter other: The value to add to this value.  
> > &nbsp;&nbsp;/// - Returns: A tuple containing the result of the addition along with a  
> > &nbsp;&nbsp;/// flag indicating whether overflow occurred. If the `overflow` component  
> > &nbsp;&nbsp;/// is `.none`, the `partialValue` component contains the entire sum. If  
> > &nbsp;&nbsp;/// the `overflow` component is `.overflow`, an overflow occurred and the  
> > &nbsp;&nbsp;/// `partialValue` component contains the truncated sum of this value and  
> > &nbsp;&nbsp;/// `other`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `+`  
> > &nbsp;&nbsp;func addingWithOverflow(\_ other: Self)  
> > &nbsp;&nbsp;&nbsp;&nbsp;-\> (partialValue: Self, overflow: ArithmeticOverflow)
> > 
> > &nbsp;&nbsp;/// Returns the difference of this value and the given value along with a  
> > &nbsp;&nbsp;/// flag indicating whether overflow occurred in the operation.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter other: The value to subtract from this value.  
> > &nbsp;&nbsp;/// - Returns: A tuple containing the result of the subtraction along with a  
> > &nbsp;&nbsp;/// flag indicating whether overflow occurred. If the `overflow` component  
> > &nbsp;&nbsp;/// is `.none`, the `partialValue` component contains the entire  
> > &nbsp;&nbsp;/// difference. If the `overflow` component is `.overflow`, an overflow  
> > &nbsp;&nbsp;/// occurred and the `partialValue` component contains the truncated  
> > &nbsp;&nbsp;/// result of `other` subtracted from this value.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `-`  
> > &nbsp;&nbsp;func subtractingWithOverflow(\_ other: Self)  
> > &nbsp;&nbsp;&nbsp;&nbsp;-\> (partialValue: Self, overflow: ArithmeticOverflow)
> > 
> > &nbsp;&nbsp;/// Returns the product of this value and the given value along with a flag  
> > &nbsp;&nbsp;/// indicating whether overflow occurred in the operation.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter other: The value to multiply by this value.  
> > &nbsp;&nbsp;/// - Returns: A tuple containing the result of the multiplication along with  
> > &nbsp;&nbsp;/// a flag indicating whether overflow occurred. If the `overflow`  
> > &nbsp;&nbsp;/// component is `.none`, the `partialValue` component contains the entire  
> > &nbsp;&nbsp;/// product. If the `overflow` component is `.overflow`, an overflow  
> > &nbsp;&nbsp;/// occurred and the `partialValue` component contains the truncated  
> > &nbsp;&nbsp;/// product of this value and `other`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `*`, `doubleWidthMultiply(_:_:)`  
> > &nbsp;&nbsp;func multipliedWithOverflow(by other: Self)  
> > &nbsp;&nbsp;&nbsp;&nbsp;-\> (partialValue: Self, overflow: ArithmeticOverflow)
> > 
> > &nbsp;&nbsp;/// Returns the quotient of dividing this value by the given value along with  
> > &nbsp;&nbsp;/// a flag indicating whether overflow occurred in the operation.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For a value `x`, if zero is passed as `other`, the result is  
> > &nbsp;&nbsp;/// `(x, .overflow)`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameter other: The value to divide this value by.  
> > &nbsp;&nbsp;/// - Returns: A tuple containing the result of the division along with a  
> > &nbsp;&nbsp;/// flag indicating whether overflow occurred. If the `overflow` component  
> > &nbsp;&nbsp;/// is `.none`, the `partialValue` component contains the entire quotient.  
> > &nbsp;&nbsp;/// If the `overflow` component is `.overflow`, an overflow occurred and  
> > &nbsp;&nbsp;/// the `partialValue` component contains the truncated quotient.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `/`, `doubleWidthDivide(_:_:)`  
> > &nbsp;&nbsp;func dividedWithOverflow(by other: Self)  
> > &nbsp;&nbsp;&nbsp;&nbsp;-\> (partialValue: Self, overflow: ArithmeticOverflow)
> > 
> > &nbsp;&nbsp;/// Returns a tuple containing the high and low parts of the result of  
> > &nbsp;&nbsp;/// multiplying its arguments.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// Use this method to calculate the full result of a product that would  
> > &nbsp;&nbsp;/// otherwise overflow. Unlike traditional truncating multiplication, the  
> > &nbsp;&nbsp;/// `doubleWidthMultiply(_:_:)` method returns both the `high` and `low`  
> > &nbsp;&nbsp;/// parts of the product of `lhs` and `rhs`. The following example uses this  
> > &nbsp;&nbsp;/// method to multiply two `UInt8` values that normally overflow when  
> > &nbsp;&nbsp;/// multiplied:  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: UInt8 = 100  
> > &nbsp;&nbsp;/// let y: UInt8 = 20  
> > &nbsp;&nbsp;/// let result = UInt8.doubleWidthMultiply(100, 20)  
> > &nbsp;&nbsp;/// // result.high == 0b00000111  
> > &nbsp;&nbsp;/// // result.low == 0b11010000  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The product of `x` and `y` is 2000, which is too large to represent in a  
> > &nbsp;&nbsp;/// `UInt8` instance. The `high` and `low` components of the `result` tuple  
> > &nbsp;&nbsp;/// represent 2000 when concatenated to form a double-width integer; that  
> > &nbsp;&nbsp;/// is, using `result.high` as the high byte and `result.low` as the low byte  
> > &nbsp;&nbsp;/// of a `UInt16` instance.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let z = UInt16(result.high) \<\< 8 | UInt16(result.low)  
> > &nbsp;&nbsp;/// // z == 2000  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameters:  
> > &nbsp;&nbsp;/// - lhs: A value to multiply.  
> > &nbsp;&nbsp;/// - rhs: Another value to multiply.  
> > &nbsp;&nbsp;/// - Returns: A tuple containing the high and low parts of the result of  
> > &nbsp;&nbsp;/// multiplying `lhs` and `rhs`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `multipliedWithOverflow(by:)`  
> > &nbsp;&nbsp;static func doubleWidthMultiply(\_ lhs: Self, \_ rhs: Self)  
> > &nbsp;&nbsp;&nbsp;&nbsp;-\> (high: Self, low: Magnitude)
> > 
> > &nbsp;&nbsp;/// Returns a tuple containing the quotient and remainder of dividing the  
> > &nbsp;&nbsp;/// first argument by the second.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// The resulting quotient must be representable within the bounds of the  
> > &nbsp;&nbsp;/// type. If the quotient of dividing `lhs` by `rhs` is too large to  
> > &nbsp;&nbsp;/// represent in the type, a runtime error may occur.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - Parameters:  
> > &nbsp;&nbsp;/// - lhs: A tuple containing the high and low parts of a double-width  
> > &nbsp;&nbsp;/// integer. The `high` component of the tuple carries the sign, if the  
> > &nbsp;&nbsp;/// type is signed.  
> > &nbsp;&nbsp;/// - rhs: The integer to divide into `lhs`.  
> > &nbsp;&nbsp;/// - Returns: A tuple containing the quotient and remainder of `lhs` divided  
> > &nbsp;&nbsp;/// by `rhs`.  
> > &nbsp;&nbsp;static func doubleWidthDivide(  
> > &nbsp;&nbsp;&nbsp;&nbsp;\_ lhs: (high: Self, low: Magnitude), \_ rhs: Self)  
> > &nbsp;&nbsp;&nbsp;&nbsp;-\> (quotient: Self, remainder: Self)
> > 
> > &nbsp;&nbsp;/// The number of bits equal to 1 in this value's binary representation.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For example, in a fixed-width integer type with a `bitWidth` value of 8,  
> > &nbsp;&nbsp;/// the number 31 has five bits equal to 1.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: Int8 = 0b0001\_1111  
> > &nbsp;&nbsp;/// // x == 31  
> > &nbsp;&nbsp;/// // x.popcount == 5  
> > &nbsp;&nbsp;var popcount: Int { get }
> > 
> > &nbsp;&nbsp;/// The number of leading zeros in this value's binary representation.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// For example, in a fixed-width integer type with a `bitWidth` value of 8,  
> > &nbsp;&nbsp;/// the number 31 has three leading zeros.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// let x: Int8 = 0b0001\_1111  
> > &nbsp;&nbsp;/// // x == 31  
> > &nbsp;&nbsp;/// // x.leadingZeros == 3  
> > &nbsp;&nbsp;/// - SeeAlso: `BinaryInteger.trailingZeros`  
> > &nbsp;&nbsp;var leadingZeros: Int { get }
> > 
> > &nbsp;&nbsp;/// Creates an integer from its big-endian representation, changing the  
> > &nbsp;&nbsp;/// byte order if necessary.  
> > &nbsp;&nbsp;init(bigEndian value: Self)
> > 
> > &nbsp;&nbsp;/// Creates an integer from its little-endian representation, changing the  
> > &nbsp;&nbsp;/// byte order if necessary.  
> > &nbsp;&nbsp;init(littleEndian value: Self)
> > 
> > &nbsp;&nbsp;/// The big-endian representation of this integer.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// If necessary, the byte order of this value is reversed from the typical  
> > &nbsp;&nbsp;/// byte order of this integer type. On a big-endian platform, for any  
> > &nbsp;&nbsp;/// integer `x`, `x == x.bigEndian`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `littleEndian`  
> > &nbsp;&nbsp;var bigEndian: Self { get }
> > 
> > &nbsp;&nbsp;/// The little-endian representation of this integer.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// If necessary, the byte order of this value is reversed from the typical  
> > &nbsp;&nbsp;/// byte order of this integer type. On a little-endian platform, for any  
> > &nbsp;&nbsp;/// integer `x`, `x == x.littleEndian`.  
> > &nbsp;&nbsp;///  
> > &nbsp;&nbsp;/// - SeeAlso: `bigEndian`  
> > &nbsp;&nbsp;var littleEndian: Self { get }
> > 
> > &nbsp;&nbsp;/// A representation of this integer with the byte order swapped.  
> > &nbsp;&nbsp;var byteSwapped: Self { get }  
> > }  
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#auxiliary-protocols&gt;Auxiliary) protocols
> > 
> > public protocol UnsignedInteger : BinaryInteger {  
> > &nbsp;&nbsp;associatedtype Magnitude : BinaryInteger  
> > }  
> > public protocol SignedInteger : BinaryInteger, SignedArithmetic {  
> > &nbsp;&nbsp;associatedtype Magnitude : BinaryInteger  
> > }  
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#doublewidth&gt;DoubleWidth)
> > 
> > The DoubleWidth\<T\> type allows to create wider fixed-width integer types from the ones available in the standard library.
> > 
> > Standard library currently provides fixed-width integer types of up to 64 bits. A value of DoubleWidth\<Int64\> will double the range of the underlying type and implement all the FixedWidthInteger requirements. Please note though that the implementation will not necessarily be the most efficient one, so it would not be a good idea to use DoubleWidth\<Int32\>instead of a built-in Int64.
> > 
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#extra-operators&gt;Extra) operators
> > 
> > In addition to the operators described in the protocols section \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#protocols&gt;), we also provide a few extensions that are not protocol requirements:
> > 
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#heterogeneous-shifts&gt;Heterogeneous) shifts
> > 
> > extension BinaryInteger {  
> > &nbsp;&nbsp;// Masking shifts  
> > &nbsp;&nbsp;static func &\>\> \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self  
> > &nbsp;&nbsp;static func &\>\>= \<Other : BinaryInteger\>(lhs: inout Self, rhs: Other)  
> > &nbsp;&nbsp;static func &\<\< \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self  
> > &nbsp;&nbsp;static func &\<\<= \<Other : BinaryInteger\>(lhs: inout Self, rhs: Other)
> > 
> > &nbsp;&nbsp;// 'Smart' shifts  
> > &nbsp;&nbsp;static func \>\> \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self  
> > &nbsp;&nbsp;static func \>\>= \<Other : BinaryInteger\>(lhs: inout Self, rhs: Other)  
> > &nbsp;&nbsp;static func \<\< \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self  
> > &nbsp;&nbsp;static func \<\<= \<Other : BinaryInteger\>(lhs: inout Self, rhs: Other)  
> > }  
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#heterogeneous-equality-and-comparison&gt;Heterogeneous) equality and comparison
> > 
> > extension BinaryInteger {  
> > &nbsp;&nbsp;// Equality  
> > &nbsp;&nbsp;static func == \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool  
> > &nbsp;&nbsp;static func != \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool
> > 
> > &nbsp;&nbsp;// Comparison  
> > &nbsp;&nbsp;static func \< \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool  
> > &nbsp;&nbsp;static func \<= \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool  
> > &nbsp;&nbsp;static func \> \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool  
> > &nbsp;&nbsp;static func \>= \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool  
> > }  
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#masking-arithmetic&gt;Masking) arithmetic
> > 
> > public func &\* \<T: FixedWidthInteger\>(lhs: T, rhs: T) -\> T  
> > public func &- \<T: FixedWidthInteger\>(lhs: T, rhs: T) -\> T  
> > public func &+ \<T: FixedWidthInteger\>(lhs: T, rhs: T) -\> T  
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#non-goals&gt;Non%5C-goals)
> > 
> > This proposal:
> > 
> > DOES NOT solve the integer promotion problem, which would allow mixed-type arithmetic. However, we believe that it is an important step in the right direction.
> > 
> > DOES NOT include the implementation of a BigInt type, but allows it to be implemented in the future.
> > 
> > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#source-compatibility&gt;Source) compatibility
> > 
> > The proposed change is designed to be as non-breaking as possible, and it has been proven that it does not break code on concrete integer types. However, there are still a few API breaking changes in the realm of generic code:
> > 
> > Integer protocols in Swift up to and including version 3 were not particularly useful for generic programming, but were rather a means of sharing implementation between conforming types. Therefore we believe the amount of code that relied on these protocols is relatively small. The breakage can be further reduced by introducing proper aliases for the removed protocols with deprecation warnings.
> > 
> > Deprecation of the BitwiseOperations protocol. We find it hard to imagine a type that conforms to this protocol, but is not a binary integer type.
> > 
> > Addition of 'smart' shifts will change the behavior of existing code. It will still compile, but will be potentially less performant due to extra logic involved. In a case, where this becomes a problem, newly introduced masking shift operators can be used instead. Unfortunately, performance characteristics of the code cannot be statically checked, and thus migration cannot be provided.
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![Brent\_Royal-Gordon](https://avatars.discourse-cdn.com/v4/letter/b/53a042/32.png) [@Brent\_Royal-Gordon](https://forums.swift.org/u/Brent_Royal-Gordon)\
**Post date:** [January 29, 2017, 12:02pm UTC](https://forums.swift.org/t/protocol-oriented-integers-take-2/4884/9 "2017-01-29T12:02:53Z")

</div>

> Protocol-oriented integers (take 2)
> 
> &nbsp;&nbsp;• Proposal: SE-NNNN  
> &nbsp;&nbsp;• Authors: Dave Abrahams, Maxim Moiseev  
> &nbsp;&nbsp;• Review Manager: TBD  
> &nbsp;&nbsp;• Status: Awaiting review  
> &nbsp;&nbsp;• Bug: SR-3196  
> &nbsp;&nbsp;• Previous Proposal: SE-0104

Definitely liking what I'm seeing here.

> public protocol Arithmetic : Equatable, ExpressibleByIntegerLiteral  
> {

Is there a reason `Arithmetic` is not `Hashable`? (I think `Comparable` isn't here because complex numbers can't be compared, but correct me if I'm wrong about that.)

> /// A type that can represent the absolute value of any possible value of the  
> &nbsp;&nbsp;/// conforming type.  
> &nbsp;&nbsp;associatedtype Magnitude : Equatable, ExpressibleByIntegerLiteral

Is there a reason not to have this be `Arithmetic`? Maybe just the circularity problem?

> /// Returns the n-th word, counting from the least significant to most  
> &nbsp;&nbsp;/// significant, of this value's binary representation.  
> &nbsp;&nbsp;///  
> &nbsp;&nbsp;/// The `word(at:)` method returns negative values in two's complement  
> &nbsp;&nbsp;/// representation, regardless of a type's underlying implementation. If `n`  
> &nbsp;&nbsp;/// is greater than the number of words in this value's current  
> &nbsp;&nbsp;/// representation, the result is `0` for positive numbers and `~0` for  
> &nbsp;&nbsp;/// negative numbers.  
> &nbsp;&nbsp;///  
> &nbsp;&nbsp;/// - Parameter n: The word to return, counting from the least significant to  
> &nbsp;&nbsp;/// most significant. `n` must be greater than or equal to zero.  
> &nbsp;&nbsp;/// - Returns: An word-sized, unsigned integer with the bit pattern of the  
> &nbsp;&nbsp;/// n-th word of this value.  
> &nbsp;&nbsp;func word(at n: Int) -\> UInt

How does the client know how many words there are? Are they supposed to calculate that from `bitWidth`?

Oh, I see:

> good catch; countRepresentedWords is in the prototype  
> ([https://github.com/apple/swift/blob/new-integer-protocols/stdlib/public/core/Integers.swift.gyb#L1521\](https://github.com/apple/swift/blob/new-integer-protocols/stdlib/public/core/Integers.swift.gyb#L1521%5C)),  
> and it should be in the proposal.

That looks fine to me.

> /// The number of bits in the current binary representation of this value.  
> &nbsp;&nbsp;///  
> &nbsp;&nbsp;/// This property is a constant for instances of fixed-width integer  
> &nbsp;&nbsp;/// types.  
> &nbsp;&nbsp;var bitWidth : Int { get }

So, um, I'm a little confused about this one. Is this the physical number of bits in the value, or is it the number of bits you need to get from `word(at:)` in order to get all bits representing the value?

For instance, when you call `UInt32.bitWidth`, does it return `32`, the physical number of bits in the value, or `33`, the number of bits including the (always zero) sign bit?

> &nbsp;&nbsp;static func doubleWidthMultiply(\_ lhs: Self, \_ rhs: Self) -\> (high: Self, low: Magnitude)  
> &nbsp;&nbsp;static func doubleWidthDivide(\_ lhs: (high: Self, low: Magnitude), \_ rhs: Self) -\> (quotient: Self, remainder: Self)

Could these take/return a single `DoubleWidth\<Self\>` value instead of two separate `Self` and `Magnitude` values? Or would that present circularity problems?

> /// The number of bits equal to 1 in this value's binary representation.  
> &nbsp;&nbsp;///  
> &nbsp;&nbsp;/// For example, in a fixed-width integer type with a `bitWidth` value of 8,  
> &nbsp;&nbsp;/// the number 31 has five bits equal to 1.  
> &nbsp;&nbsp;///  
> &nbsp;&nbsp;/// let x: Int8 = 0b0001\_1111  
> &nbsp;&nbsp;/// // x == 31  
> &nbsp;&nbsp;/// // x.popcount == 5  
> &nbsp;&nbsp;var popcount: Int { get }

I'm not super-fond of this name; I assume it's a term of art, but it's a pretty obscure one. Maybe `numberOfOnes`? `onesWithin`?

> DoubleWidth
> 
> The DoubleWidth\<T\> type allows to create wider fixed-width integer types from the ones available in the standard library.

I'm glad you're planning to include `DoubleWidth` this time.

> &nbsp;&nbsp;• Deprecation of the BitwiseOperations protocol. We find it hard to imagine a type that conforms to this protocol, but is not a binary integer type.

While I'm sure any such type \*could\* be a binary integer type, I'm not convinced they necessary \*should\* be. For instance, suppose I have a "bit vector"; I know I never want to perform arithmetic on it, but I \*do\* want to manipulate bits separately, so I make it look like a `RandomAccessCollection` of `Bool`s. It might make a great deal of sense to support bitwise operations on this type, even though I don't want to clutter it up with arithmetic.

> **···**
>
> > On Jan 13, 2017, at 12:47 PM, Max Moiseev via swift-evolution \<swift-evolution@swift.org\> wrote:
> 
> --  
> Brent Royal-Gordon  
> Architechies

---

<div class="post-metadata">

**Author:** ![David\_Sweeris](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/david_sweeris/32/31302_2.png) [@David\_Sweeris](https://forums.swift.org/u/David_Sweeris)\
**Post date:** [January 29, 2017, 6:29pm UTC](https://forums.swift.org/t/protocol-oriented-integers-take-2/4884/10 "2017-01-29T18:29:28Z")

</div>

What about having a "CompoundBinaryInteger\<T,U\>" type, and then do "typealias DoubleWidth\<T\> = CompoundBinaryInteger\<T,T\>"? That would make it easier to have, say, 40-bit ints, "CompoundBinaryInteger\<Int8,Int32\>", while still having the convenience of "DoubleWidth\<T\>".

- Dave Sweeris

> **···**
>
> > On Jan 13, 2017, at 12:47, Max Moiseev via swift-evolution \<swift-evolution@swift.org\> wrote:
> 
> > DoubleWidth  
> > The DoubleWidth\<T\> type allows to create wider fixed-width integer types from the ones available in the standard library.
> > 
> > Standard library currently provides fixed-width integer types of up to 64 bits. A value of DoubleWidth\<Int64\> will double the range of the underlying type and implement all the FixedWidthInteger requirements. Please note though that the implementation will not necessarily be the most efficient one, so it would not be a good idea to use DoubleWidth\<Int32\>instead of a built-in Int64.

---

<div class="post-metadata">

**Author:** ![moiseev](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/moiseev/32/281_2.png) [@moiseev](https://forums.swift.org/u/moiseev)\
**Post date:** [January 13, 2017, 11:12pm UTC](https://forums.swift.org/t/protocol-oriented-integers-take-2/4884/11 "2017-01-13T23:12:17Z")

</div>

Hi Xiaodi,

> What is the performance penalty as compared to the existing operators?

First of all, I don’t have the concrete numbers unfortunately. But…  
If we are talking about concrete types, there should be very little difference between the two smart and masking shifts.  
For example, the following functions:

public func foo(x: UInt) -\> UInt {  
&nbsp;&nbsp;return x \>\> 32  
}

public func bar(x: UInt) -\> UInt {  
&nbsp;&nbsp;return x &\>\> 32  
}

Produce equivalent SIL and LLVM IR when compiled with optimizations. Moreover, if you change 32 to 100, then foo will become something like:

foo(x: UInt) { return 0 }

whereas bar will still call the llvm.shl.

> Beyond performance, what are the implications for migrating existing bit twiddling algorithms written in Swift 3?

Let’s take for example the ‘&\>\>” operator. There are 2 overloads: &\>\>(Self, Self) and &\>\>\<Other : BinaryInteger\>(Self, Other)  
(In Swift 3 there is only one version of \>\>, that takes both arguments of the same type.)

So, in an expression `x &\>\> 32`, compiler assumes 32 to have type Int (which is the default type for the integer literals) and prefer the heterogeneous overload. It might not be too bad, as I showed in examples above, but in order to increase chances of success you might want to specify an explicit type context, as in `x &\>\> (32 as TypeOfX)`.

As always, only concrete benchmarks will tell. We spent many hours optimizing the implementation for our existing benchmark suite.

Max

> **···**
>
> > On Jan 13, 2017, at 2:14 PM, Xiaodi Wu \<xiaodi.wu@gmail.com\> wrote:
> > 
> > [Resending to list with original message removed for length.]
> > 
> > This is fantastic. Glad to see it take shape. Very neat and insightful to have trailingZeros on BinaryInteger but leadingZeros on FixedWidthInteger. A couple of questions on smart shifts: What is the performance penalty as compared to the existing operators? Beyond performance, what are the implications for migrating existing bit twiddling algorithms written in Swift 3?

---

<div class="post-metadata">

**Author:** ![Stephen\_Canon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/stephen_canon/32/7220_2.png) [@Stephen\_Canon](https://forums.swift.org/u/Stephen_Canon)\
**Post date:** [January 13, 2017, 11:25pm UTC](https://forums.swift.org/t/protocol-oriented-integers-take-2/4884/12 "2017-01-13T23:25:50Z")

</div>

Hi Xiaodi —

I don’t want to speak for Max and Dave, but I think I can provide some insight for your questions about shifts.

First, the overwhelming majority of shifts have a compile-time-constant RHS. For these cases, there’s no performance change (except that the smart shifts may be able to optimize away the entire expression if the shift is overlarge).

For smart shifts with non-constant right-hand sides, the compiler will frequently still be able to prove that the shift count is always positive or negative and less than word size (this handles a lot of the most common cases like normalizing an integer, reading from a bitstream, or shifting words of a bignum); again there’s no performance penalty.

In the remaining cases where the compiler cannot bound the right-hand side, there will be some branches present; there may be a few regressions from these cases, but I expect most to be small (and the code simplifications are well worth it). Users can always use the masking shifts, which lower to single instructions for 32b and 64b integers types on Intel and arm64, and which are at worst an and and a shift (two very cheap instructions) on other architectures.

Basically, I expect there to be no perf impact for almost all code, and that the perf impact is relatively easily mitigated when it does occur. This is an easy tradeoff for fully-defined and sensible operator behavior.

– Steve

> **···**
>
> > On Jan 13, 2017, at 5:14 PM, Xiaodi Wu via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > [Resending to list with original message removed for length.]
> > 
> > This is fantastic. Glad to see it take shape. Very neat and insightful to have trailingZeros on BinaryInteger but leadingZeros on FixedWidthInteger. A couple of questions on smart shifts: What is the performance penalty as compared to the existing operators? Beyond performance, what are the implications for migrating existing bit twiddling algorithms written in Swift 3?

---

<div class="post-metadata">

**Author:** ![Benjamin\_Spratling](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/benjamin_spratling/32/2488_2.png) [@Benjamin\_Spratling](https://forums.swift.org/u/Benjamin_Spratling)\
**Post date:** [January 14, 2017, 10:41am UTC](https://forums.swift.org/t/protocol-oriented-integers-take-2/4884/13 "2017-01-14T10:41:33Z")

</div>

I notice the BinaryInteger's func word(at n: Int) -\> UInt function expects a 2's complement representation. Do you expect that "BigInt" will be implemented with 2's complement? As a nonmutating function, I would think any implementation from a 1's complement big int would result in O(n^2) unless the BigInt were designed with scratch space where it could store the intermediate values of that representation. I only ask because just last week I was designing an arbitrary-width float type in 1's complement, well, really I kept the sign bit in a separate Bool. Of course, I recognize the value of being able to write integer init code from a 2's complement representation, I'm just curious if there's a way to allow this function to be more efficient for alternate representations.

I love that there's a DoubleWidth type, having coded some arbitrary precision arithmetic, that's always a downer going from generic code to having to pick a specific "big enough" result type.

I'm glad the % operator got moved. It really did stand out as not part of floating points.

Trailing zeros looks like a sensible optimization.

I agree with moving the shift operators, I like that you've called out the notion of an infinite shift. I can't say I fully understood the use of the separate mask vs. smart shift operators, but I'll take another read in the next few days and see if I understand why they exist.

I know this PR does not address the BitInt implementation, but do you have one?

I'm glad to see this moving forward.

-Ben Spratling

> **···**
>
> Sent from my iPad
> 
> > On Jan 14, 2017, at 2:00 AM, Rien via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > +1
> > 
> > Any change of including “ranged integers”?  
> > I.e. an integer with a value that must fit in a predefined range?
> > 
> > Regards,  
> > Rien
> > 
> > Site: [http://balancingrock.nl](http://balancingrock.nl)  
> > Blog: [http://swiftrien.blogspot.com](http://swiftrien.blogspot.com)  
> > Github: [Swiftrien (Rien) · GitHub](http://github.com/Swiftrien)  
> > Project: [http://swiftfire.nl](http://swiftfire.nl)
> > 
> > > On 13 Jan 2017, at 21:47, Max Moiseev via swift-evolution \<swift-evolution@swift.org\> wrote:
> > > 
> > > Hi everyone,
> > > 
> > > Back in June 2016 we discussed the new design of the integer types for the standard library. It even resulted in acceptance of SE-0104 for Swift 3. Unfortunately we were not able to implement it in time for the release.
> > > 
> > > But it was not forgotten, although, as time went by, a few changes needed to be made in order to reflect the current state of the language.  
> > > Without further introduction, please welcome the refined proposal to make integers in Swift more suitable for generic programming.
> > > 
> > > Available in this gist [Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c) and also inlined below.
> > > 
> > > Max
> > > 
> > > Protocol-oriented integers (take 2)
> > > 
> > > &nbsp;&nbsp;&nbsp;• Proposal: SE-NNNN  
> > > &nbsp;&nbsp;&nbsp;• Authors: Dave Abrahams, Maxim Moiseev  
> > > &nbsp;&nbsp;&nbsp;• Review Manager: TBD  
> > > &nbsp;&nbsp;&nbsp;• Status: Awaiting review  
> > > &nbsp;&nbsp;&nbsp;• Bug: SR-3196  
> > > &nbsp;&nbsp;&nbsp;• Previous Proposal: SE-0104  
> > > Introduction
> > > 
> > > This proposal is an evolution of SE-0104. The goal is still to clean up Swifts integer APIs and make them more useful for generic programming.
> > > 
> > > The language has evolved in ways that affect integers APIs since the time the original proposal was approved for Swift 3. We also attempted to implement the proposed model in the standard library and found that some essential APIs were missing, whereas others could be safely removed.
> > > 
> > > Major changes to the APIs introduced by this proposal (as compared to SE-0104) are listed in a dedicated section.
> > > 
> > > Motivation
> > > 
> > > Swift's integer protocols don't currently provide a suitable basis for generic programming. See this blog post for an example of an attempt to implement a generic algorithm over integers.
> > > 
> > > The way the Arithmetic protocol is defined, it does not generalize to floating point numbers and also slows down compilation by requiring every concrete type to provide an implementation of arithmetic operators, thus polluting the overload set.
> > > 
> > > Converting from one integer type to another is performed using the concept of the 'maximum width integer' (see MaxInt), which is an artificial limitation. The very existence of MaxInt makes it unclear what to do should someone implement Int256, for example.
> > > 
> > > Another annoying problem is the inability to use integers of different types in comparison and bit-shift operations. For example, the following snippets won't compile:
> > > 
> > > var x: Int8 = 42  
> > > let y = 1  
> > > let z = 0
> > > 
> > > x  
> > > \<\<= y // error: binary operator '\<\<=' cannot be applied to operands of type 'Int8' and 'Int'  
> > > if x \> z { ... } // error: binary operator '\>' cannot be applied to operands of type 'Int8' and 'Int'  
> > > Currently, bit-shifting a negative number of (or too many) bits causes a trap on some platforms, which makes low-level bit manipulations needlessly dangerous and unpredictable.
> > > 
> > > Finally, the current design predates many of the improvements that came since Swift 1, and hasn't been revised since then.
> > > 
> > > Proposed solution
> > > 
> > > We propose a new model that does not have above mentioned problems and is more easily extensible.
> > > 
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+--------------+ +-------------+  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+------\>+ Arithmetic | | Comparable |  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \> (+,-,\*,/) | | (==,\<,\>,...)|  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> +-------------++ +---+---------+  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> ^ ^  
> > > +-------+------------+ | |  
> > > \> SignedArithmetic | +-+-------+-----------+  
> > > \> (unary -) | | BinaryInteger |  
> > > +------+-------------+ |(words,%,bitwise,...)|  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^ ++---+-----+----------+  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> +-----------^ ^ ^---------------+  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \> \> \>  
> > > +------+---------++ +---------+---------------+ +--+----------------+  
> > > \> SignedInteger | | FixedWidthInteger | | UnsignedInteger |  
> > > \> \> \>(endianness,overflow,...)| | |  
> > > +---------------+-+ +-+--------------------+--+ +-+-----------------+  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^ ^ ^ ^  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \> \> \>  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \> \> \>  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++--------+-+ +-+-------+-+  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\>Int family |-+ |UInt family|-+  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+-----------+ | +-----------+ |  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+-----------+ +-----------+
> > > 
> > > There are several benefits provided by this model over the old one:
> > > 
> > > &nbsp;&nbsp;&nbsp;• It allows mixing integer types in generic functions.
> > > 
> > > The possibility to initialize instances of any concrete integer type with values of any other concrete integer type enables writing functions that operate on more than one type conforming to BinaryInteger, such as heterogeneous comparisons or bit shifts, described later.
> > > 
> > > &nbsp;&nbsp;&nbsp;• It removes the overload resolution overhead.
> > > 
> > > Arithmetic and bitwise operations can now be defined as generic operators on protocols. This approach significantly reduces the number of overloads for those operations, which used to be defined for every single concrete integer type.
> > > 
> > > &nbsp;&nbsp;&nbsp;• It enables protocol sharing between integer and floating point types.
> > > 
> > > Note the exclusion of the % operation from Arithmetic. Its behavior for floating point numbers is sufficiently different from the one for integers that using it in generic context would lead to confusion. The FloatingPoint protocol introduced by SE-0067 should now refine SignedArithmetic.
> > > 
> > > &nbsp;&nbsp;&nbsp;• It makes future extensions possible.
> > > 
> > > The proposed model eliminates the 'largest integer type' concept previously used to interoperate between integer types (see toIntMax in the current model) and instead provides access to machine words. It also introduces thedoubleWidthMultiply, doubleWidthDivide, and quotientAndRemainder methods. Together these changes can be used to provide an efficient implementation of bignums that would be hard to achieve otherwise.
> > > 
> > > The implementation of proposed model in the standard library is available in the new-integer-protocols branch.
> > > 
> > > A note on bit shifts
> > > 
> > > This proposal introduces the concepts of smart shifts and masking shifts.
> > > 
> > > The semantics of shift operations are often undefined in under- or over-shift cases. Smart shifts, implemented by \>\> and \<\<, are designed to address this problem and always behave in a well defined way, as shown in the examples below:
> > > 
> > > &nbsp;&nbsp;&nbsp;• x \<\< -2 is equivalent to x \>\> 2
> > > 
> > > &nbsp;&nbsp;&nbsp;• (1 as UInt8) \>\> 42) will evaluate to 0
> > > 
> > > &nbsp;&nbsp;&nbsp;• (-128 as Int8) \>\> 42) will evaluate to 0xff or -1
> > > 
> > > In most scenarios, the right hand operand is a literal constant, and branches for handling under- and over-shift cases can be optimized away. For other cases, this proposal provides masking shifts, implemented by &\>\> and &\<\<. A masking shift logically preprocesses the right hand operand by masking its bits to produce a value in the range 0...(x-1) where x is the number of bits in the left hand operand. On most architectures this masking is already performed by the CPU's shift instructions and has no cost. Both kinds of shift avoid undefined behavior and produce uniform semantics across architectures.
> > > 
> > > Detailed design
> > > 
> > > What's new since SE-0104
> > > 
> > > &nbsp;&nbsp;&nbsp;• SE-0091 removed the necessity to dispatch generic operators through special methods.
> > > 
> > > All operators are now declared by protocols as static funcs.
> > > 
> > > &nbsp;&nbsp;&nbsp;• Standard Library no longer provides + and - operators for Strideable types.
> > > 
> > > They were problematic, as one could have written mixed-type code like let x: Int64 = 42; x += (1 as Int), which would compile, but shouldn't. Besides, since the Stride of an unsigned type is signed, Standard Library had to implement a hack to make code like let x: UInt = 42; x += (1 as Int) ambiguous. These operators were only necessary because they made advancing collection indices convenient, which is no longer the case since the introduction of the new indexing model in Swift 3.
> > > 
> > > &nbsp;&nbsp;&nbsp;• Shifts and other bitwise operations were moved from FixedWidthInteger to BinaryInteger.
> > > 
> > > Left shift operation on an unbounded integer should infinitely extend the number, and never drop set bits when they reach the most significant position in the underlying representation.
> > > 
> > > &nbsp;&nbsp;&nbsp;• BitwiseOperations protocol was deprecated.
> > > 
> > > We believe there are no useful entities that support bitwise operations, but at the same time are not binary integers.
> > > 
> > > &nbsp;&nbsp;&nbsp;• minimumSignedRepresentationBitWidth property was removed.
> > > 
> > > &nbsp;&nbsp;&nbsp;• trailingZeros property was added to the BinaryInteger protocol.
> > > 
> > > leadingZeros and popcount properties are still defined by the FixedWidthInteger protocol.
> > > 
> > > &nbsp;&nbsp;&nbsp;• Endian-converting initializers and properties were added to the FixedWidthInteger protocol.
> > > 
> > > &nbsp;&nbsp;&nbsp;• Standard library introduces the new type DoubleWidth\<T\>.
> > > 
> > > See this section for more details.
> > > 
> > > Protocols
> > > 
> > > Arithmetic
> > > 
> > > The Arithmetic protocol declares binary arithmetic operators – such as +, -, and \* — and their mutating counterparts.
> > > 
> > > It provides a suitable basis for arithmetic on scalars such as integers and floating point numbers.
> > > 
> > > Both mutating and non-mutating operations are declared in the protocol, however only the mutating ones are required, as default implementations of the non-mutating ones are provided by a protocol extension.
> > > 
> > > The Magnitude associated type is able to hold the absolute value of any possible value of Self. Concrete types do not have to provide a type alias for it, as it can be inferred from the magnitude property. This property can be useful in operations that are simpler to implement in terms of unsigned values, for example, printing a value of an integer, which is just printing a '-' character in front of an absolute value.
> > > 
> > > Please note that for ordinary work, the magnitude property should not be preferred to the abs(\_) function, whose return value is of the same type as its argument.
> > > 
> > > public protocol Arithmetic : Equatable, ExpressibleByIntegerLiteral  
> > > {
> > > 
> > > /// Creates a new instance from the given integer, if it can be represented  
> > > /// exactly.  
> > > ///  
> > > /// If the value passed as `source` is not representable exactly, the result  
> > > /// is `nil`. In the following example, the constant `x` is successfully  
> > > /// created from a value of `100`, while the attempt to initialize the  
> > > /// constant `y` from `1_000` fails because the `Int8` type can represent  
> > > /// `127` at maximum:  
> > > ///  
> > > /// let x = Int8(exactly: 100)  
> > > /// // x == Optional(100)  
> > > /// let y = Int8(exactly: 1\_000)  
> > > /// // y == nil  
> > > ///  
> > > /// - Parameter source: A floating-point value to convert to an integer.  
> > > init?\<T : BinaryInteger\>(exactly source  
> > > : T)
> > > 
> > > /// A type that can represent the absolute value of any possible value of the  
> > > /// conforming type.  
> > > associatedtype Magnitude : Equatable, ExpressibleByIntegerLiteral
> > > 
> > > /// The magnitude of this value.  
> > > ///  
> > > /// For any numeric value `x`, `x.magnitude` is the absolute value of `x`.  
> > > /// You can use the `magnitude` property in operations that are simpler to  
> > > /// implement in terms of unsigned values, such as printing the value of an  
> > > /// integer, which is just printing a '-' character in front of an absolute  
> > > /// value.  
> > > ///  
> > > /// let x = -200  
> > > /// // x.magnitude == 200  
> > > ///  
> > > /// The global `abs(_:)` function provides more familiar syntax when you need  
> > > /// to find an absolute value. In addition, because `abs(_:)` always returns  
> > > /// a value of the same type, even in a generic context, using the function  
> > > /// instead of the `magnitude` property is encouraged.  
> > > ///  
> > > /// - SeeAlso: `abs(_:)`  
> > > var magnitude: Magnitude { get  
> > > }
> > > 
> > > /// Returns the sum of the two given values.  
> > > ///  
> > > /// The sum of `lhs` and `rhs` must be representable in the same type. In the  
> > > /// following example, the result of `100 + 200` is greater than the maximum  
> > > /// representable `Int8` value:  
> > > ///  
> > > /// let x: Int8 = 10 + 21  
> > > /// // x == 31  
> > > /// let y: Int8 = 100 + 121  
> > > /// // Overflow error  
> > > static func +(\_ lhs: Self, \_ rhs: Self) -\> Self
> > > 
> > > /// Adds the given value to this value in place.  
> > > ///  
> > > /// For example:  
> > > ///  
> > > /// var x = 15  
> > > /// y += 7  
> > > /// // y == 22  
> > > static func +=(\_ lhs: inout Self, rhs: Self  
> > > )
> > > 
> > > /// Returns the difference of the two given values.  
> > > ///  
> > > /// The difference of `lhs` and `rhs` must be representable in the same type.  
> > > /// In the following example, the result of `10 - 21` is less than zero, the  
> > > /// minimum representable `UInt` value:  
> > > ///  
> > > /// let x: UInt = 21 - 10  
> > > /// // x == 11  
> > > /// let y: UInt = 10 - 21  
> > > /// // Overflow error  
> > > static func -(\_ lhs: Self, \_ rhs: Self) -\> Self
> > > 
> > > /// Subtracts the given value from this value in place.  
> > > ///  
> > > /// For example:  
> > > ///  
> > > /// var x = 15  
> > > /// y -= 7  
> > > /// // y == 8  
> > > static func -=(\_ lhs: inout Self, rhs: Self  
> > > )
> > > 
> > > /// Returns the product of the two given values.  
> > > ///  
> > > /// The product of `lhs` and `rhs` must be representable in the same type. In  
> > > /// the following example, the result of `10 * 50` is greater than the  
> > > /// maximum representable `Int8` value.  
> > > ///  
> > > /// let x: Int8 = 10 \* 5  
> > > /// // x == 50  
> > > /// let y: Int8 = 10 \* 50  
> > > /// // Overflow error  
> > > static func \*(\_ lhs: Self, \_ rhs: Self) -\> Self
> > > 
> > > /// Multiples this value by the given value in place.  
> > > ///  
> > > /// For example:  
> > > ///  
> > > /// var x = 15  
> > > /// y \*= 7  
> > > /// // y == 105  
> > > static func \*=(\_ lhs: inout Self, rhs: Self  
> > > )
> > > 
> > > /// Returns the quotient of dividing the first value by the second.  
> > > ///  
> > > /// For integer types, any remainder of the division is discarded.  
> > > ///  
> > > /// let x = 21 / 5  
> > > /// // x == 4  
> > > static func /(\_ lhs: Self, \_ rhs: Self) -\> Self
> > > 
> > > /// Divides this value by the given value in place.  
> > > ///  
> > > /// For example:  
> > > ///  
> > > /// var x = 15  
> > > /// y /= 7  
> > > /// // y == 2  
> > > static func /=(\_ lhs: inout Self, rhs: Self  
> > > )  
> > > }
> > > 
> > > extension Arithmetic  
> > > {
> > > 
> > > public init() { self = 0  
> > > }
> > > 
> > > public static prefix func + (x: Self) -\> Self  
> > > {
> > > 
> > > return  
> > > x  
> > > }  
> > > }
> > > 
> > > SignedArithmetic
> > > 
> > > The SignedArithmetic protocol is for numbers that can be negated.
> > > 
> > > public protocol SignedArithmetic : Arithmetic  
> > > {
> > > 
> > > /// Returns the additive inverse of this value.  
> > > ///  
> > > /// let x = 21  
> > > /// let y = -x  
> > > /// // y == -21  
> > > ///  
> > > /// - Returns: The additive inverse of this value.  
> > > ///  
> > > /// - SeeAlso: `negate()`  
> > > static prefix func - (\_ operand: Self) -\> Self
> > > 
> > > /// Replaces this value with its additive inverse.  
> > > ///  
> > > /// The following example uses the `negate()` method to negate the value of  
> > > /// an integer `x`:  
> > > ///  
> > > /// var x = 21  
> > > /// x.negate()  
> > > /// // x == -21  
> > > ///  
> > > /// - SeeAlso: The unary minus operator (`-`).  
> > > mutating func negate  
> > > ()  
> > > }
> > > 
> > > extension SignedArithmetic  
> > > {
> > > 
> > > public static prefix func - (\_ operand: Self) -\> Self  
> > > {
> > > 
> > > var result =  
> > > operand  
> > > &nbsp;&nbsp;&nbsp;result.  
> > > negate  
> > > ()
> > > 
> > > return  
> > > result  
> > > }
> > > 
> > > public mutating func negate  
> > > () {
> > > 
> > > self = Self() - self
> > > 
> > > }  
> > > }
> > > 
> > > BinaryInteger
> > > 
> > > The BinaryInteger protocol is the basis for all the integer types provided by the standard library.
> > > 
> > > This protocol adds a few new initializers. Two of them allow to create integers from floating point numbers, others support construction from instances of any type conforming to BinaryInteger, using different strategies:
> > > 
> > > &nbsp;&nbsp;&nbsp;• Initialize Self with the value, provided that the value is representable. The precondition should be satisfied by the caller.
> > > 
> > > &nbsp;&nbsp;&nbsp;• Extend or truncate the value to fit into Self
> > > 
> > > &nbsp;&nbsp;&nbsp;• Clamp the value to the representable range of Self
> > > 
> > > BinaryInteger also declares bitwise and shift operators.
> > > 
> > > public protocol BinaryInteger :  
> > > Comparable, Hashable, Arithmetic, CustomStringConvertible, Strideable  
> > > {
> > > 
> > > /// A Boolean value indicating whether this type is a signed integer type.  
> > > ///  
> > > /// \*Signed\* integer types can represent both positive and negative values.  
> > > /// \*Unsigned\* integer types can represent only nonnegative values.  
> > > static var isSigned: Bool { get  
> > > }
> > > 
> > > /// Creates an integer from the given floating-point value, if it can be  
> > > /// represented exactly.  
> > > ///  
> > > /// If the value passed as `source` is not representable exactly, the result  
> > > /// is `nil`. In the following example, the constant `x` is successfully  
> > > /// created from a value of `21.0`, while the attempt to initialize the  
> > > /// constant `y` from `21.5` fails:  
> > > ///  
> > > /// let x = Int(exactly: 21.0)  
> > > /// // x == Optional(21)  
> > > /// let y = Int(exactly: 21.5)  
> > > /// // y == nil  
> > > ///  
> > > /// - Parameter source: A floating-point value to convert to an integer.  
> > > init?\<T : FloatingPoint\>(exactly source  
> > > : T)
> > > 
> > > /// Creates an integer from the given floating-point value, truncating any  
> > > /// fractional part.  
> > > ///  
> > > /// Truncating the fractional part of `source` is equivalent to rounding  
> > > /// toward zero.  
> > > ///  
> > > /// let x = Int(21.5)  
> > > /// // x == 21  
> > > /// let y = Int(-21.5)  
> > > /// // y == -21  
> > > ///  
> > > /// If `source` is outside the bounds of this type after truncation, a  
> > > /// runtime error may occur.  
> > > ///  
> > > /// let z = UInt(-21.5)  
> > > /// // Error: ...the result would be less than UInt.min  
> > > ///  
> > > /// - Parameter source: A floating-point value to convert to an integer.  
> > > /// `source` must be representable in this type after truncation.  
> > > init\<T : FloatingPoint\>(\_ source  
> > > : T)
> > > 
> > > /// Creates an new instance from the given integer.  
> > > ///  
> > > /// If the value passed as `source` is not representable in this type, a  
> > > /// runtime error may occur.  
> > > ///  
> > > /// let x = -500 as Int  
> > > /// let y = Int32(x)  
> > > /// // y == -500  
> > > ///  
> > > /// // -500 is not representable as a 'UInt32' instance  
> > > /// let z = UInt32(x)  
> > > /// // Error  
> > > ///  
> > > /// - Parameter source: An integer to convert. `source` must be representable  
> > > /// in this type.  
> > > init\<T : BinaryInteger\>(\_ source  
> > > : T)
> > > 
> > > /// Creates a new instance from the bit pattern of the given instance by  
> > > /// sign-extending or truncating to fit this type.  
> > > ///  
> > > /// When the bit width of `T` (the type of `source`) is equal to or greater  
> > > /// than this type's bit width, the result is the truncated  
> > > /// least-significant bits of `source`. For example, when converting a  
> > > /// 16-bit value to an 8-bit type, only the lower 8 bits of `source` are  
> > > /// used.  
> > > ///  
> > > /// let p: Int16 = -500  
> > > /// // 'p' has a binary representation of 11111110\_00001100  
> > > /// let q = Int8(extendingOrTruncating: p)  
> > > /// // q == 12  
> > > /// // 'q' has a binary representation of 00001100  
> > > ///  
> > > /// When the bit width of `T` is less than this type's bit width, the result  
> > > /// is \*sign-extended\* to fill the remaining bits. That is, if `source` is  
> > > /// negative, the result is padded with ones; otherwise, the result is  
> > > /// padded with zeros.  
> > > ///  
> > > /// let u: Int8 = 21  
> > > /// // 'u' has a binary representation of 00010101  
> > > /// let v = Int16(extendingOrTruncating: u)  
> > > /// // v == 21  
> > > /// // 'v' has a binary representation of 00000000\_00010101  
> > > ///  
> > > /// let w: Int8 = -21  
> > > /// // 'w' has a binary representation of 11101011  
> > > /// let x = Int16(extendingOrTruncating: w)  
> > > /// // x == -21  
> > > /// // 'x' has a binary representation of 11111111\_11101011  
> > > /// let y = UInt16(extendingOrTruncating: w)  
> > > /// // y == 65515  
> > > /// // 'y' has a binary representation of 11111111\_11101011  
> > > ///  
> > > /// - Parameter source: An integer to convert to this type.  
> > > init\<T : BinaryInteger\>(extendingOrTruncating source  
> > > : T)
> > > 
> > > /// Creates a new instance with the representable value that's closest to the  
> > > /// given integer.  
> > > ///  
> > > /// If the value passed as `source` is greater than the maximum representable  
> > > /// value in this type, the result is the type's `max` value. If `source` is  
> > > /// less than the smallest representable value in this type, the result is  
> > > /// the type's `min` value.  
> > > ///  
> > > /// In this example, `x` is initialized as an `Int8` instance by clamping  
> > > /// `500` to the range `-128...127`, and `y` is initialized as a `UInt`  
> > > /// instance by clamping `-500` to the range `0...UInt.max`.  
> > > ///  
> > > /// let x = Int8(clamping: 500)  
> > > /// // x == 127  
> > > /// // x == Int8.max  
> > > ///  
> > > /// let y = UInt(clamping: -500)  
> > > /// // y == 0  
> > > ///  
> > > /// - Parameter source: An integer to convert to this type.  
> > > init\<T : BinaryInteger\>(clamping source  
> > > : T)
> > > 
> > > /// Returns the n-th word, counting from the least significant to most  
> > > /// significant, of this value's binary representation.  
> > > ///  
> > > /// The `word(at:)` method returns negative values in two's complement  
> > > /// representation, regardless of a type's underlying implementation. If `n`  
> > > /// is greater than the number of words in this value's current  
> > > /// representation, the result is `0` for positive numbers and `~0` for  
> > > /// negative numbers.  
> > > ///  
> > > /// - Parameter n: The word to return, counting from the least significant to  
> > > /// most significant. `n` must be greater than or equal to zero.  
> > > /// - Returns: An word-sized, unsigned integer with the bit pattern of the  
> > > /// n-th word of this value.  
> > > func word(at n: Int) -\> UInt
> > > 
> > > /// The number of bits in the current binary representation of this value.  
> > > ///  
> > > /// This property is a constant for instances of fixed-width integer  
> > > /// types.  
> > > var bitWidth : Int { get  
> > > }
> > > 
> > > /// The number of trailing zeros in this value's binary representation.  
> > > ///  
> > > /// For example, in a fixed-width integer type with a `bitWidth` value of 8,  
> > > /// the number -8 has three trailing zeros.  
> > > ///  
> > > /// let x = Int8(bitPattern: 0b1111\_1000)  
> > > /// // x == -8  
> > > /// // x.trailingZeros == 3  
> > > var trailingZeros: Int { get  
> > > }
> > > 
> > > /// Returns the remainder of dividing the first value by the second.  
> > > ///  
> > > /// The result has the same sign as `lhs` and is less than `rhs.magnitude`.  
> > > ///  
> > > /// let x = 22 % 5  
> > > /// // x == 2  
> > > /// let y = 22 % -5  
> > > /// // y == 2  
> > > /// let z = -22 % -5  
> > > /// // z == -2  
> > > ///  
> > > /// - Parameters:  
> > > /// - lhs: The value to divide.  
> > > /// - rhs: The value to divide `lhs` by. `rhs` must not be zero.  
> > > static func %(\_ lhs: Self, \_ rhs: Self) -\> Self
> > > 
> > > /// Replaces this value with the remainder of itself divided by the given  
> > > /// value. For example:  
> > > ///  
> > > /// var x = 15  
> > > /// x %= 7  
> > > /// // x == 1  
> > > ///  
> > > /// - Parameter rhs: The value to divide this value by. `rhs` must not be  
> > > /// zero.  
> > > ///  
> > > /// - SeeAlso: `remainder(dividingBy:)`  
> > > static func %=(\_ lhs: inout Self, \_ rhs: Self  
> > > )
> > > 
> > > /// Returns the inverse of the bits set in the argument.  
> > > ///  
> > > /// The bitwise NOT operator (`~`) is a prefix operator that returns a value  
> > > /// in which all the bits of its argument are flipped: Bits that are `1` in  
> > > /// the argument are `0` in the result, and bits that are `0` in the argument  
> > > /// are `1` in the result. This is equivalent to the inverse of a set. For  
> > > /// example:  
> > > ///  
> > > /// let x: UInt8 = 5 // 0b00000101  
> > > /// let notX = ~x // 0b11111010  
> > > ///  
> > > /// Performing a bitwise NOT operation on 0 returns a value with every bit  
> > > /// set to `1`.  
> > > ///  
> > > /// let allOnes = ~UInt8.min // 0b11111111  
> > > ///  
> > > /// - Complexity: O(1).  
> > > static prefix func ~ (\_ x: Self) -\> Self
> > > 
> > > /// Returns the result of performing a bitwise AND operation on this value  
> > > /// and the given value.  
> > > ///  
> > > /// A bitwise AND operation results in a value that has each bit set to `1`  
> > > /// where \*both\* of its arguments have that bit set to `1`. For example:  
> > > ///  
> > > /// let x: UInt8 = 5 // 0b00000101  
> > > /// let y: UInt8 = 14 // 0b00001110  
> > > /// let z = x & y // 0b00000100  
> > > static func &(\_ lhs: Self, \_ rhs: Self) -\> Self
> > > 
> > > static func &=(\_ lhs: inout Self, \_ rhs: Self  
> > > )
> > > 
> > > /// Returns the result of performing a bitwise OR operation on this value and  
> > > /// the given value.  
> > > ///  
> > > /// A bitwise OR operation results in a value that has each bit set to `1`  
> > > /// where \*one or both\* of its arguments have that bit set to `1`. For  
> > > /// example:  
> > > ///  
> > > /// let x: UInt8 = 5 // 0b00000101  
> > > /// let y: UInt8 = 14 // 0b00001110  
> > > /// let z = x | y // 0b00001111  
> > > static func |(\_ lhs: Self, \_ rhs: Self) -\> Self
> > > 
> > > static func |=(\_ lhs: inout Self, \_ rhs: Self  
> > > )
> > > 
> > > /// Returns the result of performing a bitwise XOR operation on this value  
> > > /// and the given value.  
> > > ///  
> > > /// A bitwise XOR operation, also known as an exclusive OR operation, results  
> > > /// in a value that has each bit set to `1` where \*one or the other but not  
> > > /// both\* of its arguments had that bit set to `1`. For example:  
> > > ///  
> > > /// let x: UInt8 = 5 // 0b00000101  
> > > /// let y: UInt8 = 14 // 0b00001110  
> > > /// let z = x ^ y // 0b00001011  
> > > static func ^(\_ lhs: Self, \_ rhs: Self) -\> Self
> > > 
> > > static func ^=(\_ lhs: inout Self, \_ rhs: Self  
> > > )
> > > 
> > > /// Returns the result of shifting this value's binary representation the  
> > > /// specified number of digits to the right.  
> > > ///  
> > > /// In a \*masking shift\*, the bit pattern of the value passed as `rhs` is  
> > > /// masked to produce a value between zero and the bit width of `lhs`. The  
> > > /// shift is performed using this masked value. Masking shifts require more  
> > > /// care to use correctly than a traditional bit shift, but are likely to be  
> > > /// more efficient when used with shift amounts that are not compile-time  
> > > /// constants. On most architectures, a masking shift compiles down to a  
> > > /// single instruction.  
> > > ///  
> > > /// For example, if you shift an 8-bit, unsigned integer by 2, the shift  
> > > /// amount requires no masking.  
> > > ///  
> > > /// let x: UInt8 = 30 // 0b00011110  
> > > /// let y = x &\>\> 2  
> > > /// // y == 7 // 0b00000111  
> > > ///  
> > > /// However, if you shift it by 11, it first bitmasks `rhs` to `3`, and then  
> > > /// uses that masked value as the number of bits to shift `x`.  
> > > ///  
> > > /// let z = x &\>\> 11  
> > > /// // z == 3 // 0b00000011  
> > > ///  
> > > /// Relationship to the Right Shift Operator  
> > > /// ----------------------------------------  
> > > ///  
> > > /// The masking right shift operator handles attempted overshifts and  
> > > /// undershifts differently from the right shift operator (`\>\>`). When the  
> > > /// value passed as `rhs` in a masking shift is within the range  
> > > /// `0...\<bitWidth`, the operation is equivalent to using the right shift  
> > > /// operator.  
> > > ///  
> > > /// let x: UInt8 = 30 // 0b00011110  
> > > /// let y1 = x &\>\> 2  
> > > /// // y1 == 7 // 0b00000111  
> > > /// let y2 = x \>\> 2  
> > > /// // y2 == 7 // 0b00000111  
> > > ///  
> > > /// The right shift operator does not mask its right-hand-side argument, so  
> > > /// passing `11` as `rhs` shifts all the bits of `x` to zero.  
> > > ///  
> > > /// let z1 = x &\>\> 11  
> > > /// // z1 == 240 // 0b00000011  
> > > /// let z2 = x \>\> 11  
> > > /// // z2 == 0 // 0b00000000  
> > > ///  
> > > /// - Parameter rhs: The number of bits to shift this value to the right. If  
> > > /// `rhs` is outside the range `0..\<bitWidth`, it is masked to produce a  
> > > /// value within that range.  
> > > /// - Returns: The result of shifting this value by the masked `rhs` to the  
> > > /// right.  
> > > ///  
> > > /// - SeeAlso: `&\<\<`, `\>\>`  
> > > static func &\>\>(\_ lhs: Self, \_ rhs: Self) -\> Self
> > > 
> > > static func &\>\>=(\_ lhs: inout Self, \_ rhs: Self  
> > > )
> > > 
> > > /// Returns the result of shifting this value's binary representation the  
> > > /// specified number of digits to the left.  
> > > ///  
> > > /// In a \*masking shift\*, the bit pattern of the value passed as `rhs` is  
> > > /// masked to produce a value between zero and the bit width of `lhs`. The  
> > > /// shift is performed using this masked value. Masking shifts require more  
> > > /// care to use correctly than a traditional bit shift, but are likely to be  
> > > /// more efficient when used with shift amounts that are not compile-time  
> > > /// constants. On most architectures, a masking shift compiles down to a  
> > > /// single instruction.  
> > > ///  
> > > /// For example, if you shift an 8-bit, unsigned integer by 2, the shift  
> > > /// amount requires no masking.  
> > > ///  
> > > /// let x: UInt8 = 30 // 0b00011110  
> > > /// let y = x &\>\> 2  
> > > /// // y == 120 // 0b01111000  
> > > ///  
> > > /// However, if you shift it by 11, it first bitmasks `rhs` to `3`, and then  
> > > /// uses that masked value as the number of bits to shift `x`.  
> > > ///  
> > > /// let z = x &\<\< 11  
> > > /// // z == 240 // 0b11110000  
> > > ///  
> > > /// Relationship to the Left Shift Operator  
> > > /// ---------------------------------------  
> > > ///  
> > > /// The masking left shift operator handles attempted overshifts and  
> > > /// undershifts differently from the left shift operator (`\<\<`). When the  
> > > /// value passed as `rhs` in a masking shift is within the range  
> > > /// `0...\<bitWidth`, the operation is equivalent to using the left shift  
> > > /// operator.  
> > > ///  
> > > /// let x: UInt8 = 30 // 0b00011110  
> > > /// let y1 = x &\<\< 2  
> > > /// // y1 == 120 // 0b01111000  
> > > /// let y2 = x \<\< 2  
> > > /// // y2 == 120 // 0b01111000  
> > > ///  
> > > /// The left shift operator does not mask its right-hand-side argument, so  
> > > /// passing `11` as `rhs` shifts all the bits of `x` to zero.  
> > > ///  
> > > /// let z1 = x &\<\< 11  
> > > /// // z1 == 240 // 0b11110000  
> > > /// let z2 = x \<\< 11  
> > > /// // z2 == 0 // 0b00000000  
> > > ///  
> > > /// - Parameter rhs: The number of bits to shift this value to the left. If  
> > > /// `rhs` is outside the range `0..\<bitWidth`, it is masked to produce a  
> > > /// value within that range.  
> > > /// - Returns: The result of shifting this value by the masked `rhs` to the  
> > > /// left.  
> > > ///  
> > > /// - SeeAlso: `&\>\>`, `\<\<`  
> > > static func &\<\<(\_ lhs: Self, \_ rhs: Self) -\> Self
> > > 
> > > static func &\<\<=(\_ lhs: inout Self, \_ rhs: Self  
> > > )
> > > 
> > > /// Returns the quotient and remainder of this value divided by the given  
> > > /// value.  
> > > ///  
> > > /// Use this method to calculate the quotient and remainder of a division at  
> > > /// the same time.  
> > > ///  
> > > /// let x = 1\_000\_000  
> > > /// let (q, r) = x.quotientAndRemainder(dividingBy: 933)  
> > > /// // q == 1071  
> > > /// // r == 757  
> > > ///  
> > > /// - Parameter rhs: The value to divide this value by.  
> > > /// - Returns: A tuple containing the quotient and remainder of this value  
> > > /// divided by `rhs`.  
> > > func quotientAndRemainder(dividingBy rhs: Self  
> > > )
> > > 
> > > -\> (quotient: Self, remainder: Self  
> > > )
> > > 
> > > /// Returns `-1` if this value is negative and `1` if it's positive;  
> > > /// otherwise, `0`.  
> > > ///  
> > > /// - Returns: The sign of this number, expressed as an integer of the same  
> > > /// type.  
> > > func signum() -\> Self
> > > 
> > > }
> > > 
> > > FixedWidthInteger
> > > 
> > > The FixedWidthInteger protocol adds the notion of endianness as well as static properties for type bounds and bit width.
> > > 
> > > The WithOverflow family of methods is used in default implementations of mutating arithmetic methods (see the Arithmetic protocol). Having these methods allows the library to provide both bounds-checked and masking implementations of arithmetic operations, without duplicating code.
> > > 
> > > The doubleWidthMultiply and doubleWidthDivide methods are necessary building blocks to implement support for integer types of a greater width such as arbitrary-precision integers.
> > > 
> > > public protocol FixedWidthInteger : BinaryInteger  
> > > {
> > > 
> > > /// The number of bits used for the underlying binary representation of  
> > > /// values of this type.  
> > > ///  
> > > /// An unsigned, fixed-width integer type can represent values from 0 through  
> > > /// `(2 **bitWidth) - 1`, where `**` is exponentiation. A signed,  
> > > /// fixed-width integer type can represent values from  
> > > /// `-(2 **bitWidth - 1)` through `(2** bitWidth - 1) - 1`. For example,  
> > > /// the `Int8` type has a `bitWidth` value of 8 and can store any integer in  
> > > /// the range `-128...127`.  
> > > static var bitWidth : Int { get  
> > > }
> > > 
> > > /// The maximum representable integer in this type.  
> > > ///  
> > > /// For unsigned integer types, this value is `(2 ** bitWidth) - 1`, where  
> > > /// `**` is exponentiation. For signed integer types, this value is  
> > > /// `(2 ** bitWidth - 1) - 1`.  
> > > static var max: Self { get  
> > > }
> > > 
> > > /// The minimum representable value.  
> > > ///  
> > > /// For unsigned integer types, this value is always `0`. For signed integer  
> > > /// types, this value is `-(2 **bitWidth - 1)`, where `**` is  
> > > /// exponentiation.  
> > > static var min: Self { get  
> > > }
> > > 
> > > /// Returns the sum of this value and the given value along with a flag  
> > > /// indicating whether overflow occurred in the operation.  
> > > ///  
> > > /// - Parameter other: The value to add to this value.  
> > > /// - Returns: A tuple containing the result of the addition along with a  
> > > /// flag indicating whether overflow occurred. If the `overflow` component  
> > > /// is `.none`, the `partialValue` component contains the entire sum. If  
> > > /// the `overflow` component is `.overflow`, an overflow occurred and the  
> > > /// `partialValue` component contains the truncated sum of this value and  
> > > /// `other`.  
> > > ///  
> > > /// - SeeAlso: `+`  
> > > func addingWithOverflow(\_ other: Self  
> > > )
> > > 
> > > -\> (partialValue: Self, overflow  
> > > : ArithmeticOverflow)
> > > 
> > > /// Returns the difference of this value and the given value along with a  
> > > /// flag indicating whether overflow occurred in the operation.  
> > > ///  
> > > /// - Parameter other: The value to subtract from this value.  
> > > /// - Returns: A tuple containing the result of the subtraction along with a  
> > > /// flag indicating whether overflow occurred. If the `overflow` component  
> > > /// is `.none`, the `partialValue` component contains the entire  
> > > /// difference. If the `overflow` component is `.overflow`, an overflow  
> > > /// occurred and the `partialValue` component contains the truncated  
> > > /// result of `other` subtracted from this value.  
> > > ///  
> > > /// - SeeAlso: `-`  
> > > func subtractingWithOverflow(\_ other: Self  
> > > )
> > > 
> > > -\> (partialValue: Self, overflow  
> > > : ArithmeticOverflow)
> > > 
> > > /// Returns the product of this value and the given value along with a flag  
> > > /// indicating whether overflow occurred in the operation.  
> > > ///  
> > > /// - Parameter other: The value to multiply by this value.  
> > > /// - Returns: A tuple containing the result of the multiplication along with  
> > > /// a flag indicating whether overflow occurred. If the `overflow`  
> > > /// component is `.none`, the `partialValue` component contains the entire  
> > > /// product. If the `overflow` component is `.overflow`, an overflow  
> > > /// occurred and the `partialValue` component contains the truncated  
> > > /// product of this value and `other`.  
> > > ///  
> > > /// - SeeAlso: `*`, `doubleWidthMultiply(_:_:)`  
> > > func multipliedWithOverflow(by other: Self  
> > > )
> > > 
> > > -\> (partialValue: Self, overflow  
> > > : ArithmeticOverflow)
> > > 
> > > /// Returns the quotient of dividing this value by the given value along with  
> > > /// a flag indicating whether overflow occurred in the operation.  
> > > ///  
> > > /// For a value `x`, if zero is passed as `other`, the result is  
> > > /// `(x, .overflow)`.  
> > > ///  
> > > /// - Parameter other: The value to divide this value by.  
> > > /// - Returns: A tuple containing the result of the division along with a  
> > > /// flag indicating whether overflow occurred. If the `overflow` component  
> > > /// is `.none`, the `partialValue` component contains the entire quotient.  
> > > /// If the `overflow` component is `.overflow`, an overflow occurred and  
> > > /// the `partialValue` component contains the truncated quotient.  
> > > ///  
> > > /// - SeeAlso: `/`, `doubleWidthDivide(_:_:)`  
> > > func dividedWithOverflow(by other: Self  
> > > )
> > > 
> > > -\> (partialValue: Self, overflow  
> > > : ArithmeticOverflow)
> > > 
> > > /// Returns a tuple containing the high and low parts of the result of  
> > > /// multiplying its arguments.  
> > > ///  
> > > /// Use this method to calculate the full result of a product that would  
> > > /// otherwise overflow. Unlike traditional truncating multiplication, the  
> > > /// `doubleWidthMultiply(_:_:)` method returns both the `high` and `low`  
> > > /// parts of the product of `lhs` and `rhs`. The following example uses this  
> > > /// method to multiply two `UInt8` values that normally overflow when  
> > > /// multiplied:  
> > > ///  
> > > /// let x: UInt8 = 100  
> > > /// let y: UInt8 = 20  
> > > /// let result = UInt8.doubleWidthMultiply(100, 20)  
> > > /// // result.high == 0b00000111  
> > > /// // result.low == 0b11010000  
> > > ///  
> > > /// The product of `x` and `y` is 2000, which is too large to represent in a  
> > > /// `UInt8` instance. The `high` and `low` components of the `result` tuple  
> > > /// represent 2000 when concatenated to form a double-width integer; that  
> > > /// is, using `result.high` as the high byte and `result.low` as the low byte  
> > > /// of a `UInt16` instance.  
> > > ///  
> > > /// let z = UInt16(result.high) \<\< 8 | UInt16(result.low)  
> > > /// // z == 2000  
> > > ///  
> > > /// - Parameters:  
> > > /// - lhs: A value to multiply.  
> > > /// - rhs: Another value to multiply.  
> > > /// - Returns: A tuple containing the high and low parts of the result of  
> > > /// multiplying `lhs` and `rhs`.  
> > > ///  
> > > /// - SeeAlso: `multipliedWithOverflow(by:)`  
> > > static func doubleWidthMultiply(\_ lhs: Self, \_ rhs: Self  
> > > )
> > > 
> > > -\> (high: Self, low  
> > > : Magnitude)
> > > 
> > > /// Returns a tuple containing the quotient and remainder of dividing the  
> > > /// first argument by the second.  
> > > ///  
> > > /// The resulting quotient must be representable within the bounds of the  
> > > /// type. If the quotient of dividing `lhs` by `rhs` is too large to  
> > > /// represent in the type, a runtime error may occur.  
> > > ///  
> > > /// - Parameters:  
> > > /// - lhs: A tuple containing the high and low parts of a double-width  
> > > /// integer. The `high` component of the tuple carries the sign, if the  
> > > /// type is signed.  
> > > /// - rhs: The integer to divide into `lhs`.  
> > > /// - Returns: A tuple containing the quotient and remainder of `lhs` divided  
> > > /// by `rhs`.  
> > > static func doubleWidthDivide  
> > > (
> > > 
> > > \_ lhs: (high: Self, low: Magnitude), \_ rhs: Self  
> > > )
> > > 
> > > -\> (quotient: Self, remainder: Self  
> > > )
> > > 
> > > /// The number of bits equal to 1 in this value's binary representation.  
> > > ///  
> > > /// For example, in a fixed-width integer type with a `bitWidth` value of 8,  
> > > /// the number 31 has five bits equal to 1.  
> > > ///  
> > > /// let x: Int8 = 0b0001\_1111  
> > > /// // x == 31  
> > > /// // x.popcount == 5  
> > > var popcount: Int { get  
> > > }
> > > 
> > > /// The number of leading zeros in this value's binary representation.  
> > > ///  
> > > /// For example, in a fixed-width integer type with a `bitWidth` value of 8,  
> > > /// the number 31 has three leading zeros.  
> > > ///  
> > > /// let x: Int8 = 0b0001\_1111  
> > > /// // x == 31  
> > > /// // x.leadingZeros == 3  
> > > /// - SeeAlso: `BinaryInteger.trailingZeros`  
> > > var leadingZeros: Int { get  
> > > }
> > > 
> > > /// Creates an integer from its big-endian representation, changing the  
> > > /// byte order if necessary.  
> > > init(bigEndian value: Self  
> > > )
> > > 
> > > /// Creates an integer from its little-endian representation, changing the  
> > > /// byte order if necessary.  
> > > init(littleEndian value: Self  
> > > )
> > > 
> > > /// The big-endian representation of this integer.  
> > > ///  
> > > /// If necessary, the byte order of this value is reversed from the typical  
> > > /// byte order of this integer type. On a big-endian platform, for any  
> > > /// integer `x`, `x == x.bigEndian`.  
> > > ///  
> > > /// - SeeAlso: `littleEndian`  
> > > var bigEndian: Self { get  
> > > }
> > > 
> > > /// The little-endian representation of this integer.  
> > > ///  
> > > /// If necessary, the byte order of this value is reversed from the typical  
> > > /// byte order of this integer type. On a little-endian platform, for any  
> > > /// integer `x`, `x == x.littleEndian`.  
> > > ///  
> > > /// - SeeAlso: `bigEndian`  
> > > var littleEndian: Self { get  
> > > }
> > > 
> > > /// A representation of this integer with the byte order swapped.  
> > > var byteSwapped: Self { get  
> > > }  
> > > }
> > > 
> > > Auxiliary protocols
> > > 
> > > public protocol UnsignedInteger : BinaryInteger  
> > > {
> > > 
> > > associatedtype Magnitude : BinaryInteger
> > > 
> > > }
> > > 
> > > public protocol SignedInteger : BinaryInteger, SignedArithmetic  
> > > {
> > > 
> > > associatedtype Magnitude : BinaryInteger
> > > 
> > > }
> > > 
> > > DoubleWidth
> > > 
> > > The DoubleWidth\<T\> type allows to create wider fixed-width integer types from the ones available in the standard library.
> > > 
> > > Standard library currently provides fixed-width integer types of up to 64 bits. A value of DoubleWidth\<Int64\> will double the range of the underlying type and implement all the FixedWidthInteger requirements. Please note though that the implementation will not necessarily be the most efficient one, so it would not be a good idea to use DoubleWidth\<Int32\>instead of a built-in Int64.
> > > 
> > > Extra operators
> > > 
> > > In addition to the operators described in the protocols section, we also provide a few extensions that are not protocol requirements:
> > > 
> > > Heterogeneous shifts
> > > 
> > > extension BinaryInteger  
> > > {
> > > 
> > > // Masking shifts  
> > > static func &\>\> \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self
> > > 
> > > static func &\>\>= \<Other : BinaryInteger\>(lhs: inout Self, rhs  
> > > : Other)
> > > 
> > > static func &\<\< \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self
> > > 
> > > static func &\<\<= \<Other : BinaryInteger\>(lhs: inout Self, rhs  
> > > : Other)
> > > 
> > > // 'Smart' shifts  
> > > static func \>\> \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self
> > > 
> > > static func \>\>= \<Other : BinaryInteger\>(lhs: inout Self, rhs  
> > > : Other)
> > > 
> > > static func \<\< \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self
> > > 
> > > static func \<\<= \<Other : BinaryInteger\>(lhs: inout Self, rhs  
> > > : Other)  
> > > }
> > > 
> > > Heterogeneous equality and comparison
> > > 
> > > extension BinaryInteger  
> > > {
> > > 
> > > // Equality  
> > > static func == \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool
> > > 
> > > static func != \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool
> > > 
> > > // Comparison  
> > > static func \< \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool
> > > 
> > > static func \<= \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool
> > > 
> > > static func \> \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool
> > > 
> > > static func \>= \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool
> > > 
> > > }
> > > 
> > > Masking arithmetic
> > > 
> > > public func &\* \<T: FixedWidthInteger\>(lhs: T, rhs: T) -\>  
> > > T
> > > 
> > > public func &- \<T: FixedWidthInteger\>(lhs: T, rhs: T) -\>  
> > > T
> > > 
> > > public func &+ \<T: FixedWidthInteger\>(lhs: T, rhs: T) -\> T  
> > > Non-goals
> > > 
> > > This proposal:
> > > 
> > > &nbsp;&nbsp;&nbsp;• DOES NOT solve the integer promotion problem, which would allow mixed-type arithmetic. However, we believe that it is an important step in the right direction.
> > > 
> > > &nbsp;&nbsp;&nbsp;• DOES NOT include the implementation of a BigInt type, but allows it to be implemented in the future.
> > > 
> > > Source compatibility
> > > 
> > > The proposed change is designed to be as non-breaking as possible, and it has been proven that it does not break code on concrete integer types. However, there are still a few API breaking changes in the realm of generic code:
> > > 
> > > &nbsp;&nbsp;&nbsp;• Integer protocols in Swift up to and including version 3 were not particularly useful for generic programming, but were rather a means of sharing implementation between conforming types. Therefore we believe the amount of code that relied on these protocols is relatively small. The breakage can be further reduced by introducing proper aliases for the removed protocols with deprecation warnings.
> > > 
> > > &nbsp;&nbsp;&nbsp;• Deprecation of the BitwiseOperations protocol. We find it hard to imagine a type that conforms to this protocol, but is not a binary integer type.
> > > 
> > > &nbsp;&nbsp;&nbsp;• Addition of 'smart' shifts will change the behavior of existing code. It will still compile, but will be potentially less performant due to extra logic involved. In a case, where this becomes a problem, newly introduced masking shift operators can be used instead. Unfortunately, performance characteristics of the code cannot be statically checked, and thus migration cannot be provided.
> > > 
> > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > swift-evolution mailing list  
> > > swift-evolution@swift.org  
> > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [January 14, 2017, 4:09pm UTC](https://forums.swift.org/t/protocol-oriented-integers-take-2/4884/14 "2017-01-14T16:09:50Z")

</div>

> Great work, all. I'm not sure I ever commented on SE-0104, so I've read  
> through this one more carefully. Here are some things that came to mind:
> 
> \*## Arithmetic\*
> 
> Why are ExpressibleByIntegerLiteral and init?\<T:BinaryInteger\>(exactly:)  
> required? I could understand needing access to 0, but this could be  
> provided by a static property or nullary initializer. It doesn't seem like  
> all types supporting arithmetic operations would necessarily be convertible  
> from an arbitrary binary integer.
> 
> I tried to evaluate the Arithmetic protocol by considering what it means  
> for higher-dimensional types such as CGPoint and CGVector. My use case was  
> a linear interpolation function:
> 
> &nbsp;&nbsp;&nbsp;&nbsp;func lerp\<T: Arithmetic\>(from a: T, to b: T, by ratio: T) -\> T {  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return a + (b - a) \* ratio  
> &nbsp;&nbsp;&nbsp;&nbsp;}
> 
> If I've read the proposal correctly, this definition works for integer and  
> floating-point values. But we can't make it work properly for CGVector (or,  
> perhaps less mathematically correct but more familiar, CGPoint). It's okay  
> to define +(CGVector, CGVector) and -(CGVector, CGVector), but \*(CGVector,  
> CGVector) and /(CGVector, CGVector) don't make much sense. What we really  
> want is \*(CGVector, \*CGFloat\*) and /(CGVector, \*CGFloat\*).
> 
> After consulting a mathematician, I believe what the lerp function really  
> wants is for its generic param to be an affine space  
> \<[https://en.wikipedia.org/wiki/Affine\_space&gt;\](https://en.wikipedia.org/wiki/Affine_space&gt;%5C). I explored this a bit here:  
> [https://gist.github.com/jtbandes/93eeb7d5eee8e1a7245387c660d53b](https://gist.github.com/jtbandes/93eeb7d5eee8e1a7245387c660d53b)  
> 03#file-affine-swift-L16-L18
> 
> This approach is less restrictive and more composable than the proposed  
> Arithmetic protocol, which can be viewed as a special case with the  
> following definitions:
> 
> &nbsp;&nbsp;&nbsp;&nbsp;extension Arithmetic: AffineSpace, VectorSpace { // not actually  
> allowed in Swift  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typealias Displacement = Self  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;typealias Scalar = Self  
> &nbsp;&nbsp;&nbsp;&nbsp;}
> 
> It'd be great to be able to define a lerp() which works for all  
> floating-point and integer numbers, as well as points and vectors (assuming  
> a glorious future where CGPoint and CGVector have built-in arithmetic  
> operations). But maybe the complexity of these extra protocols isn't worth  
> it for the stdlib...

I think, in the end, it's the \_name\_ that could use improvement here. As  
the doc comments say, `Arithmetic` is supposed to provide a "suitable basis  
for arithmetic on scalars"--perhaps `ScalarArithmetic` might be more  
appropriate? It would make it clear that `CGVector` is not meant to be a  
conforming type.

> \*## BinaryInteger\*
> 
> I'm a little confused by the presence of init(extendingOrTruncating:) for  
> \*all\* binary integers. Why does it make sense to be able to write  
> UInt16(extendingOrTruncating: (-21 as Int8)) ? In my mind, sign-extension  
> only has meaning when the source and destination types are both signed.

Here (just IMHO), I disagree. Since any binary integer can be truncated and  
any can be right-shifted, it makes sense for `init(extendingOrTruncating:)`  
to be available for all of them. If I understand the proposal correctly,  
`Int(extendingOrTruncating: (-1 as Int8))` would give you a different  
result than `Int(extendingOrTruncating: (255 as UInt8)`.

Although I would not be against a clamp() function in the standard library,

> "init(clamping:)" sounds strange to me. What about calling it  
> "init(nearestTo:)"? One could also define a FloatingPoint version of  
> init(nearestTo:), i.e. lround(). For maximum annoyance and explicitness,  
> you could even rename the existing init(\_:) to init(truncating:) to make it  
> clear that truncation, not regular rounding, occurs when converting from  
> floating-point.

I would disagree with that as well; the existing `init(_:)` truncates the  
fractional part but errors if that value is outside the representable  
range, while the word "truncating" makes it sound like something is done to  
make any possible source value give you a destination value (a la  
"extendingOrTruncating" for integers).

Meanwhile, "nearest to" is problematic for me because either 127 and 129 is  
"nearest to" 128, and neither integer is "nearest to" 500, yet  
`Int8(clamping: 128)` and `Int8(clamping: 500)` both give you 127. This  
operation is very different from lround() for floating point, which in  
Swift is `rounded(.toNearestOrAwayFromZero)` (or just `rounded()`).

In both these cases, I think it's important to use spellings that  
distinguish doing things to the fractional part of floating point values  
and doing things to the binary representation of integer values. I think  
there's great value in using the term "clamp", which is very different from  
"nearest"; and in using an unlabeled `init(_:)` for initializing from FP  
values, which is most similar to the unlabeled `init(_:)` for initializing  
from integer values, as opposed to your suggested `init(truncating:)` which  
connotes some similarity to `init(extendingOrTruncating:)` for integer  
values.

\*... masking shifts\*

> The example claims that "(30 as UInt8) &\>\> 11" produces 3, because it  
> right-shifts 30 by 3. But isn't the bitWidth of UInt8 always 8 since it's a  
> fixed-width type? Why should 11 get masked to 3 before the shift? (Also, it  
> might be a good idea to choose examples with numbers whose base-ten  
> representations don't look like valid binary. 😉) What use cases are there  
> for masking shifts? I was under the impression that "smart shifts" were  
> pretty much how the usual shift instructions already behaved.
> 
> (Minor: were the smart shift operators supposed to be included as  
> BinaryInteger protocol requirements? I only see them in the "heterogeneous  
> shifts" extension.)
> 
> \*... init\<T: BinaryInteger\>(\_ source: T)\*
> 
> Now a thought experiment: suppose you wanted to write an  
> arbitrary-precision BigInt, or any binary integer such as Int256. The  
> BinaryInteger protocol requires you to provide init\<T:BinaryInteger\>(\_  
> source: T). Given the source of type T, how do you access its bits? Is  
> repeated use of word(at:) the recommended way? If so, it might be nice to  
> include a "wordCount" returning the number of available words; otherwise I  
> suppose the user has to use something like bitWidth/(8\*MemoryLayout\<Int\>.size),  
> which is pretty ugly.
> 
> \*## FixedWidthInteger\*
> 
> Why is popcount restricted to FixedWidthInteger? It seems like it could  
> theoretically apply to any UnsignedInteger.

You can perfectly legitimately get a popcount for a signed integer. It's  
just looking at the binary representation and counting the ones. But then  
with two's complement, it'd have to be restricted to FixedWidthInteger and  
not BinaryInteger, because the same negative value would have a different  
popcount depending on the type's bitwidth. I'd disagree strongly with  
removing popcount from signed binary integers. However, I suppose the same  
requirement could be applied to both FixedWidthInteger and UnsignedInteger.

\*## Heterogenous shifts, equality, and comparison\*

> **···**
>
> On Sat, Jan 14, 2017 at 1:32 AM, Jacob Bandes-Storch via swift-evolution \< swift-evolution@swift.org\> wrote:
> 
> > These look great. How will the default implementations be provided?  
> > (Equivalent question: how would a user define their own heterogeneous  
> > operators?) I suppose this works:
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;static func &\>\> \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self  
> > {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// delegate to the protocol requirement &\>\>(Self, Self)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return self &\>\> Self(extendingOrTruncating: rhs)  
> > &nbsp;&nbsp;&nbsp;&nbsp;}
> > 
> > But for operations you can't delegate so easily... I'm imagining trying to  
> > implement heterogeneous comparison (i.e. \< ) and the best I can come up  
> > with uses signum() and word(at:)...
> > 
> > Also, should these be protocol requirements so user-defined types can  
> > specialize them?
> > 
> > \*## Masking arithmetic\*
> > 
> > Do &\* and &+ and &- need their operands to have the same type, or could  
> > these be heterogeneous too (at least &+ and &-)?
> > 
> > Jacob
> > 
> > On Fri, Jan 13, 2017 at 12:47 PM, Max Moiseev via swift-evolution \< \> swift-evolution@swift.org\> wrote:
> > 
> > > Hi everyone,
> > > 
> > > Back in June 2016 we discussed the new design of the integer types for  
> > > the standard library. It even resulted in acceptance of SE-0104  
> > > \<[https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md&gt](https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md&gt); for  
> > > Swift 3. Unfortunately we were not able to implement it in time for the  
> > > release.
> > > 
> > > But it was not forgotten, although, as time went by, a few changes needed  
> > > to be made in order to reflect the current state of the language.  
> > > Without further introduction, please welcome the refined proposal to make  
> > > integers in Swift more suitable for generic programming.
> > > 
> > > Available in this gist [m’s gists · GitHub](https://gist.github.com/m)  
> > > oiseev/62ffe3c91b66866fdebf6f3fcc7cad8c and also inlined below.
> > > 
> > > Max
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![dabrahams](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dabrahams/32/9815_2.png) [@dabrahams](https://forums.swift.org/u/dabrahams)\
**Post date:** [January 15, 2017, 12:06am UTC](https://forums.swift.org/t/protocol-oriented-integers-take-2/4884/15 "2017-01-15T00:06:29Z")

</div>

It's easy to prove that the heterogeneous overload can't have different  
semantics from the homogeneous one, so there is absolutely nothing to  
worry about—other than, arguably, that it could take slightly more  
time to type-check.

> **···**
>
> on Fri Jan 13 2017, Max Moiseev \<swift-evolution@swift.org\> wrote:
> 
> > So, in an expression `x &\>\> 32`, compiler assumes 32 to have type Int  
> > (which is the default type for the integer literals) and prefer the  
> > heterogeneous overload. It might not be too bad, as I showed in  
> > examples above, but in order to increase chances of success you might  
> > want to specify an explicit type context, as in `x &\>\> (32 as  
> > TypeOfX)`.
> 
> --  
> -Dave

---

<div class="post-metadata">

**Author:** ![dabrahams](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dabrahams/32/9815_2.png) [@dabrahams](https://forums.swift.org/u/dabrahams)\
**Post date:** [January 15, 2017, 1:41am UTC](https://forums.swift.org/t/protocol-oriented-integers-take-2/4884/16 "2017-01-15T01:41:46Z")

</div>

> I notice the BinaryInteger's func word(at n: Int) -\> UInt function  
> expects a 2's complement representation. Do you expect that "BigInt"  
> will be implemented with 2's complement?

Ah, this is an excellent question, excellently phrased!

We designed it so BigInt could use 2's complement (see  
DoubleWidth\<Int64\>, which works that way), which should be faster than  
sign-magnitude...

BUT: I hadn't really considered that if existing bignum libraries use  
sign-magnitude, we'll want to be able to efficiently use their  
representations, so we need to make sure the protocols don't force those  
representations to be inefficient.

> As a nonmutating function, I would think any implementation from a 1's  
> complement big int would result in O(n^2) unless the BigInt were  
> designed with scratch space where it could store the intermediate  
> values of that representation.

Oh... you mean that word(at:) itself would be linear, and thus  
algorithms that iterate the words linearly would be O(N^2)... yuck.

So far, the only algorithm we have using word(at:) is this one, and  
[https://github.com/apple/swift/blob/new-integer-protocols/stdlib/public/core/Integers.swift.gyb#L2191](https://github.com/apple/swift/blob/new-integer-protocols/stdlib/public/core/Integers.swift.gyb#L2191)  
presumably we could adapt it to sign-magnitude by expanding the  
BinaryInteger protocol with a static var that indicates which  
representation is used.

&nbsp;&nbsp;enum Representation {  
&nbsp;&nbsp;&nbsp;&nbsp;twosComplement, signMagnitude, /\*onesComplement?\*/  
&nbsp;&nbsp;}  
&nbsp;&nbsp;static var representation: Representation { get }

Now, the other algorithms that I can anticipate would use word(at:) are  
basically... the ones you'd have to implement to build BigInt, so I  
guess this change would be OK.

Supporting sign-magnitude complicates generic programming with these  
protocols, though, so I want to be really sure we need to do this before  
we take the plunge.

> I only ask because just last week I was designing an arbitrary-width  
> float type in 1's complement, well, really I kept the sign bit in a  
> separate Bool.

Sounds like sign-magnitude rather than 1's complement if I remember my  
complements correctly.

> Of course, I recognize the value of being able to write integer init  
> code from a 2's complement representation, I'm just curious if there's  
> a way to allow this function to be more efficient for alternate  
> representations.
> 
> I love that there's a DoubleWidth type, having coded some arbitrary  
> precision arithmetic, that's always a downer going from generic code  
> to having to pick a specific "big enough" result type.
> 
> I'm glad the % operator got moved. It really did stand out as not  
> part of floating points.
> 
> Trailing zeros looks like a sensible optimization.
> 
> I agree with moving the shift operators, I like that you've called out  
> the notion of an infinite shift.

I don't think we ever meant to say anything about infinite shifts!

> I can't say I fully understood the use of the separate mask vs. smart  
> shift operators, but I'll take another read in the next few days and  
> see if I understand why they exist.

You're not alone it appears. We need to clarify that in the text,  
obviously. The smart shift operators are there to give you sensible  
semantics without undefined behavior or traps in the cases that have  
logically computable answers. The masking shifts are there for  
performance in the rare cases where smart shifting with a non-literal  
shift amount introduces non-negligible overheads (testing and branching  
to handle overshifts and negative shift amounts).

Obviously you have to know that the masking behavior is benign in your  
use case when using masking shifts in an operation. I made the mistake  
of using a masking shift to optimize some code the other day where the  
shift amount could be equal to the full width of the value being  
shifted. I ended up widening the LHS before doing the shift and then  
truncating back to the width, but that's only because I was writing  
performance-critical code. The smart shift would have “just worked.”

> I know this PR does not address the BitInt implementation, but do you  
> have one?

I know someone that implemented one... using sign-magnitude, actually,  
and his word(at:) implementation has the linear cost problem. I'll ask  
him to post a link.

> **···**
>
> on Sat Jan 14 2017, Benjamin Spratling \<swift-evolution@swift.org\> wrote:
> 
> > I'm glad to see this moving forward.
> > 
> > -Ben Spratling
> > 
> > > On Jan 14, 2017, at 2:00 AM, Rien via swift-evolution \<swift-evolution@swift.org\> wrote:
> > > 
> > > +1
> > > 
> > > Any change of including “ranged integers”?  
> > > I.e. an integer with a value that must fit in a predefined range?
> > > 
> > > Regards,  
> > > Rien
> > > 
> > > Site: [http://balancingrock.nl](http://balancingrock.nl)  
> > > Blog: [http://swiftrien.blogspot.com](http://swiftrien.blogspot.com)  
> > > Github: [Swiftrien (Rien) · GitHub](http://github.com/Swiftrien)  
> > > Project: [http://swiftfire.nl](http://swiftfire.nl)
> > > 
> > > > On 13 Jan 2017, at 21:47, Max Moiseev via swift-evolution \<swift-evolution@swift.org\> wrote:
> > > > 
> > > > Hi everyone,
> > > > 
> > > > Back in June 2016 we discussed the new design of the integer types for the standard library. It even resulted in acceptance of SE-0104 for Swift 3. Unfortunately we were not able to implement it in time for the release.
> > > > 
> > > > But it was not forgotten, although, as time went by, a few changes needed to be made in order to reflect the current state of the language.  
> > > > Without further introduction, please welcome the refined proposal to make integers in Swift more suitable for generic programming.
> > > > 
> > > > Available in this gist [Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c) and also inlined below.
> > > > 
> > > > Max
> > > > 
> > > > Protocol-oriented integers (take 2)
> > > > 
> > > > &nbsp;&nbsp;&nbsp;• Proposal: SE-NNNN  
> > > > &nbsp;&nbsp;&nbsp;• Authors: Dave Abrahams, Maxim Moiseev  
> > > > &nbsp;&nbsp;&nbsp;• Review Manager: TBD  
> > > > &nbsp;&nbsp;&nbsp;• Status: Awaiting review  
> > > > &nbsp;&nbsp;&nbsp;• Bug: SR-3196  
> > > > &nbsp;&nbsp;&nbsp;• Previous Proposal: SE-0104  
> > > > Introduction
> > > > 
> > > > This proposal is an evolution of SE-0104. The goal is still to clean up Swifts integer APIs and make them more useful for generic programming.
> > > > 
> > > > The language has evolved in ways that affect integers APIs since the time the original proposal was approved for Swift 3. We also attempted to implement the proposed model in the standard library and found that some essential APIs were missing, whereas others could be safely removed.
> > > > 
> > > > Major changes to the APIs introduced by this proposal (as compared to SE-0104) are listed in a dedicated section.
> > > > 
> > > > Motivation
> > > > 
> > > > Swift's integer protocols don't currently provide a suitable basis for generic programming. See this blog post for an example of an attempt to implement a generic algorithm over integers.
> > > > 
> > > > The way the Arithmetic protocol is defined, it does not generalize to floating point numbers and also slows down compilation by requiring every concrete type to provide an implementation of arithmetic operators, thus polluting the overload set.
> > > > 
> > > > Converting from one integer type to another is performed using the concept of the 'maximum width integer' (see MaxInt), which is an artificial limitation. The very existence of MaxInt makes it unclear what to do should someone implement Int256, for example.
> > > > 
> > > > Another annoying problem is the inability to use integers of different types in comparison and bit-shift operations. For example, the following snippets won't compile:
> > > > 
> > > > var x: Int8 = 42  
> > > > let y = 1  
> > > > let z = 0
> > > > 
> > > > x  
> > > > \<\<= y // error: binary operator '\<\<=' cannot be applied to operands of type 'Int8' and 'Int'  
> > > > if x \> z { ... } // error: binary operator '\>' cannot be applied to operands of type 'Int8' and 'Int'  
> > > > Currently, bit-shifting a negative number of (or too many) bits causes a trap on some platforms, which makes low-level bit manipulations needlessly dangerous and unpredictable.
> > > > 
> > > > Finally, the current design predates many of the improvements that came since Swift 1, and hasn't been revised since then.
> > > > 
> > > > Proposed solution
> > > > 
> > > > We propose a new model that does not have above mentioned problems and is more easily extensible.
> > > > 
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+--------------+ +-------------+  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+------\>+ Arithmetic | | Comparable |  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \> (+,-,\*,/) | | (==,\<,\>,...)|  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> +-------------++ +---+---------+  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> ^ ^  
> > > > +-------+------------+ | |  
> > > > \> SignedArithmetic | +-+-------+-----------+  
> > > > \> (unary -) | | BinaryInteger |  
> > > > +------+-------------+ |(words,%,bitwise,...)|  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^ ++---+-----+----------+  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> +-----------^ ^ ^---------------+  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \> \> \>  
> > > > +------+---------++ +---------+---------------+ +--+----------------+  
> > > > \> SignedInteger | | FixedWidthInteger | | UnsignedInteger |  
> > > > \> \> \>(endianness,overflow,...)| | |  
> > > > +---------------+-+ +-+--------------------+--+ +-+-----------------+  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^ ^ ^ ^  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \> \> \>  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \> \> \>  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++--------+-+ +-+-------+-+  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\>Int family |-+ |UInt family|-+  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+-----------+ | +-----------+ |  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+-----------+ +-----------+
> > > > 
> > > > There are several benefits provided by this model over the old one:
> > > > 
> > > > &nbsp;&nbsp;&nbsp;• It allows mixing integer types in generic functions.
> > > > 
> > > > The possibility to initialize instances of any concrete integer type with values of any other concrete integer type enables writing functions that operate on more than one type conforming to BinaryInteger, such as heterogeneous comparisons or bit shifts, described later.
> > > > 
> > > > &nbsp;&nbsp;&nbsp;• It removes the overload resolution overhead.
> > > > 
> > > > Arithmetic and bitwise operations can now be defined as generic operators on protocols. This approach significantly reduces the number of overloads for those operations, which used to be defined for every single concrete integer type.
> > > > 
> > > > &nbsp;&nbsp;&nbsp;• It enables protocol sharing between integer and floating point types.
> > > > 
> > > > Note the exclusion of the % operation from Arithmetic. Its behavior for floating point numbers is sufficiently different from the one for integers that using it in generic context would lead to confusion. The FloatingPoint protocol introduced by SE-0067 should now refine SignedArithmetic.
> > > > 
> > > > &nbsp;&nbsp;&nbsp;• It makes future extensions possible.
> > > > 
> > > > The proposed model eliminates the 'largest integer type' concept previously used to interoperate between integer types (see toIntMax in the current model) and instead provides access to machine words. It also introduces thedoubleWidthMultiply, doubleWidthDivide, and quotientAndRemainder methods. Together these changes can be used to provide an efficient implementation of bignums that would be hard to achieve otherwise.
> > > > 
> > > > The implementation of proposed model in the standard library is available in the new-integer-protocols branch.
> > > > 
> > > > A note on bit shifts
> > > > 
> > > > This proposal introduces the concepts of smart shifts and masking shifts.
> > > > 
> > > > The semantics of shift operations are often undefined in under- or over-shift cases. Smart shifts, implemented by \>\> and \<\<, are designed to address this problem and always behave in a well defined way, as shown in the examples below:
> > > > 
> > > > &nbsp;&nbsp;&nbsp;• x \<\< -2 is equivalent to x \>\> 2
> > > > 
> > > > &nbsp;&nbsp;&nbsp;• (1 as UInt8) \>\> 42) will evaluate to 0
> > > > 
> > > > &nbsp;&nbsp;&nbsp;• (-128 as Int8) \>\> 42) will evaluate to 0xff or -1
> > > > 
> > > > In most scenarios, the right hand operand is a literal constant, and branches for handling under- and over-shift cases can be optimized away. For other cases, this proposal provides masking shifts, implemented by &\>\> and &\<\<. A masking shift logically preprocesses the right hand operand by masking its bits to produce a value in the range 0...(x-1) where x is the number of bits in the left hand operand. On most architectures this masking is already performed by the CPU's shift instructions and has no cost. Both kinds of shift avoid undefined behavior and produce uniform semantics across architectures.
> > > > 
> > > > Detailed design
> > > > 
> > > > What's new since SE-0104
> > > > 
> > > > &nbsp;&nbsp;&nbsp;• SE-0091 removed the necessity to dispatch generic operators through special methods.
> > > > 
> > > > All operators are now declared by protocols as static funcs.
> > > > 
> > > > &nbsp;&nbsp;&nbsp;• Standard Library no longer provides + and - operators for Strideable types.
> > > > 
> > > > They were problematic, as one could have written mixed-type code like let x: Int64 = 42; x += (1 as Int), which would compile, but shouldn't. Besides, since the Stride of an unsigned type is signed, Standard Library had to implement a hack to make code like let x: UInt = 42; x += (1 as Int) ambiguous. These operators were only necessary because they made advancing collection indices convenient, which is no longer the case since the introduction of the new indexing model in Swift 3.
> > > > 
> > > > &nbsp;&nbsp;&nbsp;• Shifts and other bitwise operations were moved from FixedWidthInteger to BinaryInteger.
> > > > 
> > > > Left shift operation on an unbounded integer should infinitely extend the number, and never drop set bits when they reach the most significant position in the underlying representation.
> > > > 
> > > > &nbsp;&nbsp;&nbsp;• BitwiseOperations protocol was deprecated.
> > > > 
> > > > We believe there are no useful entities that support bitwise operations, but at the same time are not binary integers.
> > > > 
> > > > &nbsp;&nbsp;&nbsp;• minimumSignedRepresentationBitWidth property was removed.
> > > > 
> > > > &nbsp;&nbsp;&nbsp;• trailingZeros property was added to the BinaryInteger protocol.
> > > > 
> > > > leadingZeros and popcount properties are still defined by the FixedWidthInteger protocol.
> > > > 
> > > > &nbsp;&nbsp;&nbsp;• Endian-converting initializers and properties were added to the FixedWidthInteger protocol.
> > > > 
> > > > &nbsp;&nbsp;&nbsp;• Standard library introduces the new type DoubleWidth\<T\>.
> > > > 
> > > > See this section for more details.
> > > > 
> > > > Protocols
> > > > 
> > > > Arithmetic
> > > > 
> > > > The Arithmetic protocol declares binary arithmetic operators – such as +, -, and \* — and their mutating counterparts.
> > > > 
> > > > It provides a suitable basis for arithmetic on scalars such as integers and floating point numbers.
> > > > 
> > > > Both mutating and non-mutating operations are declared in the protocol, however only the mutating ones are required, as default implementations of the non-mutating ones are provided by a protocol extension.
> > > > 
> > > > The Magnitude associated type is able to hold the absolute value of any possible value of Self. Concrete types do not have to provide a type alias for it, as it can be inferred from the magnitude property. This property can be useful in operations that are simpler to implement in terms of unsigned values, for example, printing a value of an integer, which is just printing a '-' character in front of an absolute value.
> > > > 
> > > > Please note that for ordinary work, the magnitude property should not be preferred to the abs(\_) function, whose return value is of the same type as its argument.
> > > > 
> > > > public protocol Arithmetic : Equatable, ExpressibleByIntegerLiteral  
> > > > {
> > > > 
> > > > /// Creates a new instance from the given integer, if it can be represented  
> > > > /// exactly.  
> > > > ///  
> > > > /// If the value passed as `source` is not representable exactly, the result  
> > > > /// is `nil`. In the following example, the constant `x` is successfully  
> > > > /// created from a value of `100`, while the attempt to initialize the  
> > > > /// constant `y` from `1_000` fails because the `Int8` type can represent  
> > > > /// `127` at maximum:  
> > > > ///  
> > > > /// let x = Int8(exactly: 100)  
> > > > /// // x == Optional(100)  
> > > > /// let y = Int8(exactly: 1\_000)  
> > > > /// // y == nil  
> > > > ///  
> > > > /// - Parameter source: A floating-point value to convert to an integer.  
> > > > init?\<T : BinaryInteger\>(exactly source  
> > > > : T)
> > > > 
> > > > /// A type that can represent the absolute value of any possible value of the  
> > > > /// conforming type.  
> > > > associatedtype Magnitude : Equatable, ExpressibleByIntegerLiteral
> > > > 
> > > > /// The magnitude of this value.  
> > > > ///  
> > > > /// For any numeric value `x`, `x.magnitude` is the absolute value of `x`.  
> > > > /// You can use the `magnitude` property in operations that are simpler to  
> > > > /// implement in terms of unsigned values, such as printing the value of an  
> > > > /// integer, which is just printing a '-' character in front of an absolute  
> > > > /// value.  
> > > > ///  
> > > > /// let x = -200  
> > > > /// // x.magnitude == 200  
> > > > ///  
> > > > /// The global `abs(_:)` function provides more familiar syntax when you need  
> > > > /// to find an absolute value. In addition, because `abs(_:)` always returns  
> > > > /// a value of the same type, even in a generic context, using the function  
> > > > /// instead of the `magnitude` property is encouraged.  
> > > > ///  
> > > > /// - SeeAlso: `abs(_:)`  
> > > > var magnitude: Magnitude { get  
> > > > }
> > > > 
> > > > /// Returns the sum of the two given values.  
> > > > ///  
> > > > /// The sum of `lhs` and `rhs` must be representable in the same type. In the  
> > > > /// following example, the result of `100 + 200` is greater than the maximum  
> > > > /// representable `Int8` value:  
> > > > ///  
> > > > /// let x: Int8 = 10 + 21  
> > > > /// // x == 31  
> > > > /// let y: Int8 = 100 + 121  
> > > > /// // Overflow error  
> > > > static func +(\_ lhs: Self, \_ rhs: Self) -\> Self
> > > > 
> > > > /// Adds the given value to this value in place.  
> > > > ///  
> > > > /// For example:  
> > > > ///  
> > > > /// var x = 15  
> > > > /// y += 7  
> > > > /// // y == 22  
> > > > static func +=(\_ lhs: inout Self, rhs: Self  
> > > > )
> > > > 
> > > > /// Returns the difference of the two given values.  
> > > > ///  
> > > > /// The difference of `lhs` and `rhs` must be representable in the same type.  
> > > > /// In the following example, the result of `10 - 21` is less than zero, the  
> > > > /// minimum representable `UInt` value:  
> > > > ///  
> > > > /// let x: UInt = 21 - 10  
> > > > /// // x == 11  
> > > > /// let y: UInt = 10 - 21  
> > > > /// // Overflow error  
> > > > static func -(\_ lhs: Self, \_ rhs: Self) -\> Self
> > > > 
> > > > /// Subtracts the given value from this value in place.  
> > > > ///  
> > > > /// For example:  
> > > > ///  
> > > > /// var x = 15  
> > > > /// y -= 7  
> > > > /// // y == 8  
> > > > static func -=(\_ lhs: inout Self, rhs: Self  
> > > > )
> > > > 
> > > > /// Returns the product of the two given values.  
> > > > ///  
> > > > /// The product of `lhs` and `rhs` must be representable in the same type. In  
> > > > /// the following example, the result of `10 * 50` is greater than the  
> > > > /// maximum representable `Int8` value.  
> > > > ///  
> > > > /// let x: Int8 = 10 \* 5  
> > > > /// // x == 50  
> > > > /// let y: Int8 = 10 \* 50  
> > > > /// // Overflow error  
> > > > static func \*(\_ lhs: Self, \_ rhs: Self) -\> Self
> > > > 
> > > > /// Multiples this value by the given value in place.  
> > > > ///  
> > > > /// For example:  
> > > > ///  
> > > > /// var x = 15  
> > > > /// y \*= 7  
> > > > /// // y == 105  
> > > > static func \*=(\_ lhs: inout Self, rhs: Self  
> > > > )
> > > > 
> > > > /// Returns the quotient of dividing the first value by the second.  
> > > > ///  
> > > > /// For integer types, any remainder of the division is discarded.  
> > > > ///  
> > > > /// let x = 21 / 5  
> > > > /// // x == 4  
> > > > static func /(\_ lhs: Self, \_ rhs: Self) -\> Self
> > > > 
> > > > /// Divides this value by the given value in place.  
> > > > ///  
> > > > /// For example:  
> > > > ///  
> > > > /// var x = 15  
> > > > /// y /= 7  
> > > > /// // y == 2  
> > > > static func /=(\_ lhs: inout Self, rhs: Self  
> > > > )  
> > > > }
> > > > 
> > > > extension Arithmetic  
> > > > {
> > > > 
> > > > public init() { self = 0  
> > > > }
> > > > 
> > > > public static prefix func + (x: Self) -\> Self  
> > > > {
> > > > 
> > > > return  
> > > > x  
> > > > }  
> > > > }
> > > > 
> > > > SignedArithmetic
> > > > 
> > > > The SignedArithmetic protocol is for numbers that can be negated.
> > > > 
> > > > public protocol SignedArithmetic : Arithmetic  
> > > > {
> > > > 
> > > > /// Returns the additive inverse of this value.  
> > > > ///  
> > > > /// let x = 21  
> > > > /// let y = -x  
> > > > /// // y == -21  
> > > > ///  
> > > > /// - Returns: The additive inverse of this value.  
> > > > ///  
> > > > /// - SeeAlso: `negate()`  
> > > > static prefix func - (\_ operand: Self) -\> Self
> > > > 
> > > > /// Replaces this value with its additive inverse.  
> > > > ///  
> > > > /// The following example uses the `negate()` method to negate the value of  
> > > > /// an integer `x`:  
> > > > ///  
> > > > /// var x = 21  
> > > > /// x.negate()  
> > > > /// // x == -21  
> > > > ///  
> > > > /// - SeeAlso: The unary minus operator (`-`).  
> > > > mutating func negate  
> > > > ()  
> > > > }
> > > > 
> > > > extension SignedArithmetic  
> > > > {
> > > > 
> > > > public static prefix func - (\_ operand: Self) -\> Self  
> > > > {
> > > > 
> > > > var result =  
> > > > operand  
> > > > &nbsp;&nbsp;&nbsp;result.  
> > > > negate  
> > > > ()
> > > > 
> > > > return  
> > > > result  
> > > > }
> > > > 
> > > > public mutating func negate  
> > > > () {
> > > > 
> > > > self = Self() - self
> > > > 
> > > > }  
> > > > }
> > > > 
> > > > BinaryInteger
> > > > 
> > > > The BinaryInteger protocol is the basis for all the integer types provided by the standard library.
> > > > 
> > > > This protocol adds a few new initializers. Two of them allow to create integers from floating point numbers, others support construction from instances of any type conforming to BinaryInteger, using different strategies:
> > > > 
> > > > &nbsp;&nbsp;&nbsp;• Initialize Self with the value, provided that the value is representable. The precondition should be satisfied by the caller.
> > > > 
> > > > &nbsp;&nbsp;&nbsp;• Extend or truncate the value to fit into Self
> > > > 
> > > > &nbsp;&nbsp;&nbsp;• Clamp the value to the representable range of Self
> > > > 
> > > > BinaryInteger also declares bitwise and shift operators.
> > > > 
> > > > public protocol BinaryInteger :  
> > > > Comparable, Hashable, Arithmetic, CustomStringConvertible, Strideable  
> > > > {
> > > > 
> > > > /// A Boolean value indicating whether this type is a signed integer type.  
> > > > ///  
> > > > /// \*Signed\* integer types can represent both positive and negative values.  
> > > > /// \*Unsigned\* integer types can represent only nonnegative values.  
> > > > static var isSigned: Bool { get  
> > > > }
> > > > 
> > > > /// Creates an integer from the given floating-point value, if it can be  
> > > > /// represented exactly.  
> > > > ///  
> > > > /// If the value passed as `source` is not representable exactly, the result  
> > > > /// is `nil`. In the following example, the constant `x` is successfully  
> > > > /// created from a value of `21.0`, while the attempt to initialize the  
> > > > /// constant `y` from `21.5` fails:  
> > > > ///  
> > > > /// let x = Int(exactly: 21.0)  
> > > > /// // x == Optional(21)  
> > > > /// let y = Int(exactly: 21.5)  
> > > > /// // y == nil  
> > > > ///  
> > > > /// - Parameter source: A floating-point value to convert to an integer.  
> > > > init?\<T : FloatingPoint\>(exactly source  
> > > > : T)
> > > > 
> > > > /// Creates an integer from the given floating-point value, truncating any  
> > > > /// fractional part.  
> > > > ///  
> > > > /// Truncating the fractional part of `source` is equivalent to rounding  
> > > > /// toward zero.  
> > > > ///  
> > > > /// let x = Int(21.5)  
> > > > /// // x == 21  
> > > > /// let y = Int(-21.5)  
> > > > /// // y == -21  
> > > > ///  
> > > > /// If `source` is outside the bounds of this type after truncation, a  
> > > > /// runtime error may occur.  
> > > > ///  
> > > > /// let z = UInt(-21.5)  
> > > > /// // Error: ...the result would be less than UInt.min  
> > > > ///  
> > > > /// - Parameter source: A floating-point value to convert to an integer.  
> > > > /// `source` must be representable in this type after truncation.  
> > > > init\<T : FloatingPoint\>(\_ source  
> > > > : T)
> > > > 
> > > > /// Creates an new instance from the given integer.  
> > > > ///  
> > > > /// If the value passed as `source` is not representable in this type, a  
> > > > /// runtime error may occur.  
> > > > ///  
> > > > /// let x = -500 as Int  
> > > > /// let y = Int32(x)  
> > > > /// // y == -500  
> > > > ///  
> > > > /// // -500 is not representable as a 'UInt32' instance  
> > > > /// let z = UInt32(x)  
> > > > /// // Error  
> > > > ///  
> > > > /// - Parameter source: An integer to convert. `source` must be representable  
> > > > /// in this type.  
> > > > init\<T : BinaryInteger\>(\_ source  
> > > > : T)
> > > > 
> > > > /// Creates a new instance from the bit pattern of the given instance by  
> > > > /// sign-extending or truncating to fit this type.  
> > > > ///  
> > > > /// When the bit width of `T` (the type of `source`) is equal to or greater  
> > > > /// than this type's bit width, the result is the truncated  
> > > > /// least-significant bits of `source`. For example, when converting a  
> > > > /// 16-bit value to an 8-bit type, only the lower 8 bits of `source` are  
> > > > /// used.  
> > > > ///  
> > > > /// let p: Int16 = -500  
> > > > /// // 'p' has a binary representation of 11111110\_00001100  
> > > > /// let q = Int8(extendingOrTruncating: p)  
> > > > /// // q == 12  
> > > > /// // 'q' has a binary representation of 00001100  
> > > > ///  
> > > > /// When the bit width of `T` is less than this type's bit width, the result  
> > > > /// is \*sign-extended\* to fill the remaining bits. That is, if `source` is  
> > > > /// negative, the result is padded with ones; otherwise, the result is  
> > > > /// padded with zeros.  
> > > > ///  
> > > > /// let u: Int8 = 21  
> > > > /// // 'u' has a binary representation of 00010101  
> > > > /// let v = Int16(extendingOrTruncating: u)  
> > > > /// // v == 21  
> > > > /// // 'v' has a binary representation of 00000000\_00010101  
> > > > ///  
> > > > /// let w: Int8 = -21  
> > > > /// // 'w' has a binary representation of 11101011  
> > > > /// let x = Int16(extendingOrTruncating: w)  
> > > > /// // x == -21  
> > > > /// // 'x' has a binary representation of 11111111\_11101011  
> > > > /// let y = UInt16(extendingOrTruncating: w)  
> > > > /// // y == 65515  
> > > > /// // 'y' has a binary representation of 11111111\_11101011  
> > > > ///  
> > > > /// - Parameter source: An integer to convert to this type.  
> > > > init\<T : BinaryInteger\>(extendingOrTruncating source  
> > > > : T)
> > > > 
> > > > /// Creates a new instance with the representable value that's closest to the  
> > > > /// given integer.  
> > > > ///  
> > > > /// If the value passed as `source` is greater than the maximum representable  
> > > > /// value in this type, the result is the type's `max` value. If `source` is  
> > > > /// less than the smallest representable value in this type, the result is  
> > > > /// the type's `min` value.  
> > > > ///  
> > > > /// In this example, `x` is initialized as an `Int8` instance by clamping  
> > > > /// `500` to the range `-128...127`, and `y` is initialized as a `UInt`  
> > > > /// instance by clamping `-500` to the range `0...UInt.max`.  
> > > > ///  
> > > > /// let x = Int8(clamping: 500)  
> > > > /// // x == 127  
> > > > /// // x == Int8.max  
> > > > ///  
> > > > /// let y = UInt(clamping: -500)  
> > > > /// // y == 0  
> > > > ///  
> > > > /// - Parameter source: An integer to convert to this type.  
> > > > init\<T : BinaryInteger\>(clamping source  
> > > > : T)
> > > > 
> > > > /// Returns the n-th word, counting from the least significant to most  
> > > > /// significant, of this value's binary representation.  
> > > > ///  
> > > > /// The `word(at:)` method returns negative values in two's complement  
> > > > /// representation, regardless of a type's underlying implementation. If `n`  
> > > > /// is greater than the number of words in this value's current  
> > > > /// representation, the result is `0` for positive numbers and `~0` for  
> > > > /// negative numbers.  
> > > > ///  
> > > > /// - Parameter n: The word to return, counting from the least significant to  
> > > > /// most significant. `n` must be greater than or equal to zero.  
> > > > /// - Returns: An word-sized, unsigned integer with the bit pattern of the  
> > > > /// n-th word of this value.  
> > > > func word(at n: Int) -\> UInt
> > > > 
> > > > /// The number of bits in the current binary representation of this value.  
> > > > ///  
> > > > /// This property is a constant for instances of fixed-width integer  
> > > > /// types.  
> > > > var bitWidth : Int { get  
> > > > }
> > > > 
> > > > /// The number of trailing zeros in this value's binary representation.  
> > > > ///  
> > > > /// For example, in a fixed-width integer type with a `bitWidth` value of 8,  
> > > > /// the number -8 has three trailing zeros.  
> > > > ///  
> > > > /// let x = Int8(bitPattern: 0b1111\_1000)  
> > > > /// // x == -8  
> > > > /// // x.trailingZeros == 3  
> > > > var trailingZeros: Int { get  
> > > > }
> > > > 
> > > > /// Returns the remainder of dividing the first value by the second.  
> > > > ///  
> > > > /// The result has the same sign as `lhs` and is less than `rhs.magnitude`.  
> > > > ///  
> > > > /// let x = 22 % 5  
> > > > /// // x == 2  
> > > > /// let y = 22 % -5  
> > > > /// // y == 2  
> > > > /// let z = -22 % -5  
> > > > /// // z == -2  
> > > > ///  
> > > > /// - Parameters:  
> > > > /// - lhs: The value to divide.  
> > > > /// - rhs: The value to divide `lhs` by. `rhs` must not be zero.  
> > > > static func %(\_ lhs: Self, \_ rhs: Self) -\> Self
> > > > 
> > > > /// Replaces this value with the remainder of itself divided by the given  
> > > > /// value. For example:  
> > > > ///  
> > > > /// var x = 15  
> > > > /// x %= 7  
> > > > /// // x == 1  
> > > > ///  
> > > > /// - Parameter rhs: The value to divide this value by. `rhs` must not be  
> > > > /// zero.  
> > > > ///  
> > > > /// - SeeAlso: `remainder(dividingBy:)`  
> > > > static func %=(\_ lhs: inout Self, \_ rhs: Self  
> > > > )
> > > > 
> > > > /// Returns the inverse of the bits set in the argument.  
> > > > ///  
> > > > /// The bitwise NOT operator (`~`) is a prefix operator that returns a value  
> > > > /// in which all the bits of its argument are flipped: Bits that are `1` in  
> > > > /// the argument are `0` in the result, and bits that are `0` in the argument  
> > > > /// are `1` in the result. This is equivalent to the inverse of a set. For  
> > > > /// example:  
> > > > ///  
> > > > /// let x: UInt8 = 5 // 0b00000101  
> > > > /// let notX = ~x // 0b11111010  
> > > > ///  
> > > > /// Performing a bitwise NOT operation on 0 returns a value with every bit  
> > > > /// set to `1`.  
> > > > ///  
> > > > /// let allOnes = ~UInt8.min // 0b11111111  
> > > > ///  
> > > > /// - Complexity: O(1).  
> > > > static prefix func ~ (\_ x: Self) -\> Self
> > > > 
> > > > /// Returns the result of performing a bitwise AND operation on this value  
> > > > /// and the given value.  
> > > > ///  
> > > > /// A bitwise AND operation results in a value that has each bit set to `1`  
> > > > /// where \*both\* of its arguments have that bit set to `1`. For example:  
> > > > ///  
> > > > /// let x: UInt8 = 5 // 0b00000101  
> > > > /// let y: UInt8 = 14 // 0b00001110  
> > > > /// let z = x & y // 0b00000100  
> > > > static func &(\_ lhs: Self, \_ rhs: Self) -\> Self
> > > > 
> > > > static func &=(\_ lhs: inout Self, \_ rhs: Self  
> > > > )
> > > > 
> > > > /// Returns the result of performing a bitwise OR operation on this value and  
> > > > /// the given value.  
> > > > ///  
> > > > /// A bitwise OR operation results in a value that has each bit set to `1`  
> > > > /// where \*one or both\* of its arguments have that bit set to `1`. For  
> > > > /// example:  
> > > > ///  
> > > > /// let x: UInt8 = 5 // 0b00000101  
> > > > /// let y: UInt8 = 14 // 0b00001110  
> > > > /// let z = x | y // 0b00001111  
> > > > static func |(\_ lhs: Self, \_ rhs: Self) -\> Self
> > > > 
> > > > static func |=(\_ lhs: inout Self, \_ rhs: Self  
> > > > )
> > > > 
> > > > /// Returns the result of performing a bitwise XOR operation on this value  
> > > > /// and the given value.  
> > > > ///  
> > > > /// A bitwise XOR operation, also known as an exclusive OR operation, results  
> > > > /// in a value that has each bit set to `1` where \*one or the other but not  
> > > > /// both\* of its arguments had that bit set to `1`. For example:  
> > > > ///  
> > > > /// let x: UInt8 = 5 // 0b00000101  
> > > > /// let y: UInt8 = 14 // 0b00001110  
> > > > /// let z = x ^ y // 0b00001011  
> > > > static func ^(\_ lhs: Self, \_ rhs: Self) -\> Self
> > > > 
> > > > static func ^=(\_ lhs: inout Self, \_ rhs: Self  
> > > > )
> > > > 
> > > > /// Returns the result of shifting this value's binary representation the  
> > > > /// specified number of digits to the right.  
> > > > ///  
> > > > /// In a \*masking shift\*, the bit pattern of the value passed as `rhs` is  
> > > > /// masked to produce a value between zero and the bit width of `lhs`. The  
> > > > /// shift is performed using this masked value. Masking shifts require more  
> > > > /// care to use correctly than a traditional bit shift, but are likely to be  
> > > > /// more efficient when used with shift amounts that are not compile-time  
> > > > /// constants. On most architectures, a masking shift compiles down to a  
> > > > /// single instruction.  
> > > > ///  
> > > > /// For example, if you shift an 8-bit, unsigned integer by 2, the shift  
> > > > /// amount requires no masking.  
> > > > ///  
> > > > /// let x: UInt8 = 30 // 0b00011110  
> > > > /// let y = x &\>\> 2  
> > > > /// // y == 7 // 0b00000111  
> > > > ///  
> > > > /// However, if you shift it by 11, it first bitmasks `rhs` to `3`, and then  
> > > > /// uses that masked value as the number of bits to shift `x`.  
> > > > ///  
> > > > /// let z = x &\>\> 11  
> > > > /// // z == 3 // 0b00000011  
> > > > ///  
> > > > /// Relationship to the Right Shift Operator  
> > > > /// ----------------------------------------  
> > > > ///  
> > > > /// The masking right shift operator handles attempted overshifts and  
> > > > /// undershifts differently from the right shift operator (`\>\>`). When the  
> > > > /// value passed as `rhs` in a masking shift is within the range  
> > > > /// `0...\<bitWidth`, the operation is equivalent to using the right shift  
> > > > /// operator.  
> > > > ///  
> > > > /// let x: UInt8 = 30 // 0b00011110  
> > > > /// let y1 = x &\>\> 2  
> > > > /// // y1 == 7 // 0b00000111  
> > > > /// let y2 = x \>\> 2  
> > > > /// // y2 == 7 // 0b00000111  
> > > > ///  
> > > > /// The right shift operator does not mask its right-hand-side argument, so  
> > > > /// passing `11` as `rhs` shifts all the bits of `x` to zero.  
> > > > ///  
> > > > /// let z1 = x &\>\> 11  
> > > > /// // z1 == 240 // 0b00000011  
> > > > /// let z2 = x \>\> 11  
> > > > /// // z2 == 0 // 0b00000000  
> > > > ///  
> > > > /// - Parameter rhs: The number of bits to shift this value to the right. If  
> > > > /// `rhs` is outside the range `0..\<bitWidth`, it is masked to produce a  
> > > > /// value within that range.  
> > > > /// - Returns: The result of shifting this value by the masked `rhs` to the  
> > > > /// right.  
> > > > ///  
> > > > /// - SeeAlso: `&\<\<`, `\>\>`  
> > > > static func &\>\>(\_ lhs: Self, \_ rhs: Self) -\> Self
> > > > 
> > > > static func &\>\>=(\_ lhs: inout Self, \_ rhs: Self  
> > > > )
> > > > 
> > > > /// Returns the result of shifting this value's binary representation the  
> > > > /// specified number of digits to the left.  
> > > > ///  
> > > > /// In a \*masking shift\*, the bit pattern of the value passed as `rhs` is  
> > > > /// masked to produce a value between zero and the bit width of `lhs`. The  
> > > > /// shift is performed using this masked value. Masking shifts require more  
> > > > /// care to use correctly than a traditional bit shift, but are likely to be  
> > > > /// more efficient when used with shift amounts that are not compile-time  
> > > > /// constants. On most architectures, a masking shift compiles down to a  
> > > > /// single instruction.  
> > > > ///  
> > > > /// For example, if you shift an 8-bit, unsigned integer by 2, the shift  
> > > > /// amount requires no masking.  
> > > > ///  
> > > > /// let x: UInt8 = 30 // 0b00011110  
> > > > /// let y = x &\>\> 2  
> > > > /// // y == 120 // 0b01111000  
> > > > ///  
> > > > /// However, if you shift it by 11, it first bitmasks `rhs` to `3`, and then  
> > > > /// uses that masked value as the number of bits to shift `x`.  
> > > > ///  
> > > > /// let z = x &\<\< 11  
> > > > /// // z == 240 // 0b11110000  
> > > > ///  
> > > > /// Relationship to the Left Shift Operator  
> > > > /// ---------------------------------------  
> > > > ///  
> > > > /// The masking left shift operator handles attempted overshifts and  
> > > > /// undershifts differently from the left shift operator (`\<\<`). When the  
> > > > /// value passed as `rhs` in a masking shift is within the range  
> > > > /// `0...\<bitWidth`, the operation is equivalent to using the left shift  
> > > > /// operator.  
> > > > ///  
> > > > /// let x: UInt8 = 30 // 0b00011110  
> > > > /// let y1 = x &\<\< 2  
> > > > /// // y1 == 120 // 0b01111000  
> > > > /// let y2 = x \<\< 2  
> > > > /// // y2 == 120 // 0b01111000  
> > > > ///  
> > > > /// The left shift operator does not mask its right-hand-side argument, so  
> > > > /// passing `11` as `rhs` shifts all the bits of `x` to zero.  
> > > > ///  
> > > > /// let z1 = x &\<\< 11  
> > > > /// // z1 == 240 // 0b11110000  
> > > > /// let z2 = x \<\< 11  
> > > > /// // z2 == 0 // 0b00000000  
> > > > ///  
> > > > /// - Parameter rhs: The number of bits to shift this value to the left. If  
> > > > /// `rhs` is outside the range `0..\<bitWidth`, it is masked to produce a  
> > > > /// value within that range.  
> > > > /// - Returns: The result of shifting this value by the masked `rhs` to the  
> > > > /// left.  
> > > > ///  
> > > > /// - SeeAlso: `&\>\>`, `\<\<`  
> > > > static func &\<\<(\_ lhs: Self, \_ rhs: Self) -\> Self
> > > > 
> > > > static func &\<\<=(\_ lhs: inout Self, \_ rhs: Self  
> > > > )
> > > > 
> > > > /// Returns the quotient and remainder of this value divided by the given  
> > > > /// value.  
> > > > ///  
> > > > /// Use this method to calculate the quotient and remainder of a division at  
> > > > /// the same time.  
> > > > ///  
> > > > /// let x = 1\_000\_000  
> > > > /// let (q, r) = x.quotientAndRemainder(dividingBy: 933)  
> > > > /// // q == 1071  
> > > > /// // r == 757  
> > > > ///  
> > > > /// - Parameter rhs: The value to divide this value by.  
> > > > /// - Returns: A tuple containing the quotient and remainder of this value  
> > > > /// divided by `rhs`.  
> > > > func quotientAndRemainder(dividingBy rhs: Self  
> > > > )
> > > > 
> > > > -\> (quotient: Self, remainder: Self  
> > > > )
> > > > 
> > > > /// Returns `-1` if this value is negative and `1` if it's positive;  
> > > > /// otherwise, `0`.  
> > > > ///  
> > > > /// - Returns: The sign of this number, expressed as an integer of the same  
> > > > /// type.  
> > > > func signum() -\> Self
> > > > 
> > > > }
> > > > 
> > > > FixedWidthInteger
> > > > 
> > > > The FixedWidthInteger protocol adds the notion of endianness as well as static properties for type bounds and bit width.
> > > > 
> > > > The WithOverflow family of methods is used in default implementations of mutating arithmetic methods (see the Arithmetic protocol). Having these methods allows the library to provide both bounds-checked and masking implementations of arithmetic operations, without duplicating code.
> > > > 
> > > > The doubleWidthMultiply and doubleWidthDivide methods are necessary building blocks to implement support for integer types of a greater width such as arbitrary-precision integers.
> > > > 
> > > > public protocol FixedWidthInteger : BinaryInteger  
> > > > {
> > > > 
> > > > /// The number of bits used for the underlying binary representation of  
> > > > /// values of this type.  
> > > > ///  
> > > > /// An unsigned, fixed-width integer type can represent values from 0 through  
> > > > /// `(2 **bitWidth) - 1`, where `**` is exponentiation. A signed,  
> > > > /// fixed-width integer type can represent values from  
> > > > /// `-(2 **bitWidth - 1)` through `(2** bitWidth - 1) - 1`. For example,  
> > > > /// the `Int8` type has a `bitWidth` value of 8 and can store any integer in  
> > > > /// the range `-128...127`.  
> > > > static var bitWidth : Int { get  
> > > > }
> > > > 
> > > > /// The maximum representable integer in this type.  
> > > > ///  
> > > > /// For unsigned integer types, this value is `(2 ** bitWidth) - 1`, where  
> > > > /// `**` is exponentiation. For signed integer types, this value is  
> > > > /// `(2 ** bitWidth - 1) - 1`.  
> > > > static var max: Self { get  
> > > > }
> > > > 
> > > > /// The minimum representable value.  
> > > > ///  
> > > > /// For unsigned integer types, this value is always `0`. For signed integer  
> > > > /// types, this value is `-(2 **bitWidth - 1)`, where `**` is  
> > > > /// exponentiation.  
> > > > static var min: Self { get  
> > > > }
> > > > 
> > > > /// Returns the sum of this value and the given value along with a flag  
> > > > /// indicating whether overflow occurred in the operation.  
> > > > ///  
> > > > /// - Parameter other: The value to add to this value.  
> > > > /// - Returns: A tuple containing the result of the addition along with a  
> > > > /// flag indicating whether overflow occurred. If the `overflow` component  
> > > > /// is `.none`, the `partialValue` component contains the entire sum. If  
> > > > /// the `overflow` component is `.overflow`, an overflow occurred and the  
> > > > /// `partialValue` component contains the truncated sum of this value and  
> > > > /// `other`.  
> > > > ///  
> > > > /// - SeeAlso: `+`  
> > > > func addingWithOverflow(\_ other: Self  
> > > > )
> > > > 
> > > > -\> (partialValue: Self, overflow  
> > > > : ArithmeticOverflow)
> > > > 
> > > > /// Returns the difference of this value and the given value along with a  
> > > > /// flag indicating whether overflow occurred in the operation.  
> > > > ///  
> > > > /// - Parameter other: The value to subtract from this value.  
> > > > /// - Returns: A tuple containing the result of the subtraction along with a  
> > > > /// flag indicating whether overflow occurred. If the `overflow` component  
> > > > /// is `.none`, the `partialValue` component contains the entire  
> > > > /// difference. If the `overflow` component is `.overflow`, an overflow  
> > > > /// occurred and the `partialValue` component contains the truncated  
> > > > /// result of `other` subtracted from this value.  
> > > > ///  
> > > > /// - SeeAlso: `-`  
> > > > func subtractingWithOverflow(\_ other: Self  
> > > > )
> > > > 
> > > > -\> (partialValue: Self, overflow  
> > > > : ArithmeticOverflow)
> > > > 
> > > > /// Returns the product of this value and the given value along with a flag  
> > > > /// indicating whether overflow occurred in the operation.  
> > > > ///  
> > > > /// - Parameter other: The value to multiply by this value.  
> > > > /// - Returns: A tuple containing the result of the multiplication along with  
> > > > /// a flag indicating whether overflow occurred. If the `overflow`  
> > > > /// component is `.none`, the `partialValue` component contains the entire  
> > > > /// product. If the `overflow` component is `.overflow`, an overflow  
> > > > /// occurred and the `partialValue` component contains the truncated  
> > > > /// product of this value and `other`.  
> > > > ///  
> > > > /// - SeeAlso: `*`, `doubleWidthMultiply(_:_:)`  
> > > > func multipliedWithOverflow(by other: Self  
> > > > )
> > > > 
> > > > -\> (partialValue: Self, overflow  
> > > > : ArithmeticOverflow)
> > > > 
> > > > /// Returns the quotient of dividing this value by the given value along with  
> > > > /// a flag indicating whether overflow occurred in the operation.  
> > > > ///  
> > > > /// For a value `x`, if zero is passed as `other`, the result is  
> > > > /// `(x, .overflow)`.  
> > > > ///  
> > > > /// - Parameter other: The value to divide this value by.  
> > > > /// - Returns: A tuple containing the result of the division along with a  
> > > > /// flag indicating whether overflow occurred. If the `overflow` component  
> > > > /// is `.none`, the `partialValue` component contains the entire quotient.  
> > > > /// If the `overflow` component is `.overflow`, an overflow occurred and  
> > > > /// the `partialValue` component contains the truncated quotient.  
> > > > ///  
> > > > /// - SeeAlso: `/`, `doubleWidthDivide(_:_:)`  
> > > > func dividedWithOverflow(by other: Self  
> > > > )
> > > > 
> > > > -\> (partialValue: Self, overflow  
> > > > : ArithmeticOverflow)
> > > > 
> > > > /// Returns a tuple containing the high and low parts of the result of  
> > > > /// multiplying its arguments.  
> > > > ///  
> > > > /// Use this method to calculate the full result of a product that would  
> > > > /// otherwise overflow. Unlike traditional truncating multiplication, the  
> > > > /// `doubleWidthMultiply(_:_:)` method returns both the `high` and `low`  
> > > > /// parts of the product of `lhs` and `rhs`. The following example uses this  
> > > > /// method to multiply two `UInt8` values that normally overflow when  
> > > > /// multiplied:  
> > > > ///  
> > > > /// let x: UInt8 = 100  
> > > > /// let y: UInt8 = 20  
> > > > /// let result = UInt8.doubleWidthMultiply(100, 20)  
> > > > /// // result.high == 0b00000111  
> > > > /// // result.low == 0b11010000  
> > > > ///  
> > > > /// The product of `x` and `y` is 2000, which is too large to represent in a  
> > > > /// `UInt8` instance. The `high` and `low` components of the `result` tuple  
> > > > /// represent 2000 when concatenated to form a double-width integer; that  
> > > > /// is, using `result.high` as the high byte and `result.low` as the low byte  
> > > > /// of a `UInt16` instance.  
> > > > ///  
> > > > /// let z = UInt16(result.high) \<\< 8 | UInt16(result.low)  
> > > > /// // z == 2000  
> > > > ///  
> > > > /// - Parameters:  
> > > > /// - lhs: A value to multiply.  
> > > > /// - rhs: Another value to multiply.  
> > > > /// - Returns: A tuple containing the high and low parts of the result of  
> > > > /// multiplying `lhs` and `rhs`.  
> > > > ///  
> > > > /// - SeeAlso: `multipliedWithOverflow(by:)`  
> > > > static func doubleWidthMultiply(\_ lhs: Self, \_ rhs: Self  
> > > > )
> > > > 
> > > > -\> (high: Self, low  
> > > > : Magnitude)
> > > > 
> > > > /// Returns a tuple containing the quotient and remainder of dividing the  
> > > > /// first argument by the second.  
> > > > ///  
> > > > /// The resulting quotient must be representable within the bounds of the  
> > > > /// type. If the quotient of dividing `lhs` by `rhs` is too large to  
> > > > /// represent in the type, a runtime error may occur.  
> > > > ///  
> > > > /// - Parameters:  
> > > > /// - lhs: A tuple containing the high and low parts of a double-width  
> > > > /// integer. The `high` component of the tuple carries the sign, if the  
> > > > /// type is signed.  
> > > > /// - rhs: The integer to divide into `lhs`.  
> > > > /// - Returns: A tuple containing the quotient and remainder of `lhs` divided  
> > > > /// by `rhs`.  
> > > > static func doubleWidthDivide  
> > > > (
> > > > 
> > > > \_ lhs: (high: Self, low: Magnitude), \_ rhs: Self  
> > > > )
> > > > 
> > > > -\> (quotient: Self, remainder: Self  
> > > > )
> > > > 
> > > > /// The number of bits equal to 1 in this value's binary representation.  
> > > > ///  
> > > > /// For example, in a fixed-width integer type with a `bitWidth` value of 8,  
> > > > /// the number 31 has five bits equal to 1.  
> > > > ///  
> > > > /// let x: Int8 = 0b0001\_1111  
> > > > /// // x == 31  
> > > > /// // x.popcount == 5  
> > > > var popcount: Int { get  
> > > > }
> > > > 
> > > > /// The number of leading zeros in this value's binary representation.  
> > > > ///  
> > > > /// For example, in a fixed-width integer type with a `bitWidth` value of 8,  
> > > > /// the number 31 has three leading zeros.  
> > > > ///  
> > > > /// let x: Int8 = 0b0001\_1111  
> > > > /// // x == 31  
> > > > /// // x.leadingZeros == 3  
> > > > /// - SeeAlso: `BinaryInteger.trailingZeros`  
> > > > var leadingZeros: Int { get  
> > > > }
> > > > 
> > > > /// Creates an integer from its big-endian representation, changing the  
> > > > /// byte order if necessary.  
> > > > init(bigEndian value: Self  
> > > > )
> > > > 
> > > > /// Creates an integer from its little-endian representation, changing the  
> > > > /// byte order if necessary.  
> > > > init(littleEndian value: Self  
> > > > )
> > > > 
> > > > /// The big-endian representation of this integer.  
> > > > ///  
> > > > /// If necessary, the byte order of this value is reversed from the typical  
> > > > /// byte order of this integer type. On a big-endian platform, for any  
> > > > /// integer `x`, `x == x.bigEndian`.  
> > > > ///  
> > > > /// - SeeAlso: `littleEndian`  
> > > > var bigEndian: Self { get  
> > > > }
> > > > 
> > > > /// The little-endian representation of this integer.  
> > > > ///  
> > > > /// If necessary, the byte order of this value is reversed from the typical  
> > > > /// byte order of this integer type. On a little-endian platform, for any  
> > > > /// integer `x`, `x == x.littleEndian`.  
> > > > ///  
> > > > /// - SeeAlso: `bigEndian`  
> > > > var littleEndian: Self { get  
> > > > }
> > > > 
> > > > /// A representation of this integer with the byte order swapped.  
> > > > var byteSwapped: Self { get  
> > > > }  
> > > > }
> > > > 
> > > > Auxiliary protocols
> > > > 
> > > > public protocol UnsignedInteger : BinaryInteger  
> > > > {
> > > > 
> > > > associatedtype Magnitude : BinaryInteger
> > > > 
> > > > }
> > > > 
> > > > public protocol SignedInteger : BinaryInteger, SignedArithmetic  
> > > > {
> > > > 
> > > > associatedtype Magnitude : BinaryInteger
> > > > 
> > > > }
> > > > 
> > > > DoubleWidth
> > > > 
> > > > The DoubleWidth\<T\> type allows to create wider fixed-width integer types from the ones available in the standard library.
> > > > 
> > > > Standard library currently provides fixed-width integer types of up to 64 bits. A value of DoubleWidth\<Int64\> will double the range of the underlying type and implement all the FixedWidthInteger requirements. Please note though that the implementation will not necessarily be the most efficient one, so it would not be a good idea to use DoubleWidth\<Int32\>instead of a built-in Int64.
> > > > 
> > > > Extra operators
> > > > 
> > > > In addition to the operators described in the protocols section, we also provide a few extensions that are not protocol requirements:
> > > > 
> > > > Heterogeneous shifts
> > > > 
> > > > extension BinaryInteger  
> > > > {
> > > > 
> > > > // Masking shifts  
> > > > static func &\>\> \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self
> > > > 
> > > > static func &\>\>= \<Other : BinaryInteger\>(lhs: inout Self, rhs  
> > > > : Other)
> > > > 
> > > > static func &\<\< \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self
> > > > 
> > > > static func &\<\<= \<Other : BinaryInteger\>(lhs: inout Self, rhs  
> > > > : Other)
> > > > 
> > > > // 'Smart' shifts  
> > > > static func \>\> \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self
> > > > 
> > > > static func \>\>= \<Other : BinaryInteger\>(lhs: inout Self, rhs  
> > > > : Other)
> > > > 
> > > > static func \<\< \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self
> > > > 
> > > > static func \<\<= \<Other : BinaryInteger\>(lhs: inout Self, rhs  
> > > > : Other)  
> > > > }
> > > > 
> > > > Heterogeneous equality and comparison
> > > > 
> > > > extension BinaryInteger  
> > > > {
> > > > 
> > > > // Equality  
> > > > static func == \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool
> > > > 
> > > > static func != \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool
> > > > 
> > > > // Comparison  
> > > > static func \< \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool
> > > > 
> > > > static func \<= \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool
> > > > 
> > > > static func \> \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool
> > > > 
> > > > static func \>= \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool
> > > > 
> > > > }
> > > > 
> > > > Masking arithmetic
> > > > 
> > > > public func &\* \<T: FixedWidthInteger\>(lhs: T, rhs: T) -\>  
> > > > T
> > > > 
> > > > public func &- \<T: FixedWidthInteger\>(lhs: T, rhs: T) -\>  
> > > > T
> > > > 
> > > > public func &+ \<T: FixedWidthInteger\>(lhs: T, rhs: T) -\> T  
> > > > Non-goals
> > > > 
> > > > This proposal:
> > > > 
> > > > &nbsp;&nbsp;&nbsp;• DOES NOT solve the integer promotion problem, which would allow mixed-type arithmetic. However, we believe that it is an important step in the right direction.
> > > > 
> > > > &nbsp;&nbsp;&nbsp;• DOES NOT include the implementation of a BigInt type, but allows it to be implemented in the future.
> > > > 
> > > > Source compatibility
> > > > 
> > > > The proposed change is designed to be as non-breaking as possible, and it has been proven that it does not break code on concrete integer types. However, there are still a few API breaking changes in the realm of generic code:
> > > > 
> > > > &nbsp;&nbsp;&nbsp;• Integer protocols in Swift up to and including version 3 were not particularly useful for generic programming, but were rather a means of sharing implementation between conforming types. Therefore we believe the amount of code that relied on these protocols is relatively small. The breakage can be further reduced by introducing proper aliases for the removed protocols with deprecation warnings.
> > > > 
> > > > &nbsp;&nbsp;&nbsp;• Deprecation of the BitwiseOperations protocol. We find it hard to imagine a type that conforms to this protocol, but is not a binary integer type.
> > > > 
> > > > &nbsp;&nbsp;&nbsp;• Addition of 'smart' shifts will change the behavior of existing code. It will still compile, but will be potentially less performant due to extra logic involved. In a case, where this becomes a problem, newly introduced masking shift operators can be used instead. Unfortunately, performance characteristics of the code cannot be statically checked, and thus migration cannot be provided.
> > > > 
> > > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > > swift-evolution mailing list  
> > > > swift-evolution@swift.org  
> > > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > > 
> > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > swift-evolution mailing list  
> > > swift-evolution@swift.org  
> > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
> 
> --  
> -Dave

---

<div class="post-metadata">

**Author:** ![dabrahams](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dabrahams/32/9815_2.png) [@dabrahams](https://forums.swift.org/u/dabrahams)\
**Post date:** [January 16, 2017, 8:53pm UTC](https://forums.swift.org/t/protocol-oriented-integers-take-2/4884/17 "2017-01-16T20:53:05Z")

</div>

> > Really glad to see this coming back :)
> > 
> > I have a couple of questions:
> > 
> > 1) How does Strideable relate to Arithmetic?
> > 
> > My understanding is that Strideable allows non-numeric types to express  
> > different-type addition and subtraction, and that Arithmetic is for numeric  
> > types only (derives from ExpressibleByIntegerLiteral) and allows then to  
> > express same-type operations. Is that correct?
> 
> My understanding was that heterogeneous addition and subtraction using  
> operators are not supported not merely due to compiler limitations but as a  
> fundamental philosophy, because the type of the intended result can be  
> unclear to human readers and unintentional promotion is to be avoided?

No, not really. We'd like to introduce a promotion model.

> In that vein, my understanding was that having those operators  
> available for Strideable was inconsistent and overdue for removal, and  
> `advanced(by:)` is the intended spelling for advancing a value by a  
> distance of a different type.

The real reason to remove them from Strideable is that unsigned numbers  
are strideable with a signed stride, which made preventing people from  
adding signed and unsigned numbers unintentionally messy and unreliable.

> > If so, it would be nice to add it to the proposal so people know when they  
> > should conform (or set their generic constraints) to one or the other.
> > 
> > 2) Can SignedNumber get some operators now?
> > 
> > Strideable.Stride is bound to this weird protocol ‘SignedNumber’. You can  
> > create instances of it out of thin air via an integer literal, but you  
> > can’t accumulate Strides to find the overall distance between some adjacent  
> > Strideables.
> 
> I understood these new protocols to mean that SignedNumber is headed for  
> deprecation?

That's the plan.

> > Also, #1 is why I don’t like the Strideable operator deprecation being  
> > part of the proposal (and therefore part of the language specification). It  
> > doesn’t solve the underlying issue, which is that our integer literal  
> > protocols aren’t really good enough - they’re not useful enough outside the  
> > standard library (see: [https://bugs.swift.org/browse/SR-920\](https://bugs.swift.org/browse/SR-920%5C)), and  
> > evidently the compiler isn’t able to use them to infer types correctly.  
> > Perhaps fixing it is a low priority, and that’s fine, but what about if  
> > somebody else defines this operator in their library? They start of break  
> > lots of valid code because the compiler can’t do the right thing. Improved  
> > literal protocols may be the better way to resolve that problem.
> 
> I agree totally that literals are aching for improvements as outlined in  
> SR-920.

Indeedy.

> **···**
>
> on Mon Jan 16 2017, Xiaodi Wu \<swift-evolution@swift.org\> wrote:
> 
> > On Mon, Jan 16, 2017 at 11:57 AM, Karl Wagner via swift-evolution \< \> swift-evolution@swift.org\> wrote:
> 
> > Not sure how it relates to integer protocols though. What are some  
> > examples of valid code that get broken today because of compiler  
> > limitations?
> > 
> > > - Karl  
> > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > swift-evolution mailing list  
> > > swift-evolution@swift.org  
> > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
> 
> --  
> -Dave

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [January 16, 2017, 7:53pm UTC](https://forums.swift.org/t/protocol-oriented-integers-take-2/4884/18 "2017-01-16T19:53:01Z")

</div>

> Really glad to see this coming back :)
> 
> I have a couple of questions:
> 
> 1) How does Strideable relate to Arithmetic?
> 
> My understanding is that Strideable allows non-numeric types to express  
> different-type addition and subtraction, and that Arithmetic is for numeric  
> types only (derives from ExpressibleByIntegerLiteral) and allows then to  
> express same-type operations. Is that correct?

My understanding was that heterogeneous addition and subtraction using  
operators are not supported not merely due to compiler limitations but as a  
fundamental philosophy, because the type of the intended result can be  
unclear to human readers and unintentional promotion is to be avoided? In  
that vein, my understanding was that having those operators available for  
Strideable was inconsistent and overdue for removal, and `advanced(by:)` is  
the intended spelling for advancing a value by a distance of a different  
type.

> If so, it would be nice to add it to the proposal so people know when they  
> should conform (or set their generic constraints) to one or the other.
> 
> 2) Can SignedNumber get some operators now?
> 
> Strideable.Stride is bound to this weird protocol ‘SignedNumber’. You can  
> create instances of it out of thin air via an integer literal, but you  
> can’t accumulate Strides to find the overall distance between some adjacent  
> Strideables.

I understood these new protocols to mean that SignedNumber is headed for  
deprecation?

> Also, #1 is why I don’t like the Strideable operator deprecation being  
> part of the proposal (and therefore part of the language specification). It  
> doesn’t solve the underlying issue, which is that our integer literal  
> protocols aren’t really good enough - they’re not useful enough outside the  
> standard library (see: [https://bugs.swift.org/browse/SR-920\](https://bugs.swift.org/browse/SR-920%5C)), and  
> evidently the compiler isn’t able to use them to infer types correctly.  
> Perhaps fixing it is a low priority, and that’s fine, but what about if  
> somebody else defines this operator in their library? They start of break  
> lots of valid code because the compiler can’t do the right thing. Improved  
> literal protocols may be the better way to resolve that problem.

I agree totally that literals are aching for improvements as outlined in  
SR-920. Not sure how it relates to integer protocols though. What are some  
examples of valid code that get broken today because of compiler  
limitations?

> **···**
>
> On Mon, Jan 16, 2017 at 11:57 AM, Karl Wagner via swift-evolution \< swift-evolution@swift.org\> wrote:
> 
> > - Karl  
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![Karl](https://avatars.discourse-cdn.com/v4/letter/k/34f0e0/32.png) [@Karl](https://forums.swift.org/u/Karl)\
**Post date:** [January 16, 2017, 9:32pm UTC](https://forums.swift.org/t/protocol-oriented-integers-take-2/4884/19 "2017-01-16T21:32:02Z")

</div>

> Really glad to see this coming back :)
> 
> I have a couple of questions:
> 
> 1) How does Strideable relate to Arithmetic?
> 
> My understanding is that Strideable allows non-numeric types to express different-type addition and subtraction, and that Arithmetic is for numeric types only (derives from ExpressibleByIntegerLiteral) and allows then to express same-type operations. Is that correct?
> 
> My understanding was that heterogeneous addition and subtraction using operators are not supported not merely due to compiler limitations but as a fundamental philosophy, because the type of the intended result can be unclear to human readers and unintentional promotion is to be avoided? In that vein, my understanding was that having those operators available for Strideable was inconsistent and overdue for removal, and `advanced(by:)` is the intended spelling for advancing a value by a distance of a different type.
> 
> If so, it would be nice to add it to the proposal so people know when they should conform (or set their generic constraints) to one or the other.
> 
> 2) Can SignedNumber get some operators now?
> 
> Strideable.Stride is bound to this weird protocol ‘SignedNumber’. You can create instances of it out of thin air via an integer literal, but you can’t accumulate Strides to find the overall distance between some adjacent Strideables.
> 
> I understood these new protocols to mean that SignedNumber is headed for deprecation?

It would be nice if the proposal said that, then (and mentioned the corresponding change to Strideable.Stride). I assume it will be replaced with SignedArithmetic, then.

> Also, #1 is why I don’t like the Strideable operator deprecation being part of the proposal (and therefore part of the language specification). It doesn’t solve the underlying issue, which is that our integer literal protocols aren’t really good enough - they’re not useful enough outside the standard library (see: [https://bugs.swift.org/browse/SR-920\](https://bugs.swift.org/browse/SR-920%5C)), and evidently the compiler isn’t able to use them to infer types correctly. Perhaps fixing it is a low priority, and that’s fine, but what about if somebody else defines this operator in their library? They start of break lots of valid code because the compiler can’t do the right thing. Improved literal protocols may be the better way to resolve that problem.
> 
> I agree totally that literals are aching for improvements as outlined in SR-920. Not sure how it relates to integer protocols though. What are some examples of valid code that get broken today because of compiler limitations?

The PR that implemented this fixed a bug with integer literals - basically, the thrust of it (as I understand) is that the compiler can’t figure out which is the preferred overload. It doesn’t know to prefer same-type arithmetic when resolving literals involved in operators.

My problem with just fixing the problem by removing that operator is that anybody could add it back in their own code, and that should be perfectly allowable, but if they did so basic expressions would fail to compile. To me it sounds preferable to leave this as a implementation artefact until we get a chance to make the literal protocols better.

Strideable isn’t some esoteric protocol just for collection indexes, you know. It’s very useful for any quasi-numeric type whose absolute value is semantically different from a difference. For example, I have strongly-typed wrappers for a ByteOffset within a binary file and a LineNumber inside a text file. These wrappers allow me to write extensions (for example to clamp to the bounds of a particular file), and ensure that I don’t accidentally mix semantically different values. They are both Strideable by Int, which is a better semantic fit than Arithmetic (LineNumbers are absolute, should you be able to add them? What does LineNumber \* LineNumber mean?).

So my point is basically that it’s an important protocol (maybe not so much in the standard library, but certainly beyond).

- Karl

> **···**
>
> > On 16 Jan 2017, at 20:53, Xiaodi Wu \<xiaodi.wu@gmail.com\> wrote:  
> > On Mon, Jan 16, 2017 at 11:57 AM, Karl Wagner via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:

---

<div class="post-metadata">

**Author:** ![moiseev](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/moiseev/32/281_2.png) [@moiseev](https://forums.swift.org/u/moiseev)\
**Post date:** [January 25, 2017, 6:00pm UTC](https://forums.swift.org/t/protocol-oriented-integers-take-2/4884/20 "2017-01-25T18:00:23Z")

</div>

Hi Anton,

Arithmetic refines RepresentableByIntegerLiteral, so it is quite possible to use `0` and `1` when you need them.

Max

> **···**
>
> > On Jan 25, 2017, at 7:59 AM, Anton Mironov \<antonvmironov@gmail.com\> wrote:
> > 
> > Hi everyone,
> > 
> > I want to suggest a tiny extension to an Arithmetic protocol. It would be nice to have an additive identity and a multiplicative identity constants. Basically zero and one.
> > 
> > ```swift
> > protocol Arithmetic {
> > /* ... */
> > static var zero: Self { get } // additive identity: (value + .zero) == value
> > static var one: Self { get } // multiplicative identity: (value * .one) == value
> > }
> > 
> > ```
> > 
> > These constants will ease implementation of math structures: vectors, matrices and etc.  
> > I’m sorry if I’m duplicating someone’s suggestion. It is really hard to search for something in a long thread.
> > 
> > Thanks,  
> > Anton Mironov
> > 
> > > On Jan 13, 2017, at 10:47 PM, Max Moiseev via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:
> > > 
> > > Hi everyone,
> > > 
> > > Back in June 2016 we discussed the new design of the integer types for the standard library. It even resulted in acceptance of SE-0104 \<[https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md&gt](https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md&gt); for Swift 3. Unfortunately we were not able to implement it in time for the release.
> > > 
> > > But it was not forgotten, although, as time went by, a few changes needed to be made in order to reflect the current state of the language.  
> > > Without further introduction, please welcome the refined proposal to make integers in Swift more suitable for generic programming.
> > > 
> > > Available in this gist [Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c) and also inlined below.
> > > 
> > > Max
> > > 
> > > Protocol-oriented integers (take 2)
> > > 
> > > Proposal: SE-NNNN \<[https://gist.github.com/moiseev/0000-even-more-improved-integers.md&gt](https://gist.github.com/moiseev/0000-even-more-improved-integers.md&gt);  
> > > Authors: Dave Abrahams \<[https://github.com/dabrahams&gt;](https://github.com/dabrahams&gt;), Maxim Moiseev \<[https://github.com/moiseev&gt](https://github.com/moiseev&gt);  
> > > Review Manager: TBD  
> > > Status: Awaiting review  
> > > Bug: SR-3196 \<[Issues · apple/swift-issues · GitHub](https://bugs.swift.org/browse/SR-3196&gt);  
> > > Previous Proposal: SE-0104 \<[https://gist.github.com/moiseev/0104-improved-integers.md&gt](https://gist.github.com/moiseev/0104-improved-integers.md&gt);  
> > > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#introduction&gt;Introduction)
> > > 
> > > This proposal is an evolution of SE-0104 \<[https://gist.github.com/moiseev/0104-improved-integers.md&gt;\](https://gist.github.com/moiseev/0104-improved-integers.md&gt;%5C). The goal is still to clean up Swifts integer APIs and make them more useful for generic programming.
> > > 
> > > The language has evolved in ways that affect integers APIs since the time the original proposal was approved for Swift 3. We also attempted to implement the proposed model in the standard library and found that some essential APIs were missing, whereas others could be safely removed.
> > > 
> > > Major changes to the APIs introduced by this proposal (as compared to SE-0104 \<[https://gist.github.com/moiseev/0104-improved-integers.md&gt;\](https://gist.github.com/moiseev/0104-improved-integers.md&gt;%5C)) are listed in a dedicated section \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#whats-new-since-se-0104&gt;%5C).
> > > 
> > > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#motivation&gt;Motivation)
> > > 
> > > Swift's integer protocols don't currently provide a suitable basis for generic programming. See this blog post \<[http://blog.krzyzanowskim.com/2015/03/01/swift\_madness\_of\_generic\_integer/&gt](http://blog.krzyzanowskim.com/2015/03/01/swift_madness_of_generic_integer/&gt); for an example of an attempt to implement a generic algorithm over integers.
> > > 
> > > The way the Arithmetic protocol is defined, it does not generalize to floating point numbers and also slows down compilation by requiring every concrete type to provide an implementation of arithmetic operators, thus polluting the overload set.
> > > 
> > > Converting from one integer type to another is performed using the concept of the 'maximum width integer' (see MaxInt), which is an artificial limitation. The very existence of MaxInt makes it unclear what to do should someone implement Int256, for example.
> > > 
> > > Another annoying problem is the inability to use integers of different types in comparison and bit-shift operations. For example, the following snippets won't compile:
> > > 
> > > var x: Int8 = 42  
> > > let y = 1  
> > > let z = 0
> > > 
> > > x \<\<= y // error: binary operator '\<\<=' cannot be applied to operands of type 'Int8' and 'Int'  
> > > if x \> z { ... } // error: binary operator '\>' cannot be applied to operands of type 'Int8' and 'Int'  
> > > Currently, bit-shifting a negative number of (or too many) bits causes a trap on some platforms, which makes low-level bit manipulations needlessly dangerous and unpredictable.
> > > 
> > > Finally, the current design predates many of the improvements that came since Swift 1, and hasn't been revised since then.
> > > 
> > > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#proposed-solution&gt;Proposed) solution
> > > 
> > > We propose a new model that does not have above mentioned problems and is more easily extensible.
> > > 
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+--------------+ +-------------+  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+------\>+ Arithmetic | | Comparable |  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \> (+,-,\*,/) | | (==,\<,\>,...)|  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> +-------------++ +---+---------+  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> ^ ^  
> > > +-------+------------+ | |  
> > > \> SignedArithmetic | +-+-------+-----------+  
> > > \> (unary -) | | BinaryInteger |  
> > > +------+-------------+ |(words,%,bitwise,...)|  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^ ++---+-----+----------+  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> +-----------^ ^ ^---------------+  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \> \> \>  
> > > +------+---------++ +---------+---------------+ +--+----------------+  
> > > \> SignedInteger | | FixedWidthInteger | | UnsignedInteger |  
> > > \> \> \>(endianness,overflow,...)| | |  
> > > +---------------+-+ +-+--------------------+--+ +-+-----------------+  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^ ^ ^ ^  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \> \> \>  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\> \> \> \>  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++--------+-+ +-+-------+-+  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\>Int family |-+ |UInt family|-+  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+-----------+ | +-----------+ |  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+-----------+ +-----------+  
> > > There are several benefits provided by this model over the old one:
> > > 
> > > It allows mixing integer types in generic functions.
> > > 
> > > The possibility to initialize instances of any concrete integer type with values of any other concrete integer type enables writing functions that operate on more than one type conforming to BinaryInteger, such as heterogeneous comparisons or bit shifts, described later.
> > > 
> > > It removes the overload resolution overhead.
> > > 
> > > Arithmetic and bitwise operations can now be defined as generic operators on protocols. This approach significantly reduces the number of overloads for those operations, which used to be defined for every single concrete integer type.
> > > 
> > > It enables protocol sharing between integer and floating point types.
> > > 
> > > Note the exclusion of the % operation from Arithmetic. Its behavior for floating point numbers is sufficiently different from the one for integers that using it in generic context would lead to confusion. The FloatingPoint protocol introduced by SE-0067 \<[https://gist.github.com/moiseev/0067-floating-point-protocols.md&gt](https://gist.github.com/moiseev/0067-floating-point-protocols.md&gt); should now refine SignedArithmetic.
> > > 
> > > It makes future extensions possible.
> > > 
> > > The proposed model eliminates the 'largest integer type' concept previously used to interoperate between integer types (see toIntMax in the current model) and instead provides access to machine words. It also introduces thedoubleWidthMultiply, doubleWidthDivide, and quotientAndRemainder methods. Together these changes can be used to provide an efficient implementation of bignums that would be hard to achieve otherwise.
> > > 
> > > The implementation of proposed model in the standard library is available in the new-integer-protocols branch \<[https://github.com/apple/swift/tree/new-integer-protocols&gt;\](https://github.com/apple/swift/tree/new-integer-protocols&gt;%5C).
> > > 
> > > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#a-note-on-bit-shifts&gt;A) note on bit shifts
> > > 
> > > This proposal introduces the concepts of smart shifts and masking shifts.
> > > 
> > > The semantics of shift operations are often undefined \<[LLVM Language Reference Manual — LLVM 18.0.0git documentation](http://llvm.org/docs/LangRef.html#bitwise-binary-operations&gt); in under- or over-shift cases. Smart shifts, implemented by \>\> and \<\<, are designed to address this problem and always behave in a well defined way, as shown in the examples below:
> > > 
> > > x \<\< -2 is equivalent to x \>\> 2
> > > 
> > > (1 as UInt8) \>\> 42) will evaluate to 0
> > > 
> > > (-128 as Int8) \>\> 42) will evaluate to 0xff or -1
> > > 
> > > In most scenarios, the right hand operand is a literal constant, and branches for handling under- and over-shift cases can be optimized away. For other cases, this proposal provides masking shifts, implemented by &\>\> and &\<\<. A masking shift logically preprocesses the right hand operand by masking its bits to produce a value in the range 0...(x-1) where x is the number of bits in the left hand operand. On most architectures this masking is already performed by the CPU's shift instructions and has no cost. Both kinds of shift avoid undefined behavior and produce uniform semantics across architectures.
> > > 
> > > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#detailed-design&gt;Detailed) design
> > > 
> > > \<[https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#whats-new-since-se-0104&gt;What&#39;s](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#whats-new-since-se-0104&gt;What&#39;s) new since SE-0104
> > > 
> > > SE-0091 \<[https://gist.github.com/moiseev/0091-improving-operators-in-protocols.md&gt](https://gist.github.com/moiseev/0091-improving-operators-in-protocols.md&gt); removed the necessity to dispatch generic operators through special methods.
> > > 
> > > All operators are now declared by protocols as static funcs.
> > > 
> > > Standard Library no longer provides + and - operators for Strideable types.
> > > 
> > > They were problematic, as one could have written mixed-type code like let x: Int64 = 42; x += (1 as Int), which would compile, but shouldn't. Besides, since the Stride of an unsigned type is signed, Standard Library had to implement a hack to make code like let x: UInt = 42; x += (1 as Int) ambiguous. These operators were only necessary because they made advancing collection indices convenient, which is no longer the case since the introduction of the new indexing model \<[https://gist.github.com/moiseev/0065-collections-move-indices.md&gt](https://gist.github.com/moiseev/0065-collections-move-indices.md&gt); in Swift 3.
> > > 
> > > Shifts and other bitwise operations were moved from FixedWidthInteger to BinaryInteger.
> > > 
> > > Left shift operation on an unbounded integer should infinitely extend the number, and never drop set bits when they reach the most significant position in the underlying representation.
> > > 
> > > BitwiseOperations protocol was deprecated.
> > > 
> > > We believe there are no useful entities that support bitwise operations, but at the same time are not binary integers.
> > > 
> > > minimumSignedRepresentationBitWidth property was removed.
> > > 
> > > trailingZeros property was added to the BinaryInteger protocol.
> > > 
> > > leadingZeros and popcount properties are still defined by the FixedWidthInteger protocol.
> > > 
> > > Endian-converting initializers and properties were added to the FixedWidthInteger protocol.
> > > 
> > > Standard library introduces the new type DoubleWidth\<T\>.
> > > 
> > > See this section \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#doublewidth&gt); for more details.
> > > 
> > > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#protocols&gt;Protocols)
> > > 
> > > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#arithmetic&gt;Arithmetic)
> > > 
> > > The Arithmetic protocol declares binary arithmetic operators – such as +, -, and \* — and their mutating counterparts.
> > > 
> > > It provides a suitable basis for arithmetic on scalars such as integers and floating point numbers.
> > > 
> > > Both mutating and non-mutating operations are declared in the protocol, however only the mutating ones are required, as default implementations of the non-mutating ones are provided by a protocol extension.
> > > 
> > > The Magnitude associated type is able to hold the absolute value of any possible value of Self. Concrete types do not have to provide a type alias for it, as it can be inferred from the magnitude property. This property can be useful in operations that are simpler to implement in terms of unsigned values, for example, printing a value of an integer, which is just printing a '-' character in front of an absolute value.
> > > 
> > > Please note that for ordinary work, the magnitude property should not be preferred to the abs(\_) function, whose return value is of the same type as its argument.
> > > 
> > > public protocol Arithmetic : Equatable, ExpressibleByIntegerLiteral {  
> > > &nbsp;&nbsp;/// Creates a new instance from the given integer, if it can be represented  
> > > &nbsp;&nbsp;/// exactly.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// If the value passed as `source` is not representable exactly, the result  
> > > &nbsp;&nbsp;/// is `nil`. In the following example, the constant `x` is successfully  
> > > &nbsp;&nbsp;/// created from a value of `100`, while the attempt to initialize the  
> > > &nbsp;&nbsp;/// constant `y` from `1_000` fails because the `Int8` type can represent  
> > > &nbsp;&nbsp;/// `127` at maximum:  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let x = Int8(exactly: 100)  
> > > &nbsp;&nbsp;/// // x == Optional(100)  
> > > &nbsp;&nbsp;/// let y = Int8(exactly: 1\_000)  
> > > &nbsp;&nbsp;/// // y == nil  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - Parameter source: A floating-point value to convert to an integer.  
> > > &nbsp;&nbsp;init?\<T : BinaryInteger\>(exactly source: T)
> > > 
> > > &nbsp;&nbsp;/// A type that can represent the absolute value of any possible value of the  
> > > &nbsp;&nbsp;/// conforming type.  
> > > &nbsp;&nbsp;associatedtype Magnitude : Equatable, ExpressibleByIntegerLiteral
> > > 
> > > &nbsp;&nbsp;/// The magnitude of this value.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// For any numeric value `x`, `x.magnitude` is the absolute value of `x`.  
> > > &nbsp;&nbsp;/// You can use the `magnitude` property in operations that are simpler to  
> > > &nbsp;&nbsp;/// implement in terms of unsigned values, such as printing the value of an  
> > > &nbsp;&nbsp;/// integer, which is just printing a '-' character in front of an absolute  
> > > &nbsp;&nbsp;/// value.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let x = -200  
> > > &nbsp;&nbsp;/// // x.magnitude == 200  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// The global `abs(_:)` function provides more familiar syntax when you need  
> > > &nbsp;&nbsp;/// to find an absolute value. In addition, because `abs(_:)` always returns  
> > > &nbsp;&nbsp;/// a value of the same type, even in a generic context, using the function  
> > > &nbsp;&nbsp;/// instead of the `magnitude` property is encouraged.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - SeeAlso: `abs(_:)`  
> > > &nbsp;&nbsp;var magnitude: Magnitude { get }
> > > 
> > > &nbsp;&nbsp;/// Returns the sum of the two given values.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// The sum of `lhs` and `rhs` must be representable in the same type. In the  
> > > &nbsp;&nbsp;/// following example, the result of `100 + 200` is greater than the maximum  
> > > &nbsp;&nbsp;/// representable `Int8` value:  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let x: Int8 = 10 + 21  
> > > &nbsp;&nbsp;/// // x == 31  
> > > &nbsp;&nbsp;/// let y: Int8 = 100 + 121  
> > > &nbsp;&nbsp;/// // Overflow error  
> > > &nbsp;&nbsp;static func +(\_ lhs: Self, \_ rhs: Self) -\> Self
> > > 
> > > &nbsp;&nbsp;/// Adds the given value to this value in place.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// For example:  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// var x = 15  
> > > &nbsp;&nbsp;/// y += 7  
> > > &nbsp;&nbsp;/// // y == 22  
> > > &nbsp;&nbsp;static func +=(\_ lhs: inout Self, rhs: Self)
> > > 
> > > &nbsp;&nbsp;/// Returns the difference of the two given values.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// The difference of `lhs` and `rhs` must be representable in the same type.  
> > > &nbsp;&nbsp;/// In the following example, the result of `10 - 21` is less than zero, the  
> > > &nbsp;&nbsp;/// minimum representable `UInt` value:  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let x: UInt = 21 - 10  
> > > &nbsp;&nbsp;/// // x == 11  
> > > &nbsp;&nbsp;/// let y: UInt = 10 - 21  
> > > &nbsp;&nbsp;/// // Overflow error  
> > > &nbsp;&nbsp;static func -(\_ lhs: Self, \_ rhs: Self) -\> Self
> > > 
> > > &nbsp;&nbsp;/// Subtracts the given value from this value in place.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// For example:  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// var x = 15  
> > > &nbsp;&nbsp;/// y -= 7  
> > > &nbsp;&nbsp;/// // y == 8  
> > > &nbsp;&nbsp;static func -=(\_ lhs: inout Self, rhs: Self)
> > > 
> > > &nbsp;&nbsp;/// Returns the product of the two given values.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// The product of `lhs` and `rhs` must be representable in the same type. In  
> > > &nbsp;&nbsp;/// the following example, the result of `10 * 50` is greater than the  
> > > &nbsp;&nbsp;/// maximum representable `Int8` value.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let x: Int8 = 10 \* 5  
> > > &nbsp;&nbsp;/// // x == 50  
> > > &nbsp;&nbsp;/// let y: Int8 = 10 \* 50  
> > > &nbsp;&nbsp;/// // Overflow error  
> > > &nbsp;&nbsp;static func \*(\_ lhs: Self, \_ rhs: Self) -\> Self
> > > 
> > > &nbsp;&nbsp;/// Multiples this value by the given value in place.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// For example:  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// var x = 15  
> > > &nbsp;&nbsp;/// y \*= 7  
> > > &nbsp;&nbsp;/// // y == 105  
> > > &nbsp;&nbsp;static func \*=(\_ lhs: inout Self, rhs: Self)
> > > 
> > > &nbsp;&nbsp;/// Returns the quotient of dividing the first value by the second.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// For integer types, any remainder of the division is discarded.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let x = 21 / 5  
> > > &nbsp;&nbsp;/// // x == 4  
> > > &nbsp;&nbsp;static func /(\_ lhs: Self, \_ rhs: Self) -\> Self
> > > 
> > > &nbsp;&nbsp;/// Divides this value by the given value in place.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// For example:  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// var x = 15  
> > > &nbsp;&nbsp;/// y /= 7  
> > > &nbsp;&nbsp;/// // y == 2  
> > > &nbsp;&nbsp;static func /=(\_ lhs: inout Self, rhs: Self)  
> > > }
> > > 
> > > extension Arithmetic {  
> > > &nbsp;&nbsp;public init() { self = 0 }
> > > 
> > > &nbsp;&nbsp;public static prefix func + (x: Self) -\> Self {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;return x  
> > > &nbsp;&nbsp;}  
> > > }  
> > > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#signedarithmetic&gt;SignedArithmetic)
> > > 
> > > The SignedArithmetic protocol is for numbers that can be negated.
> > > 
> > > public protocol SignedArithmetic : Arithmetic {  
> > > &nbsp;&nbsp;/// Returns the additive inverse of this value.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let x = 21  
> > > &nbsp;&nbsp;/// let y = -x  
> > > &nbsp;&nbsp;/// // y == -21  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - Returns: The additive inverse of this value.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - SeeAlso: `negate()`  
> > > &nbsp;&nbsp;static prefix func - (\_ operand: Self) -\> Self
> > > 
> > > &nbsp;&nbsp;/// Replaces this value with its additive inverse.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// The following example uses the `negate()` method to negate the value of  
> > > &nbsp;&nbsp;/// an integer `x`:  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// var x = 21  
> > > &nbsp;&nbsp;/// x.negate()  
> > > &nbsp;&nbsp;/// // x == -21  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - SeeAlso: The unary minus operator (`-`).  
> > > &nbsp;&nbsp;mutating func negate()  
> > > }
> > > 
> > > extension SignedArithmetic {  
> > > &nbsp;&nbsp;public static prefix func - (\_ operand: Self) -\> Self {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;var result = operand  
> > > &nbsp;&nbsp;&nbsp;&nbsp;result.negate()  
> > > &nbsp;&nbsp;&nbsp;&nbsp;return result  
> > > &nbsp;&nbsp;}
> > > 
> > > &nbsp;&nbsp;public mutating func negate() {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;self = Self() - self  
> > > &nbsp;&nbsp;}  
> > > }  
> > > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#binaryinteger&gt;BinaryInteger)
> > > 
> > > The BinaryInteger protocol is the basis for all the integer types provided by the standard library.
> > > 
> > > This protocol adds a few new initializers. Two of them allow to create integers from floating point numbers, others support construction from instances of any type conforming to BinaryInteger, using different strategies:
> > > 
> > > Initialize Self with the value, provided that the value is representable. The precondition should be satisfied by the caller.
> > > 
> > > Extend or truncate the value to fit into Self
> > > 
> > > Clamp the value to the representable range of Self
> > > 
> > > BinaryInteger also declares bitwise and shift operators.
> > > 
> > > public protocol BinaryInteger :  
> > > &nbsp;&nbsp;Comparable, Hashable, Arithmetic, CustomStringConvertible, Strideable {
> > > 
> > > &nbsp;&nbsp;/// A Boolean value indicating whether this type is a signed integer type.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// \*Signed\* integer types can represent both positive and negative values.  
> > > &nbsp;&nbsp;/// \*Unsigned\* integer types can represent only nonnegative values.  
> > > &nbsp;&nbsp;static var isSigned: Bool { get }
> > > 
> > > &nbsp;&nbsp;/// Creates an integer from the given floating-point value, if it can be  
> > > &nbsp;&nbsp;/// represented exactly.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// If the value passed as `source` is not representable exactly, the result  
> > > &nbsp;&nbsp;/// is `nil`. In the following example, the constant `x` is successfully  
> > > &nbsp;&nbsp;/// created from a value of `21.0`, while the attempt to initialize the  
> > > &nbsp;&nbsp;/// constant `y` from `21.5` fails:  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let x = Int(exactly: 21.0)  
> > > &nbsp;&nbsp;/// // x == Optional(21)  
> > > &nbsp;&nbsp;/// let y = Int(exactly: 21.5)  
> > > &nbsp;&nbsp;/// // y == nil  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - Parameter source: A floating-point value to convert to an integer.  
> > > &nbsp;&nbsp;init?\<T : FloatingPoint\>(exactly source: T)
> > > 
> > > &nbsp;&nbsp;/// Creates an integer from the given floating-point value, truncating any  
> > > &nbsp;&nbsp;/// fractional part.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// Truncating the fractional part of `source` is equivalent to rounding  
> > > &nbsp;&nbsp;/// toward zero.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let x = Int(21.5)  
> > > &nbsp;&nbsp;/// // x == 21  
> > > &nbsp;&nbsp;/// let y = Int(-21.5)  
> > > &nbsp;&nbsp;/// // y == -21  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// If `source` is outside the bounds of this type after truncation, a  
> > > &nbsp;&nbsp;/// runtime error may occur.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let z = UInt(-21.5)  
> > > &nbsp;&nbsp;/// // Error: ...the result would be less than UInt.min  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - Parameter source: A floating-point value to convert to an integer.  
> > > &nbsp;&nbsp;/// `source` must be representable in this type after truncation.  
> > > &nbsp;&nbsp;init\<T : FloatingPoint\>(\_ source: T)
> > > 
> > > &nbsp;&nbsp;/// Creates an new instance from the given integer.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// If the value passed as `source` is not representable in this type, a  
> > > &nbsp;&nbsp;/// runtime error may occur.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let x = -500 as Int  
> > > &nbsp;&nbsp;/// let y = Int32(x)  
> > > &nbsp;&nbsp;/// // y == -500  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// // -500 is not representable as a 'UInt32' instance  
> > > &nbsp;&nbsp;/// let z = UInt32(x)  
> > > &nbsp;&nbsp;/// // Error  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - Parameter source: An integer to convert. `source` must be representable  
> > > &nbsp;&nbsp;/// in this type.  
> > > &nbsp;&nbsp;init\<T : BinaryInteger\>(\_ source: T)
> > > 
> > > &nbsp;&nbsp;/// Creates a new instance from the bit pattern of the given instance by  
> > > &nbsp;&nbsp;/// sign-extending or truncating to fit this type.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// When the bit width of `T` (the type of `source`) is equal to or greater  
> > > &nbsp;&nbsp;/// than this type's bit width, the result is the truncated  
> > > &nbsp;&nbsp;/// least-significant bits of `source`. For example, when converting a  
> > > &nbsp;&nbsp;/// 16-bit value to an 8-bit type, only the lower 8 bits of `source` are  
> > > &nbsp;&nbsp;/// used.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let p: Int16 = -500  
> > > &nbsp;&nbsp;/// // 'p' has a binary representation of 11111110\_00001100  
> > > &nbsp;&nbsp;/// let q = Int8(extendingOrTruncating: p)  
> > > &nbsp;&nbsp;/// // q == 12  
> > > &nbsp;&nbsp;/// // 'q' has a binary representation of 00001100  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// When the bit width of `T` is less than this type's bit width, the result  
> > > &nbsp;&nbsp;/// is \*sign-extended\* to fill the remaining bits. That is, if `source` is  
> > > &nbsp;&nbsp;/// negative, the result is padded with ones; otherwise, the result is  
> > > &nbsp;&nbsp;/// padded with zeros.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let u: Int8 = 21  
> > > &nbsp;&nbsp;/// // 'u' has a binary representation of 00010101  
> > > &nbsp;&nbsp;/// let v = Int16(extendingOrTruncating: u)  
> > > &nbsp;&nbsp;/// // v == 21  
> > > &nbsp;&nbsp;/// // 'v' has a binary representation of 00000000\_00010101  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let w: Int8 = -21  
> > > &nbsp;&nbsp;/// // 'w' has a binary representation of 11101011  
> > > &nbsp;&nbsp;/// let x = Int16(extendingOrTruncating: w)  
> > > &nbsp;&nbsp;/// // x == -21  
> > > &nbsp;&nbsp;/// // 'x' has a binary representation of 11111111\_11101011  
> > > &nbsp;&nbsp;/// let y = UInt16(extendingOrTruncating: w)  
> > > &nbsp;&nbsp;/// // y == 65515  
> > > &nbsp;&nbsp;/// // 'y' has a binary representation of 11111111\_11101011  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - Parameter source: An integer to convert to this type.  
> > > &nbsp;&nbsp;init\<T : BinaryInteger\>(extendingOrTruncating source: T)
> > > 
> > > &nbsp;&nbsp;/// Creates a new instance with the representable value that's closest to the  
> > > &nbsp;&nbsp;/// given integer.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// If the value passed as `source` is greater than the maximum representable  
> > > &nbsp;&nbsp;/// value in this type, the result is the type's `max` value. If `source` is  
> > > &nbsp;&nbsp;/// less than the smallest representable value in this type, the result is  
> > > &nbsp;&nbsp;/// the type's `min` value.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// In this example, `x` is initialized as an `Int8` instance by clamping  
> > > &nbsp;&nbsp;/// `500` to the range `-128...127`, and `y` is initialized as a `UInt`  
> > > &nbsp;&nbsp;/// instance by clamping `-500` to the range `0...UInt.max`.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let x = Int8(clamping: 500)  
> > > &nbsp;&nbsp;/// // x == 127  
> > > &nbsp;&nbsp;/// // x == Int8.max  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let y = UInt(clamping: -500)  
> > > &nbsp;&nbsp;/// // y == 0  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - Parameter source: An integer to convert to this type.  
> > > &nbsp;&nbsp;init\<T : BinaryInteger\>(clamping source: T)
> > > 
> > > &nbsp;&nbsp;/// Returns the n-th word, counting from the least significant to most  
> > > &nbsp;&nbsp;/// significant, of this value's binary representation.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// The `word(at:)` method returns negative values in two's complement  
> > > &nbsp;&nbsp;/// representation, regardless of a type's underlying implementation. If `n`  
> > > &nbsp;&nbsp;/// is greater than the number of words in this value's current  
> > > &nbsp;&nbsp;/// representation, the result is `0` for positive numbers and `~0` for  
> > > &nbsp;&nbsp;/// negative numbers.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - Parameter n: The word to return, counting from the least significant to  
> > > &nbsp;&nbsp;/// most significant. `n` must be greater than or equal to zero.  
> > > &nbsp;&nbsp;/// - Returns: An word-sized, unsigned integer with the bit pattern of the  
> > > &nbsp;&nbsp;/// n-th word of this value.  
> > > &nbsp;&nbsp;func word(at n: Int) -\> UInt
> > > 
> > > &nbsp;&nbsp;/// The number of bits in the current binary representation of this value.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// This property is a constant for instances of fixed-width integer  
> > > &nbsp;&nbsp;/// types.  
> > > &nbsp;&nbsp;var bitWidth : Int { get }
> > > 
> > > &nbsp;&nbsp;/// The number of trailing zeros in this value's binary representation.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// For example, in a fixed-width integer type with a `bitWidth` value of 8,  
> > > &nbsp;&nbsp;/// the number -8 has three trailing zeros.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let x = Int8(bitPattern: 0b1111\_1000)  
> > > &nbsp;&nbsp;/// // x == -8  
> > > &nbsp;&nbsp;/// // x.trailingZeros == 3  
> > > &nbsp;&nbsp;var trailingZeros: Int { get }
> > > 
> > > &nbsp;&nbsp;/// Returns the remainder of dividing the first value by the second.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// The result has the same sign as `lhs` and is less than `rhs.magnitude`.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let x = 22 % 5  
> > > &nbsp;&nbsp;/// // x == 2  
> > > &nbsp;&nbsp;/// let y = 22 % -5  
> > > &nbsp;&nbsp;/// // y == 2  
> > > &nbsp;&nbsp;/// let z = -22 % -5  
> > > &nbsp;&nbsp;/// // z == -2  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - Parameters:  
> > > &nbsp;&nbsp;/// - lhs: The value to divide.  
> > > &nbsp;&nbsp;/// - rhs: The value to divide `lhs` by. `rhs` must not be zero.  
> > > &nbsp;&nbsp;static func %(\_ lhs: Self, \_ rhs: Self) -\> Self
> > > 
> > > &nbsp;&nbsp;/// Replaces this value with the remainder of itself divided by the given  
> > > &nbsp;&nbsp;/// value. For example:  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// var x = 15  
> > > &nbsp;&nbsp;/// x %= 7  
> > > &nbsp;&nbsp;/// // x == 1  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - Parameter rhs: The value to divide this value by. `rhs` must not be  
> > > &nbsp;&nbsp;/// zero.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - SeeAlso: `remainder(dividingBy:)`  
> > > &nbsp;&nbsp;static func %=(\_ lhs: inout Self, \_ rhs: Self)
> > > 
> > > &nbsp;&nbsp;/// Returns the inverse of the bits set in the argument.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// The bitwise NOT operator (`~`) is a prefix operator that returns a value  
> > > &nbsp;&nbsp;/// in which all the bits of its argument are flipped: Bits that are `1` in  
> > > &nbsp;&nbsp;/// the argument are `0` in the result, and bits that are `0` in the argument  
> > > &nbsp;&nbsp;/// are `1` in the result. This is equivalent to the inverse of a set. For  
> > > &nbsp;&nbsp;/// example:  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let x: UInt8 = 5 // 0b00000101  
> > > &nbsp;&nbsp;/// let notX = ~x // 0b11111010  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// Performing a bitwise NOT operation on 0 returns a value with every bit  
> > > &nbsp;&nbsp;/// set to `1`.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let allOnes = ~UInt8.min // 0b11111111  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - Complexity: O(1).  
> > > &nbsp;&nbsp;static prefix func ~ (\_ x: Self) -\> Self
> > > 
> > > &nbsp;&nbsp;/// Returns the result of performing a bitwise AND operation on this value  
> > > &nbsp;&nbsp;/// and the given value.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// A bitwise AND operation results in a value that has each bit set to `1`  
> > > &nbsp;&nbsp;/// where \*both\* of its arguments have that bit set to `1`. For example:  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let x: UInt8 = 5 // 0b00000101  
> > > &nbsp;&nbsp;/// let y: UInt8 = 14 // 0b00001110  
> > > &nbsp;&nbsp;/// let z = x & y // 0b00000100  
> > > &nbsp;&nbsp;static func &(\_ lhs: Self, \_ rhs: Self) -\> Self  
> > > &nbsp;&nbsp;static func &=(\_ lhs: inout Self, \_ rhs: Self)
> > > 
> > > &nbsp;&nbsp;/// Returns the result of performing a bitwise OR operation on this value and  
> > > &nbsp;&nbsp;/// the given value.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// A bitwise OR operation results in a value that has each bit set to `1`  
> > > &nbsp;&nbsp;/// where \*one or both\* of its arguments have that bit set to `1`. For  
> > > &nbsp;&nbsp;/// example:  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let x: UInt8 = 5 // 0b00000101  
> > > &nbsp;&nbsp;/// let y: UInt8 = 14 // 0b00001110  
> > > &nbsp;&nbsp;/// let z = x | y // 0b00001111  
> > > &nbsp;&nbsp;static func |(\_ lhs: Self, \_ rhs: Self) -\> Self  
> > > &nbsp;&nbsp;static func |=(\_ lhs: inout Self, \_ rhs: Self)
> > > 
> > > &nbsp;&nbsp;/// Returns the result of performing a bitwise XOR operation on this value  
> > > &nbsp;&nbsp;/// and the given value.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// A bitwise XOR operation, also known as an exclusive OR operation, results  
> > > &nbsp;&nbsp;/// in a value that has each bit set to `1` where \*one or the other but not  
> > > &nbsp;&nbsp;/// both\* of its arguments had that bit set to `1`. For example:  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let x: UInt8 = 5 // 0b00000101  
> > > &nbsp;&nbsp;/// let y: UInt8 = 14 // 0b00001110  
> > > &nbsp;&nbsp;/// let z = x ^ y // 0b00001011  
> > > &nbsp;&nbsp;static func ^(\_ lhs: Self, \_ rhs: Self) -\> Self  
> > > &nbsp;&nbsp;static func ^=(\_ lhs: inout Self, \_ rhs: Self)
> > > 
> > > &nbsp;&nbsp;/// Returns the result of shifting this value's binary representation the  
> > > &nbsp;&nbsp;/// specified number of digits to the right.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// In a \*masking shift\*, the bit pattern of the value passed as `rhs` is  
> > > &nbsp;&nbsp;/// masked to produce a value between zero and the bit width of `lhs`. The  
> > > &nbsp;&nbsp;/// shift is performed using this masked value. Masking shifts require more  
> > > &nbsp;&nbsp;/// care to use correctly than a traditional bit shift, but are likely to be  
> > > &nbsp;&nbsp;/// more efficient when used with shift amounts that are not compile-time  
> > > &nbsp;&nbsp;/// constants. On most architectures, a masking shift compiles down to a  
> > > &nbsp;&nbsp;/// single instruction.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// For example, if you shift an 8-bit, unsigned integer by 2, the shift  
> > > &nbsp;&nbsp;/// amount requires no masking.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let x: UInt8 = 30 // 0b00011110  
> > > &nbsp;&nbsp;/// let y = x &\>\> 2  
> > > &nbsp;&nbsp;/// // y == 7 // 0b00000111  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// However, if you shift it by 11, it first bitmasks `rhs` to `3`, and then  
> > > &nbsp;&nbsp;/// uses that masked value as the number of bits to shift `x`.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let z = x &\>\> 11  
> > > &nbsp;&nbsp;/// // z == 3 // 0b00000011  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// Relationship to the Right Shift Operator  
> > > &nbsp;&nbsp;/// ----------------------------------------  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// The masking right shift operator handles attempted overshifts and  
> > > &nbsp;&nbsp;/// undershifts differently from the right shift operator (`\>\>`). When the  
> > > &nbsp;&nbsp;/// value passed as `rhs` in a masking shift is within the range  
> > > &nbsp;&nbsp;/// `0...\<bitWidth`, the operation is equivalent to using the right shift  
> > > &nbsp;&nbsp;/// operator.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let x: UInt8 = 30 // 0b00011110  
> > > &nbsp;&nbsp;/// let y1 = x &\>\> 2  
> > > &nbsp;&nbsp;/// // y1 == 7 // 0b00000111  
> > > &nbsp;&nbsp;/// let y2 = x \>\> 2  
> > > &nbsp;&nbsp;/// // y2 == 7 // 0b00000111  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// The right shift operator does not mask its right-hand-side argument, so  
> > > &nbsp;&nbsp;/// passing `11` as `rhs` shifts all the bits of `x` to zero.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let z1 = x &\>\> 11  
> > > &nbsp;&nbsp;/// // z1 == 240 // 0b00000011  
> > > &nbsp;&nbsp;/// let z2 = x \>\> 11  
> > > &nbsp;&nbsp;/// // z2 == 0 // 0b00000000  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - Parameter rhs: The number of bits to shift this value to the right. If  
> > > &nbsp;&nbsp;/// `rhs` is outside the range `0..\<bitWidth`, it is masked to produce a  
> > > &nbsp;&nbsp;/// value within that range.  
> > > &nbsp;&nbsp;/// - Returns: The result of shifting this value by the masked `rhs` to the  
> > > &nbsp;&nbsp;/// right.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - SeeAlso: `&\<\<`, `\>\>`  
> > > &nbsp;&nbsp;static func &\>\>(\_ lhs: Self, \_ rhs: Self) -\> Self  
> > > &nbsp;&nbsp;static func &\>\>=(\_ lhs: inout Self, \_ rhs: Self)
> > > 
> > > &nbsp;&nbsp;/// Returns the result of shifting this value's binary representation the  
> > > &nbsp;&nbsp;/// specified number of digits to the left.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// In a \*masking shift\*, the bit pattern of the value passed as `rhs` is  
> > > &nbsp;&nbsp;/// masked to produce a value between zero and the bit width of `lhs`. The  
> > > &nbsp;&nbsp;/// shift is performed using this masked value. Masking shifts require more  
> > > &nbsp;&nbsp;/// care to use correctly than a traditional bit shift, but are likely to be  
> > > &nbsp;&nbsp;/// more efficient when used with shift amounts that are not compile-time  
> > > &nbsp;&nbsp;/// constants. On most architectures, a masking shift compiles down to a  
> > > &nbsp;&nbsp;/// single instruction.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// For example, if you shift an 8-bit, unsigned integer by 2, the shift  
> > > &nbsp;&nbsp;/// amount requires no masking.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let x: UInt8 = 30 // 0b00011110  
> > > &nbsp;&nbsp;/// let y = x &\>\> 2  
> > > &nbsp;&nbsp;/// // y == 120 // 0b01111000  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// However, if you shift it by 11, it first bitmasks `rhs` to `3`, and then  
> > > &nbsp;&nbsp;/// uses that masked value as the number of bits to shift `x`.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let z = x &\<\< 11  
> > > &nbsp;&nbsp;/// // z == 240 // 0b11110000  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// Relationship to the Left Shift Operator  
> > > &nbsp;&nbsp;/// ---------------------------------------  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// The masking left shift operator handles attempted overshifts and  
> > > &nbsp;&nbsp;/// undershifts differently from the left shift operator (`\<\<`). When the  
> > > &nbsp;&nbsp;/// value passed as `rhs` in a masking shift is within the range  
> > > &nbsp;&nbsp;/// `0...\<bitWidth`, the operation is equivalent to using the left shift  
> > > &nbsp;&nbsp;/// operator.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let x: UInt8 = 30 // 0b00011110  
> > > &nbsp;&nbsp;/// let y1 = x &\<\< 2  
> > > &nbsp;&nbsp;/// // y1 == 120 // 0b01111000  
> > > &nbsp;&nbsp;/// let y2 = x \<\< 2  
> > > &nbsp;&nbsp;/// // y2 == 120 // 0b01111000  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// The left shift operator does not mask its right-hand-side argument, so  
> > > &nbsp;&nbsp;/// passing `11` as `rhs` shifts all the bits of `x` to zero.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let z1 = x &\<\< 11  
> > > &nbsp;&nbsp;/// // z1 == 240 // 0b11110000  
> > > &nbsp;&nbsp;/// let z2 = x \<\< 11  
> > > &nbsp;&nbsp;/// // z2 == 0 // 0b00000000  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - Parameter rhs: The number of bits to shift this value to the left. If  
> > > &nbsp;&nbsp;/// `rhs` is outside the range `0..\<bitWidth`, it is masked to produce a  
> > > &nbsp;&nbsp;/// value within that range.  
> > > &nbsp;&nbsp;/// - Returns: The result of shifting this value by the masked `rhs` to the  
> > > &nbsp;&nbsp;/// left.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - SeeAlso: `&\>\>`, `\<\<`  
> > > &nbsp;&nbsp;static func &\<\<(\_ lhs: Self, \_ rhs: Self) -\> Self  
> > > &nbsp;&nbsp;static func &\<\<=(\_ lhs: inout Self, \_ rhs: Self)
> > > 
> > > &nbsp;&nbsp;/// Returns the quotient and remainder of this value divided by the given  
> > > &nbsp;&nbsp;/// value.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// Use this method to calculate the quotient and remainder of a division at  
> > > &nbsp;&nbsp;/// the same time.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let x = 1\_000\_000  
> > > &nbsp;&nbsp;/// let (q, r) = x.quotientAndRemainder(dividingBy: 933)  
> > > &nbsp;&nbsp;/// // q == 1071  
> > > &nbsp;&nbsp;/// // r == 757  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - Parameter rhs: The value to divide this value by.  
> > > &nbsp;&nbsp;/// - Returns: A tuple containing the quotient and remainder of this value  
> > > &nbsp;&nbsp;/// divided by `rhs`.  
> > > &nbsp;&nbsp;func quotientAndRemainder(dividingBy rhs: Self)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;-\> (quotient: Self, remainder: Self)
> > > 
> > > &nbsp;&nbsp;/// Returns `-1` if this value is negative and `1` if it's positive;  
> > > &nbsp;&nbsp;/// otherwise, `0`.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - Returns: The sign of this number, expressed as an integer of the same  
> > > &nbsp;&nbsp;/// type.  
> > > &nbsp;&nbsp;func signum() -\> Self  
> > > }  
> > > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#fixedwidthinteger&gt;FixedWidthInteger)
> > > 
> > > The FixedWidthInteger protocol adds the notion of endianness as well as static properties for type bounds and bit width.
> > > 
> > > The WithOverflow family of methods is used in default implementations of mutating arithmetic methods (see the Arithmetic protocol). Having these methods allows the library to provide both bounds-checked and masking implementations of arithmetic operations, without duplicating code.
> > > 
> > > The doubleWidthMultiply and doubleWidthDivide methods are necessary building blocks to implement support for integer types of a greater width such as arbitrary-precision integers.
> > > 
> > > public protocol FixedWidthInteger : BinaryInteger {  
> > > &nbsp;&nbsp;/// The number of bits used for the underlying binary representation of  
> > > &nbsp;&nbsp;/// values of this type.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// An unsigned, fixed-width integer type can represent values from 0 through  
> > > &nbsp;&nbsp;/// `(2 **bitWidth) - 1`, where `**` is exponentiation. A signed,  
> > > &nbsp;&nbsp;/// fixed-width integer type can represent values from  
> > > &nbsp;&nbsp;/// `-(2 **bitWidth - 1)` through `(2** bitWidth - 1) - 1`. For example,  
> > > &nbsp;&nbsp;/// the `Int8` type has a `bitWidth` value of 8 and can store any integer in  
> > > &nbsp;&nbsp;/// the range `-128...127`.  
> > > &nbsp;&nbsp;static var bitWidth : Int { get }
> > > 
> > > &nbsp;&nbsp;/// The maximum representable integer in this type.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// For unsigned integer types, this value is `(2 ** bitWidth) - 1`, where  
> > > &nbsp;&nbsp;/// `**` is exponentiation. For signed integer types, this value is  
> > > &nbsp;&nbsp;/// `(2 ** bitWidth - 1) - 1`.  
> > > &nbsp;&nbsp;static var max: Self { get }
> > > 
> > > &nbsp;&nbsp;/// The minimum representable value.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// For unsigned integer types, this value is always `0`. For signed integer  
> > > &nbsp;&nbsp;/// types, this value is `-(2 **bitWidth - 1)`, where `**` is  
> > > &nbsp;&nbsp;/// exponentiation.  
> > > &nbsp;&nbsp;static var min: Self { get }
> > > 
> > > &nbsp;&nbsp;/// Returns the sum of this value and the given value along with a flag  
> > > &nbsp;&nbsp;/// indicating whether overflow occurred in the operation.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - Parameter other: The value to add to this value.  
> > > &nbsp;&nbsp;/// - Returns: A tuple containing the result of the addition along with a  
> > > &nbsp;&nbsp;/// flag indicating whether overflow occurred. If the `overflow` component  
> > > &nbsp;&nbsp;/// is `.none`, the `partialValue` component contains the entire sum. If  
> > > &nbsp;&nbsp;/// the `overflow` component is `.overflow`, an overflow occurred and the  
> > > &nbsp;&nbsp;/// `partialValue` component contains the truncated sum of this value and  
> > > &nbsp;&nbsp;/// `other`.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - SeeAlso: `+`  
> > > &nbsp;&nbsp;func addingWithOverflow(\_ other: Self)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;-\> (partialValue: Self, overflow: ArithmeticOverflow)
> > > 
> > > &nbsp;&nbsp;/// Returns the difference of this value and the given value along with a  
> > > &nbsp;&nbsp;/// flag indicating whether overflow occurred in the operation.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - Parameter other: The value to subtract from this value.  
> > > &nbsp;&nbsp;/// - Returns: A tuple containing the result of the subtraction along with a  
> > > &nbsp;&nbsp;/// flag indicating whether overflow occurred. If the `overflow` component  
> > > &nbsp;&nbsp;/// is `.none`, the `partialValue` component contains the entire  
> > > &nbsp;&nbsp;/// difference. If the `overflow` component is `.overflow`, an overflow  
> > > &nbsp;&nbsp;/// occurred and the `partialValue` component contains the truncated  
> > > &nbsp;&nbsp;/// result of `other` subtracted from this value.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - SeeAlso: `-`  
> > > &nbsp;&nbsp;func subtractingWithOverflow(\_ other: Self)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;-\> (partialValue: Self, overflow: ArithmeticOverflow)
> > > 
> > > &nbsp;&nbsp;/// Returns the product of this value and the given value along with a flag  
> > > &nbsp;&nbsp;/// indicating whether overflow occurred in the operation.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - Parameter other: The value to multiply by this value.  
> > > &nbsp;&nbsp;/// - Returns: A tuple containing the result of the multiplication along with  
> > > &nbsp;&nbsp;/// a flag indicating whether overflow occurred. If the `overflow`  
> > > &nbsp;&nbsp;/// component is `.none`, the `partialValue` component contains the entire  
> > > &nbsp;&nbsp;/// product. If the `overflow` component is `.overflow`, an overflow  
> > > &nbsp;&nbsp;/// occurred and the `partialValue` component contains the truncated  
> > > &nbsp;&nbsp;/// product of this value and `other`.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - SeeAlso: `*`, `doubleWidthMultiply(_:_:)`  
> > > &nbsp;&nbsp;func multipliedWithOverflow(by other: Self)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;-\> (partialValue: Self, overflow: ArithmeticOverflow)
> > > 
> > > &nbsp;&nbsp;/// Returns the quotient of dividing this value by the given value along with  
> > > &nbsp;&nbsp;/// a flag indicating whether overflow occurred in the operation.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// For a value `x`, if zero is passed as `other`, the result is  
> > > &nbsp;&nbsp;/// `(x, .overflow)`.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - Parameter other: The value to divide this value by.  
> > > &nbsp;&nbsp;/// - Returns: A tuple containing the result of the division along with a  
> > > &nbsp;&nbsp;/// flag indicating whether overflow occurred. If the `overflow` component  
> > > &nbsp;&nbsp;/// is `.none`, the `partialValue` component contains the entire quotient.  
> > > &nbsp;&nbsp;/// If the `overflow` component is `.overflow`, an overflow occurred and  
> > > &nbsp;&nbsp;/// the `partialValue` component contains the truncated quotient.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - SeeAlso: `/`, `doubleWidthDivide(_:_:)`  
> > > &nbsp;&nbsp;func dividedWithOverflow(by other: Self)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;-\> (partialValue: Self, overflow: ArithmeticOverflow)
> > > 
> > > &nbsp;&nbsp;/// Returns a tuple containing the high and low parts of the result of  
> > > &nbsp;&nbsp;/// multiplying its arguments.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// Use this method to calculate the full result of a product that would  
> > > &nbsp;&nbsp;/// otherwise overflow. Unlike traditional truncating multiplication, the  
> > > &nbsp;&nbsp;/// `doubleWidthMultiply(_:_:)` method returns both the `high` and `low`  
> > > &nbsp;&nbsp;/// parts of the product of `lhs` and `rhs`. The following example uses this  
> > > &nbsp;&nbsp;/// method to multiply two `UInt8` values that normally overflow when  
> > > &nbsp;&nbsp;/// multiplied:  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let x: UInt8 = 100  
> > > &nbsp;&nbsp;/// let y: UInt8 = 20  
> > > &nbsp;&nbsp;/// let result = UInt8.doubleWidthMultiply(100, 20)  
> > > &nbsp;&nbsp;/// // result.high == 0b00000111  
> > > &nbsp;&nbsp;/// // result.low == 0b11010000  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// The product of `x` and `y` is 2000, which is too large to represent in a  
> > > &nbsp;&nbsp;/// `UInt8` instance. The `high` and `low` components of the `result` tuple  
> > > &nbsp;&nbsp;/// represent 2000 when concatenated to form a double-width integer; that  
> > > &nbsp;&nbsp;/// is, using `result.high` as the high byte and `result.low` as the low byte  
> > > &nbsp;&nbsp;/// of a `UInt16` instance.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let z = UInt16(result.high) \<\< 8 | UInt16(result.low)  
> > > &nbsp;&nbsp;/// // z == 2000  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - Parameters:  
> > > &nbsp;&nbsp;/// - lhs: A value to multiply.  
> > > &nbsp;&nbsp;/// - rhs: Another value to multiply.  
> > > &nbsp;&nbsp;/// - Returns: A tuple containing the high and low parts of the result of  
> > > &nbsp;&nbsp;/// multiplying `lhs` and `rhs`.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - SeeAlso: `multipliedWithOverflow(by:)`  
> > > &nbsp;&nbsp;static func doubleWidthMultiply(\_ lhs: Self, \_ rhs: Self)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;-\> (high: Self, low: Magnitude)
> > > 
> > > &nbsp;&nbsp;/// Returns a tuple containing the quotient and remainder of dividing the  
> > > &nbsp;&nbsp;/// first argument by the second.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// The resulting quotient must be representable within the bounds of the  
> > > &nbsp;&nbsp;/// type. If the quotient of dividing `lhs` by `rhs` is too large to  
> > > &nbsp;&nbsp;/// represent in the type, a runtime error may occur.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - Parameters:  
> > > &nbsp;&nbsp;/// - lhs: A tuple containing the high and low parts of a double-width  
> > > &nbsp;&nbsp;/// integer. The `high` component of the tuple carries the sign, if the  
> > > &nbsp;&nbsp;/// type is signed.  
> > > &nbsp;&nbsp;/// - rhs: The integer to divide into `lhs`.  
> > > &nbsp;&nbsp;/// - Returns: A tuple containing the quotient and remainder of `lhs` divided  
> > > &nbsp;&nbsp;/// by `rhs`.  
> > > &nbsp;&nbsp;static func doubleWidthDivide(  
> > > &nbsp;&nbsp;&nbsp;&nbsp;\_ lhs: (high: Self, low: Magnitude), \_ rhs: Self)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;-\> (quotient: Self, remainder: Self)
> > > 
> > > &nbsp;&nbsp;/// The number of bits equal to 1 in this value's binary representation.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// For example, in a fixed-width integer type with a `bitWidth` value of 8,  
> > > &nbsp;&nbsp;/// the number 31 has five bits equal to 1.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let x: Int8 = 0b0001\_1111  
> > > &nbsp;&nbsp;/// // x == 31  
> > > &nbsp;&nbsp;/// // x.popcount == 5  
> > > &nbsp;&nbsp;var popcount: Int { get }
> > > 
> > > &nbsp;&nbsp;/// The number of leading zeros in this value's binary representation.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// For example, in a fixed-width integer type with a `bitWidth` value of 8,  
> > > &nbsp;&nbsp;/// the number 31 has three leading zeros.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// let x: Int8 = 0b0001\_1111  
> > > &nbsp;&nbsp;/// // x == 31  
> > > &nbsp;&nbsp;/// // x.leadingZeros == 3  
> > > &nbsp;&nbsp;/// - SeeAlso: `BinaryInteger.trailingZeros`  
> > > &nbsp;&nbsp;var leadingZeros: Int { get }
> > > 
> > > &nbsp;&nbsp;/// Creates an integer from its big-endian representation, changing the  
> > > &nbsp;&nbsp;/// byte order if necessary.  
> > > &nbsp;&nbsp;init(bigEndian value: Self)
> > > 
> > > &nbsp;&nbsp;/// Creates an integer from its little-endian representation, changing the  
> > > &nbsp;&nbsp;/// byte order if necessary.  
> > > &nbsp;&nbsp;init(littleEndian value: Self)
> > > 
> > > &nbsp;&nbsp;/// The big-endian representation of this integer.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// If necessary, the byte order of this value is reversed from the typical  
> > > &nbsp;&nbsp;/// byte order of this integer type. On a big-endian platform, for any  
> > > &nbsp;&nbsp;/// integer `x`, `x == x.bigEndian`.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - SeeAlso: `littleEndian`  
> > > &nbsp;&nbsp;var bigEndian: Self { get }
> > > 
> > > &nbsp;&nbsp;/// The little-endian representation of this integer.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// If necessary, the byte order of this value is reversed from the typical  
> > > &nbsp;&nbsp;/// byte order of this integer type. On a little-endian platform, for any  
> > > &nbsp;&nbsp;/// integer `x`, `x == x.littleEndian`.  
> > > &nbsp;&nbsp;///  
> > > &nbsp;&nbsp;/// - SeeAlso: `bigEndian`  
> > > &nbsp;&nbsp;var littleEndian: Self { get }
> > > 
> > > &nbsp;&nbsp;/// A representation of this integer with the byte order swapped.  
> > > &nbsp;&nbsp;var byteSwapped: Self { get }  
> > > }  
> > > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#auxiliary-protocols&gt;Auxiliary) protocols
> > > 
> > > public protocol UnsignedInteger : BinaryInteger {  
> > > &nbsp;&nbsp;associatedtype Magnitude : BinaryInteger  
> > > }  
> > > public protocol SignedInteger : BinaryInteger, SignedArithmetic {  
> > > &nbsp;&nbsp;associatedtype Magnitude : BinaryInteger  
> > > }  
> > > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#doublewidth&gt;DoubleWidth)
> > > 
> > > The DoubleWidth\<T\> type allows to create wider fixed-width integer types from the ones available in the standard library.
> > > 
> > > Standard library currently provides fixed-width integer types of up to 64 bits. A value of DoubleWidth\<Int64\> will double the range of the underlying type and implement all the FixedWidthInteger requirements. Please note though that the implementation will not necessarily be the most efficient one, so it would not be a good idea to use DoubleWidth\<Int32\>instead of a built-in Int64.
> > > 
> > > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#extra-operators&gt;Extra) operators
> > > 
> > > In addition to the operators described in the protocols section \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#protocols&gt;), we also provide a few extensions that are not protocol requirements:
> > > 
> > > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#heterogeneous-shifts&gt;Heterogeneous) shifts
> > > 
> > > extension BinaryInteger {  
> > > &nbsp;&nbsp;// Masking shifts  
> > > &nbsp;&nbsp;static func &\>\> \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self  
> > > &nbsp;&nbsp;static func &\>\>= \<Other : BinaryInteger\>(lhs: inout Self, rhs: Other)  
> > > &nbsp;&nbsp;static func &\<\< \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self  
> > > &nbsp;&nbsp;static func &\<\<= \<Other : BinaryInteger\>(lhs: inout Self, rhs: Other)
> > > 
> > > &nbsp;&nbsp;// 'Smart' shifts  
> > > &nbsp;&nbsp;static func \>\> \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self  
> > > &nbsp;&nbsp;static func \>\>= \<Other : BinaryInteger\>(lhs: inout Self, rhs: Other)  
> > > &nbsp;&nbsp;static func \<\< \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Self  
> > > &nbsp;&nbsp;static func \<\<= \<Other : BinaryInteger\>(lhs: inout Self, rhs: Other)  
> > > }  
> > > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#heterogeneous-equality-and-comparison&gt;Heterogeneous) equality and comparison
> > > 
> > > extension BinaryInteger {  
> > > &nbsp;&nbsp;// Equality  
> > > &nbsp;&nbsp;static func == \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool  
> > > &nbsp;&nbsp;static func != \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool
> > > 
> > > &nbsp;&nbsp;// Comparison  
> > > &nbsp;&nbsp;static func \< \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool  
> > > &nbsp;&nbsp;static func \<= \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool  
> > > &nbsp;&nbsp;static func \> \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool  
> > > &nbsp;&nbsp;static func \>= \<Other : BinaryInteger\>(lhs: Self, rhs: Other) -\> Bool  
> > > }  
> > > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#masking-arithmetic&gt;Masking) arithmetic
> > > 
> > > public func &\* \<T: FixedWidthInteger\>(lhs: T, rhs: T) -\> T  
> > > public func &- \<T: FixedWidthInteger\>(lhs: T, rhs: T) -\> T  
> > > public func &+ \<T: FixedWidthInteger\>(lhs: T, rhs: T) -\> T  
> > > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#non-goals&gt;Non%5C-goals)
> > > 
> > > This proposal:
> > > 
> > > DOES NOT solve the integer promotion problem, which would allow mixed-type arithmetic. However, we believe that it is an important step in the right direction.
> > > 
> > > DOES NOT include the implementation of a BigInt type, but allows it to be implemented in the future.
> > > 
> > > \<[Protocol-oriented integers (take 2) · GitHub](https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c#source-compatibility&gt;Source) compatibility
> > > 
> > > The proposed change is designed to be as non-breaking as possible, and it has been proven that it does not break code on concrete integer types. However, there are still a few API breaking changes in the realm of generic code:
> > > 
> > > Integer protocols in Swift up to and including version 3 were not particularly useful for generic programming, but were rather a means of sharing implementation between conforming types. Therefore we believe the amount of code that relied on these protocols is relatively small. The breakage can be further reduced by introducing proper aliases for the removed protocols with deprecation warnings.
> > > 
> > > Deprecation of the BitwiseOperations protocol. We find it hard to imagine a type that conforms to this protocol, but is not a binary integer type.
> > > 
> > > Addition of 'smart' shifts will change the behavior of existing code. It will still compile, but will be potentially less performant due to extra logic involved. In a case, where this becomes a problem, newly introduced masking shift operators can be used instead. Unfortunately, performance characteristics of the code cannot be statically checked, and thus migration cannot be provided.
> > > 
> > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > swift-evolution mailing list  
> > > swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>  
> > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

[Next page](https://forums.swift.org/t/protocol-oriented-integers-take-2/4884.md?page=2)
