Int unsigned long: Fundamental types — cppreference.com
Содержание
В чем разница между unsigned long/long/int в c/c++?
Спецификация языка C позволяет реализации типов int и long варьироваться от одной платформы к другой в пределах нескольких ограничений. Эта изменчивость является головной болью для кросс-платформенного кода, но она также является преимуществом, поскольку позволяет информированному программисту сбалансировать свои цели проектирования между собственной скоростью процессора и полным числовым диапазоном на аппаратных архитектурах, которые не предлагают ни того, ни другого.
В общем случае «int» должен отображать размер машинного регистра машины целевой архитектуры CPU, так что загрузка, хранение и работа с данными типа int должны переводиться непосредственно в операции, использующие собственные регистры целевого процессора.
Int может быть меньше размера машинного регистра в интересах экономии места в памяти (большие int занимают в два раза больше RAM, чем маленькие int). Обычно int рассматривается как 32-разрядная сущность даже на архитектурах 64 bit, где совместимость со старыми системами и эффективность памяти являются высокими приоритетами.
«long» может быть того же размера или больше, чем «int», в зависимости от размеров регистров целевой архитектуры. Операции с «long» могут быть реализованы в программном обеспечении, если целевая архитектура не поддерживает такие большие значения в собственных регистрах машины.
CPU чипы, предназначенные для повышения энергоэффективности или встроенных устройств, — это то, где в наши дни вы найдете различия между int и long. Компиляторы для общего назначения CPUs, как на вашем рабочем столе или ноутбуке PC, обычно обрабатывают int и long как один и тот же размер, потому что CPU эффективно использует 32-битные регистры. На небольших устройствах, таких как мобильные телефоны, CPU может быть сконструирован для более естественной обработки 16-битных данных и должен усердно работать для обработки 32-битных или больших данных.
Меньшее количество бит на регистр означает меньшее количество схем, требуемых на чипе, меньшее количество линий передачи данных для перемещения данных в чип и из него, меньшее энергопотребление и меньший размер матрицы чипа, все это обеспечивает более низкую стоимость (в долларах и ваттах) устройства.
В такой архитектуре вы, скорее всего, найдете int размером до be 16 бит и long размером до be 32 бит. Также может возникнуть снижение производительности, связанное с использованием длинных строк, вызванное либо состояниями ожидания загрузки 32 бит при многократном чтении по 16-битной шине данных, либо реализацией длинных операций (сложение, вычитание и т. Д.) В программном обеспечении, если собственное оборудование не поддерживает такие операции в аппаратном обеспечении.
Как правило, единственное, что вы можете предположить о ints и longs, — это то, что диапазон int всегда должен быть меньше или равен long на любой архитектуре. Вы также должны предположить, что когда-нибудь ваш код будет перекомпилирован для другой архитектуры, где любая связь, которую вы в настоящее время видите между int и long, больше не существует.
Вот почему вы должны быть осторожны, чтобы держать инты отдельно от лонгов даже в повседневном мирском кодировании. Сегодня они могут быть полностью совместимы с назначениями, поскольку их детали реализации для вашей текущей аппаратной платформы совпадают, но это совпадение не гарантируется на всех платформах.
c — Почему в CMSIS позиции битового поля ‘unsigned int’, а база маски ‘unsigned long int’?
Вот пример из заголовка ST CMSIS:
#define USART_ISR_TC_Pos (6U)
#define USART_ISR_TC_Msk (0x1UL << USART_ISR_TC_Pos)
Повсюду в заголовках CMSIS позиции битовых полей (_Pos
) задаются как десятичные целочисленные константы типа unsigned int
, а несмещенные маски — unsigned long int
.
Почему они оба не указаны как unsigned long int
?
0
novelistparty
10 Июн 2021 в 09:17
2 ответа
Лучший ответ
Битовая позиция: позиция в регистре не может быть больше 31, и любой целочисленный тип в C может ее содержать. Нет причин даже делать позицию беззнаковой.
маска . Поскольку минимальный размер
unsigned int
, требуемый стандартом C, недостаточно велик для хранения 32-битного значения, он должен быть объявлен как беззнаковый длинный. Авторы CMSIS не знают компилятор, который вы собираетесь использовать, поэтому они используют достаточный тип минимальный .
1
0___________
10 Июн 2021 в 17:06
Нет очевидной причины, почему. Я очень сомневаюсь, что эти библиотеки предназначены для совместного использования с 8- или 16-битными, что было бы единственным разумным объяснением.
Cortex M будет 32-битным, 32-битным int
и 32-битным long
. И самое главное 32-битные регистры аппаратной периферии. Так что даже если бы long
был 64-битным, было бы бессмысленно сдвигать маску за пределы регистра.
Суффикса U
достаточно, чтобы предотвратить неопределенный сдвиг влево для операнда со знаком. В других небрежных библиотеках используется стиль с ошибками 1 << n
, так что, возможно, 1UL
был быстрым исправлением этой ошибки — где 1U
работал бы так же хорошо.
0
Lundin
10 Июн 2021 в 09:04
Вся правда о целочисленных типах в C / Хабр
Для начала несколько вопросов:
- Тип
char
по умолчанию знаковый или нет? Аint
? - Законно ли неявное приведение
(signed char *)
к(char *)
? А то же дляint
? - Сколько бит в
unsigned char
? - Какое максимальное число гарантированно можно поместить в
int
? А минимальное? - Тип
long
определённо больше, чемchar
, не так ли?
Разумеется, экспериментально искать ответы на эти вопросы с помощью вашего любимого компилятора в вашей любимой системе на вашем любимом компьютере
1)
— не лучшая идея. Мы говорим о стандарте языка (С99 и новее).
Если вы уверенно сможете правильно ответить на эти вопросы, тогда эта статья не для вас. В противном случае десять минут, потраченные на её чтение, будут весьма полезны.
Предположу, что вы ответили
- Знаковые оба.
- Законны оба.
- 8.
- 2147483647. -2147483648.
- Конечно, Кэп.
А правильные ответы такие
char
— не регламентируется,int
— знаковый.- Для
int
— законно, а дляchar
— нет. - Не менее 8.
- 32767. -32767
- Вообще говоря, нет.
Про
signed
и unsigned
Все целочисленные типы кроме
char
, по умолчанию знаковые (signed).
С char
ситуация сложнее. Стандарт устанавливает три различных типа: char
, signed char
, unsigned char
. В частности, указатель типа (signed char *)
не может быть неявно приведён к типу (char *)
.
Хотя формально это три разных типа, но фактически char
эквивалентен либо signed char
, либо unsigned char
— на выбор компилятора (стандарт ничего конкретного не требует).
Подробнее про char
я написал в комментариях.
О размере
unsigned char
Тип
unsigned char
является абстракцией машинного байта. Важность этого типа проявляется в том, что С может адресовать память только с точностью до байта. На большинстве архитектур размер байта равен 8 бит, но бывают и исключения. Например, процессоры с 36-битной архитектурой как правило имеют 9-битный байт, а в некоторых DSP от Texas Instruments байты состоят из 16 или 32 бит. Древние архитектуры могут иметь короткие байты из 4, 5 или 7 бит.
Стандарт С вынужден отказаться от допотопных архитектур и требует, чтобы байты были как минимум 8-битные. Конкретное значение (CHAR_BIT
2)) для данной платформы записано в заголовочном файле limits.h
.
Размеры целочисленных типов в С
C переносимый, поэтому в нём базовые целочисленные типы (
char
,
short
,
int
и др.) не имеют строго установленного размера, а зависят от платформы. Однако эти типы не были бы переносимы, если бы
их размеры были совершенно произвольные: стандарт устанавливает
минимальные диапазоны
принимаемых значений для всех базовых целочисленные типов. А именно,
signed char:
-127…127 (не -128…127; аналогично другие типы)unsigned char
: 0…255 (= 28−1)signed short
: -32767…32767unsigned short
: 0…65535 (= 216−1)signed int
: -32767…32767unsigned int
: 0…65535 (= 216−1)signed long
: -2147483647…2147483647unsigned long
: 0…4294967295 (= 232−1)signed long long
: -9223372036854775807…9223372036854775807unsigned long long
: 0…18446744073709551615 (= 264−1)
Стандарт требует, чтобы максимальное значение
unsigned char
было 2
CHAR_BIT
−1 (см. предыдущий пункт).
Стандарт требует sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long)
. Таким образом, вполне законны ситуации типа sizeof(char)=sizeof(long)=32
. Для некоторых DSP от Texas Instruments так и есть.
Конкретные значения этих диапазонов для данной платформы указаны заголовочном файле limits.h
.
Новые типы в С99
После того, как C99 добавил тип
long long
, целочисленных типов и путаницы стало ещё больше. Чтобы навести порядок, стандарт ввёл заголовочный файл
stdint.h
, где определяются типы вроде
int16_t
(равно 16 бит),
int_least16_t
(минимальный тип, способный вместить 16 бит),
int_fast16_t
(по крайней мере 16 бит, работа с этим типом наиболее быстрая на данной платформе) и т. п.
least- и fast-типы фактически являются заменой рассмотренных выше типов int
, short
, long
и т. п. только вдобавок дают программисту возможность выбора между скоростью и размером.
От типов вроде int16_t
, со строгим указанием размера, страдает переносимость: скажем, на архитектуре с 9-битным байтом может просто не найтись 16-битного регистра. Поэтому стандарт тут явно говорит, что эти типы опциональны. Но учитывая, что какой бы код вы ни писали, чуть менее чем во всех случаях целевая архитектура фиксирована даже в худшем случае с точностью до семейства (скажем, x86 или AVR), внутри которого, размер байта не может вдруг поменяться, то переносимость фактически сохраняется. Более того, типы вроде int16_t
оказались даже более популярными, чем int_least16_t
и int_fast16_t
, а при низкоуровневом программировании (микроконтроллеры, драйверы устройств) и подавно, ибо там зачастую неопределённость размера переменной просто непозволительна.
1)
Для удобства тройку архитектура+ОС+компилятор далее будем называть просто
платформой
.
2)
Этот макрос правильнее было бы назвать
UCHAR_BIT
, но по причинам совместимости он называется так, как называется.
Синтаксис
— в чем разница между unsigned long / long / int в c / c ++?
Спецификация языка C позволяет реализовать типы int и long для разных платформ с некоторыми ограничениями. Эта изменчивость является головной болью для кросс-платформенного кода, но она также является преимуществом, поскольку позволяет информированному программисту сбалансировать свои цели проектирования между скоростью собственного процессора и полным числовым диапазоном на аппаратных архитектурах, которые не предлагают и того, и другого.
В общем, предполагается, что «int» отображает размер машинного регистра машины целевой архитектуры ЦП, так что загрузка, хранение и работа с данными типа int должны транслироваться непосредственно в операции, которые используют собственные регистры целевого процессора.
Int может быть меньше размера машинного регистра в целях экономии места в памяти (большие целые числа занимают вдвое больше ОЗУ, чем маленькие целые числа). Обычно int является 32-битной сущностью даже в 64-битных архитектурах, где совместимость со старыми системами и эффективность памяти являются высокими приоритетами.
long может иметь такой же размер или больше, чем int, в зависимости от размеров регистров целевой архитектуры. Операции с long могут быть реализованы программно, если целевая архитектура не поддерживает такие большие значения в собственных регистрах машины.
В микросхемах ЦП
, разработанных для повышения энергоэффективности или встраиваемых устройств, в наши дни вы найдете различия между int и long. Компиляторы для процессоров общего назначения, таких как ваш настольный компьютер или ноутбук, обычно обрабатывают int и long одинакового размера, потому что процессор эффективно использует 32-битные регистры. На небольших устройствах, таких как сотовые телефоны, ЦП может быть построен для более естественной обработки 16-битных данных, и ему придется много работать для обработки 32-битных или больших данных.
Меньшее количество битов на регистр означает меньшее количество схем, необходимых на микросхеме, меньшее количество линий данных для передачи данных в микросхему и из нее, более низкое энергопотребление и меньший размер кристалла кристалла, все это снижает стоимость (в долларах и ваттах) устройство.
В такой архитектуре вы, скорее всего, обнаружите, что int имеет размер 16 бит, а размер long — 32 бита. Также может быть снижение производительности, связанное с использованием long, вызванное либо состояниями ожидания для загрузки 32 бита при нескольких чтениях по 16-битной шине данных, либо вызванное реализацией длинных операций (сложение, вычитание и т. Д.) В программном обеспечении, если собственный Аппаратное обеспечение не поддерживает такие операции аппаратно.
Как правило, единственное, что вы можете предположить относительно int и long, — это то, что диапазон int всегда должен быть меньше или равен long в любой архитектуре.Вы также должны предположить, что когда-нибудь ваш код будет перекомпилирован для другой архитектуры, где любые отношения, которые вы сейчас видите между int и long, больше не существуют.
Вот почему вы должны быть осторожны, чтобы хранить целые числа отдельно от длинных даже при повседневном кодировании. Сегодня они могут быть полностью совместимы по назначению, потому что детали их реализации для вашей текущей аппаратной платформы совпадают, но это совпадение не гарантируется для всех платформ.
Тип длинного поля без знака | Руководство по Elasticsearch [7.x]
Тип длинного поля без знака
Unsigned long — это числовое поле, представляющее 64-битное беззнаковое
целое число с минимальным значением 0 и максимальным значением 2 64 -1
(от 0 до 18446744073709551615 включительно).
PUT my_index { "mappings": { "характеристики": { "my_counter": { "тип": "длина_беззнака" } } } }
Unsigned long можно проиндексировать в числовой или строковой форме,
представляющие целочисленные значения в диапазоне [0, 18446744073709551615].У них не может быть десятичной части.
POST / my_index / _bulk? Обновить {"index": {"_ id": 1}} {"my_counter": 0} {"index": {"_ id": 2}} {"my_counter": 9223372036854775808} {"index": {"_ id": 3}} {"my_counter": 18446744073709551614} {"index": {"_ id": 4}} {"my_counter": 18446744073709551615}
Term-запросы принимают любые числа в числовой или строковой форме.
GET / my_index / _search { "запрос": { "срок" : { "my_counter": 18446744073709551615 } } }
Условия запроса диапазона могут содержать значения с десятичными частями.В этом случае Elasticsearch преобразует их в целые значения:
Термины gte
и gt
преобразуются в ближайшее целое число включительно,
диапазоны lt
и lte
преобразуются в ближайшее целое число включительно.
Рекомендуется передавать диапазоны как строки, чтобы гарантировать их анализ
без потери точности.
GET / my_index / _search { "запрос": { "диапазон" : { "my_counter": { "gte": "9223372036854775808.5 ", "lte": "18446744073709551615" } } } }
Для запросов с сортировкой по полю unsigned_long
,
для конкретного документа Elasticsearch возвращает значение сортировки типа long
если значение этого документа находится в диапазоне длинных значений,
или типа BigInteger
, если значение превышает этот диапазон.
REST-клиенты должны иметь возможность обрабатывать большие целочисленные значения
в JSON, чтобы правильно поддерживать этот тип поля.
GET / my_index / _search { "запрос": { "match_all": {} }, "sort": {"my_counter": "desc"} }
Unsigned long в скриптахправить
В настоящее время unsigned_long не поддерживается в скриптах.
Сохраненное поле unsigned_long
сохраняется и возвращается как String
.
Для терминов
агрегатов, аналогично сортировке значений, Long
или
BigInteger
значений. Для других агрегатов
значения преобразуются в тип double
.
Запросы со смешанными числовыми типамиправить
Поиски со смешанными числовыми типами, одним из которых является unsigned_long
, являются
поддерживается, кроме запросов с сортировкой. Таким образом, запрос сортировки по двум индексам
где одно и то же имя поля имеет тип unsigned_long
в одном индексе,
и long
в другом, не дает правильных результатов и должен
избегать. Если есть необходимость в такой сортировке, сортировка на основе скриптов
можно использовать вместо этого.
Агрегации по нескольким числовым типам, одним из которых является unsigned_long
,
поддерживается.В этом случае значения преобразуются в тип double
.
unsigned long long long long long long int
Поздравляем! Вы столкнулись с одной из самых нелепых и глупых схем прошлого века. В ANSI C / C ++ нет способа сказать: «Мне нужно X бит памяти для этого целого числа».
Ваша первоначальная мысль могла бы быть такой: «Погодите, это не может быть … верно?» Давайте посмотрим на различные типы данных, доступные программисту ANSI C / C ++:
char
int
float
double
struct / class / template / union
pointer
‘char’ позволяет нам объявить один байт.Байт — это 8 бит … или нет? CHAR_BIT (в limits.h) обычно определяется как 8 бит (и Стандарт требует, чтобы он был определен как _minimum_ 8). Однако его можно было бы определить как 9, и было некоторое оборудование, где он был определен как 32. Кроме того, каждый компилятор должен решить, является ли просто выражение «char» подписанным или беззнаковым.
К счастью, «float» и «double» используют стандарт с плавающей запятой IEEE. Изменить: из-за некоторого ответа я должен уточнить: каждый компилятор, который я когда-либо использовал (а я использовал довольно много), полагается на плавающую точку IEEE для float и double.Тем не менее, стандарт ANSI C / C ++ не требует использования плавающей запятой IEEE (это просто удобно использовать практически везде).
Структура / класс / шаблон / объединение технически не являются «типами данных», а скорее представляют собой механизм группировки для группировки логических фрагментов типов данных (и данных) вместе.
Указатели могут указывать на любой другой тип данных.
Теперь, когда я проработал все остальные типы, у нас осталось int. Люди впервые получают представление об этой проблеме, когда обсуждают sizeof (int) на различных форумах.Они быстро узнают о «коротких», «длинных», «подписанных» и «неподписанных». Ниже приведена диаграмма, показывающая, что в стандарте ANSI C / C ++ указано _минимальное_ количество бит для каждого типа int:
short int — 16
signed short int — 16
unsigned short int — 16
int — 16
signed int — 16
unsigned int — 16
long int — 32
signed long int — 32
unsigned long int — 32
long long int — 64
long long со знаком — 64
unsigned long long int — 64
Это минимальное количество бит.Каждый автор компилятора выбирает, какие различные формы sizeof (int) выражаются в битах. Итак, некоторым компиляторам 16. Некоторым 32. Некоторым 64. И есть даже пара компиляторов, которые определяют sizeof (int) как 24 бита. Это так сильно различается.
Был добавлен тип long long, чтобы можно было программировать 64-битное оборудование на C / C ++. И, чтобы приспособиться к этому хакерскому расширению C / C ++, вы используете спецификатор формата семейства printf ()% lld,% lli или% llu для отображения целого числа.
Итак, теперь есть вопрос для размышления: что происходит, когда на оборудовании появляются собственные 256-битные типы данных? Собираемся ли мы создать больше хакерских приспособлений и весь день сидеть и писать «unsigned long long long long long int /% llllu»? Что произойдет, если какой-нибудь популярный поставщик компиляторов решит, что unsigned long long long long long int составляет 384 бита? Или мы собираемся начать смешивать «короткие» и «длинные» — «unsigned long long long long long int»? Как долго будет продолжаться эта глупость с «минимальным количеством бит»? Отсутствие возможности объявить, сколько бит / байтов нам нужно для целочисленного представления, глупо и будет становиться все глупее по мере увеличения размеров int.
Кто-нибудь укажет битовые поля. Я обращаю внимание таких людей на многочисленные проблемы, связанные с битовыми полями. Битовые поля обычно ограничены размером ‘unsigned int’, имеют более низкую производительность (по сравнению с тем, что они делают сами), доступны только
внутри ‘struct’ и т. Д. Это скромное решение, но вряд ли выполнимое в длинный пробег.
‘int’ (неявно ‘signed’) и ‘unsigned int’ должны быть всем, что нам нужно, и должны означать: «Меня не волнует, сколько бит существует для этого целого числа, и я доверяю компилятору сгенерировать достаточное количество бит для цели. платформа для наиболее распространенных операций.»То есть — 32 бита для 32-битных платформ, 64
бит для 64-битных платформ и т. Д. Для конкретных объявлений, где нам нужны точные битовые размеры и улучшенный контроль, я хотел бы видеть что-то вроде:
int @ 64 x, y;
Чтобы объявить пару 64-битных целых чисел со знаком. ‘@’ прямо сейчас является недопустимым C / C ++ (т. е. не будет компилироваться, если вы попробуете его), но был бы довольно хорошим кандидатом.
Для printf () и аналогичные процедуры,% @ 64i, похоже, могут работать достаточно хорошо.Символ ‘@’ также позволяет избежать существующих «расширений» printf (), таких как поддержка многоязычных параметров.Этот предлагаемый подход сделает вещи более удобочитаемыми, и этот подход также позволяет нам избавиться от почти бесполезных «коротких» и «длинных» ключевых слов в языке.
Я определенно согласен с ограничениями на такое добавление к языку, например, «реализации могут устанавливать ограничение на значение после ‘@’». И такие пределы могут быть «кратными 8», «степенью 2» или «от 1 до 256 включительно» (или их комбинацией). Там, где компилятор имеет ограничения и не обязательно обеспечивает встроенную поддержку, должно быть возможно сделать что-то вроде этого:
#if! Native (int @ 512)
typedef __Int512Handler int @ 512;
#endif
int @ 512 x, y;
Ключевое слово «native» препроцессора будет означать: «Если компилятор изначально поддерживает этот тип» (приведенный выше пример означает «Если компилятор НЕ поддерживает этот тип изначально»).Приведенный выше пример позволяет printf () предположить, что переданное значение будет относиться к определенному классу, если @value выпадает за пределы диапазона собственных значений. Класс предоставит необходимую логику для обработки всех обычных целочисленных операций.
Даже с учетом вышеизложенного автор компилятора должен иметь возможность наложить ограничения на то, что может быть объявлено. Допустим, автор компилятора хочет поддерживать только «целые числа, кратные 8 и степенью 2 до 512 бит», а оборудование поддерживает только все в этом диапазоне до 64-битных изначально, тогда автору нужно только определить 128, Поддержка 256 и 512 бит.По мере появления каждой платформы может быть добавлена встроенная поддержка, а в случае исчезновения старых встроенных элементов (например, 16-разрядных) поддержка может быть передана классу. Старый код просто нужно перекомпилировать для нового оборудования.
К сожалению, комитеты ANSI C / C ++ вряд ли когда-нибудь увидят это предложение. Таким образом, мы, скорее всего, в не столь отдаленном будущем напишем «unsigned long long long long long long long long long short short long int».
короткие, длинные, со знаком и без знака
В программировании на C ++ модификаторы типа используются для изменения значения основных типов данных.
В C ++ есть четыре модификатора типа .
-
короткий
-
длинный
-
с подписью
-
без знака
Вот краткое описание:
Тип данных | Размер (в байтах) | Значение |
---|---|---|
подпись int | 4 | используется для целых чисел (эквивалент int ) |
Целое без знака | 4 | может хранить только неотрицательные целые числа |
короткий | 2 | используется для малых целых чисел (диапазон от -32768 до 32767 ) |
длинный | не менее 4 | используется для больших целых чисел (эквивалент long int ) |
длинное без знака | 4 | используется для больших положительных целых чисел или 0 (эквивалент unsigned long int ) |
длинный длинный | 8 | используется для очень больших целых чисел (эквивалент long long int ). |
беззнаковый длинный длинный | 8 | используется для очень больших положительных целых чисел или 0 (эквивалент unsigned long long int ) |
длинный двойной | 8 | используется для больших чисел с плавающей запятой |
символ со знаком | 1 | используется для символов (гарантированный диапазон от -127 до 127 ) |
символ без знака | 1 | используется для символов (диапазон от 0 до 255 ) |
Модификатор короткого типа
Мы можем использовать short
для малых целых чисел (в диапазоне от −32767
до +32767
).
Например,
// маленькое целое число
короткий a = 12345;
Здесь a — это короткая целочисленная переменная short
.
Примечание: short
эквивалентно short int
.
длинный модификатор типа
Если нам нужно сохранить большое целое число (в диапазоне от -2147483647 до 2147483647), мы можем использовать спецификатор типа long
. Например,
// большое целое число
длинный b = 123456;
Примечание: long
эквивалентно long int
.
Модификатор типа long также может использоваться с переменными double
.
// большое число с плавающей запятой
длинный двойной c = 0,333333333333333333L;
Примечание: Для обозначения long double
мы используем суффикс L
. Если мы не используем суффикс L
, это значение double
, которое преобразуется в long double
(что может привести к потере данных).
длинный длинный
long
можно повторить дважды, чтобы создать тип long long
.Этот тип используется для чисел даже больших, чем long
. Модификатор типа long long
можно использовать только с int
.
Например,
// long long int
long long num = 12345678;
подписанные и беззнаковые модификаторы
Переменные со знаком могут содержать как положительное, так и отрицательное целых числа, включая ноль . Например,
// целое положительное значение
подписанный int x = 23;
// целое с отрицательным знаком
подписанный int y = -13;
// целое с нулевым знаком
подписанный int z = 0;
Здесь,
- x содержит положительное значение целое число
- y содержит целое число с отрицательным знаком
- z содержит с нулевым значением целое число
Примечание:
- По умолчанию целые числа
со знаком
.Следовательно, вместоsigned
int
мы можем напрямую использоватьint
. -
со знаком
и без знака могут использоваться только с типами int и char.
Беззнаковые переменные могут содержать только неотрицательные целые числа. Например,
// целое положительное значение
беззнаковое int x = 2;
беззнаковый int y = 0;
Здесь,
- x содержит положительное целое число
- y держит ноль
Как правило, переменная int
может хранить диапазон значений от -2 147 483 648 до 2 147 483 647 .Принимая во внимание, что беззнаковая в переменной
t может хранить диапазон значений от 0 до 4 294 967 295 .
знаковый, беззнаковый и простой символ
C ++ имеет 3 разных типа символов: char
, signed char
и unsigned char
. На практике существует всего 2 типа: signed char
и unsigned char
.
Это потому, что, хотя char
не то же самое, что signed char
или unsigned char
в стандартном C ++, разные компиляторы обрабатывают char
как подписанный char
или unsigned char
в соответствии с их собственными предпочтениями.
Примечание: Когда мы используем только char
вместо signed char
или unsigned char
, этот тип известен как plain char .
Как вы могли догадаться, signed char
может хранить как положительные, так и отрицательные целые числа, тогда как unsigned char
может хранить только положительные целые числа (включая 0 ).
гарантированный диапазон целочисленных значений, который может хранить подписанный символ
, составляет от -127 до 127 , а диапазон беззнакового символа
составляет от 0 до 255 .
// простой символ
char plain_1 = 65;
char plain_2 = 0;
// простой символ с отрицательным значением
// может вызвать проблемы с некоторыми компиляторами
char plain_3 = -56;
// знаковый символ
подписанный char sin_1 = 12;
подписанный char sin_2 = 0;
знаковый символ sin_3 = -12;
// беззнаковый символ
беззнаковый символ unsin_1 = -85;
беззнаковый символ unsin_2 = 0;
Здесь,
- plain_1 содержит положительное целое число
- plain_2 содержит целое число с нулевым значением
- sin_1 содержит положительное целое число
- sin_2 содержит целое число с нулевым знаком
- sin_3 содержит целое число с отрицательным знаком
- unsin_1 содержит целое число с отрицательным знаком
- unsin_2 содержит нулевое целое число
Примечание: желательно не использовать простой символ для выполнения числовых манипуляций; Для этого следует использовать signed char или unsigned char.Обычный символ следует использовать только для хранения символьных значений.
Беззнаковые типы данных — стенограмма видео и урока
Int
Тип данных int или целое число обычно занимает 2 байта и может сохранять значения от 0 до 65 535.
Если вы объявляете целое число как беззнаковое, оно не допускает никаких значений ниже 0. Это работает для таких значений, как возраст, которые никогда не опускаются ниже нуля. Еще одно преимущество состоит в том, что теперь вы можете хранить намного больше данных в поле. Это связано с тем, что типы данных, такие как целые числа, допускают максимальный диапазон значений.
В Java и Visual C ++ диапазон целых чисел составляет от -2 147 483 648 до 2 147 483 647.
Если бы это было беззнаковое, размер был бы почти вдвое. В Visual C ++, например, вы можете объявить беззнаковое int, и значение будет варьироваться от 0 до 4 294 967 295. Это замечательно, если вы хотите иметь возможность хранить намного больше данных в типе данных, но это также создает некоторые проблемы, если подкрадывается отрицательное значение.
Давайте вернемся к примеру возраста и рассмотрим один из больших недостатков беззнаковые значения.
Поскольку age — отличный пример значения, которое не может быть отрицательным, давайте установим беззнаковую переменную для age:
unsigned int customer_age; |
Если значение неизвестно или не введено, система может сохранить значение как -1. Поскольку целое число без знака, оно не обязательно преобразуется в 1, а в машинное значение, обычно очень большое число. Технически это называется двоичным числом без знака. -1 равно 65 535.Если вы проводите тестирование для определенного возраста клиента, скажем старше 21 года, код будет пропускать кого угодно, поскольку 65 535 человек больше 21 года!
Это причина того, что Java не допускает беззнаковые типы данных. Вместо этого Java просто предоставляет больший тип данных long, который допускает гораздо большие значения, чем стандартный int. Однако в Java есть возможность преобразовать целое или длинное число в беззнаковое. Однако, если значение отрицательное, мы возвращаемся к предыдущей проблеме: число преобразуется в гораздо большее число.
Целое число — не единственный тип данных, который может принимать беззнаковый параметр; тип данных char также может быть объявлен как беззнаковый.
Unsigned Char
Тип данных char — это в основном целое число, которое внутренне хранит значения ASCII сохраняемого символа. Он меньше, чем int. Знаковый символ находится в диапазоне от -128 до 127, а значения беззнакового символа — от 0 до 255. Помните, что это значение ASCII, числовое представление символа, которое хранит компьютер.
Это часто не имеет значения, но это может быть использовано в программе шифрования, где числа могут быть вычтены или добавлены к символу.
Вот пример, где буква a представлена числом ASCII 97:
символ без знака = ‘a’; |
символ без знака test_character = символ + 50; |
int n = test_character |
Значение test_character будет 147, поскольку мы объявили его беззнаковым и добавили 50 к значению ASCII 97.
Короткие и длинные (в основном используются для C и C ++, но также и в Java) являются вариантами целочисленного типа данных.
- Беззнаковое короткое: 2 байта; значения от 0 до 65 535
- Длина без знака: 4 байта; значения от 0 до 4,294,967,295
Сводка урока
В этом уроке представлен обзор беззнаковых типов данных. Беззнаковый тип данных принимает только положительные значения, и хотя он может увеличивать размер значения, хранящегося в поле, он может создавать проблемы, если неизвестное или отрицательное значение каким-либо образом сохраняется в поле.Отрицательное значение будет сохранено как двоичное число и приведет к сбою кода или даже к ошибкам при попытке запустить программу. Вы также можете использовать беззнаковый символ (символ наименьшего размера; в основном это значение кода ASCII одного символа). Unsigned также может применяться к типам данных short и long.
Типы данных — Руководство NumPy v1.21
Типы массивов и преобразования между типами
NumPy поддерживает гораздо большее разнообразие числовых типов, чем Python.В этом разделе показано, какие из них доступны и как изменить тип данных массива.
Поддерживаемые типы примитивов тесно связаны с типами в C:
.
Тип Numpy | Тип C | Описание |
---|---|---|
| | Логическое значение (Истина или Ложь) хранится как байт |
| | Определяется платформой |
| | Определяется платформой |
| | Определяется платформой |
| | Определяется платформой |
| | Определяется платформой |
| | Определяется платформой |
| | Определяется платформой |
| | Определяется платформой |
| | Определяется платформой |
| | Определяется платформой |
| Поплавок половинной точности: | |
| | Поплавок одинарной точности, определяемый платформой: |
| | Определяемый платформой поплавок двойной точности: |
| | Определяемый платформой поплавок повышенной точности |
| | Комплексное число, представленное двумя числами с плавающей запятой одинарной точности (действительная и мнимая составляющие) |
| | Комплексное число, представленное двумя числами с плавающей запятой двойной точности (действительная и мнимая составляющие). |
| | Комплексное число, представленное двумя числами с плавающей запятой повышенной точности (действительной и мнимой составляющими). |
Поскольку многие из них имеют определения, зависящие от платформы, набор фиксированного размера
предоставляются псевдонимы (см. Псевдонимы с указанием размера).
Числовые типы NumPy — это экземпляры объектов dtype
(тип данных), каждый
обладающие уникальными характеристиками. После того, как вы импортировали NumPy, используя
типы dtypes доступны как np.bool_
, np.float32
и т. Д.
Расширенные типы, не перечисленные выше, рассматриваются в
раздел Структурированные массивы.
Существует 5 основных числовых типов, представляющих логические значения (bool), целые числа (int),
целые числа без знака (uint) с плавающей запятой (float) и комплексные. Те, у кого есть числа
в их названии указывают битовый размер типа (т.е. сколько битов необходимо
для представления единственного значения в памяти). Некоторые типы, например int
и
intp
, имеют разные биты в зависимости от платформ (например, 32-битный
против 64-битных машин). Это следует учитывать при сопряжении
с низкоуровневым кодом (например, C или Fortran), где адресуется необработанная память.
Типы данных могут использоваться как функции для преобразования чисел Python в скаляры массива
(см. раздел скалярных массивов для объяснения), последовательности чисел Python
для массивов этого типа или в качестве аргументов ключевого слова dtype, которое многие numpy
функции или методы принимают. Некоторые примеры:
>>> импортировать numpy как np >>> x = np.float32 (1.0) >>> х 1.0 >>> y = np.int _ ([1,2,4]) >>> у массив ([1, 2, 4]) >>> z = np.arange (3, dtype = np.uint8) >>> г массив ([0, 1, 2], dtype = uint8)
Типы массивов могут также обозначаться кодами символов, в основном для сохранения
обратная совместимость со старыми пакетами, такими как Numeric.Некоторые
документация по-прежнему может ссылаться на них, например:
>>> np.array ([1, 2, 3], dtype = 'f') array ([1., 2., 3.], dtype = float32)
Вместо этого мы рекомендуем использовать объекты dtype.
Чтобы преобразовать тип массива, используйте метод .astype () (предпочтительно) или
сам тип как функция. Например:
>>> z.astype (с плавающей точкой) массив ([0., 1., 2.]) >>> np.int8 (z) array ([0, 1, 2], dtype = int8)
Обратите внимание, что выше мы используем объект с плавающей запятой Python как dtype.NumPy знает
что int
относится к np.int_
, bool
означает np.bool_
,
что float
— это np.float_
и complex
— это np.complex_
.
Остальные типы данных не имеют эквивалентов Python.
Чтобы определить тип массива, посмотрите атрибут dtype:
>>> z.dtype dtype ('uint8')
объектов dtype также содержат информацию о типе, например его разрядность.
и его порядок байтов.Тип данных также может косвенно использоваться для запроса
свойства типа, например, является ли это целым числом:
>>> d = np.dtype (число) >>> d dtype ('int32') >>> np.issubdtype (d, np.integer) Истинный >>> np.issubdtype (d, np.floating) Ложь
Скаляры массива
NumPy обычно возвращает элементы массивов как скаляры массива (скаляр
со связанным dtype). Скаляры массива отличаются от скаляров Python, но
по большей части они могут использоваться взаимозаменяемо (первичный
Исключение составляют версии Python старше v2.x, где целочисленный массив
скаляры не могут действовать как индексы для списков и кортежей). Есть некоторые
исключения, например, когда код требует очень специфических атрибутов скаляра
или когда он специально проверяет, является ли значение скаляром Python. Обычно,
проблемы легко решаются явным преобразованием скаляров массива
в скаляры Python, используя соответствующую функцию типа Python
(например, int
, float
, complex
, str
, unicode
).
Основным преимуществом использования скаляров массива является то, что
они сохраняют тип массива (Python может не иметь соответствующего скалярного типа
в наличии, эл.г. int16
). Следовательно, использование скаляров массива обеспечивает
одинаковое поведение массивов и скаляров, независимо от того,
значение находится внутри массива или нет. Скаляры NumPy также имеют много одинаковых
методы массивы делают.
Ошибки переполнения
Фиксированный размер числовых типов NumPy может вызывать ошибки переполнения, когда значение
требует больше памяти, чем доступно в типе данных. Например,
numpy.power
правильно оценивает 100 ** 8
для 64-битных целых чисел,
но дает 1874919424 (неверно) для 32-битного целого числа.
>>> np.power (100, 8, dtype = np.int64) 10000000000000000 >>> np.power (100, 8, dtype = np.int32) 1874919424
Поведение целочисленных типов NumPy и Python значительно различается для
целочисленные переполнения и могут сбить с толку пользователей, ожидающих поведения целых чисел NumPy
аналогично Python int
. В отличие от NumPy, размер Python int
равен
гибкий. Это означает, что целые числа Python могут расширяться для размещения любых целых и
не переполнится.
NumPy предоставляет чисел.iinfo
и numpy.finfo
для проверки
минимальные или максимальные значения целых чисел и значений с плавающей запятой NumPy
соответственно
>>> np.iinfo (int) # Границы целого числа по умолчанию в этой системе. iinfo (min = -9223372036854775808, max = 9223372036854775807, dtype = int64) >>> np.iinfo (np.int32) # Границы 32-битного целого числа iinfo (min = -2147483648, max = 2147483647, dtype = int32) >>> np.iinfo (np.int64) # Границы 64-битного целого числа iinfo (min = -9223372036854775808, max = 9223372036854775807, dtype = int64)
Если 64-битные целые числа все еще слишком малы, результат может быть преобразован в
число с плавающей запятой.Числа с плавающей запятой предлагают большее, но неточное,
диапазон возможных значений.
>>> np.power (100, 100, dtype = np.int64) # Неправильно даже с 64-битным int 0 >>> np.power (100, 100, dtype = np.float64) 1e + 200
Повышенная точность
Числа с плавающей запятой Python обычно представляют собой 64-битные числа с плавающей запятой,
почти эквивалентно np.float64
. В некоторых необычных ситуациях это может быть
полезно использовать числа с плавающей запятой с большей точностью. Будь это
возможно в numpy, зависит от оборудования и разработки
среда: в частности, машины x86 предоставляют аппаратное обеспечение с плавающей запятой
с 80-битной точностью, и хотя большинство компиляторов C предоставляют это как свои
long double
type, MSVC (стандарт для сборок Windows) делает
long double
идентично double
(64 бита).NumPy делает
компилятор long double
доступен как np.longdouble
(и
np.clongdouble
для комплексных чисел). Вы можете узнать, что у вас
numpy предоставляет np.finfo (np.longdouble)
.
NumPy не предоставляет dtype с большей точностью, чем C
длинный двойной
\; в частности, 128-битная четырехъядерная точность IEEE
тип данных (FORTRAN REAL * 16
\) недоступен.
Для эффективного выравнивания памяти np.longdouble
обычно хранится
дополнены нулевыми битами до 96 или 128 бит. Что более эффективно
зависит от оборудования и среды разработки; обычно на 32-битном
системы они дополнены до 96 бит, в то время как в 64-битных системах они
обычно дополняется до 128 бит. np.longdouble
добавлен к системе
дефолт; np.float96
и np.float128
предназначены для пользователей, которые
нужно конкретное заполнение. Несмотря на названия, np.float96
и
нп.float128
обеспечивает такую же точность, как np. longdouble
,
то есть 80 бит на большинстве машин x86 и 64 бит в стандартном
Сборки Windows.
Имейте в виду, что даже если np.longdouble
предлагает большую точность, чем
python float
, эту дополнительную точность легко потерять, поскольку
python часто заставляет значения проходить через float
. Например,
оператор форматирования %
требует преобразования своих аргументов
к стандартным типам Python, и поэтому невозможно сохранить
повышенная точность, даже если требуется много десятичных знаков.Это может
будет полезно протестировать ваш код со значением
1 + np.finfo (np.longdouble) .eps
.
.