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...@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) mehg...@gmail.com; http://www.facebook.com/mehgcap _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor