在 Kotlin 中,二进制操作(如位移、掩码、按位与、按位或等)是底层编程中常用的工具。为了提高代码的可读性和复用性,可以将这些操作封装成工具类或扩展函数。以下是一些常见的二进制操作封装示例:
1. 常用二进制操作封装
以下是一个工具类 BinaryUtils
,封装了常见的二进制操作:
object BinaryUtils {
// 1. 将整数转换为二进制字符串
fun Int.toBinaryString(): String {
return this.toString(2)
}
// 2. 将二进制字符串转换为整数
fun String.binaryToInt(): Int {
return this.toInt(2)
}
// 3. 按位与操作
fun bitwiseAnd(a: Int, b: Int): Int {
return a and b
}
// 4. 按位或操作
fun bitwiseOr(a: Int, b: Int): Int {
return a or b
}
// 5. 按位异或操作
fun bitwiseXor(a: Int, b: Int): Int {
return a xor b
}
// 6. 按位取反操作
fun bitwiseNot(a: Int): Int {
return a.inv()
}
// 7. 左移操作
fun leftShift(a: Int, bits: Int): Int {
return a shl bits
}
// 8. 右移操作(算术右移)
fun rightShift(a: Int, bits: Int): Int {
return a shr bits
}
// 9. 无符号右移操作(逻辑右移)
fun unsignedRightShift(a: Int, bits: Int): Int {
return a ushr bits
}
// 10. 检查特定位是否为1
fun isBitSet(a: Int, bit: Int): Boolean {
return (a and (1 shl bit)) != 0
}
// 11. 设置特定位为1
fun setBit(a: Int, bit: Int): Int {
return a or (1 shl bit)
}
// 12. 清除特定位(设置为0)
fun clearBit(a: Int, bit: Int): Int {
return a and (1 shl bit).inv()
}
// 13. 切换特定位(0变1,1变0)
fun toggleBit(a: Int, bit: Int): Int {
return a xor (1 shl bit)
}
}
2. 使用示例
以下是如何使用上述工具类的示例:
fun main() {
val a = 0b1101 // 13
val b = 0b1010 // 10
// 1. 转换为二进制字符串
println("a 的二进制表示:${BinaryUtils.toBinaryString(a)}") // 输出:1101
// 2. 二进制字符串转换为整数
val binaryStr = "1010"
println("二进制字符串 $binaryStr 转换为整数:${BinaryUtils.binaryToInt(binaryStr)}") // 输出:10
// 3. 按位与操作
println("a and b:${BinaryUtils.bitwiseAnd(a, b).toString(2)}") // 输出:1000
// 4. 按位或操作
println("a or b:${BinaryUtils.bitwiseOr(a, b).toString(2)}") // 输出:1111
// 5. 按位异或操作
println("a xor b:${BinaryUtils.bitwiseXor(a, b).toString(2)}") // 输出:0111
// 6. 按位取反操作
println("a 取反:${BinaryUtils.bitwiseNot(a).toString(2)}") // 输出:11111111111111111111111111110010(32位)
// 7. 左移操作
println("a 左移 2 位:${BinaryUtils.leftShift(a, 2).toString(2)}") // 输出:110100
// 8. 右移操作
println("a 右移 1 位:${BinaryUtils.rightShift(a, 1).toString(2)}") // 输出:110
// 9. 无符号右移操作
println("a 无符号右移 1 位:${BinaryUtils.unsignedRightShift(a, 1).toString(2)}") // 输出:110
// 10. 检查特定位是否为1
println("a 的第 2 位是否为1:${BinaryUtils.isBitSet(a, 2)}") // 输出:true
// 11. 设置特定位为1
println("设置 a 的第 1 位为1:${BinaryUtils.setBit(a, 1).toString(2)}") // 输出:1111
// 12. 清除特定位
println("清除 a 的第 3 位:${BinaryUtils.clearBit(a, 3).toString(2)}") // 输出:101
// 13. 切换特定位
println("切换 a 的第 0 位:${BinaryUtils.toggleBit(a, 0).toString(2)}") // 输出:1100
}
3. 扩展函数版本
为了更方便地使用这些操作,可以将它们封装为 Kotlin 的扩展函数:
// 扩展函数:将整数转换为二进制字符串
fun Int.toBinaryString(): String {
return this.toString(2)
}
// 扩展函数:将二进制字符串转换为整数
fun String.binaryToInt(): Int {
return this.toInt(2)
}
// 扩展函数:检查特定位是否为1
fun Int.isBitSet(bit: Int): Boolean {
return (this and (1 shl bit)) != 0
}
// 扩展函数:设置特定位为1
fun Int.setBit(bit: Int): Int {
return this or (1 shl bit)
}
// 扩展函数:清除特定位
fun Int.clearBit(bit: Int): Int {
return this and (1 shl bit).inv()
}
// 扩展函数:切换特定位
fun Int.toggleBit(bit: Int): Int {
return this xor (1 shl bit)
}
使用扩展函数:
fun main() {
val a = 0b1101 // 13
println("a 的二进制表示:${a.toBinaryString()}") // 输出:1101
println("a 的第 2 位是否为1:${a.isBitSet(2)}") // 输出:true
println("设置 a 的第 1 位为1:${a.setBit(1).toBinaryString()}") // 输出:1111
}
4. 总结
通过封装二进制操作,可以提高代码的可读性和复用性。你可以根据实际需求选择工具类或扩展函数的方式。这些封装方法特别适用于以下场景:
- 协议数据的组装与解析。
- 硬件寄存器操作。
- 位掩码和标志位的处理。