4. Представление чисел в компьютере
Представление чисел в памяти компьютера имеет специфическую особенность, связанную с тем, что в памяти ПК они должны располагаться в байтах – минимальных по размеру ячейках памяти.
Целые числа могут представляться в компьютере со знаком или без знака.
Целые числа без знака обычно занимают в памяти один байт (8-разрядная ячейка) или два байта (16-разрядная ячейка). Диапазон значений в первом случае от 000000002 до 111111112 (от 010 до 25510) , а в двухбайтовом формате — от 00000000 000000002 до 11111111 111111112 (от 010 до 6553510)
Чтобы получить внутреннее представление целого положительного числа N, хранящегося в k-разрядном машинном слове, необходимо:
перевести число N в двоичную систему счисления;
полученный результат дополнить слева незначащими нулями до k разрядов.
Например, для целого числа 1607 в двухбайтовой ячейке внутреннее представление N=(1607)10=(11001000111)2. будет следующим 0000 0110 0100 0111. Шестнадцатеричная форма внутреннего представления числа N будет 0647.
Разряды нумеруются справа налево, начиная с нуля. Примеры:
а) число 7210 = 10010002 в однобайтовом формате:
8.1.Числовые типы
Числовые типы состоят из двух-, четырех- и восьмибайтовых целых чисел, четырех- и восьмибайтовых чисел с плавающей запятой и десятичных дробей с выбираемой точностью. В таблице 8.2 перечислены доступные типы.
Таблица 8.2. Числовые типы
| Name | Storage Size | Description | Range |
|---|---|---|---|
| smallint | 2 bytes | small-range integer | От -32768 до +32767 |
| integer | 4 bytes | типичный выбор для целого числа | С -2147483648 до +2147483647 |
| bigint | 8 bytes | large-range integer | От -9223372036854775808 до +9223372036854775807 |
| decimal | variable | заданная пользователем точность,аккуратность | до 131072 цифр до запятой;до 16383 цифр после запятой |
| numeric | variable | заданная пользователем точность,аккуратность | до 131072 цифр до запятой;до 16383 цифр после запятой |
| real | 4 bytes | variable-precision, inexact | 6 десятичная точность |
| double precision | 8 bytes | variable-precision, inexact | 15-значная точность |
| smallserial | 2 bytes | малое автоинкрементирующее целое число | 1-32767 |
| serial | 4 bytes | autoincrementing integer | 1-2147483647 |
| bigserial | 8 bytes | большое автоинкрементирующее целое число | 1 до 9223372036854775807 |
Синтаксис констант для числовых типов описан в разделе 4.1.2 . Числовые типы имеют полный набор соответствующих арифметических операторов и функций. Обратитесь к главе 9 для получения дополнительной информации. В следующих разделах подробно описаны типы.
8.1.1 целые типы
Типы smallint , integer и bigint хранят целые числа, то есть числа без дробных компонентов, различных диапазонов. Попытки сохранить значения за пределами допустимого диапазона приведут к ошибке.
Тип integer является обычным выбором, так как он предлагает лучший баланс между диапазоном, размером хранилища и производительностью. Тип smallint обычно используется только в том случае, если дисковое пространство ограничено. Тип bigint предназначен для использования, когда диапазон integer типа недостаточен.
SQL определяет только целые типы integer (или int ), smallint и bigint . Имена типов int2 , int4 и int8 являются расширениями, которые также используются некоторыми другими системами баз данных SQL.
8.1.2.Произвольные номера точности
Тип numeric может хранить числа с очень большим количеством цифр. Особенно рекомендуется для хранения денежных сумм и других величин, где требуется точность. Вычисления с numeric значениями по возможности дают точные результаты, например, сложение, вычитание, умножение. Однако вычисления numeric значений очень медленны по сравнению с целочисленными типами или типами с плавающей запятой, описанными в следующем разделе.
Мы используем следующие термины ниже: точность из numeric является общее количество значащих цифр в целое число, то есть число цифр с обеих сторон десятичной точки. Шкала из numeric является счетчиком десятичных цифр в дробной части, справа от десятичной точки. Таким образом, число 23,5141 имеет точность 6 и шкалу 4. Можно считать, что целые числа имеют нулевую шкалу.
Можно настроить как максимальную точность, так и максимальный масштаб numeric столбца. Чтобы объявить столбец numeric типа, используйте синтаксис:
Точность должна быть положительной,а масштаб может быть положительным или отрицательным (см.ниже).Альтернативный вариант:
выбирает шкалу 0.Указание:
без какой-либо точности или масштаба создает «неограниченный числовой» столбец, в котором могут храниться числовые значения любой длины, вплоть до ограничений реализации. Столбец такого типа не будет приводить входные значения к какому-либо конкретному масштабу, тогда как numeric столбцы с объявленным масштабом будут приводить входные значения к этому масштабу. (Стандарт SQL требует шкалы по умолчанию, равной 0, т. е. приведения к целочисленной точности. Мы считаем это немного бесполезным. Если вас беспокоит переносимость, всегда указывайте точность и масштаб явно.)
Максимальная точность, которая может быть явно указана в объявлении numeric типа, равна 1000. Неограниченный numeric столбец подчиняется ограничениям, описанным в таблице 8.2 .
Если масштаб сохраняемого значения больше,чем заявленный масштаб столбца,система округляет значение до указанного количества дробных цифр.Затем,если количество цифр слева от десятичной точки превышает заявленную точность минус заявленный масштаб,выдается ошибка.Например,столбец,объявленный как
округляет значения до 1 десятичного знака и может хранить значения от -99,9 до 99,9,включительно.
Начиная с PostgreSQL 15 разрешено объявлять numeric столбец с отрицательной шкалой. Тогда значения будут округлены слева от десятичной точки. Точность по-прежнему представляет собой максимальное количество неокругленных цифр. Таким образом, столбец, объявленный как
округляет значения до ближайшей тысячи и может хранить значения в диапазоне от -99000 до 99000 включительно.Также разрешается объявить масштаб,больший,чем объявленная точность.Такой столбец может хранить только дробные значения и требует,чтобы количество нулевых цифр справа от десятичной точки было не меньше объявленной шкалы минус объявленная точность.Например,столбец,объявленный как
округляет значения до 5 десятичных знаков и может хранить значения от -0,00999 до 0,00999,включительно.
PostgreSQL допускает любое значение масштаба в объявлении numeric типа в диапазоне от -1000 до 1000. Однако стандарт SQL требует, чтобы масштаб находился в диапазоне от 0 до precision . Использование масштабов за пределами этого диапазона может оказаться несовместимым с другими системами баз данных.
Числовые значения физически хранятся без каких-либо дополнительных нулей в начале или в конце. Таким образом, заявленная точность и масштаб столбца являются максимальными, а не фиксированными выделениями. (В этом смысле numeric тип больше похож на varchar(n) чем на char(n) .) Фактические требования к хранилищу — два байта для каждой группы из четырех десятичных цифр плюс от трех до восьми байтов накладных расходов.
В дополнение к обычным числовым значениям numeric тип имеет несколько специальных значений:
Infinity -Infinity NaN
Они адаптированы из стандарта IEEE 754 и представляют «бесконечность», «отрицательную бесконечность» и «не-число» соответственно. Записывая эти значения как константы в команде SQL, вы должны заключать их в кавычки, например UPDATE table SET x = ‘-Infinity’ . При вводе эти строки распознаются без учета регистра. В качестве альтернативы значения бесконечности могут быть записаны как inf и -inf .
Значения бесконечности соответствуют математическим ожиданиям. Например, Infinity плюс любое конечное значение равно Infinity , как и Infinity плюс Infinity ; но Infinity минус Infinity дает NaN (не число), потому что у него нет четко определенной интерпретации. Обратите внимание, что бесконечность может храниться только в неограниченном numeric столбце, потому что она условно превышает любой предел конечной точности.
Значение NaN (не число) используется для представления неопределенных результатов вычислений. В общем, любая операция с вводом NaN дает еще одно NaN . Единственное исключение — это когда другие входные данные операции таковы, что такой же результат был бы получен, если бы NaN было заменено любым конечным или бесконечным числовым значением; затем это выходное значение также используется для NaN . (Примером этого принципа является то, что NaN , возведенное в нулевую степень, дает единицу.)
В большинстве реализаций концепции «не число» NaN не считается равным любому другому числовому значению (включая NaN ). Чтобы numeric значения можно было сортировать и использовать в древовидных индексах, PostgreSQL рассматривает значения NaN как равные и превышающие все значения, отличные от NaN .
decimal и numeric типы эквивалентны. Оба типа являются частью стандарта SQL.
При округлении значений numeric тип округляет связи от нуля, в то время как (на большинстве машин) real типы и типы double precision округляют связи до ближайшего четного числа. Например:
8.1.3.Типы с плавающей точкой
Типы данных real и double precision являются неточными числовыми типами переменной точности. На всех поддерживаемых в настоящее время платформах эти типы являются реализациями стандарта IEEE 754 для двоичной арифметики с плавающей запятой (одинарная и двойная точность, соответственно) в той мере, в какой это поддерживают базовый процессор, операционная система и компилятор.
Неточность означает,что некоторые значения не могут быть точно преобразованы во внутренний формат и хранятся в виде аппроксимаций,так что при хранении и извлечении значения могут наблюдаться небольшие расхождения.Управление этими ошибками и то,как они распространяются посредством вычислений,является предметом изучения целой отрасли математики и информатики и не будет обсуждаться здесь,за исключением следующих пунктов:
Если вам требуется точное хранение и вычисления (например, для денежных сумм), используйте вместо этого numeric тип.
Если вы хотите делать сложные вычисления с этими типами для чего-то важного,особенно если вы полагаетесь на определенное поведение в граничных случаях (бесконечность,недолив),то вы должны внимательно оценить реализацию.
Сравнение двух значений с плавающей запятой для равенства может не всегда работать так,как ожидалось.
На всех поддерживаемых в настоящее время платформах real тип имеет диапазон от 1E-37 до 1E + 37 с точностью не менее 6 десятичных знаков. Тип double precision имеет диапазон от 1E-307 до 1E + 308 с точностью не менее 15 цифр. Слишком большие или слишком маленькие значения вызовут ошибку. Округление может произойти, если точность введенного числа слишком высока. Слишком близкие к нулю числа, которые нельзя представить как отличные от нуля, вызовут ошибку потери значимости.
По умолчанию значения с плавающей запятой выводятся в текстовой форме в их кратчайшем точном десятичном представлении; полученное десятичное значение ближе к истинному сохраненному двоичному значению, чем к любому другому значению, представляемому с такой же двоичной точностью. (Однако выходное значение в настоящее время никогда не находится точно посередине между двумя представляемыми значениями, чтобы избежать широко распространенной ошибки, когда входные процедуры не соблюдают должным образом правило округления до ближайшего четного.) Это значение будет использовать не более 17 значащих десятичных знаков. цифры для значений float8 и не более 9 цифр для значений float4 .
Этот максимально точный формат вывода генерируется намного быстрее,чем исторический формат с округлением.
Для совместимости с выводом, генерируемым более старыми версиями PostgreSQL, и для снижения точности вывода можно использовать параметр extra_float_digits для выбора округленного десятичного вывода. Установка значения 0 восстанавливает предыдущее значение по умолчанию округления значения до 6 (для float4 ) или 15 (для float8 ) значащих десятичных цифр. Установка отрицательного значения еще больше уменьшает количество цифр; например -2 будет округлять вывод до 4 или 13 цифр соответственно.
Любое значение extra_float_digits больше 0 выбирает самый короткий точный формат.
Приложениям, которые хотели получить точные значения, исторически приходилось устанавливать для extra_float_digits значение 3, чтобы получить их. Для максимальной совместимости между версиями они должны продолжать это делать.
Помимо обычных числовых значений,типы с плавающей точкой имеют несколько специальных значений:
Infinity -Infinity NaN
Они представляют специальные значения IEEE 754 «бесконечность», «отрицательная бесконечность» и «не-число» соответственно. Записывая эти значения как константы в команде SQL, вы должны заключать их в кавычки, например UPDATE table SET x = ‘-Infinity’ . При вводе эти строки распознаются без учета регистра. В качестве альтернативы значения бесконечности могут быть записаны как inf и -inf .
IEEE 754 указывает, что NaN не должно сравниваться с любым другим значением с плавающей запятой (включая NaN ). Чтобы значения с плавающей запятой можно было сортировать и использовать в древовидных индексах, PostgreSQL рассматривает значения NaN как равные и большие, чем все значения, отличные от NaN .
PostgreSQL также поддерживает стандартные нотации SQL float и float(p) для указания неточных числовых типов. Здесь p указывает минимально допустимую точность двоичных цифр. PostgreSQL принимает значения от float(1) до float(24) как выбор real типа, а от float(25) до float(53) выбирает double precision . Значения p вне допустимого диапазона приводят к ошибке. float без указанной точности означает double precision .
8.1.4.Последовательные типы
В этом разделе описан специфичный для PostgreSQL способ создания столбца с автоинкрементом. Другой способ — использовать стандартную функцию столбца идентификаторов SQL, описанную в CREATE TABLE .
Типы данных smallserial , serial и bigserial не являются истинными типами, а являются просто удобством записи для создания столбцов уникальных идентификаторов (аналогично свойству AUTO_INCREMENT , поддерживаемому некоторыми другими базами данных). В текущей реализации, указав:
Таким образом, мы создали целочисленный столбец и сделали так, чтобы его значения по умолчанию назначались из генератора последовательности. Ограничение NOT NULL применяется, чтобы гарантировать, что нулевое значение не может быть вставлено. (В большинстве случаев вы также захотите прикрепить ограничение UNIQUE или PRIMARY KEY , чтобы предотвратить случайную вставку повторяющихся значений, но это не происходит автоматически.) Наконец, последовательность помечается как «принадлежащая» столбцу, чтобы она будет удален, если столбец или таблица удалены.
Поскольку smallserial , serial и bigserial реализуются с использованием последовательностей, могут быть «дыры» или пробелы в последовательности значений, которая появляется в столбце, даже если никакие строки никогда не удаляются. Значение, выделенное из последовательности, все еще «израсходовано», даже если строка, содержащая это значение, никогда не вставляется успешно в столбец таблицы. Это может произойти, например, при откате вставляющей транзакции. За подробностями nextval() в Разделе 9.17 .
Чтобы вставить следующее значение последовательности в столбец serial , укажите, что столбцу serial должно быть присвоено значение по умолчанию. Это можно сделать либо путем исключения столбца из списка столбцов в операторе INSERT , либо с помощью ключевого слова DEFAULT .
Имена типов serial и serial4 эквивалентны: оба создают integer столбцы. Имена типов bigserial и serial8 работают одинаково, за исключением того, что они создают столбец bigint . bigserial следует использовать, если вы ожидаете использования более 2 31 идентификаторов за время существования таблицы. Имена типов smallserial и serial2 также работают одинаково, за исключением того, что они создают столбец smallint .
Последовательность, созданная для serial столбца, автоматически удаляется при удалении столбца-владельца. Вы можете отбросить последовательность, не удаляя столбец, но это приведет к удалению выражения столбца по умолчанию.
8 байтовые знаковые целые числа что это
Целые числа являются простейшими числовыми данными, с которыми оперирует ЭВМ. Для целых чисел существуют два представления: беззнаковое (только для неотрицательных целых чисел) и со знаком. Очевидно, что отрицательные числа можно представлять только в знаковом виде. Целые числа в компьютере хранятся в формате с фиксированной запятой.
Представление целых чисел в беззнаковых целых типах.
Представление целых чисел в знаковых целых типах.
Прямой код числа.
Дополнительный код числа.
Дополнительный код положительного числа равен прямому коду этого числа. Дополнительный код отрицательного числа m равен 2 k -|m|, где k — количество разрядов в ячейке.
Как уже было сказано, при представлении неотрицательных чисел в беззнаковом формате все разряды ячейки отводятся под само число. Например, запись числа 243=11110011 в одном байте при беззнаковом представлении будет выглядеть следующим образом:
| 1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 |
При представлении целых чисел со знаком старший (левый) разряд отводится под знак числа, и под собственно число остаётся на один разряд меньше. Поэтому, если приведённое выше состояние ячейки рассматривать как запись целого числа со знаком, то для компьютера в этой ячейке записано число -13 (243+13=256=28).
Но если это же отрицательное число записать в ячейку из 16-ти разрядов, то содержимое ячейки будет следующим:
| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 |
Знаковый разряд
Возникает вопрос: с какой целью отрицательные числа записываются в виде дополнительного кода и как получить дополнительный код отрицательного числа?
Дополнительный код используется для упрощения выполнения арифметических операций. Если бы вычислительная машина работала с прямыми кодами положительных и отрицательных чисел, то при выполнении арифметических операций следовало бы выполнять ряд дополнительных действий. Например, при сложении нужно было бы проверять знаки обоих операндов и определять знак результата. Если знаки одинаковые, то вычисляется сумма операндов и ей присваивается тот же знак. Если знаки разные, то из большего по абсолютной величине числа вычитается меньшее и результату присваивается знак большего числа. То есть при таком представлении чисел (в виде только прямого кода) операция сложения реализуется через достаточно сложный алгоритм. Если же отрицательные числа представлять в виде дополнительного кода, то операция сложения, в том числе и разного знака, сводится к из поразрядному сложению.
Для компьютерного представления целых чисел обычно используется один, два или четыре байта, то есть ячейка памяти будет состоять из восьми, шестнадцати или тридцати двух разрядов соответственно.
Алгоритм получения дополнительного кода отрицательного числа.
- модуль отрицательного числа представить прямым кодом в k двоичных разрядах;
- значение всех бит инвертировать:все нули заменить на единицы, а единицы на нули(таким образом, получается k-разрядный обратный код исходного числа);
- к полученному обратному коду прибавить единицу.
Пример:
Получим 8-разрядный дополнительный код числа -52:
Можно заметить, что представление целого числа не очень удобно изображать в двоичной системе, поэтому часто используют шестнадцатеричное представление:
Представление вещественных чисел в компьютере.
Для представления вещественных чисел в современных компьютерах принят способ представления с плавающей запятой. Этот способ представления опирается на нормализованную (экспоненциальную) запись действительных чисел.
Как и для целых чисел, при представлении действительных чисел в компьютере чаще всего используется двоичная система, следовательно, предварительно десятичное число должно быть переведено двоичную систему.
Нормализованная запись числа.
Нормализованная запись отличного от нуля действительного числа — это запись вида a= m*P q , где q — целое число (положительное, отрицательное или ноль), а m — правильная P-ичная дробь, у которой первая цифра после запятой не равна нулю, то есть . При этом m называется мантиссой числа, q — порядком числа.
- 3,1415926 = 0, 31415926 * 10 1 ;
- 1000=0,1 * 10 4 ;
- 0,123456789 = 0,123456789 * 10 0 ;
- 0,00001078 = 0,1078 * 8 -4 ; (порядок записан в 10-й системе)
- 1000,00012 = 0, 100000012 * 2 4 .
Нормализованная экспоненциальная запись числа — это запись вида a= m*P q , где q — целое число (положительное, отрицательное или ноль), а m — P-ичная дробь, у которой целая часть состоит из одной цифры. При этом (m-целая часть) называется мантиссой числа, q — порядком числа.
Представление чисел с плавающей запятой.
При представлении чисел с плавающей запятой часть разрядов ячейки отводится для записи порядка числа, остальные разряды — для записи мантиссы. По одному разряду в каждой группе отводится для изображения знака порядка и знака мантиссы. Для того, чтобы не хранить знак порядка, был придуман так называемый смещённый порядок, который рассчитывается по формуле 2 a-1 +ИП, где a — количество разрядов, отводимых под порядок.
Пример:
Если истинный порядок равен -5, тогда смещённый порядок для 4-байтового числа будет равен 127-5=122.
Алгоритм представления числа с плавающей запятой.
- Перевести число из p-ичной системы счисления в двоичную;
- представить двоичное число в нормализованной экспоненциальной форме;
- рассчитать смещённый порядок числа;
- разместить знак, порядок и мантиссу в соответствующие разряды сетки.
Можно заметить, что представление действительного числа не очень удобно изображать в двоичной системе, поэтому часто используют шестнадцатеричное представление:
Хранение в памяти целых чисел
Целые числа являются самыми простыми числовыми данными, с которыми работает компьютер. Целые числа хранятся в двух возможных видах: беззнаковом (для положительных целых чисел) и со знаком (для отрицательных чисел). Целые числа в компьютере хранятся в формате с фиксированной запятой.
Беззнаковые целые числа
Для беззнакового представления все разряды ячейки отводятся под представление самого числа. Поэтому, если известно, что число положительное, то выгоднее рассматривать его как беззнаковое.
Положительные целые числа занимают в памяти компьютера $1$ или $2$ байта.
В $1$-байтовом формате целые числа принимают значения от $0$ до $255$.
В $2$-байтовом формате от $0$ до $65535$.
Число $30_<10>=0001 \ 1110_2$ в $1$-байтовом формате:
Число $30_<10>=0001 \ 1110_2$ в 2-байтовом формате:

