FixedWidthInteger

protocol FixedWidthInteger

An integer type that uses a fixed size for every instance.

Inheritance BinaryInteger, LosslessStringConvertible
Conforming Types Int, Int16, Int32, Int64, Int8, UInt, UInt16, UInt32, UInt64, UInt8

The FixedWidthInteger protocol adds binary bitwise operations, bit shifts, and overflow handling to the operations supported by the BinaryInteger protocol.

Use the FixedWidthInteger protocol as a constraint or extension point when writing operations that depend on bit shifting, performing bitwise operations, catching overflows, or having access to the maximum or minimum representable value of a type. For example, the following code provides a binaryString property on every fixed-width integer that represents the number's binary representation, split into 8-bit chunks.

extension FixedWidthInteger {
    var binaryString: String {
        var result: [String] = []
        for i in 0..<(Self.bitWidth / 8) {
            let byte = UInt8(truncatingIfNeeded: self >> (i * 8))
            let byteString = String(byte, radix: 2)
            let padding = String(repeating: "0",
                                 count: 8 - byteString.count)
            result.append(padding + byteString)
        }
        return "0b" + result.reversed().joined(separator: "_")
    }
}

print(Int16.max.binaryString)
// Prints "0b01111111_11111111"
print((101 as UInt8).binaryString)
// Prints "0b11001001"

The binaryString implementation uses the static bitWidth property and the right shift operator (>>), both of which are available to any type that conforms to the FixedWidthInteger protocol.

The next example declares a generic squared function, which accepts an instance x of any fixed-width integer type. The function uses the multipliedReportingOverflow(by:) method to multiply x by itself and check whether the result is too large to represent in the same type.

func squared<T: FixedWidthInteger>(_ x: T) -> T? {
    let (result, overflow) = x.multipliedReportingOverflow(by: x)
    if overflow {
        return nil
    }
    return result
}

let (x, y): (Int8, Int8) = (9, 123)
print(squared(x))
// Prints "Optional(81)"
print(squared(y))
// Prints "nil"

Conforming to the FixedWidthInteger Protocol

To make your own custom type conform to the FixedWidthInteger protocol, declare the required initializers, properties, and methods. The required methods that are suffixed with ReportingOverflow serve as the customization points for arithmetic operations. When you provide just those methods, the standard library provides default implementations for all other arithmetic methods and operators.

Initializers

init init(bigEndian:) Required

Creates an integer from its big-endian representation, changing the byte order if necessary.

  • Parameter value: A value to use as the big-endian representation of the new integer.

Declaration

init(bigEndian value: Self)
init init(littleEndian:) Required

Creates an integer from its little-endian representation, changing the byte order if necessary.

  • Parameter value: A value to use as the little-endian representation of the new integer.

Declaration

init(littleEndian value: Self)

Instance Variables

var bigEndian Required

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.

Declaration

var bigEndian: Self
var byteSwapped Required

A representation of this integer with the byte order swapped.

Declaration

var byteSwapped: Self
var leadingZeroBitCount Required

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.leadingZeroBitCount == 3

If the value is zero, then leadingZeroBitCount is equal to bitWidth.

Declaration

var leadingZeroBitCount: Int
var littleEndian Required

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.

Declaration

var littleEndian: Self
var nonzeroBitCount Required

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.nonzeroBitCount == 5

Declaration

var nonzeroBitCount: Int

Instance Methods

func addingReportingOverflow(_ rhs: Self) -> (partialValue: Self, overflow: Bool) Required

Returns the sum of this value and the given value, along with a Boolean value indicating whether overflow occurred in the operation.

  • Parameter rhs: The value to add to this value.

Declaration

func addingReportingOverflow(_ rhs: Self) -> (partialValue: Self, overflow: Bool)
func dividedReportingOverflow(by rhs: Self) -> (partialValue: Self, overflow: Bool) Required

Returns the quotient obtained by dividing this value by the given value, along with a Boolean value indicating whether overflow occurred in the operation.

