Tracks
/
Crystal
Crystal
/
Syllabus
/
Binary, Octal, and Hexadecimal
Bi

Binary, Octal, and Hexadecimal in Crystal

1 exercise

About Binary, Octal, and Hexadecimal

Binary, octal, and hexadecimal (also known as hex) are different numeral systems with different bases. Binary is base 2, octal is base 8, and hexadecimal is base 16. Normal integers are base 10 in Crystal. Binary, octal, and hexadecimal are all representations of integers. This means that they represent positive and negative numbers (including zero) without fractions or decimals and support all the operations that we can do with integers.

Binary

Binary is a base 2 numeral system, using only the digits 0 and 1. It commonly represents the 0 ("off") and 1 ("on") states of electrical flow through transistors and switches in computers, as well as the positive and negative charges in magnetic storage media. Binary can represent all the integers that are used in base 10.

A snippet from the base 2 system looks like this, although it continues infinitely and doesn't stop at 128:

128 64 32 16 8 4 2 1
2 ** 7 2 ** 6 2 ** 5 2 ** 4 2 ** 3 2 ** 2 2 ** 1 2 ** 0

So if we want to represent the number 6, it would in binary be: 110

Place value 4 2 1
Binary number 1 1 0

And the operation would be: 4 + 2 + 0 = 6

Another example: 19

Place value 16 8 4 2 1
Binary number 1 0 0 1 1

The binary number would be: 10011 And the operation would be: 16 + 0 + 0 + 2 + 1 = 19

Binary in Crystal

In Crystal, we can represent binary literals using the 0b prefix. If we write 0b10011, Crystal will interpret it as a binary number and convert it to base 10.

0b10011
# => 19

typeof(0b10011)
# => Int32

If you write a number with a 0b prefix that is not in the binary system, it will raise a compilation error.

0b10211
# => Error: unexpected token: "211"

Operations with Binary Numbers

Since binary numbers are integers, we can perform all operations on them that we can with integers.

0b10011 + 0b10011
# => 38

0b10011 * 0b10011
# => 361

0b10011 / 3
# => 6.333333333333333

Converting to and from Binary Representation

Crystal will automatically convert a binary literal into Int32. To convert an Int32 into a binary representation, use the method <int>.to_s(base) with the base argument set to 2. The method will return a string representation of the binary number:

19.to_s(2)
# => "10011"

To convert a string representation of a binary to an integer, we can use the <int>.to_i(base) method, passing the base (2) as an argument:

"10011".to_i(2)
# => 19

Giving the wrong base (or an invalid binary representation) will raise an ArgumentError:

"011021".to_i(2)
# => Invalid Int32: "011021" (ArgumentError)

Binary Methods

There are certain methods that can be used on integers to get information about the binary representation of the number.

<int>.bit_length will return the number of bits that are needed to represent the number:

19.bit_length
# => 5

<int>.bit(index) will return the bit at the given index, starting from the right (least significant bit):

19.bit(0)
# => 1

0b10011.bit(1)
# => 1

Octal

Octal is a base 8 numeral system. It uses the digits 0, 1, 2, 3, 4, 5, 6, and 7.

In Crystal, we can represent octal numbers using the 0o prefix. As with binary, Crystal automatically converts an octal representation to an Int32.

0o123
# => 83

Prefixing a number with 0o that is not in the octal system will raise a compilation error.

Converting to and from Octal Representation

As with binary, we can use the <int>.to_s(base) method to convert an Int32 into an octal representation. And we can use the <int>.to_i(base) method to convert an octal representation into an Int32.

83.to_s(8)
# => "123"

"123".to_i(8)
# => 83

As with binary, giving the wrong base will raise an ArgumentError.

Hexadecimal

Hexadecimal is a base 16 numeral system. It uses the digits 0 - 9 and the letters A, B, C, D, E, and F. A is 10, B is 11, C is 12, D is 13, E is 14, and F is 15.

We can represent hexadecimal numbers in Crystal using the 0x prefix. As with binary and octal, Crystal will automatically convert hexadecimal literals to Int32.

#=> 0x123
291

Prefixing a non-hexadecimal number with 0x will raise a compilation error.

Converting to and from Hexadecimal Representation

As with binary, we can use the <int>.to_s(base) method to convert an Int32 into a hexadecimal representation. And we can use the <int>.to_i(base) method to convert a hexadecimal representation into an Int32.

291.to_s(16)
# => "123"

"123".to_i(16)
# => 291

As with binary and octal, giving the wrong base will raise an ArgumentError.

Precision

When converting a number to a string representation, we can specify the precision of the number. Meaning the minimum amount of numbers used to represent the number. If the number has fewer digits than the precision, leading zeros will be added to the string representation. This is done by passing the precision argument to the <int>.to_s(<base>, precision: <value>) method.

291.to_s(16, precision: 5)
# => "00123"

543.to_s(precision: 2)
# => "543"

Upcase

When converting a number to a string representation, we can specify if we want the letters in the string to be uppercased. This is done by passing the upcase argument to the <int>.to_s(<base>, upcase: <value>) method.

255.to_s(16, upcase: true)
# => "FF"

255.to_s(16, upcase: false)
# => "ff"
Edit via GitHub The link opens in a new window or tab

Learn Binary, Octal, and Hexadecimal

Practicing is locked

Unlock 2 more exercises to practice Binary, Octal, and Hexadecimal