Engineering Blog

Creating confusion with octal literals

Octal is a number system with base 8, it has 8 values (0, 1, 2, 3, 4, 5, 6, and, 7).

In Go programming language, an octal literal can be written with the prefix 0 (Zero). The value which is prefixed with 0 is considered as an octal value and it can be used in the program statements like an octal value can be assigned to a variable or constant, can be used within an expression, can be assigned in an array, etc.

Let’s first look at a common misunderstanding with octal literal representation, which can lead to confusion or even bugs. What do you believe should be the out- put of the following code?

sum := 100 + 010
fmt.Println(sum)

Normally, we may expect this code to print the result of 100 + 10 = 110. But it prints 108 instead. How is that possible?

As we discuss earlier integer with 0 is considered an octal integer (base 8), so 10 in base 8 equals 8 in base 10. Thus, the sum in the previous example is equal to 100 + 8 = 108. This is an important property of integer literals to keep in mind.

Where Octal integers can be useful GoLang

suppose we want to open a file using os.OpenFile. This function requires passing a permission as a uint32. If we want to match a Linux permission, we can pass an octal number for readability instead of a base 10 number:

file, err := os.OpenFile("foo", os.O_RDONLY, 0644)

In this example, 0644 represents a specific Linux permission (read for all and write only for the current user). It’s also possible to add an o character (the letter in lower- case) following the zero:

file, err := os.OpenFile("foo", os.O_RDONLY, 0o644)

Using 0o as a prefix instead of only 0 means the same thing. However, it can help make the code clearer.

NOTE:- We can also use an uppercase O character instead of a lowercase o. But passing 0O644 can increase confusion because, depending on the character font, 0 can look very similar to O.

There are also other integer literals and they are given below:-

  • Binary —Uses a 0b or 0B prefix (for example, 0b100 is equal to 4 in base 10)
  • Hexadecimal —Uses an 0x or 0X prefix (for example, 0xF is equal to 15 in base 10)
  • Imaginary —Uses an i suffix (for example, 3i)

NOTE:- we can also use an underscore character (_) as a separator for readability. For example, we can write 1 billion this way: 1_000_000_000. We can also use the under- score character with other representations (for example, 0b00_00_01).

To conclude, Go handles binary, hexadecimal, imaginary, and octal numbers. Octal numbers start with a 0. However, to improve readability and avoid potential mistakes for future code readers, make octal numbers explicit using a 0o prefix.

References:-

  • 100 Go Mistakes and how to avoid them, Teiva Harsanyi, Manning Publications Co
  • https://www.includehelp.com/golang/octal-literals.aspx
Previous Post
Next Post