Dividing by zero is not an error when using this method. For a value x, the result of x.dividedReportingOverflow(by: 0) is (x, true).

  • Parameter rhs: The value to divide this value by.

Declaration

func dividedReportingOverflow(by rhs: Self) -> (partialValue: Self, overflow: Bool)
func dividingFullWidth(_ dividend: (high: Self, low: Self.Magnitude)) -> (quotient: Self, remainder: Self) Required

Returns a tuple containing the quotient and remainder obtained by dividing the given value by this value.

The resulting quotient must be representable within the bounds of the type. If the quotient is too large to represent in the type, a runtime error may occur.

The following example divides a value that is too large to be represented using a single Int instance by another Int value. Because the quotient is representable as an Int, the division succeeds.

// 'dividend' represents the value 0x506f70652053616e74612049494949
let dividend = (22640526660490081, 7959093232766896457 as UInt)
let divisor = 2241543570477705381

let (quotient, remainder) = divisor.dividingFullWidth(dividend)
// quotient == 186319822866995413
// remainder == 0
  • Parameter dividend: A tuple containing the high and low parts of a double-width integer.

Declaration

func dividingFullWidth(_ dividend: (high: Self, low: Self.Magnitude)) -> (quotient: Self, remainder: Self)
func multipliedFullWidth(by other: Self) -> (high: Self, low: Self.Magnitude) Required

Returns a tuple containing the high and low parts of the result of multiplying this value by the given value.

Use this method to calculate the full result of a product that would otherwise overflow. Unlike traditional truncating multiplication, the multipliedFullWidth(by:) method returns a tuple containing both the high and low parts of the product of this value and other. The following example uses this method to multiply two Int8 values that normally overflow when multiplied:

let x: Int8 = 48
let y: Int8 = -40
let result = x.multipliedFullWidth(by: y)
// result.high == -8
// result.low  == 128

The product of x and y is -1920, which is too large to represent in an Int8 instance. The high and low compnents of the result value represent -1920 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 an Int16 instance.

let z = Int16(result.high) << 8 | Int16(result.low)
// z == -1920
  • Parameter other: The value to multiply this value by.

Declaration

func multipliedFullWidth(by other: Self) -> (high: Self, low: Self.Magnitude)
func multipliedReportingOverflow(by rhs: Self) -> (partialValue: Self, overflow: Bool) Required

Returns the product of this value and the given value, along with a Boolean value indicating whether overflow occurred in the operation.

  • Parameter rhs: The value to multiply by this value.

Declaration

func multipliedReportingOverflow(by rhs: Self) -> (partialValue: Self, overflow: Bool)
func remainderReportingOverflow(dividingBy rhs: Self) -> (partialValue: Self, overflow: Bool) Required

Returns the remainder after dividing this value by the given value, along with a Boolean value indicating whether overflow occurred during division.

Dividing by zero is not an error when using this method. For a value x, the result of x.remainderReportingOverflow(dividingBy: 0) is (x, true).

  • Parameter rhs: The value to divide this value by.

Declaration

func remainderReportingOverflow(dividingBy rhs: Self) -> (partialValue: Self, overflow: Bool)
func subtractingReportingOverflow(_ rhs: Self) -> (partialValue: Self, overflow: Bool) Required

Returns the difference obtained by subtracting the given value from this value, along with a Boolean value indicating whether overflow occurred in the operation.

  • Parameter rhs: The value to subtract from this value.

Declaration

func subtractingReportingOverflow(_ rhs: Self) -> (partialValue: Self, overflow: Bool)

Type Variables

var bitWidth Required

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.

Declaration

var bitWidth: Int
var max Required

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.

Declaration

var max: Self
var min Required

The minimum representable integer in this type.

For unsigned integer types, this value is always 0. For signed integer types, this value is -(2 ** (bitWidth - 1)), where ** is exponentiation.

Declaration

var min: Self

Type Methods

func &<<(lhs: Self, rhs: Self) -> Self Required

Returns the result of shifting a value's binary representation the specified number of digits to the left, masking the shift amount to the type's bit width.

