Pergunta

import math
def hexToDec(hexi):
    result = 0
    for i in range(len(hexi)-1,-1,-1):
        if hexi[i] == 'A':
            result = result + (10 * math.pow(16,i))
        elif hexi[i] == 'B':
            result = result + (11 * math.pow(16,i))
        elif hexi[i] == 'C':
            result = result + (12 * math.pow(16,i))
        elif hexi[i] == 'D':
            result = result + (13 * math.pow(16,i))
        elif hexi[i] == 'E':
            result = result + (14 * math.pow(16,i))
        elif hexi[i] == 'F':
            result = result + (15 * math.pow(16,i))
        else:
            result = result + (int(hexi[i]) * math.pow(16,i))
    return result

Even after reversing the range order and reimporting I still get the same results.

Foi útil?

Solução

While there can be beautiful answers like this

x = int("FF0F", 16)

It's also important to see how the original code went wrong. The corrected version should be:

import math
def hexToDec(hexi):
    result = 0
    for i in range(len(hexi)):
        cur_pow = len(hexi) - i  - 1
        if hexi[i] == 'A':
            result = result + (10 * math.pow(16,cur_pow))
        elif hexi[i] == 'B':
            result = result + (11 * math.pow(16,cur_pow))
        elif hexi[i] == 'C':
            result = result + (12 * math.pow(16,cur_pow))
        elif hexi[i] == 'D':
            result = result + (13 * math.pow(16,cur_pow))
        elif hexi[i] == 'E':
            result = result + (14 * math.pow(16,cur_pow))
        elif hexi[i] == 'F':
            result = result + (15 * math.pow(16,cur_pow))
        else:
            result = result + (int(hexi[i]) * math.pow(16,cur_pow))
    return result

Whether you loop in "reverse" or not, the power order and the index to hexi should iterate at the opposite direction, one increasing another decreasing.

Now you can forget about this and use the answers suggested by others.

Outras dicas

In python if you want to re-import something, you need to restart the python process, or manually copy past the content of the file you've changed in python, or more conveniently using ℅cpaste in ipython.

Re-import doesn't work in python the way you are expexting.

did you observe the indexes generated by your for loop ?

whatever the direction you take for scanning the input string (forward or backward), the indexes generates 0 for the leftmost digit and len(i)-1 for the rightmost. so when you use the index to compute the "digit place" in math.pow(16,i), you are computing as if the first character of the input string is the rightmost (least significant) digit.

try using math.pow(16, len(hexi)-1-i)...

after making this correction, the scanning direction (forward or backward) does not matter. you can rewrite your for loop as for i in range(len(hexi)):.

also, do you know that you don't need to import the math module to compute powers ? you can use the ** operator: 2**4, 16**i, 16**(len(hexi)-1-i)

hexToDec = lambda hexi: int(hexi,16)

or in Python 2:

hexToDec = lambda hexi: long(hexi,16)

?

Others have show the fast way to do it but since you wanted it in a for loop...You problem is in your loop parameters, the power needs to be len of the string - the current place - 1 Just like @YS-L did in his answer also instead of using if-else you have dictionary! (you can also check for 'A' <= myCurrentChar <= 'F' instead)

import math
def hexToDec(hexi):
    result = 0
    convertDict = {"A": 10, "B": 11, "C": 12, "D": 13, "E": 14, "F": 15}
    for i in range(len(hexi)):    
        if str.isdigit(hexi[i]):
            result += int(hexi[i]) * math.pow(16, len(hexi) - i - 1)
        else:
            result += convertDict[hexi[i]] * math.pow(16, len(hexi) - i - 1)

    return int(result)

print hexToDec("FFA")

Output:

4090

Too many elif, pow... Just shift (result = result * 16) and add (ord(ch) - ord(...)) something like

""" Manual hexadecimal (string) to decimal (integer) conversion
    hexadecimal is expected to be in uppercase
"""
def hexToDec(hexi):
  result = 0;

  for ch in hexi:
    if 'A' <= ch <= 'F':
      result = result * 16 + ord(ch) - ord('A') + 10
    else:
      result = result * 16 + ord(ch) - ord('0')

  return result;

One-liner - (not very readable) - but works for lower case and handles 0x prefix

sum(16**pwr*(int(ch) if ch.isdigit() else (ord(ch.lower())-ord('a')+10))
    for pwr, ch in enumerate(reversed(hexi.replace('0x',''))))
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top