"0 << 1 + 1"到底是等于 0 还是 1? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
MiketsuSmasher
V2EX    程序员

"0 << 1 + 1"到底是等于 0 还是 1?

  •  
  •   MiketsuSmasher 2022-01-06 08:23:16 +08:00 4955 次点击
    这是一个创建于 1382 天前的主题,其中的信息可能已经有所发展或是发生改变。

    昨天碰上这个问题,着实把我坑惨了,花了一个晚上搞明白,python 和 golang 按位移动运算符的优先级居然不一样

    python:

    print(0 << 1 + 1) 

    输出:0

    golang:

    import "fmt" func main() { fmt.Println(0 << 1 + 1) } 

    输出:1

    第 1 条附言    2022-01-06 09:00:59 +08:00

    为了让python和golang的行为一致,我只好为表达式里的"0 << 1"加了括号

    37 条回复    2022-01-08 10:13:03 +08:00
    loading
        1
    loading  
       2022-01-06 08:25:19 +08:00
    感谢提醒,但像我这种菜鸟都是一堆括号的,如果有人说括号看晕,他是连工具都不会用的比我更菜的鸟。
    Aruforce
        2
    Aruforce  
       2022-01-06 08:29:01 +08:00 via Android
    感觉 0 好理解一点儿…
    Rocketer
        3
    Rocketer  
       2022-01-06 08:32:34 +08:00 via iPhone
    凡是有歧义的一律加括号
    hiwind
        4
    hiwind  
       2022-01-06 09:07:43 +08:00
    不加括号的话 Java 的计算结果也是 0
    cccer
        5
    cccer  
       2022-01-06 09:08:51 +08:00
    不同类型的操作符混合肯定是要加括号,就算自己能肯定顺序别人也不一定明白。
    iold
        6
    iold  
       2022-01-06 09:14:48 +08:00
    2i2Re2PLMaDnghL
        7
    2i2Re2PLMaDnghL  
       2022-01-06 09:21:35 +08:00
    Pascal 里面 and 和 or 优先级比数学运算还高(因为同时被视为位运算符
    判断条件就一直一堆括号,习惯了除了日常习惯的(基本就是四则运算)或者倒错就会立刻严重出错(比如 4/2-2 ,或者矩阵运算)的或者符合结合律的运算以外都加括号。
    nekoneko
        8
    nekoneko  
       2022-01-06 09:22:14 +08:00   1
    因为只有 go 的操作符优先级是 移位优先于加减 的
    其他 java python c 都是 加减优先于移位
    iovekkk
        9
    iovekkk  
       2022-01-06 09:24:40 +08:00
    头像不错
    www5070504
        10
    www5070504  
       2022-01-06 09:37:31 +08:00
    我猜一会就有人跳出来说基本功 balabala 的
    Leonard
        11
    Leonard  
       2022-01-06 09:44:31 +08:00
    不用在意这种事,加括号解决完事,大家看着都清晰方便。
    这种一般只有某些考试里会考,真使用时用不上这些知识。
    ychost
        12
    ychost  
       2022-01-06 10:07:55 +08:00
    工作这么多年除了之前写嵌入式用到了位移,现在写 WEB 基本没用过
    rillhu
        13
    rillhu  
       2022-01-06 10:16:00 +08:00
    看具体的语言吧,本人只熟悉 C ,C 里面`+` > `<<`,所以结果上述结果是 0 。
    ipwx
        14
    ipwx  
       2022-01-06 10:23:48 +08:00
    一般除了加减乘除这种运算,一律加括号
    msg7086
        15
    msg7086  
       2022-01-06 10:31:08 +08:00 via Android
    位移运算必加括号,血(不是)的教训。
    mainjzb
        16
    mainjzb  
       2022-01-06 10:31:17 +08:00
    fmt.Println(0<<1 + 1)
    go 会按优先级自动格式化,建议其他语言学习
    yazinnnn
        17
    yazinnnn  
       2022-01-06 10:35:30 +08:00
    我看谁还嘲笑 lisp 括号罗嗦
    socketpeng
        18
    socketpeng  
       2022-01-06 10:39:54 +08:00
    加个括号很难么?别人不知道,要是我在实际生产环境中发现这种代码,直接开骂
    BeyondBouds
        19
    BeyondBouds  
       2022-01-06 10:50:16 +08:00
    i+++++i-----的变种? 这种不直接打残?
    48y1951r9G8k7Zou
        20
    48y1951r9G8k7Zou  
       2022-01-06 11:08:35 +08:00 via iPhone
    即使很熟悉运算符优先级,在书写可能有歧义的数学表达式时也尽可能加上括号
    littlewing
        21
    littlewing  
       2022-01-06 11:48:31 +08:00
    没必要纠结这种东西,啥,你说面试有人问?我反手就给他一巴掌
    yangyaofei
        22
    yangyaofei  
       2022-01-06 11:55:28 +08:00
    这种的意义是啥, 就像 ++i+++=++i++, 没有任何意义
    cmdOptionKana
        23
    cmdOptionKana  
       2022-01-06 11:59:58 +08:00
    @yazinnnn “嘲笑 lisp 括号罗嗦”本来就是菜鸟行为
    yazinnnn
        24
    yazinnnn  
       2022-01-06 12:02:14 +08:00
    @cmdOptionKana 本站就不少。
    mikewang
        25
    mikewang  
       2022-01-06 12:03:20 +08:00
    涉及到位运算的,还是都加上括号吧。位运算本身就不是非常优美,多加点括号嗦一下也没什么事。
    ch2
        26
    ch2  
       2022-01-06 12:10:17 +08:00
    不同语言运算符优先级不一样,位运算在 C 系里优先级很低的
    acmore
        27
    acmore  
       2022-01-06 13:01:35 +08:00
    遇事不决加括号,编程不仰赖记忆力
    AoEiuV020CN
        28
    AoEiuV020CN  
       2022-01-06 13:12:04 +08:00
    先乘除后加减,其他尽量都上括号,
    crayygy
        29
    crayygy  
       2022-01-06 14:41:35 +08:00
    都说加括号,我不太一样,我宁可多用一个变量然后分两步写,位运算尽量分开,方便 debug
    icenine
        30
    icenine  
       2022-01-06 15:17:49 +08:00
    直接上括号,但凡你会一种以上的语言,深究这种语法细节有啥意义
    cht
        31
    cht  
       2022-01-06 15:46:16 +08:00
    muzuiget
        32
    muzuiget  
       2022-01-06 15:46:45 +08:00
    我不想,我直接加括号。
    gengchun
        33
    gengchun  
       2022-01-06 15:55:19 +08:00
    @crayygy 这个看具体的代码类型。

    如果是表示的是具体的业务,特别是现实中的商务订单处理这类,当然应该尽量分开。

    如果是对一张照片里的每个图素都进行一次变换操作,这么写代价就太大了。
    abersheeran
        34
    abersheeran  
       2022-01-06 23:32:08 +08:00
    我从来不考虑这个。像 Index.py 的路由,我至今记不清优先级,于是我都是

    app.router << ("/client" // client_routes) << ("/auth" // auth_routes)

    另外,考这个的多少有点魔怔了
    xuanbg
        35
    xuanbg  
       2022-01-07 07:10:25 +08:00
    不同语言的操作符优先级有可能不一致。反正加括号最保险,也更容易阅读。
    sprite82
        36
    sprite82  
       2022-01-07 17:47:59 +08:00
    楼主说的是 不同语言 运算符优先顺序不一样的问题,结果一堆“加括号”的评论,这不是废话吗?这是常识,就像乘号优先于加号一样。不应该讨论下为什么位运算符优先级不同语言不一样?
    seanzxx
        37
    seanzxx  
       2022-01-08 10:13:03 +08:00
    常用的语言测试了一圈
    0: Rust, Python, C, Java, Lua, Ruby, JS, PHP, Dart, C#
    1: Go, Swift

    一种常用的性能优化措施是把乘除法替换成位移
    比如
    buffer_size = 2 + int32_size * 4 替换成
    buffer_size = 2 + int32_size << 2
    如果是 Go 和 Swift ,那类似替换优雅又简洁;如果是其它语言,替换以后要加括号,还容易出 bug
    个人猜测
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2734 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 12:53 PVG 20:53 LAX 05:53 JFK 08:53
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86