LINUX.ORG.RU

Зачем?
Но как насчет того, чтоб сдвинуть на бит влево? Если был вытолкнут нуль, то число в два раза увеличится.

metar ★★★
()

так, забыл дать важное условие - используя _только_ побитовые операции.

jcd ★★★★★
() автор топика
Ответ на: комментарий от metar

>Но как насчет того, чтоб сдвинуть на бит влево? Если был вытолкнут нуль, то число в два раза увеличится.

ха, точно! годно, здорово, принимается. :) а можно ещё круче?

jcd ★★★★★
() автор топика

>sizeof(number)*8

Не на всех платформах покатит. Есть такие, где sizeof(char) == sizeof(short). А есть такие, где sizeof(char) == sizeof(int). В смысле, что домнажать нужно не на 8 уже, а на 16 или 32.

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

Ну можно использовать сложение, умножение, и вообще стандартные ассемблерные процедуры

jcd ★★★★★
() автор топика
Ответ на: комментарий от jcd

>стандартные ассемблерные процедуры

В ассемблере размер не может быть неизвестен :D И тогда достаточно просто сдвига с переносом влево и проверка переноса.

...

В общем, задача какая-то невнятная. Ограничения слишком искусственными выглядят.

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

>В ассемблере размер не может быть неизвестен

Я не про неизвестность размера, а про то, что мы не оперируем им в работе как значением. Т.е. какой бы регистр или ячейку памяти нам бы ни дали - мы должны ассемблерными операциями проверить её старший бит. Выгядит притянутым за уши (собственно так оно и есть), но всё же интересен результат :) metar вполне годное решение предложил

jcd ★★★★★
() автор топика

Если без сравнений, то:

if(((unsigned) n) - n) один; else ноль;

if(((unsigned) n) ^ n) один; else ноль;

if(((unsigned) n) & n) один; else ноль;

KRoN73 ★★★★★
()
Ответ на: комментарий от jcd

>какой бы регистр или ячейку памяти нам бы ни дали - мы должны ассемблерными операциями проверить её старший бит

Ассемблерные операции работают всегда с конкретным регистром конкретной разрядности. Так что старший бит всегда можно проверить по
mov eax, $test
asl eax

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

>Ассемблерные операции работают всегда с конкретным регистром конкретной разрядности

Я не про конкретные регистры, а про общий алгоритм действий, шаблон так сказать. Чтобы в вашем примере можно было заменить eax на ax или al, или вообще на rx для amd64.

jcd ★★★★★
() автор топика
Ответ на: комментарий от gavv

а если little, то надо все же знать, где искать старший. или условие только в том, чтобы не использовать слово sizeof?

gavv
()
Ответ на: комментарий от gavv

>условие только в том, чтобы не использовать слово sizeof

нет, можно использовать только «ассемблерные» процедуры. ну и главный критерий - красота и лаконичность решения.

jcd ★★★★★
() автор топика
Ответ на: комментарий от jcd

>Чтобы в вашем примере можно было заменить eax на ax или al, или вообще на rx для amd64.

Тогда просто:
test al, al
; test ax, ax
; test eax, eax
; test rx, rx
js non_zero
zero:
...
jmp next
non_zero:
...
next:
...

Вместо первой пары можно также:

add al, al
jc non_zero

или

sal al,1
jc non_zero

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

> if(((unsigned) n) - n) один; else ноль;

if(((unsigned) n) ^ n) один; else ноль;

if(((unsigned) n) & n) один; else ноль;



Хм. Либо это такие сложные способы выдать «один», либо мой мысленный транслятор барахлит. :)

metar ★★★
()
Ответ на: комментарий от KRoN73

да, всё верно, но я хотел средствами более высокоуровневого ЯП, надо было сразу поставить слово «ассемблерный» в кавычки. В общем я просто хотел красивого решения этой задачи без сравнений с нулём и оперирования размерностью типа, желательно с побитовыми операциями. Извиняюсь за нечёткий критерий, писал в спешке.

jcd ★★★★★
() автор топика

#define highbit(i) ({ int o; asm («rol %0» : «=r»(o) : «r»(i)); o & 1; })

gavv
()
Ответ на: комментарий от GArik

класс!! то, что и было нужно!!

jcd ★★★★★
() автор топика
Ответ на: комментарий от gavv

> только (unsigned)x

так потеряется вся суть. просто двинем число влево-вправо и всегда будем получать 0.

jcd ★★★★★
() автор топика
Ответ на: комментарий от gavv

>он же сдвигается с сохранением знака

да, точно... забыл

jcd ★★★★★
() автор топика
Ответ на: +/- от anonymous

для MMIX нет :)

gavv
()
Ответ на: комментарий от GArik

>int first_bit = x<<1>>1 == x?0:1;

Не сработает на знаковом x с установленным вторым битом.

linuxfan
()

Память страничная, поэтому можно прочитать байт и не получить segfault.
*((char *)(&number)) >> 7

ttnl ★★★★★
()
Ответ на: +/- от anonymous

Почти нигде, но обычно является хорошим признаком.

shoewreck
()
Ответ на: комментарий от KRoN73

>>sizeof(number)*8

Не на всех платформах покатит. Есть такие, где sizeof(char) == sizeof(short).

эээ. sizeof вроде выдает размер в байтах, а не в условных единицах = sizeof(char)
другое дело - машины, где байт был равен 4 битам, но они были ритуально уничтожены, а все свидетели убиты, дабы не наводить смуты в подростающее поколение))

xydo ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.