русс | укр

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

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

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

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


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

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


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


Целочисленные типы - это byte, short, int, long, также к ним отно­сят и char. Первые четыре типа имеют длину 1, 2, 4 и 8 байт соответст­венно, длина char — 2 байта, это непосредственно следует из того, что все символы Java описываются стандартом Unicode. Длины типов при­ведены только для оценки областей значения. Как уже говорилось, па­мять в Java представляется виртуальной, и вычислить, сколько физичес­ких ресурсов займет та или иная переменная, так прямолинейно не по­лучится.

4 основных типа являются знаковыми, char добавлен к целочислен­ным типам данных, так как с точки зрения JVM символ и его код - поня­тия взаимооднозначные. Конечно, код символа всегда положительный, поэтому char — единственный без знаковый тип. Инициализировать его можно как символьным, так и целочисленным литералом. Во всем ос­тальном char - полноценный числовой тип данных, который может уча­ствовать, например, в арифметических действиях, операциях сравнения и т.п. В таблице 4.1 сведены данные по всем разобранным типам:

Тбл. 4.1. Целочисленные типы данных.


Обратите внимание, что int вмещает примерно 2 миллиарда, а потому подходит во многих случаях, когда не требуются сверхбольшие числа. Чтобы представить себе размеры типа long, укажем, что именно он используется в Java для отсчета времени. Как и во многих языках, время отсчитывается от

1 января 1970 года в миллисекундах. Так вот, вместимость long позволяет отсчитывать время на протяжении миллионов веков(!), причем как в буду­щее, так и в прошлое.

Почему были вьделены именно эти два типа, int и long? Дело в том, что целочисленные литералы имеют тип int по умолчанию, или тип long, если стоит буква L или I. Именно поэтому корректным литералом считает­ся только такое число, которое укладывается в 4 или 8 байт, соответствен­но. Иначе компилятор сочтет это ошибкой. Таким образом, следующие литералы являются корректными:



-2147483648

2147483648L

0L

111111111111111111L

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

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

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

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

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

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

• операции битового сдвига <<, », >»

• битовые операции ^, &, |, '^

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

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

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

Операторы сравнения вполне очевидны и отдельно мы их рассмат­ривать не будем. Их результат всегда булевского типа (true или false).

Работа числовых операторов также понятна, к тому же пояснялась в предьдущей лекции. Единственное уточнение можно сделать относи­тельно операторов + и -, которые могут быть как бинарными (иметь два операнда), так и унарными (иметь один операнд). Бинарные операнды являются операторами сложения и вычитания, соответственно. Унарный оператор + возвращает значение, равное аргументу (+х всегда равно х), Унарный оператор -, примененный к значению х, возвращает результат, равный 0-х. Неожиданный эффект имеет место в том случае, если аргу­мент равен наименьшему возможному значению примитивного типа.int х=-2147483648; // наименьшее возможное значение типа int inty=-x;

Теперь значение переменной у на самом деле равно не 2147483648, поскольку такое число не укладывается в область значений типа int, а в точности равно значению х! Другими словами, в этом примере выражение –х=х истинно!

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

int х= 300000; print(x*x);

Результатом такого примера будет: -194313216

Возвращаясь к инвертированию числа -2147483648, мы видим, что математический результат равен в точности +2^\ или, в двоичном форма­те, 10....О (единица и 31 ноль). Но тип intрассматривает первую единицу как знаковый бит, и результат получается равным -2147483648.

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

Подчеркнем, что выражение типа -5 не является целочисленным ли­тералом. На самом деле оно состоит из литерала 5 и оператора -. Напом­ним, что некоторые литералы (например, 2147483648) могут встречаться только в сочетании с унарным оператором -.

Кроме того, числовые операции в Java обладают еще одной особен­ностью. Хотя целочисленные типы имеют длину 8, 16, 32 и 64 бита, вы­числения проводятся только с 32-х и 64-х битной точностью. А это значит, что перед вычислениями может потребоваться преобразовать тип одного или нескольких операндов.

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

Если же аргументов типа long нет, то вычисление производится с точностью в 32 бита, и все аргументы преобразуются в int (это относится к byte, short, char). Результат также имеет тип int. Все биты старше 32-го игнорируются.

Никакого способа узнать, произошло ли переполнение, нет. Расши­рим рассмотренный пример:

inti=300000;

print(i*i); // умножение с точностью 32 бита

long m=i;

print(m*m); // умножение с точностью 64 бита

print(1/(m-i)); // попробуем получить разность значений int и long

Результатом такого примера будет:

П94313216 90000000000

затем мы получим ошибку деления на ноль, поскольку переменные 1 и m хоть и разных типов, но хранят одинаковое математическое значение и их разность равна нулю. Первое умножение производилось с точностью в 32 бита, более старшие биты были отброшены. Второе — с точностью в 64 бита, ответ не исказился.

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

double х= 1/2;

Переменной х будет присвоено значение 0, а не 0.5, как можно было бы ожидать. Подробно операции с дробными аргументами рассматриваются ниже, но чтобы получить значение 0.5, достаточно написать 1 ./2 (теперь первый аргумент дробный и результат не будет округлен).

Как уже упоминалось, время в Java измеряется в миллисекундах. По­пробуем вычислить, сколько миллисекунд содержится в неделе и в месяце:

print( 1000*60*60*24*7); // вычисление для недели print( 1000*60*60*24*30); // вычисление для месяца

(следует перемножить количество миллисекунд в одной секунде (1000), секунд - в минуте (60), минут - в часе (60), часов - в дне (24) дней - в неделе и месяце (7 и 30, соответственно). Получаем:

604800000 -1702967296

Очевидно, во втором вычислении произошло переполнение Доста­точно сделать последний аргумент величиной типа long:

print(1000*60*60*24*30L); // вычисление для месяца

Получаем правильный результат:

Подобные вычисления разумно переводить на 64-битную точ­ность не на последней операции, а заранее, чтобы избежать переполнения

значений больший спектр значении, а потому Java не позволяет присвоить переменной меньшего

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

intx=1;

byte b=x;

А вот менее очевидный пример:

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

byteb=1;

bytec=b+1;

И здесь компилятор не сможет успешно завершить работу. При опе­рации сложения значение переменной b будет преобразовано в ХИ и таким же будет результат сложения, а значит, его нельзя так просто присвоить переменной типа byte.

Аналогично:

// пример вызовет ошибку компиляции int х=2; long у=3; int z=x+y;

Здесь результат сложения будет уже типа long. Точно так же некор­ректна такая инициализация:

// пример вызовет ошибку компиляции byte b=5; byte с=-5;

Даже унарный оператор "-" проводит вычисления с точностью не меньше 32 бит.

Хотя во всех случаях инициализация переменных приводилась толь­ко для примера, а предметом рассмотрения были числовые операции, укажем корректный способ преобразовать тип числового значения:

byteb=1;

byte c=(byte)-b;

Итак, все числовые операторы возвращают результат типа intили long.Однако существует два исключения.

Первое из них — операторы инкрементации и декрементации. Их действие заключается в прибавлении или вычитании единицы из значе­ния переменной, после чего результат сохраняется в этой переменной и значение всей операции равно значению переменной (до или после изме­нения, в зависимости от того, является оператор префиксным или пост­фиксным). А значит, и тип значения совпадает с типом переменной. (На самом деле, вычисления все равно производятся с точностью минимум 32 бита, однако при присвоении переменной результата его тип понижается.)

byte х=5;

byte у1=х++; // на момент начала исполнения х равен 5

byte у2=х—; // на момент начала исполнения х равен 6

byte уЗ=++х; // на момент начала исполнения х равен 5

byte у4=--х; // на момент начала исполнения х равен б

print(yl);

print(y2);

print(y3);

print(y4);

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

5 6 6 5

Никаких проблем с присвоением результата операторов ++ и — пере­менным типа byte. Завершая рассмотрение этих операторов, приведем еще один пример:

byte х=-128; print(-x):

byte у= 127; print(++y);

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

128 -128

Этот пример иллюстрирует вопросы преобразования типов при вы­числениях и случаи переполнения.

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

byte х=2;

byte у=3;

byte z=(x>y) ? X : у; // верно, х и у одинакового типа

byte abs=(x>0) ? х : -х; // неверно!

Последняя строка неверна, так как третий аргумент содержит число­вую операцию, стало быть, его тип int, а значит, и тип всей операции будет int, и присвоение некорректно. Даже если второй аргумент имеет тип byte, а третий — short, значение будет типа Int.

Наконец, рассмотрим оператор конкатенации со строкой. Оператор + может принимать в качестве аргумента строковые величины. Если од­ним из аргументов является строка, а вторым — целое число, то число бу­дет преобразовано в текст и строки объединятся.

Intx=1; print("x="+x);

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

Обратите внимание на следующий пример:

prlnt(1+2+"text"); print("text"+l+2);

Его результатом будет:



<== предыдущая лекция | следующая лекция ==>
Примитивные и ссылочные типы данных | Stext text12


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


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

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

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


 


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

 
 

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

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