подписанные / неподписанные целые - PullRequest
1 голос
/ 25 мая 2011

Давайте предположим, что у меня есть сценарий на C, и я объявляю несколько неподписанных int. Затем я пишу цикл while, который автоматически увеличивает их значение и выводит их: без ограничений, пока пользователь не остановит его из командной строки. Как только я достигну очень большого числа (2 миллиарда), компьютер начнет считать от -2 миллиардов. Как я могу предотвратить это? Послушайте, я могу легко напечатать, скажем, "99999999999999", не вызывая сбоев: почему я не могу просто сделать это на своем 32-битном терминале? Я попытался с длинным длинным int, подписанным и неподписанным, но у меня все еще есть эта проблема. Вот скриншот: http://img577.imageshack.us/img577/6558/schermata20110524a01012.png

Спасибо, J.

Ответы [ 4 ]

2 голосов
/ 25 мая 2011

Как вы их распечатываете?Используете ли вы printf("%u", i) или printf("%i", i)?

%i, будет ли думать, что int подписан, даже если это не так.Чтобы напечатать int без знака, используйте %u.

2 голосов
/ 25 мая 2011

Компьютер не имеет понятия подписанного / неподписанного, это вопрос интерпретации значений.Одно и то же значение можно интерпретировать как -1 или как 65535, в зависимости от того, как вы определяете тип данных.В вашем случае - цикл никогда не войдет в отрицательные числа, потому что для этого типа данных - такого нет.Вместо этого положительный диапазон будет больше, чем у signed int.

Что касается скриншота - как вы печатаете?Если вы печатаете, например, с помощью %d - значения будут интерпретированы как signed.Вместо этого используйте %u, чтобы программа интерпретировала значения как unsigned.

1 голос
/ 25 мая 2011

32-разрядное число ограничено в диапазоне тем, что оно имеет только 32-разрядное значение. Вы не можете хранить 60-70- и т. Д. Число битов в 32 битах.

Вы можете использовать что-то вроде unsigned long long, которое может быть 64-битным и, следовательно, иметь больший диапазон, но все равно будет иметь ограничение. (2 ^ 64, но это очень большое число). Если вам действительно нужно «безлимитное», посмотрите библиотеки bigint, такие как GMP.


Редактировать: , как указали другие авторы, убедитесь, что вы используете правильный спецификатор преобразования в строке формата для printf:

  • %d, %i: int, signed int, short
  • %u: unsigned int, unsigned short
  • %llu: unsigned long long
  • %lld, %lli: long long

Обратите внимание, что в некоторых версиях Windows есть нестандартные спецификаторы формата для типов long long.

0 голосов
/ 25 мая 2011

Это частично о том, как вы печатаете значение.

Если вы скажете

printf("%d\n", your_unsigned_int);

тогда даже если int не подписано ((если у вас нет компилятора, который предупреждает о таких вещах), printf будет обрабатывать его как со знаком int (потому что это то, что %d означает).

Попробуйте %u вместо %d.

Как только вы исправите это, поймите, что в 32-битной системе int (со знаком или без) обычно будет иметь размер только 32 бита и, таким образом, будет содержать значения примерно до 4 миллиардов. Если вы хотите, чтобы значения были больше этого, вам понадобится больший тип (например, long long). Если вы сделаете это, вам нужно будет изменить строку формата на что-то вроде "%ull\n" (или "%llu"? Я забыл), а также ... или кто знает, что вы получите.

...