【问题标题】:logical right shift in numbanumba 中的逻辑右移
【发布时间】:2016-07-20 16:53:38
【问题描述】:

以下代码

@jit(uint32(uint32))
def foo(x): 
    return (x >> 6)

print(hex(foo(0xffffffff)))

输出

0xffffffff

因为 numba 使用算术右移,尽管操作数被定义为无符号。

有什么方法可以传达它以使用逻辑移位?

实际上,从下面 JoshAdel 的回答中,我学到了一种解决方法 - 使用内部 64 位变量,其逻辑和算术移位不会有所不同。像这样:

@jit(uint32(uint32), locals = {'t': uint64})
def foo1(x):
    t = x 
    return t << 8

@jit(uint32(uint32), locals = {'t': uint64})
def foo2(x):
    t = x 
    return t >> 8

print(hex(foo1(0xffffffff)))
print(hex(foo2(0xffffffff)))

打印出来的

0xffffff00
0xffffff

但一个体面的编译器应该明白,&gt;&gt; 应用于 unsigned 数字会导致逻辑移位。

【问题讨论】:

  • 如果 JoshAdel 的回答没有让您找到解决方案,您可以尝试 x / (1 &lt;&lt; 6) 并查看抖动是否将其优化为逻辑右移。
  • 试过了。该部门仍在议会中。太糟糕了。
  • 你能将(1 &lt;&lt; 6) 强制转换为无符号类型(这样除法的两边都是无符号的)并检查生成的程序集吗?我建议如果它看到uint / uint,它有可能会优化它,而不是uint / int

标签: bit-shift unsigned-integer numba


【解决方案1】:

我从使用 Numba 0.27 的纯 python 和 numba jitted 版本中得到了相同的答案:

import numba as nb

def foo(x): 
    return (x >> 6)

foo_nb = nb.jit()(foo)

print(hex(foo(0xffffffff)))
print(hex(foo_nb(0xffffffff)))

结果:

0x3ffffff
0x3ffffff

以下也产生相同的结果(以确保我们不会退回到对象模式并实际使用完整的 jit):

foo_nb2 = nb.jit('uint(uint)', nopython=True)(foo)
print(hex(foo_nb2(0xffffffff)))

# prints 0x3ffffff

您使用的是哪个版本的 Numba?

【讨论】:

  • foo_nb.inspect_types() 表明实际上 numba 使用int64 和算术移位。这并不能解决问题,只是隐藏起来,直到左移压入一个数字,使64位数字的MS位变为1。然后会给出意想不到的结果。
  • 嗯...查看foo_nb2.inspect_types(),它似乎使用unint64 作为输入类型,切换到int64,然后在最后转换回uint64。如果您认为代码翻译不正确,我会在 Numba 问题跟踪器上提出问题。他们通常反应灵敏。
  • 会不会是回归到Bitwise shift operator bugs #191
猜你喜欢
  • 2017-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-12
  • 1970-01-01
相关资源
最近更新 更多