By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,036 Members | 1,963 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,036 IT Pros & Developers. It's quick & easy.

Way to know bytes of an int in Python [with bits class thrown in]

P: 7
Hi,

I need to know the byte which a number is made of. For example, let's suppose I have

i = 3000

I would like to know if there is a way to get the single byte of the number (0x0B and 0xB8).

Thanks in advance,
Daniele
May 18 '07 #1
Share this Question
Share on Google+
15 Replies


bartonc
Expert 5K+
P: 6,596
Hi,

I need to know the byte which a number is made of. For example, let's suppose I have

i = 3000

I would like to know if there is a way to get the single byte of the number (0x0B and 0xB8).

Thanks in advance,
Daniele
Expand|Select|Wrap|Line Numbers
  1. >>> aHex = hex(3000) # call built-in function to convert to hex
  2. >>> print aHex
  3. 0xbb8
  4. >>> bytes = aHex[2:].zfill(4) # slice off the '0x'
  5. >>> print bytes
  6. 0bb8
  7. >>> highByte = '0x%s' % bytes[0:2] #reformat with '0x' added to just the high byte
  8. >>> print highByte
  9. 0x0b
  10. >>> 
Let's see if you can get the low byte. We're here to help.
May 18 '07 #2

dshimer
Expert 100+
P: 136
Just a curiosity but is there any built-in that would convert to binary? For example:
3000='101110111000'
May 18 '07 #3

P: 7
First of all thanks,

the lowbyte comes from

lowByte = '0x%s' % bytes[2:4]

I've found also another solution:
Expand|Select|Wrap|Line Numbers
  1. # mod edit # added for completeness #
  2. import struct
  3. ################################
  4. def getByteLength(self, length):
  5.         temp = struct.pack('!h', length)
  6.         byteList = [firstLength, secondLength] = struct.unpack('BB', temp)
  7.         return list(byteList)
  8.  
to obtain a list in which the elements are the needed bytes
May 18 '07 #4

bartonc
Expert 5K+
P: 6,596
Just a curiosity but is there any built-in that would convert to binary? For example:
3000='101110111000'
While it's true that
>>> int('101', 2)
5
>>>
There is no bit or byte type to call for conversion to base 2.
May 18 '07 #5

bartonc
Expert 5K+
P: 6,596
While it's true that
>>> int('101', 2)
5
>>>
There is no bit or byte type to call for conversion to base 2.
How 'bout this little goodie:
Expand|Select|Wrap|Line Numbers
  1. def Byte2Bits(value):
  2.     # Create a list of bits to convert big endian wise
  3.     data = []
  4.     outStr = ""
  5.     for i in range(8):
  6.         value, rem = divmod(value, 2)
  7.         data.insert(0, rem)
  8.  
  9.     for pos, i in enumerate(data):
  10.         if not (pos % 4):
  11.             outStr += " "
  12.         outStr += str(i)
  13.     return outStr
  14.  
  15.  
  16. def Base2Repr(value):
  17.     # Create a list of bytes to convert big endian wise
  18.     data = []
  19.     outStr = ""
  20.     while value:
  21.         value, rem = divmod(value, 256)
  22.         data.insert(0, rem)
  23.     for i in data:
  24.         outStr += Byte2Bits(i)
  25.     return outStr[1:]
  26.  
  27.  
  28. class bits(object):
  29.     def __init__(self, value):
  30.         self.value = value
  31.  
  32.     def __repr__(self):
  33.         return Base2Repr(self.value)
  34.  
  35.  
  36.  
  37. if __name__ == "__main__":
  38.     b = bits(0xf5a5)
  39.     print b
  40.  
1111 0101 1010 0101
May 18 '07 #6

bvdet
Expert Mod 2.5K+
P: 2,851
Just a curiosity but is there any built-in that would convert to binary? For example:
3000='101110111000'
I don't think so, but I made this up:
Expand|Select|Wrap|Line Numbers
  1. def ConvDecToBaseVar(num, base):
  2.     if base > 10 or base < 2:
  3.         raise ValueError, 'The base number must be between 2 and 10.'
  4.     if num == 0: return 0
  5.     ans = ''
  6.     while num != 0:
  7.         num, rem = divmod(num, base)
  8.         ans =  str(rem)+ans
  9.     return int(ans)
  10.  
  11. '''
  12. >>> ConvDecToBaseVar(3000,2)
  13. 101110111000L
  14. >>>
  15. '''
May 18 '07 #7

dshimer
Expert 100+
P: 136
I was just curious about a built-in but that is absolutely Beautiful!
May 18 '07 #8

bartonc
Expert 5K+
P: 6,596
I was just curious about a built-in but that is absolutely Beautiful!
It's beautiful, all right (ain't BV good). But what about nibble formatting?
May 18 '07 #9

bvdet
Expert Mod 2.5K+
P: 2,851
I was intrigued by a problem Motoma tackled and posted to Python Articles.
http://www.thescripts.com/forum/thread648799.html
May 18 '07 #10

Expert 100+
P: 511
Just a curiosity but is there any built-in that would convert to binary? For example:
3000='101110111000'
Expand|Select|Wrap|Line Numbers
  1. def dectobin(number):
  2.     if number < 1: return ""
  3.     else:return dectobin(number/2) + str(number & 1) 
  4.  
May 19 '07 #11

bartonc
Expert 5K+
P: 6,596
Expand|Select|Wrap|Line Numbers
  1. def dectobin(number):
  2.     if number < 1: return ""
  3.     else:return dectobin(number/2) + str(number & 1) 
  4.  
VERY nice, GD. So, let's see: If <edit: this isn't right [the integer division of number by 2]> number is odd, then the next [L]MSb is a one... Am I getting that right? And where/how did you dream up that algorithm?
May 19 '07 #12

Expert 100+
P: 511
VERY nice, GD. So, let's see: If <edit: this isn't right [the integer division of number by 2]> number is odd, then the next [L]MSb is a one... Am I getting that right? And where/how did you dream up that algorithm?
the & operator is just to test the LSB of binary division.
say for example 14 divide by 2. in binary division of these 2 numbers,
1110 divide by 10 , as you slowly progress, you will reach the LSB and it will always be 0 or 1.
In & operations, a true and true is a true. So if the LSB is 0, & with 1 will be 0. (tested no remainder) . if LSB is 1, & with 1 is a 1, so there's remainder.

( in this case, 14/2 is remainder 0, so the bit tested is 0 )
and then we do 7/2 , 3/2 and so on.....the rest of the code is just to chain together all these 0's and 1's tested.
hope i didn't miss anything...
May 19 '07 #13

Motoma
Expert 2.5K+
P: 3,235
I don't think so, but I made this up:
Expand|Select|Wrap|Line Numbers
  1. def ConvDecToBaseVar(num, base):
  2.     if base > 10 or base < 2:
  3.         raise ValueError, 'The base number must be between 2 and 10.'
  4.     if num == 0: return 0
  5.     ans = ''
  6.     while num != 0:
  7.         num, rem = divmod(num, base)
  8.         ans =  str(rem)+ans
  9.     return int(ans)
  10.  
  11. '''
  12. >>> ConvDecToBaseVar(3000,2)
  13. 101110111000L
  14. >>>
  15. '''

Gotta love reusable code, eh?
May 19 '07 #14

bvdet
Expert Mod 2.5K+
P: 2,851
Gotta love reusable code, eh?
Yes. Here's some more recycling -
Expand|Select|Wrap|Line Numbers
  1. def ConvDecToBaseVar3(num, base):
  2.     if base > 16 or base < 2:
  3.         raise ValueError, 'The base number must be between 2 and 16.'
  4.     dd = dict(zip(range(16), [hex(i).split('x')[1] for i in range(16)]))
  5.     if num == 0: return ''
  6.     num, rem = divmod(num, base)
  7.     return ConvDecToBaseVar3(num, base)+dd[rem]
Expand|Select|Wrap|Line Numbers
  1. >>> ConvDecToBaseVar3(123456789, 16)
  2. '75bcd15'
  3. >>> ConvDecToBaseVar3(2**200, 16)
  4. '100000000000000000000000000000000000000000000000000'
  5. >>> ConvDecToBaseVar3(2**200, 7)
  6. '141246066533632643213232344050606053061443446006544361632102630555343054'
  7. >>> 
It's not suitable for very long numbers due to the recursion limit.
May 19 '07 #15

bvdet
Expert Mod 2.5K+
P: 2,851
This is considerably more efficient than the previous version:
Expand|Select|Wrap|Line Numbers
  1. def ConvDecToBaseVar3(num, base, dd=False):
  2.     if base > 16 or base < 2:
  3.         raise ValueError, 'The base number must be between 2 and 16.'
  4.     if not dd:
  5.         dd = dict(zip(range(16), [hex(i).split('x')[1] for i in range(16)]))
  6.     if num == 0: return ''
  7.     num, rem = divmod(num, base)
  8.     return ConvDecToBaseVar3(num, base, dd)+dd[rem]
This avoids the recursion limit:
Expand|Select|Wrap|Line Numbers
  1. def ConvDecToBaseVar4(num, base):
  2.     if num < 2: return str(num)
  3.     if base > 16 or base < 2:
  4.         raise ValueError, 'The base number must be between 2 and 16.'
  5.     dd = dict(zip(range(16), [hex(i).split('x')[1] for i in range(16)]))
  6.     ans = ''
  7.     while num != 0:
  8.         num, rem = divmod(num, base)
  9.         ans =  str(rem)+ans
  10.     return ans
May 19 '07 #16

Post your reply

Sign in to post your reply or Sign up for a free account.