Меняет ли приведенное число на беззнаковое приведение в C значения битов - PullRequest
2 голосов
/ 16 октября 2019

Я сделал несколько быстрых тестов, что приведение signed int к unsigned int в C не изменяет битовые значения (в онлайн-отладчике).

Что я хочу знать, так это то, гарантируется ли это стандартом C или только обычным (но не на 100% уверенным) поведением?

Ответы [ 2 ]

7 голосов
/ 16 октября 2019

Преобразование из signed int в unsigned int не изменяет представление битов в реализациях с двумя дополнениями C , которые являются наиболее распространенными, но изменяет представление битов дляотрицательные числа, включая возможные отрицательные нули в системах дополнения или знак-величина .

Это потому, что приведение (unsigned int) a не определено для сохранения битов, но результатом является положительный остаток деления a на UINT_MAX + 1 (или, как говорит стандарт C ( C11 6.3.1.3p2) ,

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

Представление дополнения к двум для отрицательных чисел является наиболее часто используемым представлением для чисел со знаком именно потому, что имеет этосвойство отрицательного значения n, сопоставляемое с тем же битовым шаблоном, что и математическое значение n + UINT_MAX + 1 - это позволяет использовать одну и ту же машинную инструкцию для сложения со знаком и без знака, и отрицательные числа будут работать из-за переноса.

2 голосов
/ 16 октября 2019

Преобразование из целого числа без знака требуется для получения правильного арифметического результата (того же числа), по модулю размера целого числа без знака, так сказать. То есть после

int i = anything;
unsigned int u = (unsigned int)i;

и на машине с 32-битными значениями требуется, чтобы u было равно i, по модулю 2 32 .

(Мы также можем попытаться сказать, что u получает значение i % 0x100000000, за исключением того, что оказывается, что это не совсем правильно, потому что правила C говорят, что когда вы делите отрицательное целое число на положительное целое, вы получаетечастное округляется до 0 и отрицательный остаток, который не является тем модулем, который мы хотим здесь.)

Если i равен 0 или положителен, нетрудно увидеть, что u будет иметь то же самоебитовый паттерн. Если i отрицательно, и , если вы находитесь на машине с комплементом 2, то получается, что результат также гарантированно будет иметь ту же битовую комбинацию. (Я бы хотел представить здесь хорошее доказательство этого результата, но сейчас у меня нет времени, чтобы попытаться его построить.)

Подавляющее большинство современных машин используют дополнение 2. Но если бы вы работали на машине дополнения 1 или знака / величины, я уверен, что битовые комбинации не всегда будут одинаковыми.

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

...