Шрифт:
Интервал:
Закладка:
Значение с плавающей точкой несет больше информации, чем указанное количество цифр точности. Например, тип FLOAT имеет точность 7 цифр, но его реальная точность 6 цифр. Последняя часть предоставляет дополнительную информацию о числе, такую как индикатор для округления и некоторые другие вещи, важные при выполнении арифметических операций с числом.
Например, FLOAT может содержать число 1000000000 (1 000 000 000 или 10(^9^)). "Контейнер" FLOAT рассматривает данное число как 100000*Е4. (Это лишь иллюстрация - полное представление реализации чисел с плавающей точкой выходит за рамки настоящей книги и очень далеко от того, что узнал автор!). Если вы прибавите 1 к значению FLOAT, то будет проигнорирована информация в седьмом разряде, потому что она не является значимой для текущего значения числа и его точности. Если же вы прибавляете 10 000 - число, которое значимо для хранимого в типе FLOAT числа, - то результатом может быть 100001*Е4.
Даже значения с подходящей точностью числа с плавающей точкой могут не всегда храниться в точном представлении. Такие значения, как 1.93 или даже 123, могут быть представлены в памяти как значения, очень близкие к указанному числу. Эти значения достаточно близки- когда число с плавающей точкой округляется для вывода, оно будет отображать ожидаемое значение, когда оно используется в вычислениях, результат будет очень близким приближением к ожидаемому результату.
Эффект такой: когда вы выполняете какое-либо вычисление, которое должно дать результат 123, оно может быть очень близким приближением к 123. При точных сравнениях (равенство, больше чем, меньше чем и т.д.) между двумя числами с плавающей точкой, между числом с плавающей точкой и нулем или числом с плавающей точкой и числом с фиксированной точкой не следует рассчитывать на ожидаемые результаты.
По этой причине не следует рассматривать использование столбцов с плавающей точкой в качестве ключей или применять к ним ограничения уникальности. Они не будут работать предсказуемо для отношений внешнего ключа или в объединениях.
Для сравнений проверяйте значения с плавающей точкой в предложении BETWEEN с подходящим диапазоном вместо того, чтобы выполнять точную проверку. Тот же совет применим и для сравнения с нулем - выберите подходящий диапазон значений и запишите проверку данных между нулем и близким к нулю значением или между двумя подходящими значениями, близкими к нулю[23].
В базе данных диалекта 1 необходимость хранения значений числовых данных, имеющих больший диапазон, чем предоставляет 32-битовое целое, может быть решена выбором типа DOUBLE PRECISION. Ограничения диалекта 1 также требуют использования чисел с плавающей точкой для всех действительных чисел, если к базе данных предполагается доступ из встроенного приложения (ESQL).
Firebird предоставляет два приближенных числовых типа данных с плавающей точкой (FLOAT и DOUBLE PRECISION), отличающиеся только размером точности.
FLOAT
FLOAT является 32-битовым типом данных с плавающей точкой с приблизительно 7 цифрами точности - для надежности предполагайте 6 цифр. Число с 10 цифрами 25.33333312, добавленное в столбец FLOAT, сохраняется как 25.33333. Диапазон чисел от -3.402 x 10(^38^) до 3.402 x 10(^38^). Наименьшее положительное число, которое может быть сохранено, 1.175 * 10(^-38^).
DOUBLE PRECISION
DOUBLE PRECISION является 64-битовым типом данных с плавающей точкой с приблизительно 15 цифрами точности. Диапазон от -1.797 x 10(^308^) до 1.797 x 10(^308^). Наименьшее положительное число, которое может быть сохранено, 2.225 x 10(^-308^).
Арифметические операции над смешанными типами с фиксированной и плавающей точкойКогда бинарная операция (сложение, вычитание, умножение и деление) включает в качестве операндов точные числа и числа с плавающей точкой, то результат будет типа DOUBLE PRECISION.
Следующий оператор создает столбец PERCENT_CHANGE, используя тип DOUBLE PRECISION:
CREATE TABLE SALARY_HISTORY
(
. . .
PERCENT_CHANGE DOUBLE PRECISION
DEFAULT О
NOT NULL
CHECK (PERCENT_CHANGE BETWEEN -50 AND 50),
. . .
) ;
Следующий оператор CREATE TABLE дает пример использования различных числовых типов данных: INTEGER для общего количества заказов, с фиксированной точкой DECIMAL для общей суммы продаж в долларах и FLOAT для скидки к продаже:
CREATE TABLE SALES
(. . .
QTY_ORDERED INTEGER
DEFAULT 1
CHECK (QTY_ORDERED >=1),
TOTAL_VALUE DECIMAL (9,2)
CHECK (TOTAL_VALUE >= 0),
DISCOUNT FLOAT
DEFAULT 0
CHECK (DISCOUNT >= 0 AND DISCOUNT <= 1));
Пора дальшеВ следующей главе мы рассмотрим типы данных для хранения и обработки дат и времени в Firebird.
ГЛАВА 10. Типы даты и времени.
Firebird поддерживает в диалекте 3 типы данных DATE, TIME и TIMESTAMP. В диалекте 1 поддерживается только один тип данных, подобный TIMESTAMP, который, хотя и называется DATE, не является взаимозаменяемым с типом DATE диалекта 3.
DATE
В диалекте 3 DATE хранит одну дату без времени - тип "только дата" - в виде 32-битового знакового целого. Хранимый диапазон дат от 1 января 0001 года до 31 декабря 9999 года[24].
В диалекте 1 тип DATE эквивалентен типу TIMESTAMP диалекта 3. Действительно, когда вы создаете новый столбец даты в базе данных диалекта 1 с использованием isql, появляется предупреждение, информирующее вас, что тип данных был переименован! SQLTYPE будет иметь тип ISC_TIMESTAMP.
Не существует типа "только дата" в диалекте 1. Для сохранения в диалекте 1 только даты, передайте правильное значение даты и литерал времени в виде "00:00:00.0000". Литералы даты и времени обсуждаются более подробно в следующих разделах.
! ! !
СОВЕТ. Если вы используете isql для проверки дат диалекта 1, вы можете включать/выключать отображение времени при выводе даты, используя команду isql SET TIME. По умолчанию вывод времени отключен.
. ! .
TIMESTAMP
Тип данных TIMESTAMP диалекта 3 состоит из двух 32-битовых слов, хранящих дату и время. Данные хранятся как два 32-битовых целых, что эквивалентно типу DATE в диалекте 1.
Доли секунды
Доли секунды, если хранятся, являются десятитысячными долями секунды для всех типов даты и времени.
TIME
В диалекте 3 TIME хранит время дня без даты: "только время". Для хранения используется 32-битовое беззнаковое целое. Диапазон времени от 00:00 до 23:59:59.9999.
В диалекте 1 нет эквивалента типу TIME. Если нужно сохранить время дня, выделите элементы часов, минут и секунд из данных DATE и преобразуйте в строку. Технические советы есть дальше в этой главе - обратитесь к разд. "Комбинирование EXTRACT() с другими функциями".
Интервал времени
Ошибочно предполагать, что тип TIME может хранить интервал времени. Он не может. Для вычисления интервала времени вычтите более позднюю дату или время из более раннего. Результатом будет число NUMERIC(18,9), выражающее интервал в днях. Поскольку точность теряется, доли секунд надо рассматривать как миллисекунды, а не десятитысячные доли секунд. Используйте обычные арифметические операции для конвертирования дней в часы, минуты или секунды, как вам требуется.
Предположим, что столбцы STARTED и FINISHED имеют тип TIMESTAMP (DATE В диалекте 1). Для вычисления и сохранения в столбце TIME_ELAPSED типа DOUBLE PRECISION интервала времени в минутах вы можете использовать следующее[25]:
UPDATE ATABLE
SET TIME_ELAPSED = (FINISHED - STARTED) * 24 * 60
WHERE ((FINISHED IS NOT NULL) AND (STARTED IS NOT NULL));
Литералы даты
Литералы даты являются "читаемыми человеком" строками, заключенными в апострофы. Их сервер Firebird распознает как константы даты или даты-и-времени для EXTRACT и других выражений, операций INSERT и UPDATE, а также в предложении WHERE оператора SELECT.
Литералы даты используются, когда нужно передать константы даты:
* операторам SELECT, UPDATE и DELETE в условия поиска предложения WHERE;
* операторам INSERT и UPDATE для ввода констант даты и времени;
* аргументу FROM функции EXTRACT().
Распознаваемые форматы литералов даты и времени
Количество форматов строк, распознаваемых как литералы даты, ограничено. Эти форматы используют шаблоны для подстановки элементов строк. Табл. 10.1 описывает используемые соглашения.
Таблица 10.1. Элементы литералов даты
Элемент Представление CC Столетие. Первые две цифры года (например, 20 для двадцать первого века) YY Год столетия. Firebird всегда сохраняет полное значение года, даже если год был введен без сегмента cc, при этом используется алгоритм "скользящего окна" для определения того, какое столетие сохранять MM Месяц- целое в диапазоне от 1 до 12. В некоторых форматах требуется две цифры MMM Месяц - один из [JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC] . Также допустимы полные английские названия месяцев DD День месяца- целое в диапазоне от 1 до 31. В некоторых форматах требуется две цифры. Неверное значение дня для конкретного месяца вызывает ошибку HH Часы - целое в диапазоне от 00 до 23. Требуются две цифры NN Минуты - целое в диапазоне от 00 до 59. Требуются две цифры SS Полные секунды - целое в диапазоне от 00 до 59. Требуются две цифры nnnn Десятитысячные доли секунды в диапазоне от 0 до 9999. Значение по умолчанию 0000. Если используется, то требуется четыре цифрыРаспознаваемые форматы описаны в табл. 10.2.
- Delphi. Учимся на примерах - Сергей Парижский - Программирование
- Сделай видеоигру один и не свихнись - Слава Грис - Программирование / Руководства
- Психбольница в руках пациентов - Алан Купер - Программирование