Last active
September 11, 2022 21:31
-
-
Save tuzz/fda0df6de0d1e70d4db5 to your computer and use it in GitHub Desktop.
Encode and Decode integers to and from twos complement in Ruby
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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