我需要得到一个32位数字中的1位数字,其中只有一个1位(总是)。在C++或ASM中最快的方法。
例如
input: 0x00000001, 0x10000000
output: 0, 28
#ifdef__gnuc__
,使用__builtin_ctz(无符号)
计数尾随零(GCC手册)。GCC、clang和ICC都支持它的所有目标ISAS。(在没有本机指令的ISAs上,它将调用一个GCC帮助器函数。)
前导与后导是按照打印顺序写入时,MSB优先,就像8位二进制00000010
一样,有6个前导零和1个后导零。(当转换为32位二进制时,将有24+6=30个前导零。)
对于64位整数,请使用__builtin_ctzll(无符号long long)
。不幸的是,GNU C bitscan builtins不采用固定宽度类型(尤其是前导零版本),但是unsigned
在GNU C for x86上始终是32位的(尽管不是用于AVR或MSP430)。无符号long long
总是uint64_t
在我所知道的所有GNU C目标上。
对于未设置位的输入,builtin具有未定义的行为,如果它可能以bsf
运行,则可以避免任何额外的检查。
在其他编译器中(特别是MSVC),您可能需要TZCNT的intrinsic,比如_mm_tzcnt_32
fromimmintrin.h
。(英特尔内部指南)。或者,您可能需要包含intrin.h
(MSVC)或x86intrin.h
来表示非SIMD的intrinsics。
与gcc/clang不同,MSVC并不阻止您对编译器自己没有启用的ISA扩展使用intrinsics。
MSVC对于实际的BSF/BSR也有_bitscanforward
/_bitscanreverse
,但是AMD保证的(以及Intel也实现的)离开目的地未修改的行为仍然没有被这些固有特性公开,尽管它们有指针输出API。
TZCNT在没有BMI1的CPU上解码为BSF,因为它的机器码编码是rep BSF
。对于非零输入,它们会给出相同的结果,所以编译器可以并且总是使用tzcnt
,因为这在AMD上要快得多。(它们在Intel上是相同的速度,所以没有缺点。在Skylake和以后的版本中,tzcnt没有错误的输出依赖关系。BSF有,因为它在输入=0时没有修改输出)。
(对于bsr
和lzcnt
,这种情况不太方便:bsr返回位索引,lzcnt返回前导零计数。因此,为了在AMD上获得最佳性能,您需要知道您的代码只能在支持BMI1/TBM的CPU上运行,以便编译器可以使用lzcnt
)
请注意,如果设置了1位,从两个方向扫描都会发现相同的位。因此31-lzcnt=bsr
在本例中与bsf=tzcnt
相同。如果移植到另一个只有前导零计数而没有位反向指令的ISA可能会有用。
相关的:
问题内容: 下面是我的表 当我执行 我的位置是1。 我要实现的是找到整数的第一个位置,这样我将获得以下输出。 任何想法我怎么能做到这一点? 问题答案: 在xdazz答案的帮助下,我做了一些更改,最后得到了答案… 演示版
下面代码中编写的方法需要取整数以及整数中第一位和最后一位的结果和。 注意:虽然我知道正确的解决方案,但我问这个问题的原因是我需要了解为什么我的代码不起作用,因为这使我成为一名更好的程序员,请帮助。 在上面的代码中,如果我在if块之后保持number/=10,如下所示 然后我的代码给出了正确的结果。例如,如果我在方法中输入121,因为第一个数字是1,第二个数字是1,那么它将两者相加,并给出结果2。这
我想取904并做9+0,但904是一个int变量。我确实尝试了下面的代码,但是如果用户更改了数字I,它并不总是有效的。
本文向大家介绍php查找字符串中第一个非0的位置截取,包括了php查找字符串中第一个非0的位置截取的使用技巧和注意事项,需要的朋友参考一下 话不多说,请看代码: 以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持呐喊教程!
我有一个向量,想找到第一个大于100的值的位置。
问题内容: 我找到了几个node.js模块,用于使用ip地址查找有关客户端位置和网络的信息。 要求: 位置-国家,城市,州,纬度,经度等 网络-Internet服务提供商,Internet连接类型和Internet速度等。 数据准确性-最大可能性。 注意: 寻找服务器端解决方案。 上面提到的模块使用maxmind数据。而且我还阅读了有关maxmind数据准确性的信息。 我很少选择上面的node.j