2015-02-18 2 views
2

Напишите программу MIPS, которая проверяет, является ли число двух. Установите регистр $ t0 на некоторое значение в SPIM и используйте его для проверки мощности двух. Программа будет генерировать выходные данные в консоли.Напишите программу MIPS, которая проверяет, является ли число числом двух

35 не является силой двух.

256 - это сила двух.

До сих пор, у меня есть этот

.data 

    spc1: .asciiz " " 
    nl:  .asciiz "\n" 
    tb:  .asciiz "\t" 
    msg1: .asciiz "is not a power of two." 
    msg2: .asciiz "is a power of two." 

    .text # "text section" code and read-only data 

    .globl main # declare `main' as a global symbol 

    main: #sra $t1, $t0, 1 
    li $t1, 1 
    loop: beq $t0, $t1, end 
    sra $t0, $t0, 1 
    j loop 
    end: la $a0, msg2 
    li $v0, 4 
    syscall 
    addi $v0, $0, 10 
    syscall 

Я поставил $ t0 в симуляторе, так что работает отлично. Но независимо от того, на каком количестве я его устанавливаю, я получаю «сила двух». Я использую shift left, но это продолжает давать мне неправильный ответ. Как правильно использовать сдвиг для ответа на эту проблему?

+0

'sra' - это правая смена, а не сдвиг влево. – nneonneo

ответ

3

Существует гораздо более простой способ проверить, является ли число степенью 2 . В C псевдокоде:

bool is_power_of_two(unsigned int number) { 
    return (number & (number - 1)) == 0; 
} 

Это работает, потому что сила 2 будет иметь двоичное представление вида 000…010…0, и число на единицу меньше, чем она будет иметь двоичную форму 000…001…1. То есть, мощность 2 имеет ровно один бит, а номер один меньше, чем у каждого бит до того, как он будет установлен. В результате побитовое И между этими числами будет равно нулю, потому что у них нет общих битов. Каждая другая пара последовательных чисел будет совместно использовать некоторые общие биты, поэтому побитовое И между ними не будет равно нулю.

(Обратите внимание, что этот алгоритм будет сказать вам, что 1 является степенью 2. Это правильно: 2 на 0-й мощности 1)

Поскольку это явно присвоение класса, я дам вам переведите это в код MIPS самостоятельно. :)

1

После того, как вы инициализируете $t1, вы должны сделать сдвиг влево на $t1 в каждой итерации цикла. Регистр $t1 будет равен новой мощности по 2 в каждой итерации цикла.

Вы должны выйти из цикла, если $t1 равно $t0. Это тот случай, когда $t0 это сила 2. Если $t1 становится равным 0 после сдвига влево, то $t0 не была сила 2.

Смежные вопросы