Skip to content

Latest commit

 

History

History
921 lines (631 loc) · 67.7 KB

DataTypes.md

File metadata and controls

921 lines (631 loc) · 67.7 KB

Оглавление

О типе данных

Рекомендуется прочитать: Множество (дискретная математика).

Типом данных (англ. data type) или просто типом (англ. type) называют множество (допустимых) значений и совокупность операций над этими значениями.

Компьютер не видит разницы между числом, строкой, датой - для него всё это лишь последовательности нулей и единиц.

Тип данных подсказывает компьютеру, как следует обращаться с этими данными, предоставляя (ограничивая) операции для работы с данными этого типа. Например, поиск подстроки для строковых значений, умножение для числовых значений, логические операции над логическими значениями и так далее.

Примитивные типы данных

Большинство языков программирования поддерживает 3 основных типа данных:

  1. Логический тип. Содержит логическое значение: истина или ложь. Например, true или false, 1 или 0, да или нет.
  2. Строковый тип. Содержит текст. Например, 'По ту сторону изгороди', "письма незнакомке".
  3. Числовой тип. Содержит число. Например, 7, -3, 3.14.

Эти типы данных также называют примитивными или базовыми типами.

Логический тип

О логическом типе

В основу логический типа данных легла математическая логика.

Логическим типом (англ. Boolean) называют тип данных, который принимает одно из двух логических значений, называемых истиной (англ. true) и ложью (англ. false).

Логические значения должны быть по смыслу противоположны друг другу. Например, этими значениями могут быть: да и нет, включено и выключено, присутствует и отсутствует и так далее.

Удобнее всего представлять истину в виде 1 (логическая единица), а ложь в виде 0 (логический ноль).

В компьютере значение логического типа можно задать одним битом.

Логические операции

Операции над логическими значениями называются логическими операциями (англ. Boolean algebraic operations).

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

Унарные логические операции

  • Отрицание (англ. negation). Обозначение отрицания x: !x, NOT x. Свойства отрицания: !0 = 1, !1 = 0, !!x = x (закон двойного отрицания). Подробнее об отрицании и его свойствах.

Бинарные логические операции

  • Логическое “И” (англ. logical “AND”), конъюнкция (англ. conjunction). Обозначение конъюнкции x и y: x && y, x AND y. Свойства конъюнкции: x && x = x, x && y = y && x, 0 && 0 = 0, 0 && 1 = 0, 1 && 1 = 1.
  • Логическое “ИЛИ” (англ. logical “OR”), дизъюнкция (англ. disjunction). Обозначение дизъюнкции x и y: x || y, x OR y. Свойства дизъюнкции: x || x = x, x || y = y || x, 0 || 0 = 0, 0 || 1 = 1, 1 || 1 = 1.
  • Эквиваленция (англ. equivalence). Обозначение эквиваленции x и y: x == y, x EQV y. Свойства эквиваленции: (x == x) = 1, (x == y) = (y == x), (0 == 0) = 1, (1 == 1) = 1, (0 == 1) = 0.
  • Логическое исключающее “ИЛИ” (англ. logical exclusive “OR”, logical “XOR”), отрицание эквиваленции (англ. non-equivalence). Обозначение отрицания эквиваленции x и y: x != y, x XOR y, x NEQV y. Свойства отрицания эквиваленции: (x != x) = 0, (x != y) = (y != x), (0 != 0) = 0, (1 != 1) = 0, (0 != 1) = 1.

Подробнее о конъюнкции, дизъюнкции, эквиваленции, исключающем “ИЛИ” и их свойствах можно прочитать в математической логике.

Тернарная условная операция

Тернарной условной операцией или просто тернарной операцией (англ. ternary operation) называют операцию, которая принимает три операнда (логическое выражение x и два значения любого типа y, z) и производит над ними следующее: если логическое выражение истинно (x == 1), то возвращается значение y, в противном случае возвращается значение z. Более кратко, “если x, то y, иначе z”.

Обозначение тернарной операции с операндами x, y, z:

  • x ? y : z,
  • if x then y else z.

Свойства тернарной операции с операндами x, y, z:

  • Если x == 1, то (x ? y : z) == y.
  • Если x == 0, то (x ? y : z) == z.

Тернарная операция соответствует условной дизъюнкции в математической логике.

Представление логического значения в памяти компьютера

Для представления логического значения в памяти компьютера достаточно одного бита, поскольку один бит может принять любые два возможных состояния. В таком случае, 1 - это истина, 0 - это ложь.

Реализовать сам бит в компьютере достаточно просто: например, подача напряжения по проводу - это 1 (истина), отсуствие напряжения на проводе - 0 (ложь).

Строковый тип

О строковом типе

Строковым типом (англ. String) называют тип данных, каждое значение которого представляет собой последовательность символов некоторого алфавита.

Значение строкового типа называют строкой (англ. string).

Количество символов строки называют длиной строки (англ. string length).

Обозначение строки

В программном коде значения строкового типа (строки) обычно заключаются в кавычки:

  1. Одинарные: 'Мартин Иден', 'evergreen'.
  2. Двойные: "Унесённые ветром", "inhale".
  3. Косые: `Триумфальная арка`, `Round Robin`.

Операции над строками

Над строками можно выполнять следующие операции:

  • Вычисление длины строки. Например, ("Notes").length --> 5.
  • Получение символа из строки по индексу. Например, ("Notes").find("t") --> 2.
  • Конкатенация (сложение) строк. Например, "No" + "tes" --> "Notes".
  • Сравнение двух строк. Например, "No" == "tes" --> false.
  • Поиск подстроки в строке. Например, ("Notes").includes("tes") --> true.
  • Замена подстроки в строке. Например, ("Notes").replace("es", "ion") --> "Notion".

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

Сравнение строк

В программировании символы <, <=, ==, >=, > представляют собой операторы (не отношения, как в теории множеств), которые являются частью операций сравнения.

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

Сравнение строк производится в лексикографическом порядке (посимвольно), то есть символы двух строк сравниваются попарно по их числовым кодам. Коды символов задаются кодировкой.

Больше считается та строка, чей код символа оказался больше на некотором шаге алгоритма сравнения.

Например, "music" > "museum", поскольку код символа 'i' больше кода символа 'e'. Ниже представлена таблица для наглядности сравнения сравнения. Коды символов взяты из кодировки ASCII.

Индекс символа Символ первой строки Символ второй строки Сравнение кодов символов
0 'm' 'm' 109 = 109
1 'u' 'u' 117 = 117
2 's' 's' 115 = 115
3 'e' 'i' 101 < 105
4 'u' 'c'
5 'm'

Аналогично, "музыка" > "музей" ('ы' > 'е'), ”волк < "тигр" ('в' < 'т'), "близнец" = "близнец".

Алгоритм сравнения строк

Пусть сравниваются две строки a и b.

Если хотя бы одна из строк a и b пуста, то результат сравнения можно определить сразу:

  1. Если обе строки пусты, то a = b.
  2. Если одна строка пуста, то больше непустая строка.

Далее считаем, что a и b не пусты.

Сначала берётся код первого символа строки a, код первого символа строки b и осуществляется их сравнение:

  • Если код символа строки a больше кода символа строки b, то a > b.
  • Если код символа строки a меньше кода символа строки b, то a < b.
  • Если коды символов совпали, то выполнение алгоритма продолжается.
  • Если достигнут конец хотя бы одной строки, то сравнение заканчивается:
    • Если все предыдущие символы совпали и длины строк a и b совпадают, то a = b.
    • Если все предыдущие символы совпали и длины строк a и b не совпадают, то больше та строка, в которой больше символов.
  • Берётся код следующего символа из каждой строки и выполнение алгоритма начинается сначала.

Представление строк в памяти компьютера

Существует два способа представить строку в памяти компьютера:

Массив символов

Массивом символов называют способ представления строки длины n в памяти компьютера как массива из n + 1 элементов, в котором символы строки занимают индексы массива от 1 до n, а элемент с нулевым индексом хранит длину строки (количество символов) или размер строки (количество байт).

Представление строки "Notes" массивом символов:

Индексы элементов массива 0 (длина строки) 1 2 3 4 5
Элементы массива 5 'N' 'o' 't' 'e' 's'

Нуль-терминированная строка

Нуль-терминированной строкой называют способ представления строки в памяти компьютера, при котором строка представляется непрерывной последовательностью байт, которая оканчивается специальным нуль-символом (признаком конца строки, завершающим байтом).

Нуль-символ представляет собой любой символ алфавита, который был выбран в качестве признака конца строки. Например, в алфавите ANSI нуль-символом выступает символ NUL, имеющий код 0.

Если выделяется один байт на один символ алфавита, то нуль-терминированная строка из n символов занимает n + 1 байт.

Нуль-терминированные строки являются стандартом в языке C, поэтому их иногда называют C-строками.

Размер строки

Размер строки зависит от длины этой строки (количества символов в ней), от размера одного символа (размер задаётся кодировкой) и от способа представления строки в памяти компьютера (например, если строка нуль-терминированная, то её общий размер увеличивается на один байт).

Например, при использовании однобайтовой кодировки ASCII нуль-терминировання строка "Notes" займёт 5 + 1 = 6 байт. Кстати говоря, столько же вышло бы при использовании кодировки UTF-8, поскольку она обратно совместима с кодировкой ASCII

Например, при использовании кодировки UTF-8 нуль-терминированная строка "Роза" займёт 4 • 2 + 1 = 9 байт, поскольку каждый символ кириллицы в кодировке UTF-8 представляется двумя байтами.

Представление нуль-терминированной строки "Notes" последовательностью байт, записанных в шестнадцатиричной системе счисления:

0x4e 0x6f 0x74 0x65 0x73 0x00
N    o    t    e    s    NUL

Символьный тип

Символьным типом (англ. Char) называют тип данных, каждое значение которого представляет собой один символ (англ. character) некоторого алфавита (некоторой кодировки).

Например, значениями символьного типа являются: '%', 'g', '/'.

Значение символьного типа занимает столько памяти, сколько должен занимать символ соответствующей кодировки . Например, для ANSII это всегда 1 байт, для кодировок семейства UTF размер варьируется от 1 до 4 байт.

Например, в языке C нет строкового типа, поэтому строки рассматриваются в нём как массивы символов (char[] или char*).

Целочисленный тип

О целочисленном типе

Целочисленным типом (англ. Integer, Integral data type, Int) называют тип данных, каждое значение которого представляет некоторое число из множества целых чисел Z.

Значение целочисленного типа называют целочисленным значением или целым числом.

Например, целочисленным значениями являются: 17, -3, 0.

Беззнаковые целые числа и целые числа со знаком

В программировании целые числа подразделяют на беззнаковые целые числа и целые числа со знаком

Беззнаковое целое число (англ. unsigned integer) представляет только неотрицательные целые числа:
0, 1, 2, 3, ....

Целым числом со знаком (англ. signed integer) представляюет любое целое число (положительное, отрицательное или ноль). Например, -37, 8, 0.

Представление целого числа в памяти компьютера

Математическое множество целых чисел Z, вообще говоря, бесконечно. При этом ресурсы компьютера ограничены. Компьютер не способен хранить что-либо бесконечное, поэтому представление множества целых чисел в компьютере ограничивается сверху и снизу максимальным и минимальным значениями.

Целое число представляется в памяти компьютера последовательностью байт (бит).

Длиной целочисленного значения (англ. integer width, precision) называют количество бит в его двоичном представлении.

Кодирование целых чисел

Для кодирования целого числа кодировка не нужна: достаточно применить алгоритм перевода чисел из десятичной системы счисления в двоичную.

Кодирование беззнаковых целых чисел

Всего существует m = 2^n n-битных двоичных последовательностей, что можно легко доказать комбинаторно, используя размещения с повторениями. Этими m двоичными последовательностями можно представить беззнаковые целые числа от 0 до m - 1.

Число 0 называют минимальным беззнаковым целым числом (нижняя граница множества), а число m - 1 = 2^n - 1 называют максимальным беззнаковым целым числом (верхняя граница множества).

Например, одним байтом (8 бит) можно представить беззнаковые целые числа от 0 до 2^8 - 1 = 255.

В таблице ниже беззнаковые целые числа закодированы одним байтом.

Беззнаковое целое число Двоичный код числа
0 00000000
1 00000001
2 00000010
3 00000011
127 01111111
128 10000000
254 11111110
255 11111111

Кодирование целых чисел со знаком

На кодирование знака числа выделяется один бит - старший бит (первый бит последовательности):

  • 0 - знак +, соответствует положительному числу
  • 1 - знак -, соответствует отрицательному числу.

Всего существует m = 2^n n-битных двоичных последовательностей. Этими m двоичными последовательностями можно представить целые числа со знаком от - (m / 2) до (m / 2) - 1.

Число - (m / 2) = - 2^(n - 1) называют минимальным целым числом со знаком (нижняя граница множества), а число m - 1 = 2^(n - 1) - 1 называют максимальным целым числом со знаком (верхняя граница множества).

Например, при представлении целого числа со знаком одним байтом: выделяется 1 бит на знак и остаётся 7 бит на само число. Таким образом, одним байтом могут быть представлены целые числа со знаком от 0 до 127.

В таблице ниже целые числа со знаком закодированы одним байтом.

Целое число со знаком Двоичный код числа
0 00000000
1 00000001
-1 10000001
2 00000010
-2 10000010
127 01111111
-127 11111111

Размер целого, короткое и длинное целые

Размер целочисленного значения задаётся либо языком программирования, либо зависит от размера машинного слова, который определяется архитектурой процессора (CPU).

Ранее было показано, что от размера целочисленного значения (int) напрямую зависят диапазоны допустимых знаковых и беззнаковых целых чисел.

Диапазон целых чисел в зависимости от размера целочисленного значения

Размер целого Беззнаковое целое Знаковое целое
1 байт от 0 до 2^8 - 1 = 255 от -2^7 = -128 до 2^7 - 1 = 127
2 байта от 0 до 2^16 -1 = 65535 от -2^15 = -32768 до 2^15 - 1 = 32767
4 байта от 0 до 2^32 - 1 = 4294967295 от -2^31 = -2147483648 до 2^31 - 1 = 2147483647
8 байт от 0 до 2^64 - 1 = 18446744073709551615 от -2^63 = -9223372036854775808 до 2^63 - 1 = 9223372036854775807

Коротким целым (англ. short integer) называют тип данных, предназначенный для представления целых чисел, размер которых меньше либо равен стандартному размеру целочисленного значения (int). Этот тип данных может быть использован для экономии памяти.

Длинным целым (англ. long integer) называют тип данных, предназначенный для представления целых чисел, размер которых равен или превышает стандартный размер целочисленного значения (int). Этот тип данных используется при работе с большими целыми числами.

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

Размеры короткого и длинного целых чисел в различных языках программирования

Язык программирования Размер короткого целого (short) Размер целого (int) Размер длинного целого (long)
C 2 байта 4 байта 4 байта
C++ 2 байта 4 байта 4 байта
C# 2 байта 4 байта 8 байт
Java 2 байта 4 байта 8 байт

Арифметические операции над целыми числами

Унарные арифметические операции

  • Инкремент (англ. increment) - увеличение значения на единицу. Обозначение инкремента числа x: x++ или ++x. Например, ++6 = 7.
  • Декремент (англ. decrement) - увеличение значения на единицу. Обозначение инкремента числа x: x-- или --x. Например, --4 = 3.
  • Модуль (англ. absolute value) - значение числа без учёта знака. Обозначение модуля числа x: |x| (мат.), abs(x) (прог.). Например, |-5| = 5.
  • Отрицание (англ. negation) - смена знака числа на противоположный. Обозначение отрицания числа x: -x, neg(x) (прог.). Например, отрицание числа 8: -8, отрицание числа -2: 2.
  • Взятие квадратного корня (англ. square root). Обозначение квадратного корня числа x: √x (мат.), sqrt(x) (прог.). Например, √49 = 7, то есть 7 • 7 = 49.
  • Натуральный логарифм (англ. logarithm). Обозначение натурального логарифма числа x: ln(x), log(x) (прог.). Например, ln(7) = 1.94591, то есть e^(1.94591) = 7.

Бинарные арифметические операции

  • Сложение (англ. addition). Обозначение сложения чисел x и y: x + y. Например, 7 + 6 = 13.
  • Разность (англ. subtraction). ). Обозначение вычитания числа y из числа x: x - y. Например, 7 - 6 = 1.
  • Умножение (англ. multiplication). Обозначение умножения чисел x и y: x • y (мат.), x * y (прог.). Например, 6 • 7 = 42.
  • Деление (англ. division). Обозначение деления числа x на число y: x ÷ y (мат.), x / y (прог.). Например, 42 ÷ 6 = 7.
  • Возведение в степень (англ. power). Обозначение возведения числа x в степень y: x ^ y (мат.), x ** y (прог.), pow(x, y) (прог.). Например, 2 ^ 4 = 16.

