You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何在Numba中使用uint64类型时无法执行按位与(&)操作?

Numba中uint64类型popcount函数的类型错误问题

最小可复现示例(MWE)

import numba as nb

@nb.njit(nb.uint64(nb.uint64))
def popcount(x): 
      b=0
      while(x > 0):
          x &= x - 1   
          b+=1
      return b

print(popcount(43))

运行报错信息

numba.core.errors.TypingError: Failed in nopython mode pipeline (step: nopython frontend)
No implementation of function Function(<built-in function iand>) found for signature:
 
 >>> iand(float64, float64)
 
There are 8 candidate implementations:
  - Of which 4 did not match due to:
  Overload of function 'iand': File: <numerous>: Line N/A.
    With argument(s): '(float64, float64)':
   No match.
  - Of which 2 did not match due to:
  Operator Overload in function 'iand': File: unknown: Line unknown.
    With argument(s): '(float64, float64)':
   No match for registered cases:
    * (bool, bool) -> bool
    * (int64, int64) -> int64
    * (int64, uint64) -> int64
    * (uint64, int64) -> int64
    * (uint64, uint64) -> uint64
  - Of which 2 did not match due to:
  Overload in function 'gen_operator_impl.<locals>._ol_set_operator': File: numba/cpython/setobj.py: Line 1508.
    With argument(s): '(float64, float64)':
   Rejected as the implementation raised a specific error:
     TypingError: All arguments must be Sets, got (float64, float64)
  raised from /home/user/python/mypython3.10/lib/python3.10/site-packages/numba/cpython/setobj.py:108

During: typing of intrinsic-call at /home/user/python/popcount.py (7)

File "popcount.py", line 7:
def popcount(x): 
    <source elided>
      while(x > 0):
          x &= x - 1   
          ^

补充说明

即使显式传入nb.uint64类型参数,仍会触发相同错误:

print(popcount(nb.uint64(43)))

问题原因

核心问题是隐式类型转换:

  • 函数参数x被声明为uint64,但循环条件中的0是Python默认的int64类型。
  • 由于uint64的取值范围(0到18446744073709551615)超出了int64的范围(-9223372036854775808到9223372036854775807),Numba为了执行x > 0的比较,会将x隐式转换为float64类型。
  • 一旦x的类型变为float64,后续的x &= x - 1操作就变成了对浮点数执行按位与操作,而Numba并未实现浮点数的按位与重载,因此触发TypingError。

解决方法

修改循环条件中的常量为uint64类型,避免隐式转换:

import numba as nb

@nb.njit(nb.uint64(nb.uint64))
def popcount(x): 
      b = nb.uint64(0)  # 同时将b初始化为uint64,匹配返回类型
      while(x > nb.uint64(0)):
          x &= x - 1   
          b += nb.uint64(1)
      return b

print(popcount(43))  # 输出:3

或者使用Numba的常量装饰器明确类型:

import numba as nb

@nb.njit(nb.uint64(nb.uint64))
def popcount(x): 
      b = nb.uint64(0)
      zero = nb.const(0, nb.uint64)
      one = nb.const(1, nb.uint64)
      while(x > zero):
          x &= x - one   
          b += one
      return b

内容的提问来源于stack exchange,提问作者Simd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 22:15:00