[Tutor] int to bytes and the other way around

Rich Lovely roadierich at googlemail.com
Mon Jul 6 18:24:52 CEST 2009


2009/7/6 Timo <timomlists at gmail.com>:
> I have written a program that uses a C++ module as backend. Now I found out
> that I can use Python to call an underneath C lib. That's nice, so I don't
> need to Popen() the C++ module.
>
> I have a problem though with some info that is returned (always an integer).
> I'll try to explain a bit, this is what I found out so far.
> There are 4 options in the program. The first 3 options go up to 18 and the
> fourth to 7.
> If all options are set to 0, the returned int is 0.
> If the first option is set from 1 to 18, this is what I get returned.
> However, for option 2, I get 256, 512, 768, 1024, etc.
> For option 3 I get 65536, 131072, 196608, etc, etc.
> And for option 4: 16777216, 33554432, etc.
>
> Ok, that's nice so far. But if option 1 is set to 4 and option 2 is set to 8
> and option 3 is set to 10 (for example), I get this returned: 657412
>
> The C++ module counts the bytes. First byte = option1, second byte = option2
> etc.
>       u8 *options = (u8 *)&result[1];
>       option1 = options[0]
>       option2 = options[1]
>       option3 = options[2]
>       option4 = options[3]
>
> How will I approach this in Python?
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> http://mail.python.org/mailman/listinfo/tutor
>
import itertools
i = iter(reversed(hex(657412)[2:]))
optlList = map(lambda (m, n): int(n+m, 16),
itertools.izip_longest(i,i, fillvalue="0"))
This will give you a list of the options.  You will need to check to
see if all four options are present.

Another way would be to use bitshifting and masking:

opt1= options & 0xff
opt2 = (options >> 8) & 0xff
opt3 = (options >> 16) & 0xff
opt4 = (options >> 24) & 0xff

I personally prefer the former method, as you won't need to change it
if you introduce a fifth (or more) options, but I think the second is
probably more reliable, and easier to extend if you need options that
use more than a single byte.  It is also maybe slightly easier to read
and understand.

Alternatively, to go the otherway (you aren't quite clear which way
you want to go)

opt1 thru opt4 are the original values (1-18 or 1-7)
options = opt1 | (opt2<<8) | (opt3<<16) | (opt4<<24)

Or, you seeing as you appear to be treating your options as
(effectively) a char[]:

options = "".join(chr(x) for x in (opt4, opt3, opt2, opt1))

Alternatively, like Kent said, take a look at the struct module, which
will do all this for you, but is not so educational.

-- 
Richard "Roadie Rich" Lovely, part of the JNP|UK Famile
www.theJNP.com


More information about the Tutor mailing list