I know I can store and retrieve 2 numbers of 4 bits inside 1 Byte like this :
// Store both numbers in one byte
byte firstNumber = 10;
byte secondNumber = 15;
byte bothNumbers = (byte) ((firstNumber << 4) | secondNumber);
// Retreive the original numbers
firstNumber = (byte) ((bothNumbers >> 4) & (byte) 0x0F);
secondNumber = (byte) (bothNumbers & 0x0F);
But how can I overwrite one of the two numbers (let's say the first one (10)) without touching the last 4 bits (15)?
// Store both numbers in one byte
byte firstNumber = 10;
byte secondNumber = 15;
byte bothNumbers = (byte) ((firstNumber << 4) | secondNumber);
// Replacing one of the 2 numbers without touching the other
firstNumber = 13;
bothNumbers = ...
CodePudding user response:
You would use something like this:
bothNumbers = (byte) ((bothNumbers & 0xf) | (firstNumber << 4))
CodePudding user response:
In Kotlin, you could create a value class to make it convenient to work with. It only compiles to a Byte, but you can conveniently treat it like a class instance/ boxable primitive.
@JvmInline
value class FourBitPair(val bothNumbers: Byte) {
constructor(firstNumber: Byte, secondNumber: Byte):
this((firstNumber.toInt() shl 4 or secondNumber.toInt()).toByte())
val firstNumber: Byte get() = ((bothNumbers.toInt() shr 4) and 0xF).toByte()
val secondNumber: Byte get() = (bothNumbers.toInt() and 0xF).toByte()
operator fun component1() = firstNumber
operator fun component2() = secondNumber
fun withFirstNumber(newFirstNumber: Byte) = FourBitPair(newFirstNumber, secondNumber)
fun withSecondNumber(newSecondNumber: Byte) = FourBitPair(firstNumber, newSecondNumber)
override fun toString(): String = "[$firstNumber, $secondNumber]"
}
fun main() {
val x: Byte = 3
val y: Byte = 15
var pair = FourBitPair(x, y)
println(pair)
pair = pair.withFirstNumber(13)
println(pair)
pair = pair.withSecondNumber(4)
println(pair)
val (first, second) = pair
println(second)
println(pair.bothNumbers)
}
Prints:
[3, 15]
[13, 15]
[13, 4]
4
-44