Python中的'~'是什么意思?

14 投票
4 回答
6966 浏览
提问于 2025-04-15 23:52

在Python中,'~'这个符号是什么意思呢?

我之前找到一个用Python写的BF解释器。

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

我想知道这个符号的作用,因为我想在我的TI-84计算器上做一个(还有一个PF的)。

BF是Brainfuck,而PF是类似的东西。

4 个回答

10

还有一点其他回答没有提到,就是对于用户自定义的类,~这个符号的行为是可以改变的。你可以通过重写__invert__这个方法来实现(如果你在使用Python/C API的话,可以用nb_invert这个槽)。

22

位运算中的“按位取反”,跟C语言里的用法一样。

在二进制补码表示法中,~n的意思等同于-n - 1

14

在这个特定的情况下,只需把'~'替换成'not'。

顺便说一下,我想我得解释一下 - 开始收到-1的评价,可能是因为大家觉得我不懂逻辑取反和位运算取反的区别。

问题是,提问中的代码是有问题的。里面有个bug。如果你检查一下Brainfuck的工作原理,它会在[ ]括号内循环,前提是当前的内存单元不等于0(在进入[时会检查这个条件,并在返回]之前进行优化)。

但是与其争论,不如用代码不工作的例子来说明。我们来看一个简单的程序'[+]'。尝试运行这个程序应该直接退出(因为当前单元是0,它根本不会进入循环)。然而,如果你在这个解释器中运行它,它会进入无限循环。

所以我恳请你们,如果我刚才的解释让你明白了,就把你们的-1评价撤回吧;-)

这里是稍微美化过的解释器,修复了~的bug,并且我还添加了缺失的,输入:

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

撰写回答