views:

461

answers:

5

what does the '~' mean in python?

i found this BF interpreter in python a while ago.

import sys

#c,i,r,p=0,0,[0]*255,raw_input()

c=0   
i=0
p=raw_input()    
r=[0]*255 

while c<len(p):
    m,n,u=p[c],0,r[i]
    if m==">":i+=1
    if m=="<":i-=1
    if m=="+":r[i]+=1
    if m=="-":r[i]-=1
    if m==".":sys.stdout.write(chr(u))  
    if m=="[":
        if ~u:
            while 1:
                m=p[c]
                if m=="]":n-=1
                if m=="[":n+=1
                if ~n:break
                c+=1
    if m=="]":
        if u:
            while 1:
                m=p[c]
                if m=="]":n-=1
                if m=="[":n+=1
                if ~n:break
                c-=1    
    c+=1

and i want to know what it does because i want to make one on my ti 84 (and a PF one)

BF is http://en.wikipedia.org/wiki/Brainfuck and PF is something similar

+4  A: 

~ is bitwise-not.

I can't really think of a good way to illustrate it (unless you know that -1 is the bitwise negation of 0), but the wikipedia entry is pretty good.

David Wolever
+18  A: 

Bitwise NOT, just like in C.

In two's complement representation, ~n is equivalent to -n - 1.

dan04
For the purpose of shift and mask operations two's complement representation for negative number are always assumed in Python http://docs.python.org/reference/datamodel.html
J.F. Sebastian
+3  A: 

Just to belabor the point: the '~' is called a tilde.

ray023
I'd +1 you if I wasn't giving you free rep.
Wallacoloo
free rep?!? my comment now makes this topic search-able.try: [python] tilde then try: [python] ~ Compare the results.IMHO, it's well earned rep.But go ahead and tickle my butt with a feather.Don't like that mental image? Let me help: my butt is more hairy than a Trekkie's palms. Just for reference: http://www.urbandictionary.com/define.php?term=hairy%20palms
ray023
+8  A: 

And to bring up one thing none of the other answers mentioned: the behavior of ~ for user-defined classes can be changed by overriding the __invert__ method (or the nb_invert slot if you're using the Python/C API).

Craig Citro
+4  A: 

In this particular context, just replace '~' with 'not'.

PS. ok i guess i will have to explain - started getting slapped with -1's, probably on the premise i don't know the difference between logical and bitwise negation.

The thing is, the code in the question is broken. There is a bug in it. If you check how Brainfuck should work, it loops within [ ] braces while the current memory cell is !=0 (this is checked as pre-condition when entering [ and as optimization before returning from ]).

But instead of arguing, perhaps is easier to show with examples of the code not working. Let's take the simple program '[+]'. Trying to tun this should just exit (because current cell is 0, it won even enter the loop). Instead if you run it in this interpreter, it goes into infinite loop.

So i'll kindly ask you to revert your -1 votes if my clarification makes sense now ;-)

Here is the interpreter slightly beautified, with fixed ~ bug and i also added the missing , input:

from sys import stdin, stdout

bfHelloWorld = '++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.'

# http://esoteric.sange.fi/brainfuck/bf-source/prog/yapi.b
bfPiDigits = '''>  +++++ (5 digits)
[<+>>>>>>>>++++++++++<<<<<<<-]>+++++[<+++++++++>-]+>>>>>>+[<<+++[>>[-<]<[>]<-]>>
[>+>]<[<]>]>[[->>>>+<<<<]>>>+++>-]<[<<<<]<<<<<<<<+[->>>>>>>>>>>>[<+[->>>>+<<<<]>
>>>>]<<<<[>>>>>[<<<<+>>>>-]<<<<<-[<<++++++++++>>-]>>>[<<[<+<<+>>>-]<[>+<-]<++<<+
>>>>>>-]<<[-]<<-<[->>+<-[>>>]>[[<+>-]>+>>]<<<<<]>[-]>+<<<-[>>+<<-]<]<<<<+>>>>>>>
>[-]>[<<<+>>>-]<<++++++++++<[->>+<-[>>>]>[[<+>-]>+>>]<<<<<]>[-]>+>[<<+<+>>>-]<<<
<+<+>>[-[-[-[-[-[-[-[-[-<->[-<+<->>]]]]]]]]]]<[+++++[<<<++++++++<++++++++>>>>-]<
<<<+<->>>>[>+<<<+++++++++<->>>-]<<<<<[>>+<<-]+<[->-<]>[>>.<<<<[+.[-]]>>-]>[>>.<<
-]>[-]>[-]>>>[>>[<<<<<<<<+>>>>>>>>-]<<-]]>>[-]<<<[-]<<<<<<<<]++++++++++.
'''

code = bfPiDigits   # the code
data = [0] * 255    # data memory
cp = 0              # code pointer
dp = 0              # data pointer

while cp < len(code):
    cmd = code[cp]
    if   cmd == '>': dp += 1
    elif cmd == '<': dp -= 1
    elif cmd == '+': data[dp] += 1 
    elif cmd == '-': data[dp] -= 1 
    elif cmd == '.': stdout.write(chr(data[dp]))
    elif cmd == ',': data[dp] = ord(stdin.read(1))
    elif cmd == '[' and not data[dp]: # skip loop if ==0
        n = 0
        while True:
            cmd = code[cp]
            if   cmd == '[': n += 1
            elif cmd == ']': n -= 1
            if not n: break
            cp += 1
    elif cmd == ']' and data[dp]:  # loop back if !=0
        n = 0
        while True:
            cmd = code[cp]
            if   cmd == '[': n+=1
            elif cmd == ']': n-=1
            if not n: break
            cp -= 1
    cp += 1
Nas Banov
if ~x will execute for every value except -1
mikerobi
@mikerobi: see my answer - i added explanation and code
Nas Banov