A Beginner’s Guide to Bit Manipulation: Converting Binary-Coded Decimal (BCD) to Hexadecimal in…
Understanding how to work with bits is foundational for low-level programming and working with binary data.
A Beginner’s Guide to Bit Manipulation: Converting Binary-Coded Decimal (BCD) to Hexadecimal in Kotlin
Understanding how to work with bits is foundational for low-level programming and working with binary data.
If you’ve ever wondered how to read individual parts of a byte, convert binary-coded decimal (BCD) data into readable formats, or isolate bits using bit masking, this article will walk you through it using a practical example in Kotlin.
In this article, we’ll:
- Define bits, bytes, and nibbles.
- Explain bit masking and its uses.
- Convert a BCD to a hexadecimal string using Kotlin.
Let’s dive into these core concepts and see how they work together in code.
What are Bits, Bytes, and Nibbles?
Bits
A bit is the smallest unit of data in computing, representing a binary value of either 0 or 1. Bits are the foundation of all data storage, but they’re usually grouped to create more complex data types.
Bytes
A byte is made up of 8 bits. By combining bits, we can represent larger values:
- For example, a byte with all bits set to
1(11111111in binary) represents the decimal value255.
Nibbles
A nibble is a group of 4 bits, or half of a byte. Since a nibble is 4 bits long, it can represent any number from 0 to 15 (in decimal), or 0 to F (in hexadecimal).
For instance:
- If you have a byte value
0xAB(binary1010 1011), it’s made up of two nibbles: - Higher nibble:
1010(orAin hex) - Lower nibble:
1011(orBin hex)
Understanding nibbles and their use is crucial in working with hexadecimal representations, as each nibble corresponds to one hexadecimal digit.
Bit Masking and Bitwise Operations
Bit masking is a technique to isolate, set, or clear specific bits in data using bitwise operations. A mask is a binary pattern applied to data to select or ignore certain bits, depending on whether the bits in the mask are 1 or 0.
Common Bitwise Operations
- AND (
&): Used to keep certain bits. If both bits in a position are1, the result is1; otherwise, it’s0. - OR (
|): Used to set specific bits. If either bit in a position is1, the result is1. - XOR (
^): Toggles bits. If the bits are different, the result is1; otherwise, it’s0. - NOT (
~): Flips all bits.
Masking Example
Imagine we want to isolate the higher nibble of a byte, 0xAB (binary 1010 1011). We can create a mask with 1111 0000(or 0xF0 in hex) and use the AND operation:
1010 1011 (Byte data)
AND 1111 0000 (Mask to isolate higher nibble)
----------------
1010 0000 (Result)
This result, 1010 0000, keeps the higher nibble (1010) and clears the lower nibble. To shift the bits into a more useful position, we can apply a bitwise right shift by 4 positions.
Converting BCD to a Hexadecimal String in Kotlin
Now, let’s apply this knowledge in a Kotlin function that converts a BCD byte array to a hexadecimal string.
Full Kotlin Code Example
Here’s the method that does just that:
fun bcdToStr(bcdArray: ByteArray?): String {
require(bcdArray != null) { "Input array cannot be null" }
val hexDigits = charArrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F')
val result = StringBuilder(bcdArray.size * 2)
for (byte in bcdArray) {
// Higher nibble
val highNibble = (byte.toInt() and 0xF0) ushr 4
result.append(hexDigits[highNibble])
// Lower nibble
val lowNibble = byte.toInt() and 0x0F
result.append(hexDigits[lowNibble])
}
return result.toString()
}
How This Code Works
- Parameter Validation: We first check that the input
bcdArrayis notnull. If it is, an exception is thrown. - Hex Digit Array: We create an array
hexDigitsto map decimal values to their hexadecimal equivalents (0-9andA-F). - Processing Each Byte:
- For each byte in the array, we isolate its higher and lower nibbles using bit masking:
- Higher nibble:
byte.toInt() and 0xF0keeps the first 4 bits of the byte. We then right shift these bits by 4 withushr 4to place them in the lower position. - Lower nibble:
byte.toInt() and 0x0Fisolates the last 4 bits directly, so no shifting is needed. - Each nibble is then used as an index to look up the corresponding hexadecimal character in
hexDigits.
4. Building the Result: We append each hexadecimal character (both the higher and lower nibble of each byte) to result, a StringBuilder instance, to efficiently build the final string.
Running the Code with an Example
Let’s say we want to convert the following BCD byte array: [0x12, 0x34, 0xAB].
- For
0x12:
Higher nibble is 1, and lower nibble is 2.
Result: 12
- For
0x34:
Higher nibble is 3, and lower nibble is 4.
Result: 34
- For
0xAB:
Higher nibble is A, and lower nibble is B.
Result: AB
The output of bcdToStr(byteArrayOf(0x12, 0x34, 0xAB)) will be "1234AB".
Summary
In this article, we covered key concepts for handling binary data at the bit level:
- We learned about bits, bytes, and nibbles.
- We explored how bit masking with the AND operation allows us to isolate specific parts of a byte.
- Finally, we implemented a Kotlin function that converts a BCD byte array to a hexadecimal string using bit manipulation techniques.
Bit manipulation is a powerful tool for programmers working with low-level data. Mastering these concepts will open up ways to optimize your code and handle binary data efficiently!
Kindly follow and you can also contact for questions and contributions.
메타데이터
- post_id
- f3c7d68ead2a
- slug
- a-beginners-guide-to-bit-manipulation-converting-binary-coded-decimal-bcd-to-hexadecimal-in-f3c7d68ead2a
- url
- https://medium.com/@lovisgod/a-beginners-guide-to-bit-manipulation-converting-binary-coded-decimal-bcd-to-hexadecimal-in-f3c7d68ead2a
- canonical_url
- https://medium.com/@lovisgod/a-beginners-guide-to-bit-manipulation-converting-binary-coded-decimal-bcd-to-hexadecimal-in-f3c7d68ead2a
- author_url
- https://medium.com/@lovisgod
- status
- ok
- fetched_at
- 2026-06-27 07:40:21