Created
May 15, 2020 00:00
-
-
Save gigamonkey/9da80b71a2878f3ddb3141c4b6f8501f to your computer and use it in GitHub Desktop.
Got nerd sniped by a terrible interview question
This file contains 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
#!/usr/bin/env python3 | |
# Let's pretend we have to implement 32-bit multiplication with just | |
# addition, subtraction, equality/inequality tests, and bit twiddling | |
# (shifts and bitwise logical ops). For bonus points detect overflow | |
# and signal via an exception. | |
# A friend got asked this on an interview. It is a terrible interview | |
# question unless possibly you're interviewing someone to be a junior | |
# chip designer or something. But it nerd sniped me anyway as an | |
# amusing thing to spend a little time on in the comfort of my own | |
# home. | |
import sys | |
multiplier, multiplicand = [int(x) for x in sys.argv[1:]] | |
r0 = multiplier | |
r1 = multiplicand | |
acc = 0 | |
high_bit = 1 << 31 | |
bits = (1 << 32) - 1 | |
while r0 != 0: | |
if r0 & 1 != 0: | |
# Check for overflow before we do addition. | |
limit = bits & (~ acc) | |
r2 = r1 | |
overflow = False | |
while limit != r2: | |
if r2 == 0: | |
overflow = False | |
break | |
if (r2 & 1) != 0 and (limit & 1) == 0: | |
overflow = True | |
elif (r2 & 1) == 0 and (limit & 1) != 0: | |
overflow = False | |
limit >>= 1 | |
r2 >>= 1 | |
if overflow: | |
raise Exception("Overflow in addition.") | |
acc += r1 | |
r0 >>= 1 | |
# Check for overflow if we're about to shift off an on 32nd bit | |
# and there is still multiplication left to do. | |
if (high_bit & r1) != 0 and r0 != 0: | |
raise Exception("Overflow in shift") | |
r1 <<= 1 | |
print(f"{multiplier} x {multiplicand} = {acc} ({multiplier * multiplicand == acc})") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment