首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >什么是std::__lg?

什么是std::__lg?
EN

Stack Overflow用户
提问于 2016-11-05 12:09:54
回答 2查看 4.9K关注 0票数 5

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

EN

回答 2

Stack Overflow用户

发布于 2016-11-05 12:16:16

它的帮助是计算整数的以2为底的对数,即它返回数字中最高设置位的索引(或-1表示0)。

例如,对于1,它将返回0;对于16,它将返回4;对于1024,它将返回10,依此类推。

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

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

POSIX提供了类似的函数- ffs(),还有GNU扩展的ffsl和ffsll (见同一页),分别与long和long long一起工作。

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

票数 7
EN

Stack Overflow用户

发布于 2016-11-05 17:06:49

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

在您自己的代码中,不应该看到或使用像__lg这样的东西。使用标准库的接口,而不是它的实现。如果您自己的代码直接使用__lg,那么您不能保证代码可以使用任何其他编译器,甚至使用相同编译器的任何其他版本来编译或执行正确的操作。

正如§2.10 [lex.name]中所述的C++标准

包含双下划线 __或以下划线后跟大写字母开头的每个标识符都保留给实现以供任何使用。

至于那个GCC到底是什么,只要看看谷歌搜索"std::__lg“后出现的source code就知道了。

根据block_szpos_l的实际类型,它应该是以下两种之一:

/这是排序例程和random.tcc的帮助器函数。//前提条件:__n > 0。template 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 documentation所说:

定义为在字符数据类型表示中使用的位数的

。它的存在是为了使给定数字限制的标准标题正确工作。不应直接使用此宏;相反,应包括适当的标头。

__builtin_clz是另一个特定于GCC的函数。GCC documentation再次解释了它的用途:

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

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

要牢记的事情:

  • 不要在自己的代码中使用任何带有两个连续下划线的内容。
  • GCC是开源的,因此特殊函数或宏的内部实现不是秘密,但可以很容易地在线浏览。
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40434664

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档