Шестнадцатеричный и десятичный в C ++ - PullRequest
0 голосов
/ 18 октября 2018

Таким образом, следующий код

#include <stdio.h>
int main() {
  int myInt;
  myInt = 0xFFFFFFE2;
  printf("%d\n",myInt);
  return 0;
}

дает -30.

Я понимаю идею дополнения до двух, но когда я непосредственно набираю -30, я тоже получаю то же число.Поэтому мой вопрос: зачем мне писать мой номер в шестнадцатеричной форме?И если я использую шестнадцатеричную форму, как компилятор различает, имею ли я в виду, что 0xFFFFFFE2 является дополнением до двух для -30 или значением 4294967266?

Редактировать: Это не имеет ничего общего с дополнением до двух, как я позже выясню.Дополнение Two - это просто дизайнерский способ, позволяющий процессорам работать с целыми числами более эффективным образом.[Для получения дополнительной информации Wiki].См. @Lightness Races in Orbit's answer для объяснения приведенного выше кода.

Ответы [ 2 ]

0 голосов
/ 18 октября 2018

Шестнадцатеричное и десятичное не имеет никакого отношения к тому, почему отображается -30 или нет.

Для 32-битного слова, которое обрабатывается как подписанное (поскольку вы используете% d), любое без знакачисло, превышающее 2147483648, будет считаться отрицательным (номер дополнения 2 с)

, поэтому myInt может быть -30, 0xFFFFFFE2, 4294967266 или -0x1E, и если рассматривать его как 32-разрядное целое число со знаком, будет отображаться как-30.

0 голосов
/ 18 октября 2018

Здесь есть некоторые заблуждения, все из которых можно исправить, пересмотрев первые принципы:

Число - это число.

Когда вы пишете десятичный литерал42, это число 42.

Когда вы пишете шестнадцатеричный литерал 0x2A, это все равно число 42.

Когда вы присваиваете любое из этих выражений для int, int содержит число 42.

Число - это число.

Какая база используется, не имеет значения.Это ничего не меняет.Запись литерала в шестнадцатеричном виде, а затем присвоение его int не меняет того, что происходит.Он не делает магическим образом номер, который интерпретируется, обрабатывается или представляется по-другому.

Число - это число.

То, что вы сделали, это присвоение 0xFFFFFFE2, который является номером 4294967266, до myInt.Это число превышает максимальное значение [подписано] int на вашей платформе, поэтому оно переполняет .Результаты не определены, но вы видите «обтекание» до -30, возможно, из-за того, что представление дополнения до двух работает и реализовано в микросхемах и памяти вашего компьютера.

Вот и все.

Это не имеет ничего общего с шестнадцатеричным, поэтому нет никакого "выбора" между шестнадцатеричными и десятичными литералами.То же самое произошло бы, если бы вы использовали десятичный литерал:

myInt = 4294967266;

Более того, если вы искали способ «вызвать» это поведение с циклическим изменением, не делайте этого, потому что переполнение имеет неопределенное поведение.

Если вы хотите манипулировать необработанными битами и байтами, составляющими myInt, вы можете присвоить ему псевдоним через char*, unsigned char* или std::byte* и поэкспериментировать с этим.

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