What is std::__lg?

What is std::__lg?

本文关键字:lg is What std      更新时间:2023-10-16

作为标题,我不知道谷歌之后std::__lg是什么意思?int n = std::__lg(block_sz - pos_l + 1);

它是计算整数的基于2的对数的助手,即它返回该数字的最高集位的索引(或-1表示0)。

。对于1它将返回0,对于16它将返回4,对于1024它将返回10,等等。

这可以用来有效地预测数组的预分配大小,四舍五入到最接近的2的幂之类的。

注意,与其他任何以__开头的函数一样,它是编译器或库的内部函数,所以你不应该依赖它的存在,这样的代码是不可移植的。std库的其他实现可以提供完整的解决方案和类似的帮助程序的不同名称(如果它们使用类似的东西)。

POSIX提供了类似的功能- ffs(),也有ffsl和ffsll(见同一页),它们是GNU扩展,分别使用long和long long。

对于来自评论的问题-如何在Java中使用它。由于上述原因,首先这不是一个好主意,其次它需要JNI包装器。第三,也是最重要的一点,这其实是没有理由的。Java已经提供了类似的方法Integer.heghestOneBit(),不过请注意,与所描述的std::__lg相比,它返回+1,即0表示0,1表示1,11表示1024,等等。

是编译器内部使用的标识符(很可能是GCC),因为所有带有双下划线的标识符都属于编译器实现。

在您自己的代码中不应该看到或使用像__lg这样的东西。使用标准库的接口,而不是其实现。如果您自己的代码直接使用__lg,那么您无法保证代码将在任何其他编译器中编译或做正确的事情,甚至与相同编译器的任何其他版本。

如c++标准§2.10 [lex.name]所述:

包含双下划线 __或开始的每个标识符的下划线后跟大写字母,保留给任何用途的实现。

至于GCC实际上是什么,只要看看源代码,谷歌搜索"std::__lg"出现。

根据block_szpos_l的实际类型,它应该是:

/// This is a helper function for the sort routines and for random.tcc.
//  Precondition: __n > 0.
template<typename _Size>
  inline _Size
  __lg(_Size __n)
  {
    _Size __k;
    for (__k = 0; __n != 0; __n >>= 1)
  ++__k;
    return __k - 1;
  }

或:

inline int
__lg(int __n)
{ return sizeof(int) * __CHAR_BIT__  - 1 - __builtin_clz(__n); }

现在,__CHAR_BIT__就像标准的CHAR_BIT宏。正如GCC文档所说:

定义为在char的表示中使用的位数数据类型。它的存在是为了使标准头给出数值限制正常工作。你不应该直接使用这个宏;相反,应该包含适当的头文件。

__builtin_clz是另一个gcc特有的函数。同样,GCC文档解释了它的目的:

返回x中前导0位的个数,最多从0位开始有效位位置。如果x为0,则结果未定义。

我认为如果你需要这样的功能,那么自己编写它是微不足道的。事实上,问题是你为什么首先需要它。您实际问题的真正答案可能就在int n = std::__lg(block_sz - pos_l + 1);行周围的代码中。


注意事项:

  • 不要在你自己的代码中使用任何带有两个连续下划线的东西。
  • GCC是开源的,所以特殊函数或宏的内部实现不是秘密的,但可以很容易地在线浏览。