V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MiketsuSmasher
V2EX  ›  程序员

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

  •  
  •   MiketsuSmasher ·
    nukemiko · 181 天前 · 3873 次点击
    这是一个创建于 181 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    python:

    print(0 << 1 + 1)
    

    输出:0

    golang:

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

    输出:1

    第 1 条附言  ·  181 天前

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

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

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

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

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

    😓另外,考这个的多少有点魔怔了
    xuanbg
        35
    xuanbg  
       180 天前
    不同语言的操作符优先级有可能不一致。反正加括号最保险,也更容易阅读。
    sprite82
        36
    sprite82  
       179 天前
    楼主说的是 不同语言 运算符优先顺序不一样的问题,结果一堆“加括号”的评论,这不是废话吗?这是常识,就像乘号优先于加号一样。不应该讨论下为什么位运算符优先级不同语言不一样?
    seanzxx
        37
    seanzxx  
       179 天前
    常用的语言测试了一圈
    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   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   4082 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 07:27 · PVG 15:27 · LAX 00:27 · JFK 03:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.