Битовые операции над целыми числами

О битовых операциях

Битовые, побитовые операции (англ. bitwise operation), поразрядные операции предназначены для работы с последовательностями бит.

Поскольку целое число можно представить в двоичной системе счисления (как двоичное число), к нему применимы битовые операции.

Первый бит двоичной последовательности называют старшим битом, последний бит - младшим битом.

Старший и младший биты называют крайними битами, оставшиеся биты последовательности называют средними битами.

Различие битовых и логических операций

Логические операции принимают операнды логического типа (или операнды приводятся к данному типу) и возвращают результат логического типа.

В большинстве языков программирования логические значения представлены значениями true и false (иногда 1 и 0).

0 && 1 = false /* false && true */
3 && 2 = true /* true && true */

Битовые операции принимают в качестве операндов последовательности бит (или значения другого типа приводятся к последовательностям бит) и возвращают последовательность бит.

0 & 1 = 0
3 & 2 = 0010 /* 0011 & 0010 */
01100011 & 11110000 = 01100000

Унарные битовые операции

  • Битовое отрицание, битовое “НЕ" (англ. bitwise “NOT”), дополнение (англ. complement) принимает двоичную последовательность и производит логическое отрицание каждого её бита, то есть каждый ноль становится единицей и каждая единица становится нулём. Обозначение побитового отрицания последовательности x: NOT x.
Выражение Значение # 1 Значение # 2 Значение # 3
x 00000001 10111010 11111111
NOT x 11111110 01000101 00000000
  • Получение знака целого числа со знаком. Знак определяется старшим битом: 0 - +, 1 - -.
Число Знак
00000001 +
10111010 -
11111111 -
  • Получение чётности целого числа. Чётность определяется младшим битом: 0 - чётное, 1 - нечётное.
Число Чётность
00000001 нечётное
10111010 чётное
11111111 нечётное

Бинарные битовые операции

  • Битовое “И” (англ. bitwise “AND”) принимает две двоичные последовательности и производит логическое “И” над каждой парой бит, которые стоят на одинаковых позициях в последовательностях. Обозначение битового “И” для последовательностей x и y: x AND y.
Выражение Значение # 1 Значение # 2 Значение # 3
x 10000001 10101010 11110001
y 00000111 01010101 00010000
x AND y 00000001 00000000 00010000
  • Битовое “ИЛИ” (англ. bitwise “OR”) принимает две двоичные последовательности и производит логическое “ИЛИ” над каждой парой бит, которые стоят на одинаковых позициях в последовательностях. Обозначение битового “ИЛИ” для последовательностей x и y: x OR y.
Выражение Значение # 1 Значение # 2 Значение # 3
x 10000001 10101010 11110001
y 00000111 01010101 00010000
x OR y 10000111 11111111 11110001
  • Битовое “ИЛИ-НЕ”, битовое исключающее “ИЛИ” (англ. bitwise exclusive “OR”, bitwise XOR) принимает две двоичные последовательности и производит логическое исключающее “ИЛИ” над каждой парой бит, которые стоят на одинаковых позициях в последовательностях. Обозначение битового исключающего “ИЛИ” для последовательностей x и y: x XOR y.
Выражение Значение # 1 Значение # 2 Значение # 3
x 10000001 10101010 11110001
y 00000111 01010101 00010000
x XOR y 01111001 00000000 00011110

Сводная таблица битовых операций

Выражение Значение # 1 Значение # 2 Значение # 3
x 10000001 10101010 11110001
y 00000111 01010101 00010000
NOT x 01111110 01010101 00001110
NOT y 11111000 10101010 11101111
x AND y 00000001 00000000 00010000
x OR y 10000111 11111111 11110001
x XOR y 01111001 00000000 00011110

Битовые сдвиги

Битовым сдвигом (англ. bit shift) называют битовую операцию, которая принимает двоичную последовательность и смещает биты (позиции бит) в ней.

Сдвиги по направлению смещения бит

  • Битовый сдвиг влево (англ. left bitwise shift), сдвиг от младшего бита к старшему, подразумевает смещение (перестановку) кадого из значений средних бит на 1 бит влево.
  • Битовый сдвиг вправо (англ. right bitwise shift), сдвиг от старшего бита к младшему, подразумевает смещение кадого из значений средних бит на 1 бит вправо.

Сдвиги по поведению крайних бит

  • При логическом сдвиге (англ. logical shift) один из крайних битов выпадает из последовательности, другой принимает нулевое значение.
>> 10001111 = 01000111
>> 01000111 = 00100011

<< 10001111 = 00011110
<< 00011110 = 00111100
  • При арифметическом сдвиге (англ. arithmetic shift) сохраняется знак числа, который хранится в старшем бите (сохраняется значение старшего бита). В остальном арифметический сдвиг аналогичен логическому.
>> 10001111 = 11000111
>> 11000111 = 11100011

>> 01000111 = 00100011

<< 10001111 = 00011110
<< 00011110 = 00111100
  • При циклическом сдвиге (англ. circular shift, bitwise rotation) значение одного крайнего бита переносится в другой крайний бит, то есть производится круговая перестановка.
>> 10001111 = 11000111
>> 11000111 = 11100011
>> 11100011 = 11110001

<< 10001111 = 00011111
<< 00011111 = 00111110
<< 00111110 = 01111100

Логический сдвиг влево эквивалентен умножению беззнакового целого на два, а логический сдвиг вправо - делению беззнакового целого на два.

Арифметический сдвиг влево эквивалентен умножению целых чисел со знаком на два, а арифметический сдвиг вправо - делению целых чисел со знаком на два.

Число с плавающей точкой

Экспоненциальная форма записи числа

Экспоненциальной формой записи числа n называют представление числа в виде произведения некоторого другого числа m, называемого мантиссой (англ. mantissa, significand), и показательной функции b^e, в которой число b называют основанием (англ. base), а число e - экспонентой (англ. exponent) или порядком: n = m • b^e .

Обычно в качестве основания берут число 10. В этом случае n = m • 10^e. Такую форму записи числа называют стандартной формой (англ. standard form) или научной формой (англ. scientific form)

В научной форме записи мантисса содержит все ненулевые цифры числа n, а все нулевые цифры представляются порядком e.

В математике доказано, что любое действительное число может быть представлено десятичной дробью, а значит любое число можно представить в научной форме записи, причём бесконечным множеством способов. Например, 17 можно представить как 17 • 10^0, 1.7 • 10^1, 0.17 • 10^2, 0.017 • 10^3 и так далее.

Чаще всего порядок e подбирают так, чтобы значение модуля числа m было между 1 и 10: 1 <= |m| < 10. Такую форму записи числа называют нормализованной формой (англ. normalized form).

Число Нормализованная форма
3 3 • 10^0
17 1.7 • 10^1
-10 -1 • 10^1
1000 1 • 10^3
-0.051 -5.1 • 10^(-2)
123 1.23 • 10^2
0.0008 8 • 10^(-4)

В компьютере для записи очень больших и очень маленьких чисел так же используется научная (нормализованная) форма записи чисел в виде: n = mEe, где E означает 10^.

Порядок e содержит знак +, если число n больше единицы, и знак -, если число n меньше. Порядок e также содержит ведущий ноль, если число порядка меньше 10.

Число Нормализованная форма Представление в компьютере
17000000000 1.7 • 10^10 1.7E+10
-73650000 -7.365 • 10^7 -7.365E+07
0.00000154 1.54 • 10^(-6) 1.54E-06
-0.000000037 -3.7 • 10^(-8) -3.7E-08

О числе с плавающей точкой

Числом с плавающей точкой (англ. floating-point number) или числом с плавающей запятой называют представление числа в экспоненциальной форме записи.

Числом с плавающей точкой можно представить как любое целое число (например, 371 = 3.71 • 10^2), так и любую десятичную дробь (например, 0.0333 = 3.33 • 10^(-2)).

Название числа с плавающей точкой объясняется тем, что точку можно поставить где угодно между цифр во внутреннем представлении. Например, число 1984 можно представить как 0,1984 • 10^4, 1,984 • 10^3, 1984 * 10^0, 19840 * 10^(-1) и так далее.