Use the masking left shift operator (&<<) when you need to perform a shift and are sure that the shift amount is in the range 0..<lhs.bitWidth. Before shifting, the masking left shift operator masks the shift to this range. The shift is performed using this masked value.

The following example defines x as an instance of UInt8, an 8-bit, unsigned integer type. If you use 2 as the right-hand-side value in an operation on x, the shift amount requires no masking.

let x: UInt8 = 30                 // 0b00011110
let y = x &<< 2
// y == 120                       // 0b01111000

However, if you use 8 as the shift amount, the method first masks the shift amount to zero, and then performs the shift, resulting in no change to the original value.

let z = x &<< 8
// z == 30                        // 0b00011110

If the bit width of the shifted integer type is a power of two, masking is performed using a bitmask; otherwise, masking is performed using a modulo operation.

Declaration

static func &<<(lhs: Self, rhs: Self) -> Self
func &<<=(lhs: inout Self, rhs: Self) Required

Returns the result of shifting a value's binary representation the specified number of digits to the left, masking the shift amount to the type's bit width, and stores the result in the left-hand-side variable.

The &<<= operator performs a masking shift, where the value used as rhs is masked to produce a value in the range 0..<lhs.bitWidth. The shift is performed using this masked value.

The following example defines x as an instance of UInt8, an 8-bit, unsigned integer type. If you use 2 as the right-hand-side value in an operation on x, the shift amount requires no masking.

var x: UInt8 = 30                 // 0b00011110
x &<<= 2
// x == 120                       // 0b01111000

However, if you pass 19 as rhs, the method first bitmasks rhs to 3, and then uses that masked value as the number of bits to shift lhs.

var y: UInt8 = 30                 // 0b00011110
y &<<= 19
// y == 240                       // 0b11110000

Declaration

static func &<<=(lhs: inout Self, rhs: Self)
func &>>(lhs: Self, rhs: Self) -> Self Required

Returns the result of shifting a value's binary representation the specified number of digits to the right, masking the shift amount to the type's bit width.

Use the masking right shift operator (&>>) when you need to perform a shift and are sure that the shift amount is in the range 0..<lhs.bitWidth. Before shifting, the masking right shift operator masks the shift to this range. The shift is performed using this masked value.

The following example defines x as an instance of UInt8, an 8-bit, unsigned integer type. If you use 2 as the right-hand-side value in an operation on x, the shift amount requires no masking.

let x: UInt8 = 30                 // 0b00011110
let y = x &>> 2
// y == 7                         // 0b00000111

However, if you use 8 as the shift amount, the method first masks the shift amount to zero, and then performs the shift, resulting in no change to the original value.

let z = x &>> 8
// z == 30                        // 0b00011110

If the bit width of the shifted integer type is a power of two, masking is performed using a bitmask; otherwise, masking is performed using a modulo operation.

Declaration

static func &>>(lhs: Self, rhs: Self) -> Self
func &>>=(lhs: inout Self, rhs: Self) Required

Calculates the result of shifting a value's binary representation the specified number of digits to the right, masking the shift amount to the type's bit width, and stores the result in the left-hand-side variable.

The &>>= operator performs a masking shift, where the value passed as rhs is masked to produce a value in the range 0..<lhs.bitWidth. The shift is performed using this masked value.

The following example defines x as an instance of UInt8, an 8-bit, unsigned integer type. If you use 2 as the right-hand-side value in an operation on x, the shift amount requires no masking.

var x: UInt8 = 30                 // 0b00011110
x &>>= 2
// x == 7                         // 0b00000111

However, if you use 19 as rhs, the operation first bitmasks rhs to 3, and then uses that masked value as the number of bits to shift lhs.

var y: UInt8 = 30                 // 0b00011110
y &>>= 19
// y == 3                         // 0b00000011

Declaration

static func &>>=(lhs: inout Self, rhs: Self)

Default Implementations

func !=(lhs: Self, rhs: Other) -> Bool

Returns a Boolean value indicating whether the two given values are not equal.