Алгоритм представления в компьютере беззнаковых целых чисел
Беззнаковое целое положительное число перевести в двоичную систему счисления.
Записать число в $8$ разрядах так, чтобы младший разряд числа соответствовал младшему разряду ячейки.
Дополнить число, если необходимо, слева нулями до нужного числа разрядов ($8$-ми, $16$-ти, $32$-х).
Получить 8-разрядное представление числа $30$.

Дополним до $8$-ми разрядов:
Целые числа со знаком
Целые числа со знаком (отрицательные) занимают в памяти компьютера $1$, $2$ или $4$ байта, при этом самый старший (знаковый) разряд содержит информацию о знаке числа.
Если число положительное, то в знаковом разряде помещается $«0»$, если число отрицательное — $«1»$.
Целые числа со знаком в разных форматах принимают соответствующие значения:
в $1$-байтовом формате — от $-128$ до $127$;
в $2$-байтовом формате — от $-32768$ до $32767$;
в $4$-байтовом формате — от $-2147483648$ до $2147483647$.
Для хранения целых чисел со знаком отводится $1$ разряд для знака, а остальные — для цифр модуля числа.
Например, для хранения числа в $1$-байтовом формате ($8$ бит) $1$ разряд отводится для знака числа, остальные $7$ разрядов — для модуля числа.
Для хранения целых чисел со знаком применяется $3$ формы кода:
Особенно широко используется обратный и дополнительный код, которые позволяют существенно облегчить элементарные операции: сложение, вычитание, умножение и деление.
Положительные числа в прямом, обратном и дополнительном кодах изображают двоичными кодами с цифрой $0$ в знаковом разряде.
У положительных чисел все коды одинаковы, т.е. прямой, обратный и дополнительный коды равны между собой.

