Решено: В чем отличие unsigned long long от int?

Модератор: Модераторы разделов

azsx
Сообщения: 3684
ОС: calculate linux, debian, ubuntu

Решено: В чем отличие unsigned long long от int?

Сообщение azsx »

ЯП С11 (надеюсь).
Не понимаю отличия этих двух типов. Почему переменная y в восьмиричном представлении показывает 0???
Также мне не понятно, unsigned long long; long long имеют какие то конкретные значения или в зависимости от разных компиляторов будут давать разные цифры? зы уточню. то есть мне не понятно, почему указаные значения указываются именно в минимальных значениях.

Код: Выделить всё

#include <stdio.h>
int main(void)
{
int x = 256;
unsigned long long y = 256;
printf ("десятичное = %d; восьмеричное = %o; шестнадцатеричное = %x ", x, x, x);
printf  ("десятичное = %d; восьмеричное = %#o; шестнадцатеричное = %#x ", x, x, x);
printf  ("\n");
printf ("десятичное = %d; восьмеричное = %o; шестнадцатеричное = %x ", y, y, y);
printf  ("десятичное = %d; восьмеричное = %#o; шестнадцатеричное = %#x ", y, y, y);
return 0;
}

десятичное = 256; восьмеричное = 400; шестнадцатеричное = 100 десятичное = 256; восьмеричное = 0400; шестнадцатеричное = 0x100
десятичное = 256; восьмеричное = 0; шестнадцатеричное = 100 десятичное = 256; восьмеричное = 0; шестнадцатеричное = 0x100
Спасибо сказали:
yoshakar
Сообщения: 259
ОС: Debian Stretch

Re: Решено: В чем отличие unsigned long long от int?

Сообщение yoshakar »

У меня при компиляции с GCC 4.9.2 на 64-битном Linux не воспроизводится. С какими ОС и компилятором вы получаете такой результат?
Спасибо сказали:
Аватара пользователя
bormant
Сообщения: 1354

Re: Решено: В чем отличие unsigned long long от int?

Сообщение bormant »

С нулем не совсем понятно, можно только гадать. Ясно одно -- источник ошибки вы, вы не указали правильный спецификатор размера в форматной строке, так что printf считает, что получил три int, а не три long long int.

Код: Выделить всё

  printf("dec = %lld; oct = %llo; hex = %llx\n",y,y,y);
  printf("dec = %lld; oct = %#llo; hex = %#llx\n",y,y,y);


Про размеры типов -- все просто, C изначально задуман как "переносимая замена ассемблеру", поэтому целевой платформой может оказаться всё что угодно, с какими угодно аппаратно поддерживаемыми размерами данных. Сам язык сильно далеко за пределы аппаратных возможностей выпрыгивать не собирался.
Спасибо сказали:
yoshakar
Сообщения: 259
ОС: Debian Stretch

Re: Решено: В чем отличие unsigned long long от int?

Сообщение yoshakar »

Кстати, компиляторы умеют находить подобные ошибки, хотя по-умолчанию как правило молчат. Для gcc и похожих на него эта проверка (и много других полезных) включается опцией -Wall:

Shell

$ gcc -Wall 1.c -o 1 1.c: In function ‘main’: 1.c:9:2: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long long unsigned int’ [-Wformat=] printf("десятичное = %d; восьмеричное = %o; шестнадцатеричное = %x ", y, y, y); ^ 1.c:9:2: warning: format ‘%o’ expects argument of type ‘unsigned int’, but argument 3 has type ‘long long unsigned int’ [-Wformat=] 1.c:9:2: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 4 has type ‘long long unsigned int’ [-Wformat=] 1.c:10:2: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long long unsigned int’ [-Wformat=] printf("десятичное = %d; восьмеричное = %#o; шестнадцатеричное = %#x ", y, y, y); ^ 1.c:10:2: warning: format ‘%o’ expects argument of type ‘unsigned int’, but argument 3 has type ‘long long unsigned int’ [-Wformat=] 1.c:10:2: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 4 has type ‘long long unsigned int’ [-Wformat=]

Спасибо сказали:
azsx
Сообщения: 3684
ОС: calculate linux, debian, ubuntu

Re: Решено: В чем отличие unsigned long long от int?

