468,288 Members | 1,941 Online

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

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).

Daniele
May 18 '07 #1
15 5324
bartonc
6,596 Expert 4TB
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).

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
136 Expert 100+
Just a curiosity but is there any built-in that would convert to binary? For example:
3000='101110111000'
May 18 '07 #3
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
6,596 Expert 4TB
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
6,596 Expert 4TB
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
2,851 Expert Mod 2GB
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
136 Expert 100+
I was just curious about a built-in but that is absolutely Beautiful!
May 18 '07 #8
bartonc
6,596 Expert 4TB
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
2,851 Expert Mod 2GB
I was intrigued by a problem Motoma tackled and posted to Python Articles.
May 18 '07 #10
ghostdog74
511 Expert 256MB
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
6,596 Expert 4TB
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
ghostdog74
511 Expert 256MB
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
3,237 Expert 2GB
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
2,851 Expert Mod 2GB
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
2,851 Expert Mod 2GB
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