[Tutor] working with c_byte?

Alex Hall mehgcap at gmail.com
Sat Mar 24 06:10:59 CET 2012


Thanks, the & (bitwise operator) trick seems to be promising. Should I
still mod by 256? If so, could you explain why, since the value cannot
exceed 127? Also, how does that work if a possible vlaue is 255,
according to the documentation?

On 3/24/12, Dave Angel <d at davea.name> wrote:
> On 03/23/2012 11:51 PM, Alex Hall wrote:
>> Hi all,
>> I am trying to read battery information. I found an example that sets
>> up a ctypes structure to get the information from a kernel call, and
>> it works... except that I just realized the values of some fields are
>> added. For instance, a value of 1 means that the battery is "high",
>> and 8 means it is charging. I didn't realize until just now that
>> Windows will give both of these to me as 9, so the dict I set up to
>> see what the value is won't work. Similarly, a value of 255 is always
>> seen in Python as -128, even if I multiply it by -1 to flip it.
>
> Don't multiply by -1, simply convert to an int, and use modulo 256 to
> get it to a positive value.
>      newval = int(cbyte) % 256
>
> Or perhaps use c_ubyte instead of c_byte to get unsigned values in the
> first place.
>
> A signed value uses the highest bit to indicate a negative value.  For
> an 8 bit signed value, the values range from -128 to 127.  There is no
> positive value above 127, so multiplying by -1 is the wrong answer.
> Besides if there are other bits in the byte, they'll get changed as
> well.  The modulo trick won't affect any of the 8 bits, only their
> interpretation.
>
>>   The
>> value I'm working with is a ctypes.c_byte. Here is the data structure:
>> class SYSTEM_POWER_STATUS(ctypes.Structure):
>>   _fields_=[
>>    ("ACLineStatus", ctypes.c_byte),
>>    ("BatteryFlag", ctypes.c_byte),
>>    ("BatteryLifePercent", ctypes.c_byte),
>>    ("Reserved1", ctypes.c_byte),
>>    ("BatteryLifeTime", ctypes.wintypes.DWORD),
>>    ("BatteryFullLiveTime", ctypes.wintypes.DWORD)
>>   ]
>>
>> and here is my dict to use when looking up the meaning of the BatteryFlag:
>> status_constants = {
>>   1:"high",
>>   2:"low",
>>   4:"critical",
>>   8:"charging",
>>   128:"no system battery",
>>   -128:"no system battery", #hack to get around odd negation of 128
>> flag... how to fix?
>>   255:"unknown"
>> }
>>
>
> cbyte & 1   will be nonzero (1) if that one "high" flag is set,
> regardless of the others.
> cbyte & 2    will be nonzero (2) if  "low", and so on.
>
> for flag in 1,2,4,8,16,32,64,128:
>        if cbyte & flag:
>               print  status_constants[cbyte & flag]
>
>
>> Of course, 9 means the battery is high and charging, but how do I
>> interpret an arbitrary integer as the sum of its flags? Is there a
>> binary trick I can use? I could record all the 1s in the binary number
>> and look up their positions... but is there a simpler way? If I do
>> that, where is the sign bit in c_byte? TIA.
>>
>>
>
> As I said earlier, the sign bit is 128, the highest bit in the byte.
> The number is 2's complement, which is why you must use modulo to
> convert it, not multiplication by -1.  The latter approach would work if
> the machine used ones complement.
>
> --
>
> DaveA
>
>


-- 
Have a great day,
Alex (msg sent from GMail website)
mehgcap at gmail.com; http://www.facebook.com/mehgcap


More information about the Tutor mailing list