0

I have the follow array:

val cells = arrayOf(
  0b1, 0b1, 0b1,
  0b0, 0b0, 0b0,
  0b0, 0b0, 0b0,
)

And I want to convert it to number e.g: 0b111000000, to be able to compare with another byte after:

val cells = arrayOf(
  0b1, 0b1, 0b1,
  0b0, 0b0, 0b0,
  0b0, 0b0, 0b0,
)

print(arrayOfBitsToByte(cells) == 0b111000000)

I could make this:

val cells = arrayOf(
  0b1, 0b1, 0b1,
  0b0, 0b0, 0b0,
  0b1, 0b1, 0b1,
)

print(cells.joinToString("") == 0b111000000.toString(2))

But in the above case, the 2 values were cast to String

And I would like to know if it is possible to compare the numbers without cast to string

ℛɑƒæĿᴿᴹᴿ
  • 4,983
  • 4
  • 38
  • 58
ayelsew
  • 156
  • 7
  • 1
    You can use bitwise operators to create an `Int` with the bits defined in the array. See https://stackoverflow.com/questions/48474520/how-do-i-use-javas-bitwise-operators-in-kotlin – Slaw Jan 08 '23 at 00:45

2 Answers2

2

Convert the array of bits into a single Int using bitwise operations. This assumes that each element is either 0 or 1, and will break otherwise (due to only shifting by 1 bit).

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)
adnan_e
  • 1,764
  • 2
  • 16
  • 25
  • 1
    Try _fold(0) { acc, int -> (acc shl 1) or int }_. It seems to be drastically faster. Why I do not know. – lukas.j Jan 08 '23 at 13:18
  • @lukas.j Cannot reproduce, it seems to be _slightly_ faster with fold (19 nanoseconds) - https://pl.kotl.in/3NbDzG0VO – adnan_e Jan 09 '23 at 12:19
  • It seems to be rather quite a lot of faster when running that in the playground too. _reduce_ takes at leats 50% longer than _fold_. – lukas.j Jan 09 '23 at 12:30
  • Looking at the generated Kotlin bytecode it seems that _reduce_ creates an _IntIterator_ while _fold_ uses a 'goto-loop'. That might explain why _fold_ is faster. – lukas.j Jan 09 '23 at 13:09
1

Simple conversion of the array to an int (avoiding bitwise operations):

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

Note that @adnan_e's solutions is faster than this one.

lukas.j
  • 6,453
  • 2
  • 5
  • 24