如何将比特数组转换为数值(而非字节字符串)以直接进行数值比较?
比特数组转数值直接比较的实现方法
我有如下比特数组:
val cells = arrayOf( 0b1, 0b1, 0b1, 0b0, 0b0, 0b0, 0b0, 0b0, 0b0, )
我希望将其转换为类似0b111000000这样的数值,以便后续与其他数值直接比较:
val cells = arrayOf( 0b1, 0b1, 0b1, 0b0, 0b0, 0b0, 0b0, 0b0, 0b0, ) print(arrayOfBitsToByte(cells) == 0b111000000)
我目前能通过字符串转换实现比较:
val cells = arrayOf( 0b1, 0b1, 0b1, 0b0, 0b0, 0b0, 0b1, 0b1, 0b1, ) print(cells.joinToString("") == 0b111000000.toString(2))
但这种方式依赖字符串转换,我想知道有没有不转字符串、直接做数值比较的方法。
当然可以,直接通过位运算就能把比特数组转换成对应的数值,完全不需要字符串转换。
实现思路是遍历数组中的每个比特位,根据它在数组中的位置,将其移动到数值对应的二进制位上,最后累加得到目标数值。
比如可以写这样一个函数:
fun arrayOfBitsToLong(cells: Array<Int>): Long { var result = 0L cells.forEachIndexed { index, bit -> // 数组第一个元素对应最高位,计算需要左移的位数 val shiftAmount = cells.size - 1 - index result = result or ((bit and 1).toLong() shl shiftAmount) } return result }
这里用Long是为了兼容更长的数组,如果你的数组长度不超过32位,也可以替换成Int类型。
测试验证:
val cells = arrayOf( 0b1, 0b1, 0b1, 0b0, 0b0, 0b0, 0b0, 0b0, 0b0, ) // 直接数值比较,无需字符串转换 println(arrayOfBitsToLong(cells) == 0b111000000L) // 输出 true val anotherCells = arrayOf( 0b1, 0b1, 0b1, 0b0, 0b0, 0b0, 0b1, 0b1, 0b1, ) println(arrayOfBitsToLong(anotherCells) == 0b111000111L) // 输出 true
原理说明
forEachIndexed遍历数组,同时获取每个比特的索引和值shiftAmount计算当前比特需要左移的位数:数组第一个元素对应二进制数的最高位,因此用数组总长度减1再减索引,比如9个元素的数组,第一个元素(index=0)需要左移8位,对应二进制的第8位(从0开始计数)bit and 1确保只取比特的最低位(避免输入的bit不是0或1的异常情况)shl是左移操作,把当前比特放到对应的位置,再用or操作累加到结果中
这样就能直接得到对应的数值,之后就可以和目标数值直接做相等比较,完全绕开字符串转换的开销。
内容的提问来源于stack exchange,提问作者ayelsew
相关产品推荐
相关产品推荐

