So far this is just some roughed out code based on this explanation. Feel free to comment, adapt and streamline. I have no doubts that it can be improved, but for a start it works. All comments welcome.
extension String {
func binaryToDecimal() -> Double {
func binaryBeforePoint(binary:String) -> Int {
let values = Array(binary.characters).reverse()
var num = 0
var div = 1
for v in values {
guard let n = Int(String(v)) where n == 1 || n == 0 else {fatalError("Contains invalid character.")}
num += n * div
div *= 2
}
return num
}
func binaryAfterPoint(binary:String) -> Double {
let values = Array(binary.characters)
var num:Double = 0
var div:Double = 2
for v in values {
guard let d = Double(String(v)) where d == 1 || d == 0 else {fatalError("Contains invalid character.")}
num += d/div
div *= 2
}
return num
}
let binaryArray = Array(self.characters).split(".", maxSplit: 1, allowEmptySlices: false)
if let beforePoint = binaryArray.first,
afterPoint = binaryArray.last where binaryArray.count > 1 {
return binaryAfterPoint(String(afterPoint)) + Double(binaryBeforePoint(String(beforePoint)))
}
else if self.containsString(".") == false {
if let bValue = binaryArray.first {
return Double(binaryBeforePoint(String(bValue)))
}
else {
return 0
}
}
else {
if let bValue = binaryArray.first {
return Double(binaryAfterPoint(String(bValue)))
}
else {
return 0
}
}
}
}
"11011".binaryToDecimal() // 27
"11011.010".binaryToDecimal() // 27.25
".11011".binaryToDecimal() // 0.84375
Comments
Post a Comment