Сообщение azsx »

Ясно одно -- источник ошибки вы, вы не указали правильный спецификатор размера в форматной строке, так что printf читает, что получил три int, а не три long long int.

ясно. Хотя сложно утверждать наверняка, но поэкспереминтировав с отрицательными числами у меня сложилось мнение, что вывод:

Код: Выделить всё

unsigned long long y = -4294967295;
  printf("dec = %ulld; oct = %ullo; hex = %ullx\n",y,y,y);
  printf("dec = %ulld; oct = %#ullo; hex = %#ullx\n",y,y,y);
dec = 1lld; oct = 0llo; hex = 1llx
dec = 1lld; oct = 0llo; hex = 1llx

более корректен. Особенно это видно на разных минусовых суммах. зы хотя восьмеричный формат и в минусах не очень :(
Сам язык сильно далеко за пределы аппаратных возможностей выпрыгивать не собирался.

ясно.
С какими ОС и компилятором вы получаете такой результат?

в виндос mingw. У меня в линукс пока не получилось настроить gcc. И gtk+ у меня ваще нигде не получилось настроить. Я пока учусь тому (в том) что получилось.
зызы
посмотрел лог ошибки от yoshakar. А может надо:

Код: Выделить всё

unsigned long long y = -4294967295;
  printf("dec = %ulld; oct = %lluo; hex = %llux\n",y,y,y);
  printf("dec = %ulld; oct = %#lluo; hex = %#llux\n",y,y,y);
dec = 1lld; oct = 4294967296o; hex = 4294967296x
dec = 1lld; oct = 4294967296o; hex = 4294967296x

загадка пока...
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 21359
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Решено: В чем отличие unsigned long long от int?

Сообщение Bizdelnick »

azsx писал(а):
03.10.2015 10:38
У меня в линукс пока не получилось настроить gcc.

Что там настраивать-то? Устанавливаешь — и он работает. Это не php же.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
Bizdelnick
Модератор
Сообщения: 21359
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Решено: В чем отличие unsigned long long от int?

Сообщение Bizdelnick »

azsx писал(а):
03.10.2015 10:38

Код: Выделить всё

printf("dec = %ulld; oct = %lluo; hex = %llux\n",y,y,y);
  printf("dec = %ulld; oct = %#lluo; hex = %#llux\n",y,y,y);

s/llu/ull/

А вообще лимиты, которые Вас интересуют, определены в заголовке limits.h.

Код: Выделить всё

#include <stdio.h>
#include <limits.h>

int main(void) {
        printf("int: %d - %d\n", INT_MIN, INT_MAX);
        printf("unsigned int: 0 - %u\n", UINT_MAX);
        printf("long: %ld - %ld\n", LONG_MIN, LONG_MAX);
        printf("unsigned long: 0 - %lu\n", ULONG_MAX);
        printf("long long: %lld - %lld\n", LLONG_MIN, LLONG_MAX);
        printf("unsigned long long: 0 - %llu\n", ULLONG_MAX);
        return 0;
}

Но при написании кода не стоит рассчитывать, что они всегда будут именно такими. Исходите из минимально допустимых значений. А когда нужен более точный контроль над размером типов, используйте типы из stdint.h (это POSIX и C99).
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:
Аватара пользователя
Hephaestus
Сообщения: 3728
Статус: Многоуважаемый джинн...
ОС: Slackware64-14.1/14.2

Re: Решено: В чем отличие unsigned long long от int?

Сообщение Hephaestus »

yoshakar писал(а):
03.10.2015 10:25
Кстати, компиляторы умеют находить подобные ошибки, хотя по-умолчанию как правило молчат. Для gcc и похожих на него эта проверка (и много других полезных) включается опцией -Wall
А я у Праты прочитал ещё об утилите lint из состава unix.
В книге сказано, что при работе над примерами использовались разные ОС и разные компиляторы.
Если верить Прате, lint проводит более строгую проверку, он у них там в каком-то случае выловил то, чего не смог gcc -Wall.

В этих наших линуксах оригинальный lint отсутствует, но есть аналог - splint.
Пускай скрипят мои конечности.
Я - повелитель бесконечности...
Мой блог
Спасибо сказали: