~ operator binary complement
~ operator binary complement
it seems that the operator ~ is not implemented in micropython, what is the best way to complement a byte? thanks in advance.
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: ~ operator binary complement
It is implemented:
The 1's complement of 1 is 11111110 which, viewed as a signed number in 2's complement notation, is -2.
Code: Select all
>>> a = b'\x01'
>>> ~a[0]
-2
>>>
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
Re: ~ operator binary complement
hello thank you for answering pythoncoder, I am learning to program in micropython with a nodemcu module, well the question is that in my application I need to read a binary file one byte at a time complement it and send it to a machinein parallel fashion, is already working but the complementation I do it by harware with a integrated circuit 74ls240 because I do not know how to do it by software.
with open("Design.DST", "rb") as f: # open design file in binary.
f.seek(511) # point to start of design data.
byte = f.read(1) # buffer one byte only.
while byte != b"": # read until end of design
if D_set.value()== False: #Request data from machine.
byte = f.read(1) # read design file byte by byte.
i2c.writeto(0x20,byte) # write to output port.
this is part of the code what I need to complement is the variable byte in such a way that if its value is 63 when complementing it it is equal to 9C.
deal with byte = ~ (f.read (1))
or using another variable inv = ~byte
or inv = ~byte[0]
hahaha I think I made the harder and this look so simple I can't do it.
with open("Design.DST", "rb") as f: # open design file in binary.
f.seek(511) # point to start of design data.
byte = f.read(1) # buffer one byte only.
while byte != b"": # read until end of design
if D_set.value()== False: #Request data from machine.
byte = f.read(1) # read design file byte by byte.
i2c.writeto(0x20,byte) # write to output port.
this is part of the code what I need to complement is the variable byte in such a way that if its value is 63 when complementing it it is equal to 9C.
deal with byte = ~ (f.read (1))
or using another variable inv = ~byte
or inv = ~byte[0]
hahaha I think I made the harder and this look so simple I can't do it.
Re: ~ operator binary complement
f.read(1) returns a bytes object with zero or one elements.
So ~(f.read(1)) is invalid. ~f.read(1)[0] would be valid in the case that f.read(1) returns 1 byte, but wouldn't be valid if f.read(1) returns zero bytes.
So storing the data into a variable and checking the variable length for > 0 is the best way to do it.
So ~(f.read(1)) is invalid. ~f.read(1)[0] would be valid in the case that f.read(1) returns 1 byte, but wouldn't be valid if f.read(1) returns zero bytes.
So storing the data into a variable and checking the variable length for > 0 is the best way to do it.
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: ~ operator binary complement
There is another issue here. Bitwise operations in Python have a subtlety based on the fact that Python supports arithmetic with arbitrary precision. So if you ones-complement a value you get a negative result
The value -0x64 is surprising until you consider what numbers look like in arbitrary precision arithmetic. 0x63 notionally has an infinite number of leading 0's, so its one's complement has an infinite number of leading 1's. The only sensible way to represent this is as a negative number. This can confuse those of us with a background in hardware or languages with fixed size integers.
To constrain things to 8 bits you can use the exclusive or operator ^ with an 8 bit operand:
Or use the ~ operator and constrain to 8 bits with a logical and:
Code: Select all
>>> print(hex(~0x63))
-0x64
>>>
To constrain things to 8 bits you can use the exclusive or operator ^ with an 8 bit operand:
Code: Select all
>>> hex(0x63^0xff)
'0x9c'
>>> hex(0x9c^0xff)
'0x63'
>>>
Code: Select all
>>> print(hex(~0x63 & 0xff))
0x9c
>>>
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
Re: ~ operator binary complement
hello, thanks again for your time answering, dhylans deal with byte = ~ f.read (1) [0] but TypeError: object with buffer protocol required. and pythoncoder deal with byte = f.read (1) ^ 0xff as well bitwise = byte ^ 0xff but TypeError: unsupported types for __xor__: 'bytes', 'int' and with bitwise = hex (byte ^ 0xff) SyntaxError: invalid syntax for integer with base 10
Sorry but remember that I am new and I try to learn, thanks again for your time.
Sorry but remember that I am new and I try to learn, thanks again for your time.
-
- Posts: 847
- Joined: Mon Nov 20, 2017 10:18 am
Re: ~ operator binary complement
Hopefully I can help some.
~ is definitely implemented and as far as I can tell it works the same way as CPython.
I think that you don't understand how python stores data in its memory. So signed integers are stored in 4 bytes of memory with a method know as two's complement see https://en.wikipedia.org/wiki/Two%27s_complement.
See this 1 byte version. You can see storing the number 1 in a 1 byte of memory and flip all the bits then you will get how -2 is stored.
Now looking at it as a human this looks a super strange way to store number but then if you start to do math addition the way a computer then it will make sense. Get the way -2 is stored then add add the way 1 is stored to it and see whast the result is then add 1 again and you can see this makes it easy to add negitive and positive numbers.
Looking at the table fo numbers you can also see why ~a = -a-1
~ is definitely implemented and as far as I can tell it works the same way as CPython.
I think that you don't understand how python stores data in its memory. So signed integers are stored in 4 bytes of memory with a method know as two's complement see https://en.wikipedia.org/wiki/Two%27s_complement.
See this 1 byte version. You can see storing the number 1 in a 1 byte of memory and flip all the bits then you will get how -2 is stored.
Now looking at it as a human this looks a super strange way to store number but then if you start to do math addition the way a computer then it will make sense. Get the way -2 is stored then add add the way 1 is stored to it and see whast the result is then add 1 again and you can see this makes it easy to add negitive and positive numbers.
Looking at the table fo numbers you can also see why ~a = -a-1
Re: ~ operator binary complement
good day OutoftheBOTS_ thanks for answering, then according to the information I need the complement of an unsigned byte as well as the zero number ie 00000000 = 11111111 then it would be the option byte ^ 0xff, but I do not know how to implement it so that I do not get errors before mentioned.
-
- Posts: 847
- Joined: Mon Nov 20, 2017 10:18 am
Re: ~ operator binary complement
First of all can you please post your code in code tags so that it is readable for us with correct spacing. To get code tags just press the icon that looks like </> and paste your code between the 2 code tags. Please use # and commit out what you want us to know and where your problem is.
Also I have loticed from your code is that you read 1 byte at a time into a byte array of size 1.
byte = f.read(1)
Will result in byte[0] = to the read byte
you can just use this byte = f.read(1)[0] then byte won't be an array.
Also do beware that although your calling it a byte it is in fact a signed integer of size 4 bytes because is how python stores data in memory. Python will read 1 byte from the file then store it into 4 bytes in memory and treat it as a signed int.
So if you want to do biniary operations on it as a unsigned byte then you need to cut off the excess 3 bytes.
Also I have loticed from your code is that you read 1 byte at a time into a byte array of size 1.
byte = f.read(1)
Will result in byte[0] = to the read byte
you can just use this byte = f.read(1)[0] then byte won't be an array.
Also do beware that although your calling it a byte it is in fact a signed integer of size 4 bytes because is how python stores data in memory. Python will read 1 byte from the file then store it into 4 bytes in memory and treat it as a signed int.
So if you want to do biniary operations on it as a unsigned byte then you need to cut off the excess 3 bytes.
Code: Select all
byte = f.read(1)[0]
#find the inverse of just the first byte by using &0xff to cut off everything outside first byte
byte_inverse = ~byte & 0xff
Re: ~ operator binary complement
hello again and thanks for your interest, my project consists of 2 applications one is installed on a pc and consists of sending a binary file to an esp8266 module via wifi and the second is the one I install in that module which consists of reading the binary file of one byte at a time complement the bits and send it in parallel to a machine through a serial to parallel i2c ic.
up to now it works but the complement of the bits is done by hardware with a 74ls240 ic.
my intention is to perfect it so that the complement of the bits is in software and thus save an ic.
in such a way when byte = 00000000 after inverting it is byte = 11111111 and so with all 255 different one-byte values, but I could not do it, thank you very much for your help.
this is part of code of interest:
up to now it works but the complement of the bits is done by hardware with a 74ls240 ic.
my intention is to perfect it so that the complement of the bits is in software and thus save an ic.
in such a way when byte = 00000000 after inverting it is byte = 11111111 and so with all 255 different one-byte values, but I could not do it, thank you very much for your help.
this is part of code of interest:
Code: Select all
with open("Design.DST", "rb") as f: # open design file in binary.
f.seek(511) # point to start of design data.
byte = f.read(1) # buffer one byte only.
lcd.move_to(0,1)
lcd.putstr("Sending >")
while byte != b"": # read until end of design file.
if D_set.value()== False: #Request data from machine.
time_out=0
byte = f.read(1) # the value of byte i need the complement ej: byte = 0x00 after complement byte = 0xff
i2c.writeto(0x20,byte) # write to output port.
time.sleep_us(1)# delay for stable data on output port
Strobe.value(1) # strobe pulse for machine.
time.sleep_us(10) # width of strobe pulse.
Strobe.value(0)