Как преобразовать массив битов в байт (а не в байтовую строку)?

У меня есть следующий массив:

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 с битами, определенными в массиве. См. stackoverflow.com/questions/48474520/…

Slaw 08.01.2023 01:45
0
1
67
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Преобразуйте массив битов в один 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 08.01.2023 14:18

@lukas.j Не могу воспроизвести, кажется чуть быстрее с фолдом (19 наносекунд) - pl.kotl.in/3NbDzG0VO

adnan_e 09.01.2023 13:19

Кажется, что он работает намного быстрее и на игровой площадке. уменьшить занимает как минимум на 50% больше времени, чем свернуть.

lukas.j 09.01.2023 13:30

Глядя на сгенерированный байт-код Kotlin, кажется, что reduce создает IntIterator, а fold использует «цикл перехода». Это может объяснить, почему фолд работает быстрее.

lukas.j 09.01.2023 14:09

Простое преобразование массива в 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 быстрее, чем это.

Другие вопросы по теме