As the title says I need to make a function that converts between the 2 bases, DEC and HEX in twos complement. The number of bits the value uses is known from the start.
After doing more than a little digging around i found the following algorithm:
- Given a number in DEC.
- Get the absolute value of the number.
- Get the binary(BIN) value of the abs from step 2.
- Pad with
0s on the left until the number is the desired length. NOTall the bits obtained in step 4.- Add 1 to the result. (Easiest way in practice is probably to convert back to DEC, add 1, and back to BIN)
- Convert to HEX. Done.
This algorithm from what I observer might only work if the original number is negative(<0). I managed to get results that seem correct by making the following modification:
On step 6, don't add 1. Instead add the opposite of the signature of the original number. For example if the original number was negative, like -455 then add 1, if it was positive, like 10002 then "add" -1.
This does seem to give positive results but I'm not sure about it's soundness as I have never worked with two's complement before this and this modification to step 6 was in my view logic + guesswork - formal_knowledge.
Here is the Python 3.6 function I came up with, the DEC value is an int, all other values are represented as strings, the desired length i assumed was just the next multiple of 4:
def d2h(i: int) -> str:
sign = (i // abs(i)) if i is not 0 else 1
step1 = i
step2 = abs(step1)
step3 = bin(step2)[2:]
step4 = step3
while len(step4) % 4 != 0:
step4 = '0' + step4
step5 = step4.replace('0', 'O') \
.replace('1', '0') \
.replace('O', '1')
step6 = bin(int(step5, 2) + -sign)[2:]
step7 = hex(int(step6, 2))[2:]
return step7
As for converting back, from a HEX value to a DEC one, what I managed to kind of "reverse engineer"(as I was not able to find something that actually explained this):
- Given a number in HEX.
- Get it's representation in binary, BIN.
- Pad with
0until the desired length. - Check if the leftmost bit is
1(a.k.a. the number is negative). - If the number is negative, then convert the BIN value from step 3 to DEC and then subtract 2 to the power of however many bits we have(
2 ^ len(BIN)), if the number is NOT negative(the leading bit is0) then simply convert it to DEC like usual. Done.
Here is the Python function I wrote for that(same implementation details as above):
def h2d(h: str) -> int:
step1 = h
step2 = bin(int(h, 16))[2:]
step3 = step2
while len(step3) % 4 != 0:
step3 = '0' + step3
if step3[0] == '1':
step4 = int(step3, 2) - (2**len(step3))
else:
step4 = int(step3, 2)
return step4
My bottom question is: Will these functions convert any number to and from two's complement in HEX correctly or did I just stumble into a coincidence of lucky test values? Is this correct?
EDIT: Upon further testing I have found that h2d(d2h()) does not always give the correct values. For numbers such as 0, 1, 2, etc. it gives the negative values -2, -3, -4, etc. but for the border cases, -32768 and 32767 it works.
Since it is obviously incorrect now, what should I change(for both algorithms) so that they would be correct?
Thank you in advance!
-455and10002? Edit the question. - Peter Wood