Под конец урока вы сможете:

  • Использовать 10 типов целых чисел;
  • Выбрать верный тип при написании кода;
  • Использовать шестнадцатеричные и двоичные значения.

В Go есть 10 типов данных для целых чисел. В общем и целом их называют integer. У типов integer нет проблем с точностью, что присуща числам с плавающей запятой float, однако их нельзя использовать для хранения дробей, их диапазон также ограничен. Тип выбранного целого числа зависит от диапазона значений, которые необходимы для данной конкретной ситуации.

Форум Гоферов

Мы работаем над форумом для программистов на Golang. Очень нужны модераторы которые хотят помочь с ответами для новичков и помочь в развитии Go-сообщества.

Go на Форум

Уроки, статьи и Видео

Мы публикуем в паблике ВК и Telegram качественные обучающие материалы для быстрого изучения Go. Подпишитесь на нас в ВК и в Telegram. Поддержите сообщество Go программистов.

Go в ВК Go в Telegram

Содержание статьи

Сколько чисел можно представить с помощью двух жетонов? Если у каждого жетона своя индивидуальная позиция, тогда у нас будет четыре варианта. Два жетона, ни одного, один или другой. Вы можете представить четыре числа.

В основе компьютеров находятся биты. Бит может либо отсутствовать, либо представлен в виде 0 или 1. Восемь битов могут представлять 256 различных значений. Как много битов понадобится для представления числа 4 000 000 000?

Объявление переменных integer в Golang

Пять целочисленных типов Go являются подписанными, или знаковыми. Это значит, что они могут представлять как положительные, так и отрицательные целые числа. Самым популярным знаковым типом целых чисел является int:

Другие пять целочисленных типов являются неподписанными, то есть они лишь для положительных чисел. Для неподписанных целых чисел используется аббревиатура uint:

При использовании назначения типа для целого числа Go всегда выберет тип int. Следующие три строки кода эквиваленты:

На заметку: При возможности лучше опускать уточнение типа int. Точно также как можно не уточнять тип числа с плавающей запятой float64.

Вопрос для проверки:

Если стакан наполовину полон, какое тип целого числа вы используете для представления количества миллилитров воды в стакане?

Тип целого числа integer для каждого случая Golang

Целые числа, будь они подписанными или нет, отличаются по размеру. Размер влияет на минимальное и максимальное значение, а также на то, сколько памяти они занимают. Есть восемь независимых от архитектуры типов суффиксов с количеством необходимых битов. Показано в следующей таблице:

Тип Диапазон Занимаемая память
int8 –128 — 127 8 бит (1 байт)
uint8 0 — 255
int16 –32 768 — 32 767 16 бит (2 байта)
uint16 0 — 65535
int32 –2 147 483 648 — 2 147 483 647 32 бита (4 байта)
uint32 0 — 4 294 967 295
int64 –9 223 372 036 854 775 808 — 9 223 372 036 854 775 807 64 бита (8 байт)
uint64 0 — 18 446 744 073 709 551 615

Есть из чего выбрать. Далее мы рассмотрим, где какие целочисленные типы лучше использовать и когда. Также будет показано, что произойдет, если программа выйдет за пределы допустимого диапазона.

В таблице выше не указано два целочисленных типа. Типы int и uint оптимальны для целевого устройства. Go Playground, Raspberry Pi 2 и более старые мобильные устройства обеспечивают 32-битную среду, int и uint являются 32-битными значениями. Любой современный компьютер может обеспечить 64-битную среду, где int и uint будут 64-битными значениями.

На заметку: Если работаете на компьютере с 32-битной архитектурой над кодом, в котором используются числа со значениями более двух миллиардов, не забудьте использовать типы int64 и uint64 вместо int и uint.

Может показаться, что на некоторых устройствах int идентичен int32, а на других — int64, все-таки это три разных типа. Тип int не является заменой других типов.

Вопрос для проверки:

Какой целочисленный тип включает значение –20 151 021?

Выбор правильного типа данных для целых чисел в Go

Узнать, к какому типу данных компилятор Go относит определенную переменную, можно через функцию Printf. У нее есть специальный символ %T, что выводит тип переменной. Это показано в примере ниже.

Вместо повторения переменной дважды можно указать Printf, чтобы тот использовал первый аргумент [1] для второго специального символа для форматирования:

Задание для проверки:

Какие типы данных Go присвоит тексту в кавычках, целому числу, вещественному числу и слову true (без кавычек)? Напишите простой код, где будут объявляться переменные с различными значениями. Запустите программу и посмотрите, к какому типу Go отнесет каждую переменную.

Шестнадцатеричные значения в Go

Цвета в CSS указываются шестнадцатеричными, а не десятичными значениями. В шестнадцатеричной системе используется на 6 знаков больше, чем в десятичной. Первые десять те же самые — от 0 до 9, за ними следуют символы от A до F. A является эквивалентом 10 в десятичной системе, B — 11 и так далее до F, что соответствует 15.

Десятичная система отлично подходит для организмов с десятью пальцами. Шестнадцатеричная система лучше подходит компьютерам. Одно шестнадцатеричное число тратит четыре бита памяти, или полубайта. Два шестнадцатеричных числа запрашивают ровно восемь битой, то есть один байт, делая шестнадцатеричную систему удобной для уточнения значений uint8.