You can check the inequality of instances of any BinaryInteger types using the not-equal-to operator (!=). For example, you can test whether the first UInt8 value in a string's UTF-8 encoding is not equal to the first UInt32 value in its Unicode scalar view:

let gameName = "Red Light, Green Light"
if let firstUTF8 = gameName.utf8.first,
    let firstScalar = gameName.unicodeScalars.first?.value {
    print("First code values are different: \(firstUTF8 != firstScalar)")
}
// Prints "First code values are different: false"

Declaration

public static func !=<Other>(lhs: Self, rhs: Other) -> Bool where Other: BinaryInteger
func !=(lhs: Self, rhs: Self) -> Bool

Declaration

public static func !=(lhs: Self, rhs: Self) -> Bool
func &(lhs: Self, rhs: Self) -> Self

Returns the result of performing a bitwise AND operation on the two given values.

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
// z == 4

Declaration

public static func &(lhs: Self, rhs: Self) -> Self
func <(lhs: Self, rhs: Other) -> Bool

Returns a Boolean value indicating whether the value of the first argument is less than that of the second argument.

You can compare instances of any BinaryInteger types using the less-than operator (<), even if the two instances are of different types.

Declaration

public static func <<Other>(lhs: Self, rhs: Other) -> Bool where Other: BinaryInteger
func <<(lhs: Self, rhs: RHS) -> Self

Returns the result of shifting a value's binary representation the specified number of digits to the left.

The << operator performs a smart shift, which defines a result for a shift of any value.

The following example defines x as an instance of UInt8, an 8-bit, unsigned integer type. If you use 2 as the right-hand-side value in an operation on x, the value is shifted left by two bits.

let x: UInt8 = 30                 // 0b00011110
let y = x << 2
// y == 120                       // 0b01111000

If you use 11 as rhs, x is overshifted such that all of its bits are set to zero.

let z = x << 11
// z == 0                         // 0b00000000

Using a negative value as rhs is the same as performing a right shift with abs(rhs).

let a = x << -3
// a == 3                         // 0b00000011
let b = x >> 3
// b == 3                         // 0b00000011

Declaration

public static func <<<RHS>(lhs: Self, rhs: RHS) -> Self where RHS: BinaryInteger
func <=(lhs: Self, rhs: Other) -> Bool

Returns a Boolean value indicating whether the value of the first argument is less than or equal to that of the second argument.

You can compare instances of any BinaryInteger types using the less-than-or-equal-to operator (<=), even if the two instances are of different types.

Declaration

public static func <=<Other>(lhs: Self, rhs: Other) -> Bool where Other: BinaryInteger
func <=(lhs: Self, rhs: Self) -> Bool

Returns a Boolean value indicating whether the value of the first argument is less than or equal to that of the second argument.

Declaration

public static func <=(lhs: Self, rhs: Self) -> Bool
func ==(lhs: Self, rhs: Other) -> Bool

Returns a Boolean value indicating whether the two given values are equal.

You can check the equality of instances of any BinaryInteger types using the equal-to operator (==). For example, you can test whether the first UInt8 value in a string's UTF-8 encoding is equal to the first UInt32 value in its Unicode scalar view:

let gameName = "Red Light, Green Light"
if let firstUTF8 = gameName.utf8.first,
    let firstScalar = gameName.unicodeScalars.first?.value {
    print("First code values are equal: \(firstUTF8 == firstScalar)")
}
// Prints "First code values are equal: true"

Declaration

public static func ==<Other>(lhs: Self, rhs: Other) -> Bool where Other: BinaryInteger
func >(lhs: Self, rhs: Other) -> Bool

Returns a Boolean value indicating whether the value of the first argument is greater than that of the second argument.

You can compare instances of any BinaryInteger types using the greater-than operator (>), even if the two instances are of different types.

Declaration

public static func ><Other>(lhs: Self, rhs: Other) -> Bool where Other: BinaryInteger
func >(lhs: Self, rhs: Self) -> Bool

Returns a Boolean value indicating whether the value of the first argument is greater than that of the second argument.

