Многие люди часто отмечают при обсуждении оператора сдвига вправо, что в стандарте C явно указано, что эффект сдвига вправо отрицательного числа определяется реализацией. Я могу понять историческую основу для этого утверждения, учитывая, что компиляторы C использовались для генерации кода для различных платформ, которые не используют арифметику с дополнением до двух. Однако вся разработка новых продуктов, о которой я знаю, сосредоточена вокруг процессоров, которые не имеют встроенной поддержки какой-либо целочисленной арифметики, кроме двух в дополнении.
Если код хочет выполнить целочисленное деление со знаком на пол, кратное степени двойки, и он будет выполняться только для текущей или будущей архитектуры, существует ли реальная опасность, которую какой-либо будущий компилятор будет интерпретировать оператор сдвига вправо как делает что-нибудь еще? Если существует реальная возможность, есть ли хороший способ обеспечить ее без негативного влияния на читаемость, производительность или и то, и другое? Существуют ли какие-либо другие зависимости, которые оправдали бы прямое предположение о поведении оператора (например, код будет бесполезен в реализациях, которые не поддерживают функцию X, а реализации вряд ли будут поддерживать X, если они не используют расширенные знаками сдвиги вправо )?
Примечание. Я спрашиваю под тегами C99 и C11, потому что я ожидаю, что новые языковые функции будут среди вещей, которые, если они будут поддерживаться, предполагают, что платформа, вероятно, будет использовать сдвиг вправо, который арифметически эквивалентен делению по полу, и было бы интересно узнать о компиляторах C99 или C11, которые реализуют сдвиг вправо любым другим способом.
>>
и+
, не определяют используемые процессором инструкции; они определяют операции в абстрактной машине. Когда компилятор переводит язык абстрактной машины в реальный код, он может реализовывать только функции, указанные для абстрактной машины. В частности, когда применяется оптимизация, неопределенное поведение абстрактной машины может быть преобразовано во что угодно. - person Eric Postpischil   schedule 20.11.2013>>
. - person Eric Postpischil   schedule 20.11.2013(n+d)/d == (n/d)+1
, который справедлив как для натуральных, так и для действительных чисел, а также для используемых значений? Я не знаю ни одной хорошей формулировки для деления степени двойки, кроме использования знакового сдвига, и ни одной некрасивой формулировки для деления не степени двойки [лучший подход, который я могу придумать для последнего, это добавить (UINT_MAX/d) *d, выполнить деление без знака, а затем вычесть (UINT_MAX/d); Я бы предпочел избегать таких конструкций, когда это возможно, и для степеней двойки это может быть. - person supercat   schedule 20.11.2013do { value >>= 1; } while (--count);
. Предварительное декремент означало, что если вы попытаетесь сдвинуться на 0, это закончится повторением 2 ^ 32 раз... с отключенными прерываниями. Это займет несколько дней. - person David Given   schedule 21.11.2013