Пример выше показывает, что существует бесконечное множество представлений числа как числа с плавающей точкой.

В программировании для представления слишком больших или слишком малых чисел с плавающей точкой используют научную форму записи, остальные числа с плавающей точкой записываются как обыкновенная десятичная дробь (порядок не указывается).

Число Научная форма записи Компьютерное представление числом с плавающей точкой
7 7 • 10^0 7.0
-322 -3.22 • 10^2 -322.0
19.84 1.984 • 10 19.84
0.000000001 1 • 10^(-9) 1E-09
-0.0000000000177 -1.77 • 10^(-11) -1.77E-11
300000000 3 • 10^8 3E+08

Часто языки программирования предоставляют несколько типов данных, каждый из которых используется для целых чисел с плавающей точкой. Обычно такими являются типы данных Float и Double,

Операции над числами с плавающей точкой

Для чисел с плавающей точкой доступны базовые бинарные арифметические операции:

Далее будем рассматривать операции над числами x = m1 • 10^e1 и y = m2 • 10^e2.

О сложении и разности чисел с плавающей точкой

Сложение и разность чисел с плавающей точкой требуют совпадения порядков чисел: e = e1 = e2. Если порядки не совпадают, то необходимо перенести точку в одной из мажорант m1 и m2 так, чтобы порядки e1 и e2 совпали.

Например, если x = 3 • 10^2 и y = 2 • 10^3, то перед сложением или разностью x и y необходимо

  • либо x привести к форме x = 0.3 • 10^3,
  • либо y привести к форме y = 20 • 10^2.

Сложение чисел с плавающей точкой

Сложение (англ. addition) чисел с плавающей точкой x и y осуществляется по формуле:
x + y = (m1 + m2) • 10^e.

Ниже представлено сложение чисел 2.5 • 10^5 и 3.25 • 10^6.

2.5  10^5 + 3.25  10^6 = 
2.5  10^5 + 32.5  10^5 =
(2.5 + 32.5)  10^5 =
36.0  10^5 =
3.6  10^6 /* инженерная форма */

Разность чисел с плавающей точкой

Разность (англ. subtraction) чисел с плавающей точкой x и y осуществляется по формуле:
x - y = (m1 - m2) • 10^e.

Ниже представлена разность чисел 3.5 • 10^3 и 4.5 • 10^2.

3.5  10^3 - 4.5  10^2 = 
35  10^2 - 4.5  10^2 =
(35 - 4.5)  10^2 =
30.5  10^2 =
3.05  10^3 /* инженерная форма */

Умножение чисел с плавающей точкой

Умножение (англ. multiplication) чисел с плавающей точкой x и y осуществляется по формуле:
x • y = (m1 • m2) • 10^(e1 + e2).

Ниже представлено умножение чисел 7.25 • 10^3 и 3.0 • 10^2.

(7.25  10^3)  (3.0  10^2) = 
(7.25  3.0)  10^(3 + 2) =
21.75  10^5 =
2.175  10^6 /* инженерная форма */

Деление чисел с плавающей точкой

Деление (англ. division) чисел с плавающей точкой x и y осуществляется по формуле:
x ÷ y = (m1 ÷ m2) • 10^(e1 - e2).

Ниже представлено деление чисел 26.4 • 10^8 и 2.4 • 10^6.

(26.4  10^8) ÷ (2.4  10^6) = 
(26.4 ÷ 2.4)  10^(8 - 6) =
11  10^2 =
1.1  10^3 /* инженерная форма */

Точность

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

Например, число 0.16738 может быть математически округлено до 0.0, 0.2, 0.17, 0.167 или 0.1674.

Округляемое число называют истинным значением (англ. true value) или действительным (фактическим) значением (англ. actual value).

Результат округления называют измеренным значением (англ. measured value).

Из примера выше следует, что вместо истинного значения 0.16738 может быть использовано одно из измеренных значений 0.0, 0.2, 0.17, 0.167, 0.1674 в зависимости от требуемой точности.

Точностью вычислений (англ. accuracy) a называют меру близости измеренного значения x1 к истинному значению x. Обычно эта мера выражается разницей между значениями x и x1, представленной их модулем разности:
a = |x - x1|.