В следующей таблице представлены некоторые шестнадцатеричные числа и их эквиваленты в десятичной системе.

Шестнадцатеричное значение Десятичное значение
A 10
F 15
10 16
FF 255

Для различия между шестнадцатеричными и десятичными значениями Go запрашивает префикс для шестнадцатеричных значений. Следующие две строки кода эквиваленты:

Для отображения чисел в шестнадцатеричной системе можно использовать специальные символы %x или %X с Printf:

Для вывода цвета, что будет уместен в файле .css, шестнадцатеричным значениям нужны отступы. С помощью специальных символов %v и %f можно уточнить минимальное количество знаков [2] и нулевой отступ с %02х:

Вопрос для проверки:

Сколько байтов требуется для хранения значения типа uint8?

Целочисленное переполнение в Go

Целым числам не присущи ошибки округления, характерные для менее точных чисел с плавающей запятой. Тем не менее, у всех целочисленных типов есть другая проблема: ограниченный диапазон. При выходе за пределы типового диапазона Go сталкивается с таким явлением, как целочисленное переполнение.

У 8-битного неподписанного целого числа (uint8) диапазон 0-255. Значения выше 255 возвращаются к 0. Следующая программа увеличивает подписанные и неподписанные 8-битные целые числа, что в конечном итоге приводит к целочисленному переполнению.

Биты целочисленных значений

Для того чтобы понять, почему при выходе из диапазона целые числа сбрасываются, рассмотрим биты. Специальный символ %b покажет биты целочисленного значения. Как и другие специальные символы %b может задействовать нулевой отступ с минимальной длиной, что показано в следующем примере:

Задание для проверки:

Используйте Go Playground, чтобы поэкспериментировать с целочисленным переполнением:

  1. Листинг 2 (один из примеров урока) увеличивает значения red и number на 1. Что произойдет при добавлении более крупного числа к каждой переменной?
  2. Рассмотрите иной вариант развития событий. Что случится при уменьшении значения red, когда то равно 0 или уменьшения number, когда то равно -128?
  3. Целочисленное переполнение также касается 16, 32 и 64-битных целых чисел. Что произойдет при объявлении uint16, присвоенного к максимальному значению 65535, а затем уменьшенному на 1?

Пакет math определяет math.MaxUint16 как 65535 и min/max константы для каждого независимого от архитектуры целочисленного типа. Помните, что int и uint могут быть как 32, так и 64-битными, зависит от компьютера.

В примере выше (Листинг 3) увеличение green приводит к перемещению 1, что оставляет нули справа. Результат 00000100 является бинарным, что равняется 4 в десятичной системе. Это показано на схеме ниже.

Integers golang

Перемещение 1 в бинарном дополнении

То же самое происходит при увеличении 255. Однако есть одна кардинальная разница: оставшейся только с восемью доступными битами переместившейся 1 некуда больше деваться, поэтому значение blue остается как 0. Это показано в следующей схеме:

wrap integers

Куда перемещаться дальше?

В некоторых ситуациях целочисленное переполнение может прийтись кстати, но не всегда. Самым простым способом избежать его является использование целочисленного типа с достаточно большим диапазоном, что способен вместить все задействованные значения.

Вопрос для проверки: 

Какой специальный символ нужно использовать, чтобы увидеть биты?

Как избежать переполнения по времени в Go

В операционных системах на основе Unix время представлено в виде количества секунд, начиная с 1 Января 1970 UTC (Coordinated Universal Time). В 2038 году число секунд с 1 Января 1970 году превысит 2 миллиарда, что является пределом для int32.

К счастью, int64 сможет поддерживать даты, следующие после 2038 года. Это одна из тех ситуаций, когда int32 или int совсем не подойдут. Только целочисленные типы int64 и uint64 могут хранить числа крупнее двух миллиардов на всех платформах.

Код ниже использует функцию Unix из пакета time. Она принимает два параметра int64, отвечая на количество секунд и наносекунд с 1 Января 1970 года. Использование подходящего крупного значения (более 12 миллиардов) демонстрирует, что датами после 2038 года можно будет оперировать в Go.

Вопрос для проверки:

Какой тип целых чисел лучше использовать, чтобы избежать целочисленного переполнения?

Заключение

  • Самыми популярными целочисленными типами являются int и uint, однако в некоторых ситуациях лучше использовать типы с меньшим или большим диапазоном;
  • Важно внимательно выбирать целочисленные типы — это поможет избежать переполнения. Хотя в некоторых случаях оно может потребоваться;
  • Мы рассмотрели 10 из 15 числовых типов Go — int, int8, int16, int32, int64, uint, uint8, uint16, uint32 и uint64.

Итоговое задание для проверки:

Напишите программу для копилки, где для подсчета количества центов (не долларов) будут использоваться целые числа. В копилку случайным образом будут складываться монеты в пять (5¢), десять (10¢) и двадцать пять (25¢) центов до тех пор, пока в копилке не будет 25 долларов ($25).

Пускай программа показывает баланс после каждого добавления монет в копилку. Баланс должен отображаться в долларах. К примеру, $1.05.

При необходимости найти остаток от деления двух чисел используйте оператор модуля %.

Понравилась статья?

Поддержи наш проект, чтобы мы могли создать больше хорошего контента!