Отрицательные числа в прямом, обратном и дополнительном кодах изображаются по-разному.
Прямой код числа — это его модуль, переведенный в двоичную систему с измененным старшим битом, в зависимости от знака.
В знаковом разряде помещается цифра $1$, а в разрядах цифровой части числа — двоичный код модуля числа.
Числа в компьютере хранятся целыми байтами; $1$, $2$, $4$ или $8$. От количества памяти зависит количество разрядов данного числа. В $1$ байте их $8$, в $2$ — $16$ и т.д. Поэтому представляемые числа нужно дополнять нулями до необходимого количества.

Если числа будут занимать в памяти $2$ байта, то знаковым все равно будет самый старший, то есть: $-30_<10>=1001 \ 1110_2= 1000 \ 0000 \ 0001 \ 1110_2$
Обратный код. Для операций с отрицательными числами обычно не используется прямой код, поэтому для облегчения алгоритмов выполнения арифметических операций был создан обратный код.
Для получения обратного кода выполняется инвертирование всех цифр двоичного кода модуля числа: $0$ заменяется на $1$, а $1$ — на $0$. Знак разряда остается без изменений.

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

Алгоритм получения дополнительного кода отрицательного числа
Модуль отрицательного числа представить прямым кодом.
Значение всех бит инвертировать: все $0$ заменить на $1$, а $1$ на $0$ (кроме значения знакового разряда).
К младшему разряду полученного обратного кода прибавить единицу.
Получим $8$-разрядный дополнительный код числа $-30$:
$00011110 — \ число \mid -30\mid =30$ в прямом коде
$11100001 — \ число \ -30$ в обратном коде
$11100010 — \ число \ -30$ в дополнительном коде
Целые отрицательные числа при вводе в компьютер преобразуются в обратный или дополнительный двоичный код и в таком виде хранятся и принимают участие в операциях. При выводе их из компьютера происходит обратное преобразование в отрицательные десятичные числа.