Skip to content

Instantly share code, notes, and snippets.

@dacr
Last active May 27, 2023 06:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dacr/f5142acec372aeb90010e676292d5142 to your computer and use it in GitHub Desktop.
Save dacr/f5142acec372aeb90010e676292d5142 to your computer and use it in GitHub Desktop.
various binary operations (cheat sheet) / published by https://github.com/dacr/code-examples-manager #5208940e-5e7f-4df2-862d-74c8c5a390bb/7357d6fb6d8b8278bed9b411ddfa474ee574753a
// summary : various binary operations (cheat sheet)
// keywords : scala, scalatest, binary, cheatsheet, @testable
// publish : gist
// authors : David Crosson
// license : Apache NON-AI License Version 2.0 (https://raw.githubusercontent.com/non-ai-licenses/non-ai-licenses/main/NON-AI-APACHE2)
// id : 5208940e-5e7f-4df2-862d-74c8c5a390bb
// created-on : 2020-12-24T10:04:53Z
// managed-by : https://github.com/dacr/code-examples-manager
// run-with : scala-cli $file
// ---------------------
//> using scala "3.3.0"
//> using dep "org.scalatest::scalatest:3.2.16"
//> using objectWrapper
// ---------------------
import org.scalatest._
import flatspec._
import matchers._
import OptionValues._
// ---------------------------------------------------------------------------------------------
val hex2bin = Map(
"0" -> "0000",
"1" -> "0001",
"2" -> "0010",
"3" -> "0011",
"4" -> "0100",
"5" -> "0101",
"6" -> "0110",
"7" -> "0111",
"8" -> "1000",
"9" -> "1001",
"A" -> "1010",
"B" -> "1011",
"C" -> "1100",
"D" -> "1101",
"E" -> "1110",
"F" -> "1111"
)
def hex2bits(input: String): String = input.split("").map(hex2bin).mkString
// ---------------------------------------------------------------------------------------------
def pow2(p: Int): Int = 1 << p
// ---------------------------------------------------------------------------------------------
def flipBits(in: Int, bitsCount: Int = 10): Int = {
(0 until bitsCount).foldLeft(0) { case (out, n) => out | (((in & pow2(n)) >> n) << (bitsCount - 1 - n)) }
}
// ---------------------------------------------------------------------------------------------
def intToPaddedBin(n: Int, bitsCount: Int): String = {
s"%${bitsCount}s"
.format(n.toBinaryString)
.replaceAll(" ", "0")
.takeRight(bitsCount)
}
// ---------------------------------------------------------------------------------------------
def intToBin(n: Int): String = n.toBinaryString
def binToInt(in: String): Int = java.lang.Integer.parseInt(in, 2)
def bigToBin(n: BigInt): String = n.toString(2)
def binToBig(in: String): BigInt = BigInt(in, 2)
// ---------------------------------------------------------------------------------------------
type BitType = Int
def isBitSet(from: BitType, bitPos: Int): Boolean = (from & (1 << bitPos)) != 0
def changeBit(state: Boolean, bitPos: Int): BitType = changeBit(state, bitPos, 0)
def changeBit(state: Boolean, bitPos: Int, current: BitType): BitType = {
val mask = 1 << bitPos
if (state) current | mask
else current & ~mask
}
def decodeSubBinValue(from: BitType, bitPos: Int, sizeMask: BitType): BitType = (from >>> bitPos) & sizeMask
def encodeSubBinValue(value: BitType, bitPos: Int, sizeMask: BitType): BitType = encodeSubBinValue(value, bitPos, sizeMask, 0)
def encodeSubBinValue(value: BitType, bitPos: Int, sizeMask: BitType, current: BitType): BitType = {
(current & (~(sizeMask << bitPos))) | ((value & sizeMask) << bitPos)
}
// ---------------------------------------------------------------------------------------------
def switchBits(base: BitType, numBits: Int): BitType = {
val maskRight = (2 << numBits) - 1
val maskLeft = maskRight << numBits
((base & maskRight) << numBits) | ((base & maskLeft) >>> numBits) | (base & ~(maskLeft | maskRight))
}
// ---------------------------------------------------------------------------------------------
class BinaryOperations extends AnyFlatSpec with should.Matchers {
override def suiteName = "BinaryOperations"
"binToInt" should "convert a binary string to a decimal" in {
binToInt("10") shouldBe 2
binToInt("100") shouldBe 4
}
"intToPaddedBin" should "convert a decimal to a binary string" in {
intToPaddedBin(4, 3) shouldBe "100"
intToPaddedBin(4, 4) shouldBe "0100"
intToPaddedBin(4, 6) shouldBe "000100"
}
"intToBin" should "convert a decimal to a binary string" in {
intToBin(4) shouldBe "100"
intToBin(42) shouldBe "101010"
}
"flipBits" should "flip the specified number of bits horizontally" in {
intToPaddedBin(flipBits(binToInt("00101"), 5), 5) shouldBe "10100"
intToPaddedBin(flipBits(binToInt("00001"), 5), 5) shouldBe "10000"
intToPaddedBin(flipBits(binToInt("10000"), 5), 5) shouldBe "00001"
intToPaddedBin(flipBits(binToInt("01000"), 5), 5) shouldBe "00010"
intToPaddedBin(flipBits(binToInt("00100"), 5), 5) shouldBe "00100"
flipBits(1, 3) shouldBe 4
flipBits(4, 3) shouldBe 1
}
"binToBig" should "convert a binary string to a decimal" in {
binToBig("10") shouldBe 2
binToBig("100") shouldBe 4
}
"bigToBin" should "convert a decimal to a binary string" in {
bigToBin(4) shouldBe "100"
bigToBin(42) shouldBe "101010"
}
"isBitSet" should "check if a bit is set or not" in {
isBitSet(0x1, 0) shouldBe true
isBitSet(0x1, 1) shouldBe false
isBitSet(0xff00, 7) shouldBe false
isBitSet(0xff00, 8) shouldBe true
isBitSet(0xff00, 15) shouldBe true
isBitSet(0xff00, 16) shouldBe false
isBitSet(0x80000000, 31) shouldBe true
isBitSet(0x80000000, 30) shouldBe false
}
def encodeDecode(value: BitType, bitPos: Int, sizeMask: Int): BitType = encodeDecode(value, sizeMask, bitPos, 0)
def encodeDecode(value: BitType, bitPos: Int, sizeMask: Int, current: Int): BitType = {
val encoded = encodeSubBinValue(value, sizeMask, bitPos, current)
decodeSubBinValue(encoded, sizeMask, bitPos)
}
"subBinValue functions" should "encode/decode an int value" in {
encodeDecode(0x42, 0, 0xff) shouldBe 0x42
encodeDecode(0x42, 24, 0xff) shouldBe 0x42
encodeDecode(0x142, 0, 0xff) shouldBe 0x42
encodeDecode(0xffff, 0, 0xffff) shouldBe 0xffff
encodeDecode(0xffff, 16, 0xffff) shouldBe 0xffff
}
"switchBits" should "allow to switch sub values" in {
switchBits(0xcafebabe, 16) shouldBe 0xbabecafe
switchBits(0xcafe, 8) shouldBe 0xfeca
switchBits(0x42cafe, 8) shouldBe 0x42feca
switchBits(0xff42cafe, 8) shouldBe 0xff42feca
switchBits(0x7f42cafe, 8) shouldBe 0x7f42feca
}
}
org.scalatest.tools.Runner.main(Array("-oDF", "-s", classOf[BinaryOperations].getName))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment