Подтвердить что ты не робот

В С++ преобразование из unsigned int в int всегда сохраняет битовый шаблон?

Из стандарта (4.7) это выглядит как преобразование из int в unsigned int, когда они оба используют одинаковое количество бит, чисто концептуально:

Если тип назначения не указан, результирующее значение является наименьшим беззнаковое целое, совпадающее с целым числом источника (по модулю 2 n, где n - количество бит, используемых для представления неподписанного типа). [Примечание: в представление двойного дополнения, это преобразование является концептуальным и в битовой схеме нет изменений (если нет усечения). - end note]

Итак, в этом направлении преобразование сохраняет битмаску. Я не уверен, что стандарт гарантирует то же самое для преобразования из unsigned int в int (опять же, при условии, что используется такое же количество бит). В стандарте здесь говорится:

Если тип назначения подписан, значение не изменяется, если оно может быть представленные в типе назначения (и ширине битового поля); в противном случае, значение определяется реализацией.

Что здесь означает "тип назначения"? Например, 2 ^ 32-1 не может быть представлен 32-битным int. Означает ли это, что он не может быть представлен в целевом типе, и поэтому нельзя предположить, что бит-шаблон останется прежним?

4b9b3361

Ответ 1

Вы ничего не можете принять.

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

Во-вторых, реализация-определение означает, что реализована реализация, вы вообще ничего не можете принять.

Теоретически представление может быть совершенно различным после каждого преобразования. Что это.


Если вы посмотрите на это реалистично, все станет более конкретным. Обычно int хранится в двух дополнениях и signed- > unsigned сохраняет шаблон как unsigned- > signed (так как значение может быть определено при реализации, самый дешевый способ ничего не делает).

Ответ 2

int - это тип назначения в этом случае. Как вы говорите, 2 ^ 32-1 не может быть представлен так в этом случае, поэтому он специфичен для реализации. Хотя, я только видел, что он сохраняет битовые шаблоны.

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

поэтому в этом случае

union FOO {
    int32_t signedVal;
    uint32_t unsignedVal;
} var;

var можно получить как var.signedVal, чтобы получить 32 бита, сохраненные как подписанные int и var.unsignedVal, чтобы получить 32 бита, сохраненные как значение без знака. В этом случае биты будут сохранены.

Ответ 3

"Тип назначения" относится к типу, который вы назначаете/выполняете.

Весь абзац означает, что 32-разрядный unsigned int, преобразованный в 32-разрядный signed int, останется как есть, если значение вписывается в signed int. Если они не подходят, это зависит от реализации того, что он делает (например, усекать). Это означает, что это действительно зависит от реализации, остаются ли биты или изменены ли они (нет гарантии).

Или другими словами: если unsigned int использует свой самый старший бит, результат больше не предсказуем. В противном случае нет изменений (кроме изменения имени в поле).