How to copy bits from M into N (numbers) between bit positions i and j (edge‑case‑safe) in Scala

1 Answer

0 votes
/*
    Handles edge cases:
    - Validates i and j
    - Prevents undefined behavior from shifting by ≥ 64 bits
    - Masks M so only the required bits are copied
*/

object CopyBitsApp {

  // Convert unsigned 64‑bit integer to binary string without leading zeros
  def toBinary(x: Long): String = {
    if (x == 0L) "0"
    else {
      val sb = new StringBuilder
      var n = x

      while (n != 0L) {
        sb.insert(0, if ((n & 1L) == 1L) '1' else '0')
        n = n >>> 1 // unsigned shift
      }

      sb.toString
    }
  }

  // Copy bits from M into N between bit positions [i, j]
  def copyBits(N: Long, M: Long, i: Int, j: Int): Long = {
    if (i < 0 || j < 0 || i > j || j >= 63)
      throw new IllegalArgumentException("Invalid bit range")

    val length = j - i + 1

    // Mask for bits i..j
    val mask = ((1L << length) - 1L) << i

    // Clear bits i..j in N
    val Ncleared = N & ~mask

    // Take only the needed bits from M and shift into place
    val Mshifted = (M & ((1L << length) - 1L)) << i

    Ncleared | Mshifted
  }

  def main(args: Array[String]): Unit = {

    /*
        N:      100 011111 00
        M:          110011
        Result: 100 110011 00
    */

    val N = 0b10001111100L
    val M = 0b110011L

    val result = copyBits(N, M, 2, 7)

    println("N:      " + toBinary(N))
    println("M:      " + toBinary(M))
    println("Result: " + toBinary(result))
  }
}



/*
OUTPUT:

N:      10001111100
M:      110011
Result: 10011001100

*/

 



answered Mar 30 by avibootz

Related questions

...