Я хочу превратить подписанное значение в беззнаковый (например, int8_t
- uint8_t
), но также он должен хранить свои биты.Как превратить знаковое целое значение в unsigned, в соответствии с его битами?
Как я могу это сделать?
Я хочу превратить подписанное значение в беззнаковый (например, int8_t
- uint8_t
), но также он должен хранить свои биты.Как превратить знаковое целое значение в unsigned, в соответствии с его битами?
Как я могу это сделать?
На практике вы можете просто присвоить подписанное значение в uint8_t
,
u = i;
или вы можете инициализировать его с подписанным значением,
uint8_t u = i;
Это предполагает дополнение до двух подписанного целочисленное представление, которое сегодня широко используется. С этим представлением биты сохраняются точно. “ на практике ” Квалификация относится к этому допущению.
Например, на современной машине 8-разрядное подписанное представление, например. -42, - это число битпаттеров -42 + 256, которое является (число битпаттеров) 214. Преобразование этого в unsigned гарантируется стандартом для получения того же значения по модулю 256. И так это тот же битпаттерн, а именно битпаттерн 214.
Переход от подписанного к знаку без знака четко определен стандартом, хотя сохранение битовой диаграммы (1) обычно является просто практическим эффектом (все эти современные компьютеры разработаны таким образом). Однако, идя в противоположном направлении, вы сталкиваетесь с специфическими для компилятора эффектами, если значение unsigned не может быть представлено. Для этого преобразования требуется больше внимания, потому что это вопрос усмотрения компилятора, а не практическая гарантия на аппаратном уровне.
(1) Как М.М. объясняет в his answer конкретный тип подписки в вашем примере, int8_t
, тот, который с C11 был гарантированно дополнен двумя дополнениями в C. Я не вижу этого языка в окончательной черновике стандарта C99, поэтому, предположительно, его не было на C99, и, следовательно, не в C++ 11 или C++ 14, которые основаны на C99, но, вероятно, есть в C++ 17, который, как я полагаю, основан на C11.
Целочисленная упаковка без знака определяется стандартом, независимо от целочисленного представления. (Подписанная упаковка отсутствует.) –
@JonPurdy: бит, который вы, кажется, не видите в своем представлении, состоит в том, что стандарт позволяет деревьям разные подписанные представления, из которых только один гарантирует сохранение битпаттерна при преобразовании значения в соответствующий неподписанный тип. –
Ах, вы правы, я потерял контекст вопроса, читая ваш ответ. Это то, что я получаю за слишком много вкладок. Тем не менее, стоит отметить, что просто инициализация значения без знака из знакового значения не делает никаких предположений для конкретной платформы. –
С intN_t
типов вы можете просто написать:
int8_t i = something;
uint8_t u = i;
, потому что эти типы должны использовать 2 в дополнение представление, где это преобразование определяется, чтобы сохранить биты.
Ссылка: C++, 14 [cstdint.syn]/2:
Заголовок определяет все функции, типы и макросы так же, как в 7.18 C стандартной
и С11 7.20.1.1/1 (С99 7.18.1.1):
название ЬурейеЕ
intN_t
обозначает целочисленный тип с ширинойN
, без заполнения битов, и представления дополняют до двух.
Чтобы сохранить представление для других целочисленных типов, использование:
int i = something;
unsigned int i = *(unsigned int *)&i;
Вы можете сделать это с любой парой соответствующих подписанных и неподписанных типов. Это безопасно, за исключением возможности генерации ловушки.
Просьба указать источник для «тех типов, которые необходимы для использования представления дополнений 2». –
@ Cheersandhth.-Alf добавил –
Спасибо, я не видел этого в C99 и не знал, что он был добавлен. –
Попробуйте с явным преобразованием типов. Преобразование типа (небезопасное) с использованием static_cast необходимо для получения «необработанных байтов» переменной. Для преобразования значения Ан данного типа, напишите следующее:
static_cast<type_to_convert_to>(expression)
С static_cast гипсом проверяется статический во время компиляции.
#include <iostream>
int main() {
int8_t i {11};
uint8_t i2 = static_cast<uint8_t>(i);
std::cout << "i occupies " << sizeof(i) << " bytes." << std::endl;
std::cout << "i2 occupies " << sizeof(i2) << " bytes." << std::endl;
}
Как один получить пинту в кварт горшок - http://idioms.thefreedictionary.com/put+a+quart+into+a+pint+pot - Знак важно –
Обратитесь к банковской выписке для полной информации –