user3529546
user3529546

Reputation: 13

Python program explanation: Decimal to hex

Can someone explain to me how this works? I keep looking at it but I just don't understand. It seems to work just fine but to the life of me this makes no sense. Somebody please help.

# Convert a decimal to a hex as a string 
def decimalToHex(decimalValue):
    hex = ""

    while decimalValue != 0:
        hexValue = decimalValue % 16 
        hex = toHexChar(hexValue) + hex
        decimalValue = decimalValue // 16

    return hex

# Convert an integer to a single hex digit in a character 
def toHexChar(hexValue):
    if 0 <= hexValue <= 9:
        return chr(hexValue + ord('0'))
    else:  # 10 <= hexValue <= 15
        return chr(hexValue - 10 + ord('A'))

def main():
    # Prompt the user to enter a decimal integer
    decimalValue = eval(input("Enter a decimal number: "))

    print("The hex number for decimal", 
        decimalValue, "is", decimalToHex(decimalValue))

main() # Call the main function

Upvotes: 1

Views: 569

Answers (2)

Manuel Arwed Schmidt
Manuel Arwed Schmidt

Reputation: 3596

Printing characters

Alright, im gonna try to explain it a bit. First, lets see the function that converts a number from 0-15 to 0123...ABCDEF:

def toHexChar(hexValue):
  if 0 <= hexValue <= 9:
    return chr(hexValue + ord('0'))
  else:  # 10 <= hexValue <= 15
    return chr(hexValue - 10 + ord('A'))

You can see, its handling two cases: one, where the number 0-9 need to get converted into a text character from '0' to '9', another one where the number 10-16 need to get converted into a text character from 'A' to 'F'. It will return characters based on their ASCII-Code. For example, ord('A') returns 65.. chr() will convert an integer from 65 back to the ascii char 'A'.

Thats it about the print function. Now the loop:

Iterating number until all hex-chars are made

while decimalValue != 0:

This loop will run until not 16er chunk can be fetched

hexValue = decimalValue % 16

Normal modulo. It extracts a chunk from the decimal (hexValue will be 0-15)

hex = toHexChar(hexValue) + hex

Builds up a string. As HEX is standardtized to have bigger parts of the number on the left side, it is prepending the converted character.

decimalValue = decimalValue // 16

Preparing for the next loop: remove this 16er chunk by using a floordiv(a, b) (written as a // b).

Example

Lets understand how that works. Lets assume we want to convert the number 255 into a HexString. It will start by calling modulo 255 % 16 = 15. Then it will get converted toHexChar(15) = 'F'.

Next step is to remove that 16er chunk. If we would use normal division, we would get 255 / 16 = 15.9375. However, this would be rounded up because its above .5 after decimalpoint Causing a wrong behaviour (result would be 0x1FF).. Thats why we have to use a floordivsion which is floor(255/16) = 15 or shortly: 255 // 16 = 15.

I hope this explains it a bit better, especially why the // is needed.

Upvotes: 1

Angus Comber
Angus Comber

Reputation: 9708

I will have a go explaining using an example decimal number 11 to start with.

11 decimal is 0xB

11 modulo 16 is 11. Agreed? That means hexValue becomes the integer 11.

So the integer 11 gets passed to toHexChar.

so we have:

toHexChar(11)

11 is greater than 9, so the else path is called.

11 - 10 is of course 1.

The ascii value 'A' is 65 or 0x41, so ord('A') yields 65

1 + 65 = 66.

chr() function converts an integer value to an ASCII character. ascii 66 is 'B'. so toHexChar returns 'B'

Therefore, hex = 'B'

Now, decimalValue // 16, remember this is integer division, results in zero and hence we break out of the while loop and therefore decimalToHex(11) returns 'B'.

Example number 17.

17 modulo 16 = 1 - we have a string '1'

17 / 16 = 1 also. So we loop round one more time.

on the next iteration 1 % 16 yields 1, toHexChar returns '1' as a result.

hex = toHexChar(hexValue) + hex

will then mean that:

hex = toHexChar(1) + '1'

hex = '1' + '1'

results in "11"

Think it through with a few example numbers. Substituting as you go.

The basis of it is modulo 16 to get a remainder. The remainder cannot immediately be used because if the number is between 10 and 16 then you need to use the A-F characters, hence use of toHexChar function.

Then you divide by 16 and continue taking the remainder of what's left.

Upvotes: 1

Related Questions