Если вы поместите:
printf("%d %d\n", num, mask);
непосредственно в петлю for
, вы поймете, почему:
2 -2147483648
2 -2147483648
2 -2147483648
2 -2147483648
:
2 -2147483648
Выражение mask >> 1
делает вправо смещает значение mask
, но фактически не присваивает его обратно mask
.Я думаю, вы имели в виду использовать:
mask >>= 1;
Кроме того (как только вы исправите эту проблему), вы увидите, что значения в маске немногостранно, потому что смещение вправо отрицательного значения может сохранить знак, означая, что в итоге вы получите множество битов.
Было бы лучше использовать целые числа без знака, так как оператор >>
будет действовать в соответствии с вашими ожиданиями.
Кроме того, нет смысла записывать все эти биты в буфер, чтобы вы могли распечатать их позже.Если вам не нужно делать какие-либо манипуляции с битами (а здесь, похоже, это не так), вы можете просто выводить их напрямую по мере их вычисления (и избавиться от ненужной теперь i
переменной).
Итак, принимая во внимание все эти моменты, вы можете значительно упростить ваш код, например, с помощью следующей полной программы:
#include <stdio.h>
#include <limits.h>
int binaryConversion(unsigned num) {
for (unsigned mask = (unsigned)INT_MIN; mask != 0; mask >>= 1)
putchar((num & mask) ? '1' : '0');
}
int main(void) {
binaryConversion(2);
putchar('\n');
}
И только одинОбратите внимание, что значение INT_MIN
на самом деле не требуется, чтобы просто был установлен верхний бит.Из-за того, что в настоящее время C допускает обработку дополнения и величины знака (а также дополнения двух) для отрицательных чисел, для INT_MIN может быть установлено значение с несколькими установленными битами (например, -32767
).
Есть шаги, чтобы удалить эти малоиспользуемые кодировки из C (C ++ 20 уже пометил это), но для максимальной переносимости вы могли бы вместо этого выбрать следующую функцию:
int binaryConversion(unsigned int num) {
// Done once to set topBit.
static unsigned topBit = 0;
if (topBit == 0) {
topBit = 1;
while (topBit << 1 != 0) topBit <<= 1;
}
// Loop to process all bits.
for (unsigned mask = topBit; mask != 0; mask >>= 1)
putchar(num & mask ? '1' : '0');
}
Это вычисляет значение с верхним битом, установленным при первом вызове функции, независимо от капризов отрицательных кодировок.Просто будьте осторожны, если вы вызываете его одновременно в многопоточной программе.
Но, как уже упоминалось, в этом, вероятно, нет необходимости, количество сред, в которых используются два других кодирования, будет подсчитываться на пальцах очень неосторожный / невезучий оператор промышленной машины.