-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathInteger+Extensions.swift
87 lines (70 loc) · 2.61 KB
/
Integer+Extensions.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import Foundation
extension BinaryInteger {
public var ip_isEven: Bool {
return (self % 2) == 0
}
public var ip_isOdd: Bool {
return !ip_isEven
}
}
extension Int {
public func ip_times(closure: () -> Void) {
precondition(self >= 0)
(0..<self).forEach { _ in closure() }
}
}
extension BinaryInteger {
public func ip_toMagnitudeString(withDecimalPlaces decimalPlaces: Int = 1) -> String {
guard self > 999 else { return "\(self)" }
let units = ["K", "M", "B", "T", "Q"]
let value = Double(Int64(self))
var magnitude: Int = Int(log10(value) / 3.0) // the order of magnitude of our value in thousands
// divide value by 1000^magnitude to get hundreds value, then round to desired decimal places
var roundedHundredsValue = (value / pow(1000.0, Double(magnitude))).ip_rounded(toDecimalPlaces: decimalPlaces)
// if rounding brings our display value over 1000, divide by 1000 and then bump the magnitude
if roundedHundredsValue >= 1000 {
roundedHundredsValue /= 1000.0
magnitude += 1
}
// if our number exceeds our current magnitude system return the scientific notation
let magnitudeSuffix = units[ip_safely: magnitude - 1] ?? "E\(magnitude * 3)"
guard let valueFormatted = NumberFormatter.decimalFormatter.string(from: NSNumber(value: roundedHundredsValue)) else {
return "\(roundedHundredsValue)\(magnitudeSuffix)"
}
return "\(valueFormatted)\(magnitudeSuffix)"
}
}
extension NumberFormatter {
fileprivate static var decimalFormatter: NumberFormatter {
let decimalFormatter = NumberFormatter()
decimalFormatter.numberStyle = .decimal
decimalFormatter.minimumFractionDigits = 0
return decimalFormatter
}
}
extension BinaryInteger {
fileprivate var ip_data: Data {
var copy = self
return Data(bytes: ©, count: MemoryLayout<Self>.size)
}
public var ip_bigEndianData: Data? {
switch UInt32(CFByteOrderGetCurrent()) {
case CFByteOrderLittleEndian.rawValue:
return Data(self.ip_data.reversed())
case CFByteOrderBigEndian.rawValue:
return self.ip_data
default:
return nil
}
}
public var ip_littleEndianData: Data? {
switch UInt32(CFByteOrderGetCurrent()) {
case CFByteOrderLittleEndian.rawValue:
return self.ip_data
case CFByteOrderBigEndian.rawValue:
return Data(self.ip_data.reversed())
default:
return nil
}
}
}