Ответ 1
C работает на множестве разных архитектур. Я имею в виду много разных архитектур. Вы можете получить код C на встроенном DSP и на суперкомпьютере Cray.
Большинство "определенных реализацией" частей стандарта C, которые люди воспринимают как нечто само собой разумеющееся, действительно делают перерыв на неясных архитектурах. Например, есть DSP и суперкомпьютеры Cray, где CHAR_BIT
- это что-то огромное, например 32 или 64. Поэтому, если вы попробуете свой код на x86, и, возможно, если вы щедрые PowerPC, ARM или SPARC, вы вряд ли столкнется с каким-либо из действительно странных случаев. И это хорошо. Большинство кодов в эти дни всегда будут работать в байт-ориентированной архитектуре с целыми числами с двумя дополнениями и арифметическими сдвигами. Я не сомневаюсь, что любые новые архитектуры процессоров в обозримом будущем будут такими же.
Но рассмотрим два наиболее распространенных представления для целых чисел: twos-дополнение и дополнения:
switch ((-1) >> 1) {
case 0:
case -0:
puts("Hello, one complement world!");
// Possibly sign-magnitude.
break;
case -1:
puts("Hello, two complement world!");
break;
default:
puts("Hello, computer without arithmetic shift");
break;
}
Не потейте. Просто придерживайтесь /
, когда хотите разделить, и >>
, когда вам нужно сдвинуть. Даже плохие компиляторы хорошо оптимизируют эти операции. (И помните, что x/2 != x>>1
, если x
отрицательный, если вы не используете одну машину дополнения, что почти наверняка не соответствует действительности.)
Стандарт гарантирует, что если (int) x
не является отрицательным, то (int) x >> n == (unsigned) x >> n
, поэтому компилятор не может сделать что-то совершенно неожиданное.