2

I can easily turn a decimal number into an octal but I'm trying to do the reverse and I've got stuck.

let decimal = 11_224_393
let octString = String(rawAddress, radix: 8, uppercase: false)
let octal = octString.toInt()

Question

I want a function that given an Int of octal digits will read it in as an octal and convert it to decimal

such as:

// oct2dec(777) = 511
// oct2dec(10) = 8

func oct2dec(octal : Int) -> Int {
    // what goes here?
}
Jeef
  • 26,861
  • 21
  • 78
  • 156
  • 1
    You shouldn't think of an `Int` as having any specific radix. In memory, it's always binary, anyway. In your example, `777` is `777` in decimal, `1,411` in octal, and `1,100,001,001` in binary all at the same time. It doesn't need to be "converted" to octal; all you need to do is make sure that string conversion is told what radix to use. – Ky - Jul 21 '17 at 20:59

2 Answers2

8

Just use Swift native octal literals and initializers (String from integer | Int from String).

let octalInt = 0o1234 // 668
let octalString = "1234" // "1234"

let decimalIntFromOctalString = Int(octalString, radix: 0o10) // 668
let octalStringFromInt = String(octalInt, radix: 0o10) // "1234"

For your specific use-case:

let decimal = 11_224_393
let octString = String(rawAddress, radix: 0o10, uppercase: false)
guard let octal = Int(octString, radix: 0o10) else {
    print("octString was not a valid octal string:", octString)
}
Ky -
  • 30,724
  • 51
  • 192
  • 308
  • Strangely, the Swift documentation for `String.init(_:radix:)` that I linked claims it was introduced in Xcode 9, there are [old](https://stackoverflow.com/a/39496909/3939277) [SO](https://stackoverflow.com/a/26181323/3939277) [answers](https://stackoverflow.com/a/28531883/3939277) that use it, so it must be older than Swift 4. – Ky - Jul 21 '17 at 21:08
  • I've filed [a radar describing the strangeness in my above comment](https://openradar.appspot.com/33462479) – Ky - Jul 21 '17 at 21:21
2

Using string conversion functions is pretty horrible in my option. How about something like this instead:

func octalToDecimal(var octal: Int) -> Int {
    var decimal = 0, i = 0
    while octal != 0 {
        var remainder = octal % 10
        octal /= 10
        decimal += remainder * Int(pow(8, Double(i++)))
    }
    return decimal
}

var decimal = octalToDecimal(777) // decimal is 511
Stefan Arentz
  • 34,311
  • 8
  • 67
  • 88