Bytes For Beginners: Cook Your Ain Conversions From Int Together With Double To Binary (And Other Pose Out Bases) Inwards Swift (Update: Xcode 8, Beta 6; Swift 3)
Why convert a decimal to a binary yourself when Swift tin create it for you?
Note: You tin larn almost the theory on Purple Math or no dubiety many other places.
String(500, radix:2)Well it helps inwards learning:
extension Int { func binary() -> String { var num = self var str = "" repeat { str = String(num%2) + str num = num/2 } piece num > 0 supply str } } 500.binary()And every bit you lot tin run into the procedure of going from base of operations 10 to base of operations two is a straightforward exercise. We just keep dividing past times the base of operations give away in addition to adding the remainder to the commencement of our string. In fact going from base of operations 10 to whatever base of operations from two through to ix is straightforward, because nosotros tin create just the same matter for those give away bases too.
extension Int { func toBase(b:Int) -> String { guard b > 1 && b < xi else { fatalError("base also high") } var num = self var str = "" repeat { str = String(num%b) + str num = num/b } piece num > 0 supply str } } 500.toBase(5) == String(500, radix:5) // truthfulWe tin fifty-fifty grip bases inwards a higher house 10 without also much strain (all the agency upwards to 36). Also added hither is the treatment of negative numbers:
extension Int { func toBase(b:Int) -> String { guard b > 1 && b < 37 else { fatalError("base out of range") } allow dict = [10:"A", 11:"B", 12:"C", 13:"D",14:"E",15:"F", 16:"G", 17:"H", 18:"I", 19:"J", 20:"K", 21:"L",22:"M", 23:"N", 24:"O", 25:"P", 26:"Q",27:"R", 28:"S", 29:"T", 30:"U", 31:"V", 32:"W", 33:"X", 34:"Y", 35:"Z"] var num = abs(self) var str = "" repeat { if allow l = dict[num%b] { str = l + str } else { str = String(num%b) + str } num = num/b } piece num > 0 supply self < 0 ? "-\(str)" : str } } 172508.toBase(36) == String(172508, radix:36).uppercaseString // true
Note: You tin larn almost the theory on Purple Math or no dubiety many other places.
Additional fun
It is possible to grip Double to binary every bit good alongside the assist of the toBase() method:extension Double { func toBinary() -> String { func afterDecimal(d:Double) -> String { var str = "" var num = d piece num != 1 { num *= two str = str + String(Int(num)) if num > 1 { num = num - Double(Int(num)) } } supply str } // dissever into earlier in addition to later decimal signal allow split = String(self).componentsSeparatedByString(".") allow consequence = Int(split[0])!.toBase(2) + "." + afterDecimal(Double("0." + split[1])!) supply consequence } } allow abc = 2.122228867 abc.toBinary()This tin move backwards checked using floating-point binary to Double conversion. But in 1 lawsuit over again nosotros tin become farther than binary in addition to transform a Double into a String representation of whatever base of operations betwixt two in addition to 36:
extension Double { // banking corporation jibe results against http://baseconvert.com func toBase(b:Int, maxPrecision:Int = 100) -> String { func afterDecimal(d:Double) -> String { var str = "" var num = d allow dict = [10:"A", 11:"B", 12:"C", 13:"D",14:"E",15:"F", 16:"G", 17:"H", 18:"I", 19:"J", 20:"K", 21:"L",22:"M", 23:"N", 24:"O", 25:"P", 26:"Q",27:"R", 28:"S", 29:"T", 30:"U", 31:"V", 32:"W", 33:"X", 34:"Y", 35:"Z"] for _ inwards 0..<100 { num *= Double(b) // if finished earlier maxPrecision supply early on if num % Double(b) == 0 { supply str } if allow l = dict[Int(num)] { str = str + l } else { str = str + String(Int(num)) } if num > 1 { num = num - Double(Int(num)) } } supply str.stringByTrimmingCharactersInSet(NSCharacterSet(charactersInString: "0")) } // dissever into earlier in addition to later decimal signal allow split = String(self).componentsSeparatedByString(".") allow consequence = Int(split[0])!.toBase(b) + "." + afterDecimal(Double("0." + split[1])!) supply consequence } } allow abc = 7.96 abc.toBase(16) // 7.F5C28F5C28F5CFinally, the adjacent pace is to transform this String dorsum to a Double in addition to banking corporation jibe that everything is working every bit it should.
extension String { func fromBase(b:Int, maxPrecision:Int = 100) -> Double { allow dict:[Int:Character] = [10:"A", 11:"B", 12:"C", 13:"D",14:"E",15:"F", 16:"G", 17:"H", 18:"I", 19:"J", 20:"K", 21:"L",22:"M", 23:"N", 24:"O", 25:"P", 26:"Q",27:"R", 28:"S", 29:"T", 30:"U", 31:"V", 32:"W", 33:"X", 34:"Y", 35:"Z"] func beforeDecimal(str:String) -> Double { var num = 0.0 for c inwards str.characters.reverse().enumerate() { allow multi = pow(Double(b), Double(c.index)) if allow v = Int(String(c.element)) { num += multi * Double(v) } else { for (i, s) inwards dict where s == c.element { num += multi * Double(i) } } } supply num } func afterDecimal(str:String) -> Double { var num = 0.0 for c inwards str.characters.enumerate() { allow multi = pow(1/Double(b), Double(c.index + 1)) if allow v = Int(String(c.element)) { num += multi * Double(v) } else { for (i, s) inwards dict where s == c.element { num += multi * Double(i) } } } supply num } allow split = self.componentsSeparatedByString(".") allow isNegative = split[0].hasPrefix("-") if isNegative { split[0].removeAtIndex(split[0].startIndex) } allow consequence = beforeDecimal(split[0]) + afterDecimal(split[1]) supply isNegative ? -result : consequence } } 221.16.toBase(16).fromBase(16) // 221.16 allow a = -136.36 a.toBase(36).fromBase(36) // -136.36 "C.3".fromBase(16) == 0xC.3p0 // truthful - run into http://stackoverflow.com/a/29735236/1694526So at that topographic point nosotros accept it, a journeying for floating-point numbers into some other give away base of operations in addition to dorsum for bases two to 36.
Swift three (Xcode 8, beta 6)
func pow(base:Double, power:Int) -> Double { precondition(power >= 0) var response : Double = 1 for _ inwards 0..<power { response *= base of operations } supply response } extension String { func split(separator:String) -> [String] { supply self.characters.split(separator: Character(separator)).map{String($0)} } } extension Int { func toBase(b:Int) -> String { guard b > 1 && b < 37 else { fatalError("base out of range") } allow dict = [10:"A", 11:"B", 12:"C", 13:"D",14:"E",15:"F", 16:"G", 17:"H", 18:"I", 19:"J", 20:"K", 21:"L",22:"M", 23:"N", 24:"O", 25:"P", 26:"Q",27:"R", 28:"S", 29:"T", 30:"U", 31:"V", 32:"W", 33:"X", 34:"Y", 35:"Z"] var num = abs(self) var str = "" repeat { if allow l = dict[num%b] { str = l + str } else { str = String(num%b) + str } num = num/b } piece num > 0 supply self < 0 ? "-\(str)" : str } } 172508.toBase(b: 36) String(172508, radix:36).uppercased() // truthful extension Double { func toBinary() -> String { func afterDecimal(d:Double) -> String { var str = "" var num = d piece num != 1 { num *= two str = str + String(Int(num)) if num > 1 { num = num - Double(Int(num)) } } supply str } // dissever into earlier in addition to later decimal signal allow split = String(self).split(separator: ".") allow consequence = Int(split[0])!.toBase(b: 2) + "." + afterDecimal(d: Double("0." + split[1])!) supply consequence } } allow abc = 2.122228867 abc.toBinary() extension Double { // banking corporation jibe results against http://baseconvert.com func toBase(b:Int, maxPrecision:Int = 100) -> String { func afterDecimal(d:Double) -> String { var str = "" var num = d allow dict = [10:"A", 11:"B", 12:"C", 13:"D",14:"E",15:"F", 16:"G", 17:"H", 18:"I", 19:"J", 20:"K", 21:"L",22:"M", 23:"N", 24:"O", 25:"P", 26:"Q",27:"R", 28:"S", 29:"T", 30:"U", 31:"V", 32:"W", 33:"X", 34:"Y", 35:"Z"] for _ inwards 0..<100 { num *= Double(b) // if finished earlier maxPrecision supply early on if num.truncatingRemainder(dividingBy: Double(b)) == 0 { supply str } if allow l = dict[Int(num)] { str = str + l } else { str = str + String(Int(num)) } if num > 1 { num = num - Double(Int(num)) } } // FIXME: cut back zeroes supply str } // dissever into earlier in addition to later decimal signal allow split = String(self).split(separator: ".") allow consequence = Int(split[0])!.toBase(b:b) + "." + afterDecimal(d: Double("0." + split[1])!) supply consequence } } allow abcd = 7.96 abcd.toBase(b: 16) // 7.F5C28F5C28F5C extension String { func fromBase(b:Int, maxPrecision:Int = 100) -> Double { allow dict:[Int:Character] = [10:"A", 11:"B", 12:"C", 13:"D",14:"E",15:"F", 16:"G", 17:"H", 18:"I", 19:"J", 20:"K", 21:"L",22:"M", 23:"N", 24:"O", 25:"P", 26:"Q",27:"R", 28:"S", 29:"T", 30:"U", 31:"V", 32:"W", 33:"X", 34:"Y", 35:"Z"] func beforeDecimal(str:String) -> Double { var num = 0.0 for c inwards str.characters.reversed().enumerated() { allow multi = pow(base: Double(b), power: c.offset) if allow v = Int(String(c.element)) { num += Double(multi) * Double(v) } else { for (i, s) inwards dict where s == c.element { num += Double(multi) * Double(i) } } } supply num } func afterDecimal(str:String) -> Double { var num = 0.0 for c inwards str.characters.enumerated() { allow multi = pow(base: 1/Double(b), power: c.offset + 1) if allow v = Int(String(c.element)) { num += Double(multi) * Double(v) } else { for (i, s) inwards dict where s == c.element { num += Double(multi) * Double(i) } } } supply num } var split = self.split(separator: ".") allow isNegative = split[0].hasPrefix("-") if isNegative { split[0].remove(at: split[0].startIndex) } allow consequence = beforeDecimal(str: split[0]) + afterDecimal(str: split[1]) supply isNegative ? -result : consequence } } 221.16.toBase(b: 16).fromBase(b: 16) // 221.16 allow a = -136.36 a.toBase(b: 36).fromBase(b: 36) // -136.36 "C.3".fromBase(b: 16) == 0xC.3p0 // truthful - run into http://stackoverflow.com/a/29735236/1694526
Comments
Post a Comment