Страницы

Поиск по вопросам

вторник, 26 ноября 2019 г.

Зачем нужен тип long когда есть int?


В С есть тип long. Согласно: Wiki c-types он занимет в памяти 4 байта, да и диапазон значений у него такой же как и у int.
Тогда зачем он нужен?

Выписка из wiki: 

int:


  Основной тип целого числа со знаком. Может содержать числа в диапазоне
  [−32767, +32767]. range;[3][4] Таким образом, это по крайней мере 16
  бит (2 байта). На практике, во всех современных компиляторах имеет
  размер в 4 байта и диапазон [-2147483648, +2147483647]


long:


  Тип длинного целого числа со знаком. Может содержать числа, как
  минимум, в диапазоне [−2 147 483 647, +2 147 483 647].[3][4] Таким
  образом, это по крайней мере 32 бита (4 байта).

    


Ответы

Ответ 1



Процессоры развивались постепенно все более расширяя емкость регистров. Например ранее в DOS тип int соответствовал 16 разрядному целочисленному значению, так как н IBM-совместимых компьютеров регистры были 16-разрядными. Например, регистр AX является 16 разрядным, а его подрегистры AL и AH имели разрядность равную 8 битам. До этого вообще регистры процессоров были 8 разрядными. Если выполнить, допустим, умножение двух объектов 16-разрядного типа int, то дл хранения результата нужно использовать два регистра как, например, регистры AX и DX. Для этого результата уже нужно вводить новый целочисленный тип. И такой тип был введен. Это тип long . Затем появились 64-разрядные процессоры. Необходимо различать 16-разрядные целы числа, 32-разрядные целые числа и 64- разрядные целые числа. Поэтому был введен дополнительный целый тип Long long. Имейте в виду, что нужно было сохранять обратную совместимость с целыми типами, введенными ранее для процессоров с меньшей разрядностью. Поэтому в стандарте C принято, что sizeof( short ) <= sizeof( int ) sizeof( int ) <= sizeof( long ) sizeof( long ) <= sizeof( long long ) У разработчиков компиляторов есть свобода выбора, какая разрядность будет у тип long и других целочисленных типов. Например, разрядность типа long может составлять не `32 бита, а 64 бита. Чтобы программы были переносимы, возникла необходимость вводить новые типы со строго указанной разрядностью такие, как, например, int_least32_t или int32_t. На одних 64-битовых платформах тип long и тип long long могут иметь 64-битовуж разрядность На других 64-битовых платформах тип long может быть 32-битовым и тип int также может быть 32-битовым, а тип long long - 64 битовым. Тем не менее ранг типа long long больше ранга типа long, а тип long в свою очередь имеет ранг выше, чем тип int. На этом основываются правила преобразования типов в выражениях. Например, если тип long и тип int имеют разрядность равную 32 битам, то в следующем фрагменте кода long x = 0; unsigned int y = 0; x + y; тип выражения x + y имеет тип unsigned long. В связи с этим имеются некоторые курьезы, связанные с такими преобразованиями особенно при выборе перегруженной функции в C++. Один из таких примеров описан в следующей теме, где ближе к ее концу (можно быстр найти это сообщение по ключевому слову int64_t) описывается один из таких курьезов связанных с вызовом перегруженной функции, у которой параметр имеет тип std::int64_t, который, как оказалось, является не алиасом типа long long int, а алиасом типа long int, который на данной платформе является 64-битовым.

Ответ 2



Размеры типов int и long не регламентированы Стандартом языка. Но регламентировано отношение их размеров, т.е. sizeof(int) <= sizeof(long). На текущий момент можно сказать, что размер long зависит как от разрядности процессора так и от используемой ОС. Например, для Linux и MacOS он будет 8 байт для 64bit архитектур, и 4 байта для 32bit архитектур. В Windows размер будет 4 байта, независимо от разрядности архитектуры. Например, в Стандарте С++ даже встречается такой пример: static_assert(sizeof(long) >= 8, "64-bit code generation required for this library."); Использовать разные типы можно, например, для обеспечения перегрузки функций: void f(int) {} void f(long) {} f(42); // int f(42L); // long Также не стоит забывать, что данные типы имеют разный ранг (integer conversion rank), что влияет на правила преобразования целочисленных типов. Уточнение по поводу размеров long после комментариев @AnT со страницы cygwin: While the Mingw and Microsoft compilers use the LLP64 data model, Cygwin compiler use the LP64 data model, just like Linux. This affects the size of the type long. In the LLP64 model preferred by Microsoft, sizeof(long) is 4. This applies for the related Win32 types like LONG, ULONG, DWORD, etc., too. In the LP64 model used by Cygwin, sizeof(long) is 8, just like the size of pointer or the types size_t/ssize_t. This simplifies porting Linux applications to 64 bit Cygwin, but it requires due diligence when calling Windows functions taking LONG, ULONG, DWORD, or any other equivalent type. This is especially important in conjunction with pointers.

Ответ 3



Тип long не "занимает в памяти 4 байта". Он занимает как минимум 32 бита, т.е. имеет диапазон как минимум [−2147483647, +2147483647]. А сверху его размер не ограничен. Тип int занимает как минимум 16 бит, ибо имеет диапазон как минимум [−32767, +32767] (как вы сами заметили). Поэтому не совсем ясно, откуда вы взяли предположение об одинаковости диапазоно этих типов - уже из процитированного вами видно, что они запросто могут быть разными. В языке С++ система целочисленных типов обладает тем свойством, что sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long) т.е. вполне возможно что размеры (и диапазоны) этих типов все будут различными. В языке С, по каким-то историческим причинам, это соотношение определяется как диапазон(signed char) ⊆ диапазон(short) ⊆ диапазон(int) ⊆ диапазон(long) ⊆ диапазон(long long) Но идея, понятное дело, в обоих случаях одна и та же. И все эти типы могут быть различным с точки зрения диапазона. Как, впрочем, все они могу быть и одинаковыми с точки зрения размера и диапазона. То, что у вас на какой то платформе тип long совпал по представлению с типом in является лишь особенностью вашей платформы.

Ответ 4



Язык C предлагает Вам множество типов. В частности гарантированно, что int не больше long. А long не больше long long. Вы выбираете по своим нуждам и удобству. Когда тип используются часто, то компилятор оптимизирует работу с ним. После оптимизации в компиляторе, начинают рекомендовать использование типа для каких-то целей. На разных архитектурах ЭВМ разные размеры регистров процессора, но соотношение размеров типов сохраняется. Простыми словами: часто использовали int в программах, поэтому его вытянули под разме 4 байта на PC, что соответствует регистру процессора x32. long не стали вытягивать до 8 байт, потому что на x32 потребуется две команды процессору вместо одной. Но не удалять же long, ведь его используют какие-то программы.

Комментариев нет:

Отправить комментарий