Skip to content

Instantly share code, notes, and snippets.

@tuzz
Last active September 11, 2022 21:31
Show Gist options
  • Select an option

  • Save tuzz/fda0df6de0d1e70d4db5 to your computer and use it in GitHub Desktop.

Select an option

Save tuzz/fda0df6de0d1e70d4db5 to your computer and use it in GitHub Desktop.
Encode and Decode integers to and from twos complement in Ruby
module TwosComplement
def self.encode(n)
if n < 0
binary = (n + 1).abs.to_s(2).chars.map { |c| c == "0" }
binary.unshift(true) unless binary.first == true
else
binary = n.to_s(2).chars.map { |c| c == "1" }
binary.unshift(false) unless binary.first == false
end
binary
end
def self.decode(array)
total = 0
array.each.with_index do |bit, index|
total += 2 ** (array.length - index - 1) if bit
total = -total if index.zero?
end
total
end
end
require "rspec"
describe TwosComplement do
it "encodes integers to twos-complement bit arrays" do
expect(described_class.encode(7)).to eq [false, true, true, true]
expect(described_class.encode(6)).to eq [false, true, true, false]
expect(described_class.encode(5)).to eq [false, true, false, true]
expect(described_class.encode(4)).to eq [false, true, false, false]
expect(described_class.encode(3)).to eq [false, true, true]
expect(described_class.encode(2)).to eq [false, true, false]
expect(described_class.encode(1)).to eq [false, true]
expect(described_class.encode(0)).to eq [false]
expect(described_class.encode(-1)).to eq [true]
expect(described_class.encode(-2)).to eq [true, false]
expect(described_class.encode(-3)).to eq [true, false, true]
expect(described_class.encode(-4)).to eq [true, false, false]
expect(described_class.encode(-5)).to eq [true, false, true, true]
expect(described_class.encode(-6)).to eq [true, false, true, false]
expect(described_class.encode(-7)).to eq [true, false, false, true]
expect(described_class.encode(-8)).to eq [true, false, false, false]
end
it "decodes twos-complement bit arrays to integers" do
expect(described_class.decode([false, true, true, true])).to eq(7)
expect(described_class.decode([false, true, true, false])).to eq(6)
expect(described_class.decode([false, true, false, true])).to eq(5)
expect(described_class.decode([false, true, false, false])).to eq(4)
expect(described_class.decode([false, true, true])).to eq(3)
expect(described_class.decode([false, true, false])).to eq(2)
expect(described_class.decode([false, true])).to eq(1)
expect(described_class.decode([false])).to eq(0)
expect(described_class.decode([true])).to eq(-1)
expect(described_class.decode([true, false])).to eq(-2)
expect(described_class.decode([true, false, true])).to eq(-3)
expect(described_class.decode([true, false, false])).to eq(-4)
expect(described_class.decode([true, false, true, true])).to eq(-5)
expect(described_class.decode([true, false, true, false])).to eq(-6)
expect(described_class.decode([true, false, false, true])).to eq(-7)
expect(described_class.decode([true, false, false, false])).to eq(-8)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment