У меня есть следующий массив:
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))
Но в приведенном выше случае 2 значения были преобразованы в String
И я хотел бы знать, можно ли сравнивать числа без приведения к строке
Преобразуйте массив битов в один Int, используя побитовые операции. Это предполагает, что каждый элемент равен либо 0, либо 1, и в противном случае он сломается (из-за сдвига только на 1 бит).
val cells = arrayOf(
0b1, 0b1, 0b1,
0b0, 0b0, 0b0,
0b0, 0b0, 0b0,
)
var joined = cells.reduce{ acc, curr -> ((acc shl 1) or curr) }
print(joined == 0b111000000)
Попробуйте fold(0) {acc, int -> (acc shl 1) или int}. Кажется, это значительно быстрее. Почему я не знаю.
@lukas.j Не могу воспроизвести, кажется чуть быстрее с фолдом (19 наносекунд) - pl.kotl.in/3NbDzG0VO
Кажется, что он работает намного быстрее и на игровой площадке. уменьшить занимает как минимум на 50% больше времени, чем свернуть.
Глядя на сгенерированный байт-код Kotlin, кажется, что reduce создает IntIterator, а fold использует «цикл перехода». Это может объяснить, почему фолд работает быстрее.
Простое преобразование массива в int (избегая побитовых операций):
import kotlin.math.pow
val cells = arrayOf(
0b1, 0b1, 0b1,
0b0, 0b0, 0b0,
0b1, 0b1, 0b1,
)
fun Array<Int>.toInt() = this
.foldIndexed(0) { index, acc, int ->
acc + if (int == 0b1) 2.0.pow(index).toInt() else 0
}
println(cells.toInt() == 0b111000000) // false
println(cells.toInt() == 0b111000111) // true
Обратите внимание, что решения @adnan_e быстрее, чем это.
Вы можете использовать побитовые операторы для создания
Int
с битами, определенными в массиве. См. stackoverflow.com/questions/48474520/…