2

How can we get the length of a hexadecimal number in the Python language? I tried using this code but even this is showing some error.

i = 0
def hex_len(a):
    if a > 0x0:
        # i = 0
        i = i + 1
        a = a/16
        return i
b = 0x346
print(hex_len(b))

Here I just used 346 as the hexadecimal number, but my actual numbers are very big to be counted manually.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ashray Malhotra
  • 171
  • 1
  • 1
  • 8
  • Can you use the number of letters of the string representation? – Alex L Jun 28 '13 at 15:14
  • 1
    What exactly do you mean by "Length of a hex number"? What are you expecting the length of `0x346` to be? – Justin Ethier Jun 28 '13 at 15:15
  • @DavidJashi - I suppose that is obvious now, having read the question again. I must have been over-thinking it. – Justin Ethier Jun 28 '13 at 15:27
  • @JustinEthier I expect the length to be 3. – Ashray Malhotra Jun 28 '13 at 15:31
  • Re *"showing some error"*: That is not such a big surprise. In the two lines with "a=a/16" and "return i" you used a mix of tabs and spaces. If you are lucky you may get away with that, but [the rules are complicated](https://stackoverflow.com/questions/2034517/pythons-interpretation-of-tabs-and-spaces-to-indent/25471702#25471702). – Peter Mortensen Jul 03 '18 at 03:10
  • As it is, there is also the runtime error *UnboundLocalError: local variable 'i' referenced before assignment*. – Peter Mortensen Jul 03 '18 at 03:21

5 Answers5

7

Use the function hex:

>>> b = 0x346
>>> hex(b)
'0x346'
>>> len(hex(b))-2
3

or using string formatting:

>>> len("{:x}".format(b))
3
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
7

While using the string representation as intermediate result has some merits in simplicity it's somewhat wasted time and memory. I'd prefer a mathematical solution (returning the pure number of digits without any 0x-prefix):

from math import ceil, log

def numberLength(n, base=16): 
    return ceil(log(n+1)/log(base))

The +1 adjustment takes care of the fact, that for an exact power of your number base you need a leading "1".

Jon Clements
  • 138,671
  • 33
  • 247
  • 280
guidot
  • 5,095
  • 2
  • 25
  • 37
  • "somewhat wasted time and memory"—I'm sceptical – Colonel Panic Jun 28 '13 at 15:58
  • Considering this is python I doubt the difference in resources matters. If it was code for an embedded controller, then maybe. But +1 for thinking beyond the "obvious" string-based solution. – Justin Ethier Jun 28 '13 at 16:05
  • My measurements using the timeit module gave these results: the string solution has a runtime nearly linear to the number of digits, the log solution a nearly constant one. Break even is at about 240 bit numbers. For a 32 bit number the string routine needs half the time, for a 1024 bit number the string solution needs factor 3 of the log solution. The original question mentioned **very big** numbers... – guidot Jun 29 '13 at 12:18
2

As Ashwini wrote, the hex function does the hard work for you:

hex(x)

Convert an integer number (of any size) to a hexadecimal string. The result is a valid Python expression.

Justin Ethier
  • 131,333
  • 52
  • 229
  • 284
0

This is the program to count the num of digits in hex number using recursion

def count_hex(n):
    ''' returns the num of digits in hex'''
    if n == 0:
        return 0
    n >>= 4
    return 1 + count_hex(n)

print(count_hex(0xFFFF))

4

Gagan
  • 1
  • 1
0

You could also do this without converting to a string using the bit_length method:

def hexLen(N): 
    return (N.bit_length()+3)//4

Note that his returns a length of zero when N is 0, your function would return None but, in reality, you still need one hex digit to represent zero. (hint: add max(1,...) to cover that edge case)

Alain T.
  • 40,517
  • 4
  • 31
  • 51