Skip to content

Instantly share code, notes, and snippets.

@kharrison
Created February 17, 2017 16:43
Show Gist options
  • Star 27 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save kharrison/0879fc225121edaec903799cf0afb091 to your computer and use it in GitHub Desktop.
Save kharrison/0879fc225121edaec903799cf0afb091 to your computer and use it in GitHub Desktop.
Swift Integer Quick Guide
// -------------------------------------
// Swift Integer Quick Guide
// -------------------------------------
// Created by Keith Harrison http://useyourloaf.com
// Copyright (c) 2017 Keith Harrison. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
// -------------------------------------
// Integer Types
// -------------------------------------
Int8(42) // 8-bit signed
UInt8(42) // 8-bit unsigned
Int16(42) // 16-bit signed
UInt16(42) // 16-bit unsigned
Int32(42) // 32-bit signed
UInt32(42) // 32-bit unsigned
Int64(42) // 64-bit signed
UInt64(42) // 64-bit unsigned
Int(42) // platform word size signed
UInt(42) // platform word size unsigned
// -------------------------------------
// Max and min values of each type
// -------------------------------------
Int8.min // -128
Int8.max // 127
UInt8.min // 0
UInt8.max // 255
Int16.min // -32768
Int16.max // 32767
UInt16.min // 0
UInt16.max // 65535
Int32.min // -2147483648
Int32.max // 2147483647
UInt32.min // 0
UInt32.max // 4294967295
Int64.min // -9223372036854775808
Int64.max // 9223372036854775807
UInt64.min // 0
UInt64.max // 18446744073709551615
Int.min // platform dependent (32/64 bit)
Int.max // platform dependent (32/64 bit)
UInt.min // 0
UInt.max // platform dependent (32/64 bit)
// -------------------------------------
// Integer literals
// -------------------------------------
let decimal = 42 // 42
let binary = 0b101010 // 42
let octal = 0o52 // 42
let hex = 0x2A // 42
let hex2bytes = 0x00_ff
let downloads = 1_000_000_000
// -------------------------------------
// Initializers
// -------------------------------------
let someInt = 42 // Int
let int8 = Int8(127) // 8-bit signed integer
let unit8 = UInt8(255) // 8-bit unsigned integer
// let tooBig = Int8(128) // Integer overflow
// Strings
// These can fail so return an optional (Int?)
let zip = Int("95014") // 95014
let unzip = Int("XYZ 30") // nil
let rad16 = Int("FF", radix: 16) // 255
let bitrot = Int8("020", radix: 2) // nil
// Doubles are truncated
let pi = Int(3.14) // 3
// Endian
let fromBigEnd = Int.init(bigEndian: 0x4000_0000_0000_0000) // 0x40
let fromLittleEnd = Int.init(littleEndian: 0x40) // 0x40
// Swapping bytes
let aa:UInt16 = 0x00AA
let swapped = aa.byteSwapped // 0xAA00
// Bit Patterns
// when you need to convert between signed and unsigned
// maintaining an exact bit pattern
let bits: UInt8 = 0b1000_0000 // 128
// let topBit = Int8(bits) // error - overflows
let topBit = Int8(bitPattern: bits) // -128 = 0b10000000
let back = UInt8(bitPattern: topBit) // 128 = 0b10000000
let full16 = 0xAA05
let lower8 = UInt8(truncatingBitPattern: full16) // 5
// -------------------------------------
// Failable Initializers
// -------------------------------------
// https://github.com/apple/swift-evolution/blob/master/proposals/0080-failable-numeric-initializers.md
// Following is an error as 128 is too big for Int8
//let tooBig = Int8(128)
let input = 128
let tooBig = Int8(exactly: input) // nil
let fits = Int16(exactly: input) // 128
// -------------------------------------
// Integer conversions
// -------------------------------------
// Conversions must be explicit, you cannot perform
// operations on different types:
let height = Int8(5)
let width = 10
// let area = height * width // error operands are Int8 and Int
let area = Int(height) * width // 50
// Overflow is an error
let h = UInt8(25) // UInt8(25)
let x = 10 * h // UInt8(250)
// let y = 100 * h // error
let y = 100 * Int(h) // Int(2500)
// IntMax is a typealias for the largest native signed integer
let bigInt: IntMax = 1 // Int64 on 64-bit platform
let singleByte = Int8(15) // 15
let maxSize = singleByte.toIntMax() // 15
// -------------------------------------
// Overflow operators
// -------------------------------------
let maxInt32 = Int32.max // 2147483647
let minInt32 = Int32.min // -2147483648
// The following overflows a 32-bit integer
// causing an exception
// let moreThan32 = maxInt32 + 1
// let lessThan32 = minInt32 - 1
// let twiceAsBig = maxInt32 * 2
// Swift has three overflow operators
// overflowing causes the result to wrap around
// from the maximum to minimum value (or vice versa for underflow)
// Overflow addition: &+
let overflowAdd = maxInt32 &+ 1 // -2147483648
// Overflow substraction: &-
let overflowSub = minInt32 &- 1 // 2147483647
// Overflow multiplication: &*
let overflowMult = maxInt32 &* 2 // -2
// If you want to know if an under/overflow happened:
// returns a tuple (Int32, Bool)
let wrapAdd = Int32.addWithOverflow(maxInt32, maxInt32) // (-2, true)
let wrapSub = Int8.subtractWithOverflow(-127, 2) // (127, true)
let wrapMult = UInt8.multiplyWithOverflow(128, 2) // (0, true)
let wrapDiv = Int32.divideWithOverflow(minInt32, -1) // (0, true)
// Remainder of lhs / rhs and bool for overflow
let remainder = Int8.remainderWithOverflow(127, 10) // (7, false)
// This seems to be a bug, gives an error when
// it should be an overflow
// https://bugs.swift.org/browse/SR-3535
// let bug = Int.divideWithOverflow(Int.min, -1)
// -------------------------------------
// Bitwise operators
// -------------------------------------
// As with C bitwise operators
// ~ NOT
// & AND
// | OR
// ^ XOR
let byte:UInt8 = 0b1010_0000 // 160 (0b1010_0000)
let mask:UInt8 = 0b0011_0011 // 51 (0b0011_0011)
let notByte = ~byte // 95 (0b0101_1111)
let andByte = byte & mask // 32 (0b0010_0000)
let orByte = byte | mask // 168 (0b1011_0011)
let xorByte = byte ^ mask // 147 (0b1001_0011)
// Bit shifting - unsigned
// bits shifted beyond bounds are discarded
// empty bits are filled with zeroes
let pattern:UInt8 = 0b1100_0011
pattern << 2 // 0b0000_1100
pattern >> 2 // 0b0011_0000
// rotating an unsigned integer
// 8-bits rotated by 2 bits
let rotateLeft = pattern << 2 | pattern >> 6 // 0b0000_1111
let rotateRight = pattern << 6 | pattern >> 2 // 0b1111_0000
// Bit shifting - signed
// Shifting to the right fill empty bits on the left with the sign bit
// For an 8-bit integer, top bit is the sign and seven bits the value
// using 2's complement for negative values so subtract from 2^7 = 128
// -10 => 128 - 10 = 118 = 0b111_0110
let minus10 = Int8(bitPattern: 0b1_111_0110) // -10
minus10 << 2 // -40
minus10 >> 2 // -3
let minus40 = Int8(bitPattern: 0b1_101_1000) // -40
let minus3 = Int8(bitPattern: 0b1_111_1101) // -3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment