Целочисленные типы (справочник по C#)
Целочисленные типы представляют целые числа. Все целочисленные типы являются типами значений. Они также представляют собой простые типы и могут быть инициализированы литералами. Все целочисленные типы поддерживают арифметические операторы, побитовые логические операторы, операторы сравнения и равенства.
Характеристики целочисленных типов
C# поддерживает следующие предварительно определенные целочисленные типы:
Используйте структуру System.Numerics.BigInteger, чтобы представить целое число со знаком без верхней и нижней границ.
Целочисленные литералы
Целочисленные литералы могут быть:
В приведенном ниже коде показан пример каждого из них.
В предыдущем примере также показано использование _ в качестве цифрового разделителя, который поддерживается, начиная с версии C# 7.0. Цифровой разделитель можно использовать со всеми видами числовых литералов.
Тип целочисленного литерала определяется его суффиксом следующим образом:
Если значение, представленное целочисленным литералом, превышает UInt64.MaxValue, происходит ошибка компиляции CS1021.
Как показано в предыдущем примере, если значение литерала выходит за пределы диапазона целевого типа, возникает ошибка компилятора CS0031.
Можно также использовать приведение для преобразования значения, представленного целочисленным литералом, в тип, отличный от определенного типа литерала:
Преобразования
Любой целочисленный тип можно преобразовать в любой другой целочисленный тип. Если целевой тип может хранить все значения исходного типа, преобразование является неявным. В противном случае необходимо использовать выражение приведения для выполнения явного преобразования. Для получения дополнительной информации см. статью Встроенные числовые преобразования.
Спецификация языка C#
Дополнительные сведения см. в следующих разделах статьи Спецификация языка C#:
Числовые типы данных (Visual Basic)
Visual Basic предоставляет несколько числовых типов данных для обработки чисел в различных представлениях. Целочисленные типы представляют только целые числа (положительные, отрицательные и нулевые), а Нецелочисленные типы — числа с целой и дробной частями.
для таблицы, показывающей параллельное сравнение типов данных Visual Basic, см. в разделе типы данных.
Целочисленные типы
Целочисленные типы данных — это те, которые представляют только числа без дробных частей.
Целочисленные типы данных со знаком имеют тип данных SByte (8-разрядный), короткий тип данных (16-разрядный), целочисленный тип данных (32 бит) и тип данных Long (64-бит). Если переменная всегда хранит целые числа, а не дробные числа, объявите ее как один из этих типов.
Целочисленные типы без знака имеют тип данных Byte (8-разрядный), тип данных UShort (16-разрядный), тип данных UInteger (32 бит) и тип данных ULong (64-бит). Если переменная содержит двоичные данные или данные неизвестной природы, объявите ее как один из этих типов.
Производительность
Арифметические операции выполняются быстрее с целочисленными типами, чем с другими типами данных. Они работают быстрее с Integer типами и UInteger в Visual Basic.
Большие целые числа
Если вам нужны еще большие значения, можно использовать тип данных Decimal. Можно хранить числа от-79,228,162,514,264,337,593,543,950,335 до 79,228,162,514,264,337,593,543,950,335 в переменной, Decimal если не используются десятичные разряды. Однако операции с Decimal числами выполняются значительно медленнее, чем с любым другим числовым типом данных.
Небольшие целые числа
Целые числа без знака
Нецелочисленные числовые типы
Нецелочисленные типы данных — это значения, представляющие числа с целой и дробной частями.
Нецелочисленные числовые типы данных: Decimal (128-разрядная Фиксированная точка), один тип данных (32-разрядная с плавающей запятой) и тип данных double (64-разрядный с плавающей запятой). Все типы со знаком. Если переменная может содержать дробную часть, объявите ее как один из этих типов.
Decimal не является типом данных с плавающей запятой. Decimal числа имеют двоичное целочисленное значение и коэффициент масштабирования целого числа, который указывает, какая часть значения является десятичной дробью.
Вы можете использовать Decimal переменные для денежных значений. Преимущество — точность значений. Double Тип данных является более быстрым и требует меньше памяти, но он подвергается ошибкам округления. Decimal Тип данных сохраняет полную точность до 28 десятичных разрядов.
Производительность
Небольшие величины
Для чисел с наименьшей возможной величиной (ближайшее к 0) Double переменные могут содержать цифры как небольшие, например, 4.94065645841246544 e-324 для отрицательных значений и 4.94065645841246544 e-324 для положительных значений.
Небольшие дробные числа
Если не требуется полный диапазон Double типа данных, можно использовать Single тип данных, который может содержать числа с плавающей запятой в диапазоне от-4028235E e + 38 до 4028235E e + 38. Наименьшими значениями для Single переменных являются-1.401298 e-45 для отрицательных значений и 1.401298 e-45 для положительных значений. При наличии очень большого числа переменных, содержащих небольшие числа с плавающей запятой, среда CLR иногда может Single более эффективно хранить переменные и экономить потребление памяти.
Целое (тип данных)
Содержание
Представление
В памяти типовой компьютерной системы целое число представлено в виде цепочки битов фиксированного (кратного 8) размера. Эта последовательность нолей и единиц — ни что иное, как двоичная запись числа, поскольку обычно для представления чисел в современной компьютерной технике используется позиционный двоичный код. Диапазон целых чисел, как правило, определяется количеством байтов в памяти компьютера, отводимых под одну переменную.
Для 64-разрядных операционных систем учитывая разность моделей данных (LP64, LLP64, ILP64), представление целого типа на разных моделях данных может отличаться между собой. Тип int и long может составлять как 4 так и 8 байт.
Стоит отметить, что каждый язык программирования реализует свою сигнатуру представления целых чисел, которая может отличатся от международных стандартов, но обязана его/их поддерживать. К примеру можно отнести кросс-платформенную библиотеку Qt, где целое представляется типом qintX и quintX, где X-8,16,32,64.
Целые типы подразделяются на беззнаковые (англ. unsigned ) и знаковые (англ. signed ).
Беззнаковые целые
В C и C++ для обозначения беззнаковых типов используется префикс unsigned. В C# в качестве показателя беззнаковости используется префикс u (англ. unsigned). Например, для объявления беззнакового целого, равного по размеру одному машинному слову используется тип uint.
Беззнаковые целые, в частности, используются для адресации памяти, представления символов.
Иногда в литературе [1] встречаются рекомендации не использовать тип беззнаковые целые, поскольку он может быть не реализован процессором компьютера, однако вряд ли этот совет следует считать актуальным — большинство современных процессоров (в том числе x86-совместимые [2] ) одинаково хорошо работают как со знаковыми, так и с беззнаковыми целыми.
В некоторых языках, например java, беззнаковые целые типы (за исключением символьного) отсутствуют. [3]
Целые со знаком
Предельные значения для разных битностей
Ниже представлена таблица предельных значений десятичных чисел для разных битностей при кодировании дополнительным кодом. Не зависимо от битности у целых без знака минимальным значением всегда является 0 и поэтому оно не упомянуто. Справа от значения указано количество значащих цифр.
Бит | Максимальное без знака | Минимальное со знаком | Максимальное со знаком | |||
---|---|---|---|---|---|---|
Значение | Цифр | Значение | Цифр | Значение | Цифр | |
4 | 15 | 2 | -8 | 1 | 7 | 1 |
8 | 255 | 3 | -128 | 3 | 127 | 3 |
16 | 65 535 | 5 | -32 768 | 5 | 32 767 | 5 |
24 | 16 777 215 | 8 | -8 388 608 | 7 | 8 388 607 | 7 |
32 | 4 294 967 295 | 10 | -2 147 483 648 | 10 | 2 147 483 647 | 10 |
48 | 281 474 976 710 655 | 15 | -140 737 488 355 328 | 15 | 140 737 488 355 327 | 15 |
64 | 18 446 744 073 709 551 615 | 20 | -9 223 372 036 854 775 808 | 19 | 9 223 372 036 854 775 807 | 19 |
96 | 79 228 162 514 264 337 593 543 950 335 | 29 | -39 614 081 257 132 168 796 771 975 168 | 29 | 39 614 081 257 132 168 796 771 975 167 | 29 |
128 | 340 282 366 920 938 463 463 374 607 431 768 211 455 | 39 | -170 141 183 460 469 231 731 687 303 715 884 105 728 | 39 | 170 141 183 460 469 231 731 687 303 715 884 105 727 | 39 |
Операции над целыми
Арифметические операции
К целочисленным значениям применимы в первую очередь арифметические операции. Ниже приведены самые часто используемые (в скобках указаны их обозначения в различных языках программирования и им аналогичным средствах).
В некоторых языках программирования для лаконичности есть операторы, которые позволяют производить арифметическую операцию с присвоением. Например, «+=» складывает текущее значение переменной слева с выражением справа и помещает результат в исходную переменную. Так же в некоторых языках и средах доступна совмещённая операция MulDiv, которая умножает на одно число, а потом делит результат на второе.
Обычно самыми дорогими по скорости операциями являются умножение и деление (получение остатка от деления).
В памяти компьютера для хранения целых чисел обычно отводится ячейки фиксированного объёма. Из-за этого операции увеличения и уменьшения значений могут приводить к переполнению, что оборачивается искажением результата. Некоторые языки программирования позволяют производит вызов исключения в таких случаях. Кроме этого можно определять поведение при переполнении:
Побитовые операции
Помимо математических, к целым числам применимы битовые операции, которые основаны на особенностях позиционного двоичного кодирования. Обычно они выполняются значительно быстрее арифметических операций и поэтому их используют как более оптимальные аналоги.
Работа со строками
Довольно частыми операциями являются получение строки из числового значения во внутреннем представлении и обратно — число из строки. При преобразовании в строку обычно доступны средства задания форматирования в зависимости от языка пользователя.
Ниже перечислены некоторые из представлений чисел строкой.
Перечислимый тип
К целым относится также перечислимый тип. Переменные перечислимого типа принимают конечный заранее заданный набор значений. Размер набора не определяется числом байтов, используемых для представления целочисленных значений переменных такого типа.
Свод правил по работе с целыми числами в C/C++
В основу статьи легли мои собственные выработанные нелегким путем знания о принципах работы и правильном использовании целых чисел в C/C++. Помимо самих правил, я решил привести список распространенных заблуждений и сделать небольшое сравнение системы целочисленных типов в нескольких передовых языках. Все изложение строилось вокруг баланса между краткостью и полноценностью, чтобы не усложнять восприятие и при этом отчетливо передать важные детали.
Всякий раз, когда я читаю или пишу код на C/C++, мне приходится вспоминать и применять эти правила в тех или иных ситуациях, например при выборе подходящего типа для локальной переменной/элемента массива/поля структуры, при преобразовании типов, а также в любых арифметических операциях или сравнениях. Обратите внимание, что типы чисел с плавающей запятой мы затрагивать не будем, так как это большей частью относится к анализу и обработке ошибок аппроксимации, вызванных округлением. В противоположность этому, математика целых чисел лежит в основе как программирования, так и компьютерной науки в целом, и в теории вычисления здесь всегда точны (не считая проблем реализации вроде переполнения).
Типы данных
Базовые целочисленные типы
Целочисленные типы устанавливаются с помощью допустимой последовательности ключевых слов, взятых из набора
Несмотря на то, что битовая ширина каждого базового целочисленного типа определяется реализацией (т.е. зависит от компилятора и платформы), стандартом закреплены следующие их свойства:
Наличие знака
Дополнительные правила
Типы из стандартных библиотек
Преобразования
Представим, что значение исходного целочисленного типа нужно преобразовать в значение целевого целочисленного типа. Такая ситуация может возникнуть при явном приведении, неявном приведении в процессе присваивания или при продвижении типов.
Как происходит преобразование?
Главный принцип в том, что, если целевой тип может содержать значение исходного типа, то это значение семантически сохраняется.
Арифметика
Продвижение/преобразование
Неопределенное поведение
Счетчик цикла
Выбор типа
Отсчет вниз
Для циклов, ведущих отсчет вниз, более естественным будет использовать счетчик со знаком, потому что тогда можно написать:
При этом для беззнакового счетчика код будет таким:
Заблуждения
Все пункты приведенного ниже списка являются мифами. Не опирайтесь на эти ложные убеждения, если хотите писать корректный и портируемый код.
Типы данных
Общие понятия
Типом данных в программировании называют совокупность двух множеств: множество значений и множество операций, которые можно применять к ним. Например, к типу данных целых неотрицательных чисел, состоящего из конечного множества натуральных чисел, можно применить операции сложения (+), умножения (*), целочисленного деления (/), нахождения остатка (%) и вычитания (−).
Поверх перечисленных строятся следующие типы:
Перейдём к понятию литерала (напр., 1, 2.4F, 25e-4, ‘a’ и др.): литерал — запись в исходном коде программы, представляющаясобой фиксированное значение. Другими словами, литерал — это просто отображение объекта (значение) какого-либо типа в коде программы. В C++ есть возможность записи целочисленных значений, значений с плавающей точкой, символьных, булевых, строковых.
Литерал целого типа можно записать в:
Имя, с которым мы можем связать записанные литералами значения, называют переменной. Переменная — это поименованная либо адресуемая иным способом область памяти, адрес которой можно использовать для доступа к данным. Эти данные записываются, переписываются и стираются в памяти определённым образом во время выполнения программы. Переменная позволяет в любой момент времени получить доступ к данным и при необходимости изменить их. Данные, которые можно получить по имени переменной, называют значением переменной.
Для того, чтобы использовать в программе переменную, её обязательно нужно объявить, а при необходимости можно определить (= инициализировать). Объявление переменной в тексте программы обязательно содержит 2 части: базовый тип и декларатор. Спецификатор и инициализатор являются необязательными частями:
Декларатор кроме имени переменной может содержать дополнительные символы:
Инициализатор позволяет определить для переменной её значение сразу после объявления. Инициализатор начинается с литерала равенства (=) и далее происходит процесс задания значения переменной. Вообще говоря, знак равенства в C++ обозначает операцию присваивания; с её помощью можно задавать и изменять значение переменной. Для разных типов он может быть разным.
Спецификатор задаёт дополнительные атрибуты, отличные от типа. Приведённый в примере спецификатор const позволяет запретить последующее изменение значение переменной. Такие неизменяемые переменные называют константными или константой.
Объявить константу без инициализации не получится по логичным причинам:
Для именования констант принято использовать только прописные буквы, разделяя слова символом нижнего подчёркивания.
Основные типы данных в C++
Разбирая каждый тип, читатель не должен забывать об определении типа данных.
1. Целочисленный тип (char, short (int), int, long (int), long long)
Из названия легко понять, что множество значений состоит из целых чисел. Также множество значений каждого из перечисленных типов может быть знаковым (signed) или беззнаковым (unsigned). Количество элементов, содержащееся в множестве, зависит от размера памяти, которая используется для хранения значения этого типа. Например, для переменной типа char отводится 1 байт памяти, поэтому всего элементов будет:
В таком случае диапазоны доступных целых чисел следующие:
По умолчанию переменная целого типа считается знаковой. Чтобы указать в коде, что переменная должна быть беззнаковой, к базовому типу слева приписывают признак знаковости, т.е. unsigned:
Перечисленные типы отличаются только размерами памяти, которая требуется для хранения. Поскольку язык C++ достаточно машинно-зависимый стандарт языка лишь гарантирует выполнение следующего условия:
Обычно размеры типов следующие: char — 1, short — 2, int — 4, long —8, long long — 8 байт.
Символ процента (%) обозначает операцию определение остатка от деления двух целых чисел:
Более сложные для понимания операции — битовые: & (И), | (ИЛИ), xor (исключающее ИЛИ), > (побитовый сдвиг вправо).
Битовые операции И, ИЛИ и XOR к каждому биту информации применяют соответствующую логическую операцию:
Советы
В обработке изображения используют 3 канала для цвета: красный, синий и зелёный — плюс прозрачность, которые хранятся в переменной типа int, т.к. каждый канал имеет диапазон значений от 0 до 255. В 16-иричной системе счисления некоторое значение записывается следующим образом: 0x180013FF; тогда значение 1816 соответствует красному каналу, 0016 — синему, 1316 — зелёному, FF — альфа-каналу (прозрачности). Чтобы выделить из такого целого числа определённый канал используют т.н. маску, где на интересующих нас позициях стоят F16 или 12. Т.е., чтобы выделить значение синего канала необходимо использовать маску, т.е. побитовое И:
После чего полученное значение сдвигается вправо на необходимое число бит.
Побитовый сдвиг смещает влево или вправо на столько двоичных разрядов числа, сколько указано в правой части операции. Например, число 39 для типа char в двоичном виде записывается в следующем виде: 00100111. Тогда:
2. Тип с плавающей точкой (float, double (float))
Множество значений типа с плавающей точкой является подмножеством вещественных чисел, но не каждое вещественное число представимо в двоичном виде, что приводит иногда к глупым ошибкам:
Работая с переменными с плавающей точкой, программист не должен использовать операцию проверки на равенство или неравенство, вместо этого обычно используют проверку на попадание в определённый интервал:
Помимо операций сравнения тип с плавающей точкой поддерживает 4 арифметические операции, которые полностью соответствуют математическим операциям с вещественными числами.
3. Булевый (логический) тип (bool)
4. Символьный тип (char, wchar_t)
Иногда возникает необходимость использования символов, которые не закреплены в таблицы ASCII и поэтому требует для хранения более 1-го байта. Для них существует широкий символ (wchar_t).
5.1. Массивы
Для инициализации массива значения перечисляют в фигурных скобках. Инициализировать таким образом можно только во время объявления переменной. Кстати, в этом случае необязательно указывать размер массива:
Для доступа к определённому значению в массиве (элемента массива) используют операцию доступа по индексу ([]) с указанием номера элемента (номера начинаются с 0). Например:
5.3. Строки
Для записи строки программисты используют идею, что строка — последовательный ряд (массив) символов. Для идентификации конца строки используют специальный символ конца строки: ‘\0’. Такие специальные символы, состоящие из обратного слэша и идентифицирующего символа, называют управляющими или escape-символами. Ещё существуют, например, ‘\n’ — начало новой строки, ‘\t’ — табуляция. Для записи в строке обратного слэша применяют экранирование — перед самим знаком ставят ещё один слэш: ‘\’. Экранирование также применяют для записи кавычек.
Создадим переменную строки:
Существует упрощённая запись инициализации строки:
Не вдаваясь в подробности, приведём ещё один полезный тип данных — string. Строки
такого типа можно, например, складывать:
6. Ссылка
Ссылка — объект, указывающий на какие-либо данные, но не хранящий их. Например:
Ссылка является весьма удобным средством для оптимизации выполнения программы, в чём читатель убедится, когда разговор зайдёт о функциях и передачи значений параметров в функции.
7. Указатель
Чтобы разобраться с этим типом данных, необходимо запомнить, что множество значений этого типа — адреса ячеек памяти, откуда начинаются данные. Также указатель поддерживает операции сложения (+), вычитания (-) и разыменовывания (*).
Адреса 0x0 означает, что указатель пуст, т.е. не указывает ни на какие данные. Этот адрес имеет свой литерал — NULL :
Сложение и вычитание адреса с целым числом или другим адресом позволяет
передвигаться по памяти, доступной программе.
Операция получения данных, начинающихся по адресу, хранящемуся в указателе, называется разыменовывания (*). Программа считывает необходимое количество ячеек памяти и возвращает значение, хранимое в памяти.
Для указателей не доступна операция присваивания, которая синтаксически совпадает с операцией копирования. Другими словами, можно скопировать адрес другого указателя или адрес переменной, но определить значение адреса самому нельзя.
Сам указатель хранится в памяти, как и значения переменных других типов, и занимает 4 байта, поэтому можно создать указатель на указатель.
8. Перечисления
Перечисления единственный базовый тип, задаваемый программистом. По большому счёту перечисление — упорядоченный набор именованных целочисленных констант, при этом имя перечисления будет базовым типом.