Dealing with Octal numbers in swift
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
How to convert from Octal to Decimal in Swift
From Octal to Decimal
There is a specific Int
initializer for this
let octal = 10
if let decimal = Int(String(octal), radix: 8) {
print(decimal) // 8
}
From Decimal to Octal
let decimal = 8
if let octal = Int(String(decimal, radix: 8)) {
print(octal) // 10
}
Note 1: Please pay attention: parenthesis are different in the 2 code snippets.
Note 2:
Int
initializer can fail for string representations of number with more exotic radixes. Please read the comment by @AMomchilov below.
Only allowing octal numbers
I would replace all the scanf
and harcoded functions with fgets
and strtol
:
enum {oct = 8, dec = 10, hex = 16};
int to_number(int base, bool *match)
{
char str[32];
long num = 0;
*match = false;
if (fgets(str, sizeof str, stdin))
{
char *ptr;
num = strtol(str, &ptr, base);
*match = (*ptr == '\n'); // match is true if strtol stops scanning
// at the newline left by fgets
}
return (int)num;
}
...
bool match;
int num = to_number(oct, &match);
printf("%d %s an octal\n", num, match ? "is" : "is not");
EDIT:
As pointed out by @klutt in comments, since strtol
returns a long
, ideally the function should also return long
in order to avoid the cast, then, if you really need an int
, you can cast the return of the function:
long to_number(int base, bool *match);
int num = (int)to_number(oct, &match);
How to convert a fractional Octal to Hex fraction and vice versa in Swift 3?
Convert hex to binary, pad to make binary string a multiple of 3 in length, then convert binary to octal:
func hexadecimalFractToOctal(_ hex: String) -> String {
let hexToBin = ["0": "0000", "1": "0001", "2": "0010", "3": "0011",
"4": "0100", "5": "0101", "6": "0110", "7": "0111",
"8": "1000", "9": "1001", "A": "1010", "B": "1011",
"C": "1100", "D": "1101", "E": "1110", "F": "1111"]
let binToOct = ["000": "0", "001": "1", "010": "2", "011": "3",
"100": "4", "101": "5", "110": "6", "111": "7"]
// Convert hex string to binary
var bin = ""
for char in hex.characters {
bin += hexToBin[String(char)] ?? ""
}
// Pad the string to a multiple of 3 binary digits
bin += ["", "00", "0"][bin.characters.count % 3]
var binChars = bin.characters
var oct = ""
// Convert binary string to octal 3 digits at a time
while binChars.count > 0 {
let b = String(binChars.prefix(3))
binChars = binChars.dropFirst(3)
oct += binToOct[b] ?? ""
}
return oct
}
print(hexadecimalFractToOctal("3AF9F")) // "1657476"
And the other direction (octal -> hexadecimal):
func octalFractToHexadecimal(_ oct: String) -> String {
let octToBin = ["0": "000", "1": "001", "2": "010", "3": "011",
"4": "100", "5": "101", "6": "110", "7": "111"]
let binToHex = ["0000": "0", "0001": "1", "0010": "2", "0011": "3",
"0100": "4", "0101": "5", "0110": "6", "0111": "7",
"1000": "8", "1001": "9", "1010": "A", "1011": "B",
"1100": "C", "1101": "D", "1110": "E", "1111": "F"]
// Convert octal string to binary
var bin = ""
for char in oct.characters {
bin += octToBin[String(char)] ?? ""
}
// Pad the string to a multiple of 4 binary digits
bin += ["", "000", "00", "0"][bin.characters.count % 4]
var binChars = bin.characters
var hex = ""
// Convert binary string to hexadecimal 4 digits at a time
while binChars.count > 0 {
let b = String(binChars.prefix(4))
binChars = binChars.dropFirst(4)
hex += binToHex[b] ?? ""
}
return hex
}
print(octalFractToHexadecimal("1657476")) // "3AF9F0"
Octal Numbering System
Easy. Just continue the pattern from the left side of the dot:
1*8^1 + 0*8^0 + 3*8^-1 + 4*8^-2 = 8.4375
Related Topics
Swift: Trunc a Floating Number to Show It in a Label
Swiftui Go Back Programmatically from Representable to View
Why Is This Predicate Format Being Turned into '= Nil'
Cannot Use Mutating Member ... Because Append
Swift - Connect Delegate to Custom Xib Cell
Why Does a Function Have Long-Term Write Access to All of Its In-Out Parameters
Convert Input Data to Integer in Swift
Swift Bug? Calling Super Class Method When Subclass with Generic Type
List Scroll Freeze on Catalyst Navigationview
Swift Auto Completion Not Working in Xcode 6 Beta
Idiomatic Way to Test Swift Optionals
How to Loop Over The Output of a Publisher with Combine
Root Class of All Classes in Swift
Compiler Segmentation Fault While Using Set in Swift
Why Swift Disallows Weak Reference for Non-Optional Type
How to Refer to a Global Type from Within a Class That Has a Nested Type with The Same Name