русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Дробные типы


Дата добавления: 2015-06-12; просмотров: 673; Нарушение авторских прав


дробные типы — это float и double. Их длина - 4 и 8 байт, соответст­венно. Оба типа знаковые. Ниже в таблице сведены их характеристики:

Для целочисленных типов область значений задавалась верхней и нижней границами, весьма близкими по модулю. Для дробных типов добавляется еще одно ограничение — насколько можно приблизиться к нулю, другими словами — каково наименьшее положительное нену­левое значение. Таким образом, нельзя задать литерал заведомо боль­ший, чем позволяет соответствующий тип данных, это приведет к ошибке overflow. И нельзя задать литерал, значение которого по моду­лю слишком мало для данного типа, компилятор сгенерирует ошибкуunderflow.

// пример вызовет ошибку компиляции

float f = 1e40f; // значение слишком велико, overflow

Табл. 4. Дробные типы данных.


double d = 1е-350; // значение слишком мало, underflow

Напомним, что если в конце литерала стоит буква F или f, то литерал рассматривается как значение типа float. По умолчанию дробный литерал имеет тип double, при желании это можно подчеркнуть буквой D или d.

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

• операции сравнения (возвращают булевское значение)

• числовые операции (возвращают числовое значение)

• унарные операции + и -

• арифметические операции +,-,*,/,%

• операции инкремента и декремента (в префиксной и пост­фиксной форме): ++ и —

• оператор с условием ?

• оператор приведения типов

• оператор конкатенации со строкой +

Практически все операторы действуют по тем же принципам, кото­рые предусмотрены для целочисленных операторов (оператор деления с остатком % рассматривался в предыдущей лекции, а операторы ++ и -- так­же увеличивают или уменьшают значение переменной на единицу). Уточ­ним лишь, что операторы сравнения корректно работают и в случае срав­нения целочисленных значений с дробными. Таким образом, в основном необходимо рассмотреть вопросы переполнения и преобразования типов при вычислениях.



Для дробных вычислений появляется уже два типа переполнения — Overflow и underflow. Тем не менее, Java и здесь никак не сообщает о возник­новении подобных ситуаций. Нет ни ошибок, ни других способов обнару­жить их. Более того, даже деление на ноль не приводит к некорректной ситуации. А значит, дробные вычисления вообще не порождают никаких

ошибок.

Такая свобода связана с наличием специальных значений дробного типа. Они определяются спецификацией IEEE 754 и уже перечислялись в лекции 3:

• положительная и отрицательная бесконечности (positive/negative infinity);

• значение "не число", Not-a-Number, сокращенно NaN;

• положительный и отрицательный нули.

Все эти значения представлены как для типа float, так и для double. Положительную и отрицательную бесконечности можно получить Следующим образом:

1f/0f // положительная бесконечность, тип float -Id/Od // отрицательная бесконечность, тип double

Также в классах Float и Double определены константы POSITIVEJNFINITY и NEGATIVEJNFINITY. Как видно из примера, такие величины получаются при делении конечных величин на ноль.

Значение NaN можно получить, например, в результате следующих действий:

0.0/0.0 // деление ноль на ноль

(1.0/0.0)*0.0 // умножение бесконечности на ноль эта величина также представлена константами NaN в классах Float и Double.

Величины положительный и отрицательный ноль записываются очевидным образом:

0.0 // дробный литерал со значением положительного нуля +0.0//унарная операция +, ее значение - положительный ноль -0.0 // унарная операция -, ее значение - отрицательный ноль все дробные значения строго упорядочены. Отрицательная беско­нечность меньше любого другого дробного значения, положительная -больше. Значения +0.0 и -0.0 считаются равными, то есть выражение 0.0==-0.0 истинно, а 0.0>-0.0 — ложно. Однако другие операторы разли­чают их, например, выражение 1.0/0.0 дает положительную бесконеч­ность, а 1.0/-0.0 — отрицательную.

Единственное исключение - значение NaN. Если хотя бы один из ар­гументов операции сравнения равняется NaN, то результат заведомо бу­дет false (для оператора != соответственно всегда true). Таким образом, единственное значение х, при котором выражение х1=х истинно,— имен­но NaN.

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

print(1e20f*1e20f); print(-1e200*1e200);

В результате получаем:

Infinity -Infinity

Если результат, напротив, получается слишком мал (underflow), то он просто округляется до нуля. Так же поступают и в том случае, когда ко­личество десятичных знаков превышает допустимое:

print(1e-40f/1e10f); // underflow для float

print(-1e-300/1e100); // underflow для double

float f=1e-6f;

print(f);

f+=0.002f;

print(f);

f+=3;

print(f);

f+=4000;

prlnt(f);

Результатом будет:

0.0 -0.0

1.0E-6 0.002001 3.002001 4003.002

Как видно, в последней строке был утрачен 6-й разряд после десятич­ной точки.

Другой пример (из спецификации языка Java):

double d = 1е-305 * Math.PI;

print(d);

for (int I = 0; i < 4; i++)

print(d/= 100000);

Результатом будет:

3.141592653589793E-305

3.1415926535898E-310

3.141592653E-315

3.142E-320

0.0

Таким образом, как и для целочисленных значений, явное выписыва­ние в коде литералов, которые слишком велики (overflow) или слишком малы (underflow) для используемых типов, приводит к ошибке компиля­ции (см. лекцию 3). Если же переполнение возникает в результате выпол­нения операции, то возвращается одно из специальных значений.

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

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

Эти утверждения верны и в случае, если один из аргументов цело­численный. Если хотя бы один из аргументов имеет значение NaN, то и результатом операции будет NaN,

Еще раз рассмотрим простой пример:

print(1/2); print(1/2.);

Результатом будет:

О 0.5

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

intx=3;

int у=5;

print (х/у);

print((double)x/y);

print(1.0*x/y);

Результатом будет:

О

0.6

0.6

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

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

Приведение типов подробно рассматривается в другой лекции, од­нако обратим здесь внимание на несколько моментов.

Во-первых, при приведении дробных значений к целым типам дробная часть просто отбрасывается. Например, число 3.84 будет преоб­разовано в целое 3, а -3.84 превратится в -3. Для математического округ­ления необходимо воспользоваться методом класса Math.round(,..).

Во-вторых, при приведении значений int к типу float и при приведении значений типа long к типу float и double возможны потери точности, несмотря на то, что эти дробные типы вмещают гораздо большие числа, чем соответствующие целые. Рассмотрим следующий пример:

long 1=1111111111111; float f = l; I = (long) f; print(l);

Результатом будет:

Тип float не смог сохранить все значащие разряды, хотя преобразо­вание от long к float произошло без специального оператора в отличие от обратного перехода.

Для каждого примитивного типа существуют специальные вспо­могательные классы-обертки (wrapper classes). Для типов float и double это Float и Double. Эти классы содержат многие полезные методы для работы с дробными значениями. Например, преобразование из текста в число.

Кроме того, класс Math предоставляет большое количество методов для операций над дробными значениями, например, извлечение квадрат­ного корня, возведение в любую степень, тригонометрические и другие. Также в этом классе определены константы PI и основание натурального логарифма Е.



<== предыдущая лекция | следующая лекция ==>
Stext text12 | Булевский тип


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 4.306 сек.