GCC 的 __builtin_popcountl、__builtin_clz 和 __builtin_ctz是否有 Delphi 等价物?

Is there a Delphi equivalent for GCC's __builtin_popcountl, __builtin_clz, and __builtin_ctz?

提问人:zeus 提问时间:8/23/2023 最后编辑:zeus 更新时间:9/2/2023 访问量:117

问:

我目前正在将一些 C++ 代码翻译成 Delphi,并遇到了以下 GCC 内置函数:

  • __builtin_popcountl(x):计算整数 x 中的设置位数 (1s)。
  • __builtin_clz(x):计算整数 x 中的前导零数。
  • __builtin_ctz(x):计算整数 x 中的尾随零数。

在 Delphi 中是否有等效函数或通用方法来实现相同的功能?

C++ C 德尔福 帕斯卡 FreePascal

评论

0赞 PaulMcKenzie 8/23/2023
请参阅此 popcount。一般的想法是使用汇编语言。
0赞 zeus 8/23/2023
@PaulMcKenzie不幸的是,我不能使用 ASM,因为我需要一个多板型解决方案:(
0赞 Remy Lebeau 8/23/2023
@zeus使用汇编代码并不妨碍您提供多平台支持。这只是意味着您必须为要针对的每个平台使用不同的汇编代码。{$IFDEF}
0赞 Dalija Prasnikar 8/23/2023
@RemyLebeau Delphi 仅支持 Windows 平台上的汇编。
0赞 Botje 8/23/2023
这些函数都可以在普通的 C 或 Delphi 中轻松实现。如果你需要一点速度,可以参考一下 Bit twiddling hacks

答:

1赞 Bodo Hugo Barwich 9/2/2023 #1

虽然你可以做位检查。处理这个问题的更习惯的方法是内置功能,如以下所示:
FreePascal Set 文档
这也将产生更多的可读性和可维护性。
set of <Type>

然后,用法将如下所示:

type
  TFlag = (FLAG_A, FLAG_B, FLAG_C);
  TFlags = set of TFlag;

var
  Flags: TFlags;

// ...

  // check if Flags is empty
  if Flags = [] then
     Flags := [FLAG_A, FLAG_C];

  // check FLAG_A is set in flags variable
  if FLAG_A in Flags then 
    // ...  

评论

0赞 phuclv 11/8/2023
这与 clz、ctz 或 popcount 无关,尽管某些操作可以利用它。这些在许多非应用中非常常见SetSet
0赞 Bodo Hugo Barwich 11/10/2023
是的,这不是 1 对 1 等同于 C 函数,但它是实现相同目标的更惯用的方式。很可能需要重写一些代码才能使用此功能。但可以肯定的是,该应用程序将获得可读性和可维护性,这是 Pascal 的强大功能。