Last active
October 7, 2017 14:40
-
-
Save munckymagik/3136616f566d6843f27fa0ab3502268f to your computer and use it in GitHub Desktop.
Using Ruby to emulate how hardware adds binary numbers
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
# Sums two bits | |
def half_adder(a, b) | |
sum = a ^ b | |
carry = a & b | |
[carry, sum] | |
end | |
# Sums three bits | |
def full_adder(a, b, c) | |
carry1, sum1 = half_adder(a, b) | |
carry2, sum = half_adder(sum1, c) | |
carry = carry1 | carry2 | |
[carry, sum] | |
end | |
# Sum two nibbles (a 'nibble' is 4 bits or half a byte) | |
def sum_nibbles(nibble_a, nibble_b) | |
carry0, sum0 = half_adder(nibble_a[3], nibble_b[3]) | |
carry1, sum1 = full_adder(nibble_a[2], nibble_b[2], carry0) | |
carry2, sum2 = full_adder(nibble_a[1], nibble_b[2], carry1) | |
carry3, sum3 = full_adder(nibble_a[0], nibble_b[0], carry2) | |
[carry3, sum3, sum2, sum1, sum0] | |
end | |
def test_half_adder | |
[ | |
[0, 0, 0, 0], | |
[0, 1, 0, 1], | |
[1, 0, 0, 1], | |
[1, 1, 1, 0] | |
].each do |fixture| | |
a, b, *expected = fixture | |
result = half_adder(a, b) | |
raise [fixture, result].to_s unless result == expected | |
end | |
'pass' | |
end | |
def test_full_adder | |
[ | |
[0, 0, 0, 0, 0], | |
[0, 0, 1, 0, 1], | |
[0, 1, 0, 0, 1], | |
[1, 0, 0, 0, 1], | |
[0, 1, 1, 1, 0], | |
[1, 0, 1, 1, 0], | |
[1, 1, 0, 1, 0], | |
[1, 1, 1, 1, 1] | |
].each do |fixture| | |
a, b, c, *expected = fixture | |
result = full_adder(a, b, c) | |
raise fixture.to_s unless result == expected | |
end | |
'pass' | |
end | |
def test_sum_nibbles | |
[ | |
{ a: [0, 0, 0, 1], b: [0, 0, 0, 0], sum: [0, 0, 0, 0, 1] }, | |
{ a: [0, 0, 0, 1], b: [0, 0, 0, 1], sum: [0, 0, 0, 1, 0] }, | |
{ a: [0, 0, 0, 0], b: [1, 1, 1, 1], sum: [0, 1, 1, 1, 1] }, | |
{ a: [1, 1, 1, 1], b: [1, 1, 1, 1], sum: [1, 1, 1, 1, 0] } | |
].each do |fixture| | |
result = sum_nibbles(fixture[:a], fixture[:b]) | |
raise [fixture, result].to_s unless result == fixture[:sum] | |
end | |
'pass' | |
end | |
[ | |
:test_half_adder, | |
:test_full_adder, | |
:test_sum_nibbles | |
].each { |t| puts '%s: %s' % [t, send(t)] } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment