我有一个数字,它是 2 的幂。(例如:2^k)我想在不使用循环、除法或任何类型的函数的情况下获得 k 的值?位操作,加,减,条件都可以使用。如果您有任何算法或代码,请提供一些帮助。
问问题
265 次
2 回答
2
我有一个数字,它是 2 的幂。(例如:2^k)我想在不使用循环的情况下获得 k 的值
一些 MIPS CPU 具有CLZ
计算前导零数量的指令。如果您反转该指令的结果,您将获得第一个设置位的索引。
如果您没有CLZ
指令,您可以通过以下方式实现相同的目标。可能有更紧凑的实现,但这至少是用于查找整数的 log2 的无分支实现(它是this的变体):
# The number to find log2 of
li $t0,512
li $t1,0
li $t2,0xFFFF0000
and $t3,$t2,$t0
sltu $t4,$zero,$t3 # if (($t0 & 0xFFFF0000) == 0) {
xori $t4,$t4,1
sll $t4,$t4,4
addu $t1,$t1,$t4 # $t1 += 16
sllv $t0,$t0,$t4 # $t0 <<= 16 }
sll $t2,$t2,8 # $t2 = 0xFF000000
and $t3,$t2,$t0
sltu $t4,$zero,$t3 # if (($t0 & 0xFF000000) == 0) {
xori $t4,$t4,1
sll $t4,$t4,3
addu $t1,$t1,$t4
sllv $t0,$t0,$t4
sll $t2,$t2,4
and $t3,$t2,$t0
sltu $t4,$zero,$t3 # if (($t0 & 0xF0000000) == 0) {
xori $t4,$t4,1
sll $t4,$t4,2
addu $t1,$t1,$t4
sllv $t0,$t0,$t4
sll $t2,$t2,2
and $t3,$t2,$t0
sltu $t4,$zero,$t3 # if (($t0 & 0xC0000000) == 0) {
xori $t4,$t4,1
sll $t4,$t4,1
addu $t1,$t1,$t4
sllv $t0,$t0,$t4
sll $t2,$t2,1
and $t3,$t2,$t0
sltu $t4,$zero,$t3 # if (($t0 & 0x80000000) == 0) {
xori $t4,$t4,1
addu $t1,$t1,$t4
xori $t0,$t1,31 # $t1 holds the number of leading zeroes; invert to get the highest set bit
# The output is in $t0
于 2013-10-11T11:34:45.567 回答
1
如果我可以问,为什么不允许使用循环?这是一个课堂项目,你被告知以特定的方式去做吗?如果没有,循环会更容易编码和更容易理解:
.text
# The number to find log2 of
li $t0,512
add $t1, $zero, $zero # init counter with 2^0
addi $t2, $zero, 1 # init mask
loop:
and $t3, $t0, $t2 # mask all but current bit
bne $t3, $zero, done
# Current bit of $t1 is zero. Look at the next one to the left.
sll $t2, $t2, 1 # shift mask
addi $t1, $t1, 1 # bump counter
j loop
done:
# $t1 contains power of 2 (original number = 2^$t1)
注意事项:此代码不检查它是否真的是 2 的幂,它是 0 的无限循环!这些验证留给学生作为练习。:)
于 2013-10-16T18:56:42.857 回答