Итак, я работаю над проектом nand2tetris, и я хочу реализовать логический сдвиг справа на уровне программного обеспечения, поскольку аппаратное обеспечение не поддерживает его. Я знаю, что сдвиг вправо логический - это деление на два. Таким образом, мой первый выстрел при его реализации подсчитал бы количество раз, когда я смог вычесть 2 из начального значения до того, как значение станет 0 или отрицательным. Аналогично, если число было отрицательным. Но, я нашел сценарий, где он не работает. Я хочу перейти вправо -27139. Ну, двоичное значение после переключения - 19199. Это должно быть 19198. Таким образом, я ищу новый способ реализовать сдвиг. Я могу и ценности, или значения, добавлять и вычитать, и это все, что у меня есть в моем распоряжении.Реализация логического сдвига вправо
Спасибо за помощь.
OSFTW
Вот код, у меня есть на ассемблере данной реализации Hack по:
//============================================================
// SLR: Shift Logical Right (by 1)
//============================================================
(SLR)
@SLR.1 // Load value
D=M
@SLR.2
M=0 // Clear variables
@SLR_POSITIVE_LOOP // If value is positive, go to the positive loop
D;JGT
(SLR_NEGATIVE_LOOP)
@SLR.1 // Add 2 to value, since it's negative
M=M+1
M=M+1
@SLR.1 // If initial value was negative and current value is positive or zero, jump out of loop
D=M
@SLR_NEG
D; JGE
@SLR.2 // If value is negative, add 1 to SLR.2 (we're dividing)
M=M+1
@SLR.1 // If value is less than 0, restart the loop
D=M
@SLR_NEGATIVE_LOOP
D; JLT
(SLR_NEG)
@SLR.2
D=M
D=!D // Invert the result
D=D+1 // Add 1 to finish converting
@32767 // And it with 0111111111111111 to clear the sign bit
D=D&A
@SLR.2
M=D // Set value
@SLR_END // Jump to end of loop
0;JMP
(SLR_POSITIVE_LOOP)
@SLR.1 // Subtract 2 from value
M=M-1
M=M-1
@SLR.1 // If initial value was positive and current value is negative or zero, jump out of loop
D=M
@SLR_END
D; JLE
@SLR.2 // If value is still positive, add 1 to SLR.2 (we're dividing)
M=M+1
@SLR.1 // If value is greater than 0, restart the loop
D=M
@SLR_POSITIVE_LOOP
D; JGT
(SLR_END) // Loop is over. Set value of SLR.1 to that of SLR.2, for return purposes
@SLR.2 // Place result in correct place
D=M
@SLR.1
M=D
@SLR.0 // Return to calling function
A = M
0; JMP
Если вы вычитаете нечетное число на 2, то оно всегда будет нечетным, поэтому результат.Кроме того, многократное вычитание не является хорошим решением, поскольку оно вызовет цикл цикла в тысячу раз. –
Неоднократно вычитание числа с номером на 2 похоже на арифметический сдвиг, поскольку бит знака всегда копирует результат (-27139 - 2 = -27137), который округляется к -Inf. Вот почему вы видите результат. Чтобы сдвинуть нуль, сделайте беззнаковое вычитание ((без знака) -27139 - 2 = 38397 - 2 = 38395) –
сдвиньте вправо, затем восстановите мсбит, чтобы он соответствовал значению msbit. гораздо меньше работают намного быстрее. если это неподписанное число, тогда вам не нужно это делать вообще, просто сдвиньте правое и это будет разделение на 2. –