识别两个整数的幂

时间:2013-10-11 10:42:19

标签: assembly mips

我有一个数字,它是2的幂。(例如:2 ^ k) 我想获得k的值而不使用循环,除法或任何类型的函数? 可以使用位操作,加,减,条件。 如果您有任何算法或代码,请帮忙。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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的无限循环!这些验证留给学生练习。 :)