Declaration

public static func >(lhs: Self, rhs: Self) -> Bool
func >=(lhs: Self, rhs: Other) -> Bool

Returns a Boolean value indicating whether the value of the first argument is greater than or equal to that of the second argument.

You can compare instances of any BinaryInteger types using the greater-than-or-equal-to operator (>=), even if the two instances are of different types.

Declaration

public static func >=<Other>(lhs: Self, rhs: Other) -> Bool where Other: BinaryInteger
func >=(lhs: Self, rhs: Self) -> Bool

Returns a Boolean value indicating whether the value of the first argument is greater than or equal to that of the second argument.

Declaration

public static func >=(lhs: Self, rhs: Self) -> Bool
func >>(lhs: Self, rhs: RHS) -> Self

Returns the result of shifting a value's binary representation the specified number of digits to the right.

The >> operator performs a smart shift, which defines a result for a shift of any value.

The following example defines x as an instance of UInt8, an 8-bit, unsigned integer type. If you use 2 as the right-hand-side value in an operation on x, the value is shifted right by two bits.

let x: UInt8 = 30                 // 0b00011110
let y = x >> 2
// y == 7                         // 0b00000111

If you use 11 as rhs, x is overshifted such that all of its bits are set to zero.

let z = x >> 11
// z == 0                         // 0b00000000

Using a negative value as rhs is the same as performing a left shift using abs(rhs).

let a = x >> -3
// a == 240                       // 0b11110000
let b = x << 3
// b == 240                       // 0b11110000

Right shift operations on negative values "fill in" the high bits with ones instead of zeros.

let q: Int8 = -30                 // 0b11100010
let r = q >> 2
// r == -8                        // 0b11111000

let s = q >> 11
// s == -1                        // 0b11111111

Declaration

public static func >><RHS>(lhs: Self, rhs: RHS) -> Self where RHS: BinaryInteger
func ^(lhs: Self, rhs: Self) -> Self

Returns the result of performing a bitwise XOR operation on the two given values.

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
// z == 11

Declaration

public static func ^(lhs: Self, rhs: Self) -> Self
func advanced(by n: Int) -> Self

Returns a value that is offset the specified distance from this value.

Use the advanced(by:) method in generic code to offset a value by a specified distance. If you're working directly with numeric values, use the addition operator (+) instead of this method.

For a value x, a distance n, and a value y = x.advanced(by: n), x.distance(to: y) == n.

  • Parameter n: The distance to advance this value.

Declaration

@inlinable public func advanced(by n: Int) -> Self
var description

A textual representation of this value.

Declaration

var description: String
func distance(to other: Self) -> Int

Returns the distance from this value to the given value, expressed as a stride.

For two values x and y, and a distance n = x.distance(to: y), x.advanced(by: n) == y.

  • Parameter other: The value to calculate the distance to.

Declaration

@inlinable public func distance(to other: Self) -> Int
init init()

Creates a new value equal to zero.

Declaration

public init()
func isMultiple(of other: Self) -> Bool

Returns true if this value is a multiple of the given value, and false otherwise.

For two integers a and b, a is a multiple of b if there exists a third integer q such that a = q*b. For example, 6 is a multiple of 3 because 6 = 2*3. Zero is a multiple of everything because 0 = 0*x for any integer x.

Two edge cases are worth particular attention:

  • Parameter other: The value to test.

Declaration

@inlinable public func isMultiple(of other: Self) -> Bool
func quotientAndRemainder(dividingBy rhs: Self) -> (quotient: Self, remainder: 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.

Declaration

@inlinable public func quotientAndRemainder(dividingBy rhs: Self) -> (quotient: Self, remainder: Self)
func signum() -> Self

Returns -1 if this value is negative and 1 if it's positive; otherwise, 0.

Declaration

@inlinable public func signum() -> Self
func |(lhs: Self, rhs: Self) -> Self

Returns the result of performing a bitwise OR operation on the two given values.

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
// z == 15

Declaration

public static func |(lhs: Self, rhs: Self) -> Self