Точностью (англ. precision) p называют меру разброса измеренных значений. Например, для измеренных значений x1 и x2 она выражается модулем разности этих значений: p = |x1 - x2|·

Несмотря на похожесть формул, точность p и точность вычислений a имеют существенное различие, выраженное в их предназначении: a вычисляется для проверки точности промежуточного или конечного результата, а p задаётся для ограничения области допустимых значений.

Ссылка

О ссылке

Ссылкой (англ. reference) называют объект, который указывает на определённые данные, но не хранит их.

Говорят, что ссылка ссылается (англ. refers) на некоторые данные в памяти компьютера.

Значением ссылки являются сами данные, на которые она ссылается.

Создание и разыменование ссылки

Получение данных (доступ к данным) по ссылке называют разыменованием ссылки (англ. dereferencing).

Для разыменования ссылки достаточно просто использовать значение ссылки.

Ниже представлен пример создания и разыменования ссылки на языке C++. При создании ссылки перед названием переменной добавляется амперсанд (&).

/* объявление переменной value целочисленного типа */
int value = 17;
/* создание ссылки ref на переменную value */
int &ref = value;
/* разыменование ссылки ref, то есть получение значения переменной value, и вывод значения на консоль */
cout << ref; // 17

В языке C++ также имеется возможность получить физический адрес любой переменной с помощью оператора &.

cout << &value; // 0017BF22
cout << &ref; // 0017BF22

Ссылка не может быть пустой, то есть она не может не иметь значения, не может не ссылаться на данные.

int &ref; // ошибка

Из примеров выше следует, что ссылку можно использовать как псевдоним: создание ссылки позволяет обратиться к некоторому старому значению по новому (еще одному) имени.

Изменение данных по ссылке

По ссылке можно не только получать, но и изменять данные.

Ниже представлен пример изменения данных по ссылке на языке C++.

/* объявление переменной value целочисленного типа */
int value = 17;
/* создание ссылки ref на переменную value */
int &ref = value;
/* изменение значения переменной value по ссылке */
ref = 18;
/* вывод значения переменной value на консоль */
cout << value; // 18

Ссылка как параметр функции

Вспомним, что объекты передаются по ссылке, а значения примитивных типов данных просто копируются.

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

Следующий код отработает ожидаемо: значение переменной foo не изменится.

/* функция, увеличивающая значение аргумента на 1 */
void increment(int x) {
  return ++x;
}

int foo = 0;
/* результат выполнения функции никуда не присваивается */
increment(foo); // 1
cout << foo; // 0
/* значение переменной foo не изменилось */

Использование ссылки в качестве параметра позволяет изменять значение аргумента примитивного типа прямо в самой функции (путём изменения параметра ссылочного типа).

/* функция, увеличивающая значение аргумента на 1 */
void increment(int &x) {
  return ++x;
}

int foo = 0;
/* результат выполнения функции никуда не присваивается */
increment(foo); // 1
cout << foo; // 1
/* значение переменной foo изменилось по ссылке */

Использование ссылок в различных языках программирования

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

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

/* создание объекта foo с полем notes */
const foo = { notes: 17 }; 
/* передача объекта foo по ссылке в переменную bar */
const bar = foo; 
/* изменение объекта foo по ссылке через переменную bar */
bar.notes = 18;
console.log(foo); // { notes: 18 }

Указатель

Об указателе

Указателем (англ. pointer) называют объект, хранящий некоторый адрес в памяти компьютера.

Значением указателя является физический адрес некоторых данных. Говорят, что указатель указывает (англ. points) на эти данные.

Создание и разыменование указателя

Получение данных (доступ к данным) по адресу, хранящемуся в указателе, называют разыменованием указателя (англ. dereferencing the pointer).

Ниже представлен пример создания и разыменования указателя на языке C++. При создании указателя перед названием переменной добавляется *.

/* объявление переменной value целочисленного типа */
int value = 17;
/* создание указателя pointer на переменную value */
int *pointer = &value;
/* вывод значения указателя на консоль */
cout << pointer; // 0017BF22

В языке C++ указатель разыменовывается с помощью оператора *.

cout << pointer; // 0017BF22
cout << *pointer; // 17

В отличии от ссылки, указатель может быть нулевым, то есть может не указывать ни на один объект.

int *ref = NULL;