2016-03-30 8 views
0

В C99 спецификации состояний:Арифметический сдвиг вправо знаковой целого

Результат Е1 >> Е2 Е1 правый смещенной позиции битов E2. Если E1 имеет неподписанный тип или если E1 имеет подписанный тип и неотрицательное значение, значение результата является неотъемлемой частью частного E1/2^E2. Если E1 имеет подписанный тип и отрицательное значение, результирующее значение определяется реализацией.

Мне интересно знать, какой именно реализации/Составители не будет рассматривать подписанную E1 >> 31 как гроздь 11111....?

+3

Несколько чей -1 не 1111 .... и много, чей int не 32 бит. – user3528438

+1

Примечание. Не используйте устаревшую версию стандарта. C - C11, а не C99. Сказал, что текст очень ясен. Не полагайтесь на него, если вы хотите, чтобы ваш код переносился. Обратите внимание, что сдвиг также может вызывать неопределенное поведение. См. 6.5.7p3 в стандарте (т. Е. Единственная допустимая версия). – Olaf

+0

Также существует множество 32-битных реализаций с двумя дополнениями, которые игнорируют подпись и производят «1» в качестве результата. Стандарт на самом деле тщательно сформулирован, чтобы избежать указания того, выполняет ли '>>' арифметический сдвиг или логический сдвиг. –

ответ

2

Большинство встроенных компиляторов для микроконтроллеров, как правило, предпочитают логический сдвиг (сдвиг в нулях) вместо арифметического сдвига (сдвиг знака).

Это, вероятно, связано с тем, что в встроенных системах цифры со знаком несколько редки, поскольку такое программирование намного ближе к оборудованию и дальше от пользователей, чем, например, настольное программирование с экранами.

Подписанные номера - это не что иное, как презентация пользователя. Если вам не нужно печатать номера для пользователя, вам часто не нужны подписанные номера.

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

+0

@ Lundin Я работаю с некоторым криптовым кодом, который использует арифметическое правое смещение как способ удаления оператора if. Спасибо за Ваш ответ. – MarkP

+0

@MarkP О, но тогда вам обязательно нужно пересмотреть этот алгоритм, если важна мобильность. – Lundin

+0

@ Lundin Да, в этом суть проблемы. Маловероятно, что этот код будет работать на микроконтроллерах. Основная проблема заключалась в том, что есть большие компьютеры, которые не могут справиться с этой ситуацией. – MarkP

0

Вы можете имитировать подписанный арифметический сдвиг вправо 2-го порядка с использованием беззнаковых типов без использования операторов if. Например:

#include <limits.h> 

unsigned int asr(unsigned int x, unsigned int shift) 
{ 
    return (x >> shift) | -((x & ~(UINT_MAX >> 1)) >> shift); 
} 

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

+1

Что это касается вопроса? – Lundin

+0

@ Lundin Это связано с вопросом, хотя и не отвечает на вопрос напрямую. Трудно ввести код в обычный комментарий. Это похоже на проблему X Y. Если вы не можете полагаться на '>>', чтобы сделать арифметический сдвиг вправо, как это можно сделать портативно? –

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