- •Содержание
- •Глава 1. Общие представления о языке Java 6
- •Глава 2. Объектно-ориентированное проектирование и платформа NetBeans 26
- •Глава 3. Примитивные типы данных и операторы для работы с ними 78
- •Глава 4. Работа с числами в языке Java 95
- •Глава 5. Управляющие конструкции 112
- •Глава 6. Начальные сведения об объектном программировании 128
- •Глава 7. Важнейшие объектные типы 175
- •Глава 1. Общие представления о языке Java
- •1.1. Java и другие языки программирования. Системное и прикладное программирование
- •Введение
- •1.2. Виртуальная Java-машина, байт-код, jit-компиляция. Категории программ, написанных на языке Java
- •1.3.Алфавит языка Java. Десятичные и шестнадцатеричные цифры и целые числа. Зарезервированные слова Алфавит языка Java
- •Десятичные и шестнадцатеричные цифры и целые числа
- •Зарезервированные слова языка Java
- •1.4. Управляющие последовательности. Символы Unicode. Специальные символы Управляющие последовательности
- •Простые специальные символы
- •Составные специальные символы
- •1.5.Идентификаторы. Переменные и типы. Примитивные и ссылочные типы
- •Краткие итоги по главе 1
- •Задания
- •Глава 2. Объектно-ориентированное проектирование и платформа NetBeans
- •2.1.Процедурное и объектно-ориентированное программирование. Инкапсуляция
- •2.2. Работа со ссылочными переменными. Сборка мусора
- •2.3. Проекты NetBeans. Пакеты. Уровни видимости классов. Импорт классов
- •2.4. Базовые пакеты и классы Java
- •2.5. Создание в NetBeans простейшего приложения Java
- •2.6. Компиляция файлов проекта и запуск приложения
- •2.7. Структура проекта NetBeans
- •2.8. Создание в NetBeans приложения Java с графическим интерфейсом
- •2.9. Редактор экранных форм
- •2.10. Внешний вид приложения
- •2.11. Ведение проектов
- •2.11. Редактирование меню экранной формы
- •2.12. Создание нового класса
- •2.13. Документирование исходного кода в Java
- •2.14. Основные компоненты пакетов swing и awt
- •2.15. Технологии Java и .Net
- •Краткие итоги по главе 2
- •Задания
- •Глава 3. Примитивные типы данных и операторы для работы с ними
- •3.1.Булевский (логический) тип
- •3.2.Целые типы, переменные, константы
- •3.3.Основные операторы для работы с целочисленными величинами
- •3.4.Вещественные типы и класс Math
- •3.5.Правила явного и автоматического преобразования типа при работе с числовыми величинами
- •3.6. Оболочечные классы. Упаковка (boxing) и распаковка (unboxing)
- •3.7.Приоритет операторов
- •3.8.Типы-перечисления (enum)
- •Краткие итоги по главе 3
- •Задания
- •Глава 4. Работа с числами в языке Java
- •4.1 Двоичное представление целых чисел Позиционные и непозиционные системы счисления
- •Двоичное представление положительных целых чисел
- •Двоичное представление отрицательных целых чисел. Дополнительный код
- •Проблемы целочисленной машинной арифметики
- •Шестнадцатеричное представление целых чисел и перевод из одной системы счисления в другую
- •4.2. Побитовые маски и сдвиги
- •4.3. Двоичное представление вещественных чисел Двоичные дроби
- •Мантисса и порядок числа
- •Стандарт ieee 754 представления чисел в формате с плавающей точкой*
- •Краткие итоги по главе 4
- •Задания
- •Глава 5. Управляющие конструкции Составной оператор
- •Условный оператор if
- •Оператор выбора switch
- •Условное выражение …?... : …
- •Оператор цикла for
- •Оператор цикла while – цикл с предусловием
- •Оператор цикла do...While – цикл с постусловием
- •Операторы прерывания continue, break, return, System.Exit
- •Краткие итоги по главе 5
- •Задания
- •Глава 6. Начальные сведения об объектном программировании
- •Наследование и полиморфизм. Uml-диаграммы
- •Функции. Модификаторы. Передача примитивных типов в функции
- •Локальные и глобальные переменные. Модификаторы доступа и правила видимости. Ссылка this
- •Передача ссылочных типов в функции. Проблема изменения ссылки внутри подпрограммы
- •Наследование. Суперклассы и подклассы. Переопределение методов
- •Наследование и правила видимости. Зарезервированное слово super
- •Статическое и динамическое связывание методов. Полиморфизм
- •Базовый класс Object
- •Конструкторы. Зарезервированные слова super и this. Блоки инициализации
- •Удаление неиспользуемых объектов и метод finalize. Проблема деструкторов для сложно устроенных объектов
- •Перегрузка методов
- •Правила совместимости ссылочных типов как основа использования полиморфного кода. Приведение и проверка типов
- •Рефакторинг
- •Reverse engineering – построение uml-диаграмм по разработанным классам
- •Краткие итоги по главе 6
- •Задания
- •Глава 7. Важнейшие объектные типы Массивы
- •Коллекции, списки, итераторы
- •Работа со строками в Java. Строки как объекты. Классы String, StringBuffer и StringBuilder
- •Работа с графикой
- •Исключительные ситуации Обработка исключительных ситуаций
- •Иерархия исключительных ситуаций
- •Объявление типа исключительной ситуации и оператор throw
- •Объявление метода, который может возбуждать исключительную ситуацию. Зарезервированное слово throws
- •Работа с файлами и папками
- •Краткие итоги по главе 7
- •Задания
- •Глава 8. Наследование: проблемы и альтернативы. Интерфейсы. Композиция Проблемы множественного наследования классов. Интерфейсы
- •Отличия интерфейсов от классов. Проблемы наследования интерфейсов
- •Пример на использование интерфейсов
- •Композиция как альтернатива множественному наследованию
- •Краткие итоги по главе 8
- •Задания
- •Глава 9. Дополнительные элементы объектного программирования на языке Java Потоки выполнения (threads) и синхронизация
- •Преимущества и проблемы при работе с потоками выполнения
- •Синхронизация по ресурсам и событиям
- •Класс Thread и интерфейс Runnable. Создание и запуск потока выполнения
- •Поля и методы, заданные в классе Thread
- •Подключение внешних библиотек dll.“Родные” (native) методы*
- •Краткие итоги по главе 9
- •Задания
- •Глава 10. Введение в сетевое программирование Краткая справка по языку html
- •Апплеты
- •Сервлеты
- •Технология jsp – Java Server Pages
- •Краткие итоги по главе 10
- •Задания
- •Глава 11. Встроенные классы Виды встроенных классов
- •Вложенные (nested) классы и интерфейсы
- •Внутренние (inner) классы
- •Локальные (local) классы
- •Анонимные (anonimous) классы и обработчики событий
- •Анонимные (anonimous) классы и слушатели событий (listeners)
- •Краткие итоги по главе 11
- •Задания
- •Глава 12. Компонентное программирование Компонентная архитектура JavaBeans
- •Мастер создания компонента в NetBeans
- •Пример создания компонента в NetBeans – панель с заголовком
- •Добавление в компонент новых свойств
- •Добавление в компонент новых событий
- •Краткие итоги по главе 12
- •Задания
- •Литература
- •Дополнительная литература
- •276 Курс подготовлен при поддержке Sun Microsystems
4.3. Двоичное представление вещественных чисел Двоичные дроби
Целое число 01012 можно представить в виде 01012 =0*23 + 1*22 + 0*21 + 1*20
Аналогично можно записать двоичную дробь:
11.01012 =1*21+ 1*20 + 0*2-1 + 1*2-2 + 0*2-3 + 1*2-4
Заметим, что сдвиг двоичной точки на n разрядов вправо (чаще говорят о сдвиге самого числа влево) эквивалентен умножению числа на (102)n = 2n. Сдвиг точки влево (то есть сдвиг самого числа вправо) – делению на 2n.
Мантисса и порядок числа
Рассмотрим сначала упрощенную схему хранения чисел в формате с плавающей точкой (floating point), несколько отличающуюся от реальной.
Число x с плавающей точкой может быть представлено в виде x=s*m*2p. Множитель s – знак числа. Второй множитель m называется мантиссой, а число p – порядком числа.
Для простоты рассмотрим 10-битовую ячейку, состоящую из трёх независимых частей:
знак порядок мантисса
1 бит 4 бита 5 бит
Первым идёт знаковый бит. Если он равен 0, число положительно, если равен 1 – отрицательно. Набор бит, хранящийся в мантиссе, задает положительное число m, лежащее в пределах 1≤m<2. Оно получается из нашего двоичного числа путем переноса двоичной точки на место после первой значащей цифры числа. Например, числа 1.01012, 10.1012 и 0.101012 и имеют одну и ту же мантиссу, равную 1.01012. При этом следующая за ведущей единицей точка в ячейке, выделяемой под мантиссу, не хранится - она подразумевается. То есть мантиссы приведённых чисел будут храниться в виде 101012.
Число сдвигов двоичной точки (с учетом знака) хранится в части ячейки, выделяемой под порядок числа. В нашем примере числа 1.01012, 10.1012 и 0.101012 будут иметь порядки 0, 1 и -1, соответственно. При перемножении чисел их мантиссы перемножаются, а порядки складываются. При делении – мантиссы делятся, а порядки вычитаются. И умножение, и деление мантисс происходит по тем же алгоритмам, что и для целых чисел. Но при выходе за размеры ячейки отбрасываются не старшие, а младшие байты. В результате каждая операция умножения или деления даёт результат, отличающийся от точного на несколько значений младшего бита мантиссы. Аналогичная ситуация с потерей младших бит возникает при умножениях и делениях. Ведь если в ячейках для чисел данного типа хранится k значащих цифр числа, то при умножении двух чисел точный результат будет иметь 2k значащих цифр, последние k из которых при записи результата в ячейку будут отброшены даже в том случае, если они сохранялись при вычислениях. А при делении в общем случае при точных вычислениях должна получаться бесконечная периодическая двоичная дробь, так что даже теоретически невозможно провести эти вычисления без округлений. С этим связана конечная точность вычислений на компьютерах при использовании формата с “плавающей точкой”. При этом чем больше двоичных разрядов выделяется под мантиссу числа, тем меньше погрешность в такого рода операциях.
Замечание: системы символьных вычислений (или, что то же, – аналитических вычислений, или, что то же, системы компьютерной алгебры) позволяют проводить точные численные расчеты с получением результатов в виде формул. Однако они выполняют вычисления на много порядков медленнее, требуют намного больше ресурсов и не могут работать без громоздкой среды разработки. Поэтому для решения большинства практически важных задач они либо неприменимы, либо их использование нецелесообразно.
При сложении или вычитании сначала происходит приведение чисел к одному порядку: мантисса числа с меньшим порядком делится на 2n, а порядок увеличивается на n, где n – разница в порядке чисел. При этом деление на 2n осуществляется путем сдвига мантиссы на n бит вправо, с заполнением освобождающихся слева бит нулями. Младшие биты мантиссы, выходящие за пределы отведенной под нее части ячейки, теряются.
Пример:
сложим числа 11.0112 и 0.110112 . Для первого числа мантисса 1.10112, порядок 1, так как 11.0112=1.10112*(102)1. Для второго – мантисса 1.10112 , порядок -1, так как 0.110112 =1.10112*(102)-1. Приводим порядок второго числа к значению 1, сдвигая мантиссу на 2 места вправо, так как разница порядков равна 2:
0.110112 = 0.0110112* (102)1.
Но при таком сдвиге теряется два последних значащих бита мантиссы (напомним, хранится 5 бит), поэтому получаем приближенное значение 0.01102* (102)1. Из-за чего в машинной арифметике получается
1.10112*(102)1 + 0.0110112*(102)1 = (1.10112 + 0.0110112)*(102)1 ≈ (1.10112 + 0.01102)*(102)1 =10.00012* (102)1 ≈ 1.00002*(102)2
вместо точного значения 1.00001112*(102)2.
Таким образом, числа в описанном формате являются на деле рациональными, а не вещественными. При этом операции сложения, вычитания, умножения и деления выполняются с погрешностями, тем меньшими, чем больше разрядность мантиссы. Число двоичных разрядов, отводимых под порядок числа, влияет лишь на допустимый диапазон значений чисел, и не влияет на точность вычислений.
Научная нотация записи вещественных чисел
При
записи программы в текстовом файле или
выдачи результатов в виде “плоского
текста” (plain text) невозможна запись
выражений типа
.
В этом случае используется так называемая
научная нотация, когда вместо основания
10 пишется латинская буква E (сокращение
от Exponent – экспонента). Таким образом,
запишется как 1.5E14, а
как 0.31E-7. Первоначально буква E писалась
заглавной, что не вызывало проблем.
Однако с появлением возможности набора
текста программы в нижнем регистре
стали использовать строчную букву e,
которая в математике используется для
обозначения основания натуральных
логарифмов. Запись вида 3e2
легко воспринять как
,
а не
.
Поэтому лучше использовать заглавную
букву.
Литерные константы для вещественных типов по умолчанию имеют тип double. Например, 1.5 , -17E2 , 0.0 . Если требуется ввести литерную константу типа float, после записи числа добавляют постфикс f (сокращение от “float”): 1.5f , -17E2f , 0.0f .
Минимальное по модулю не равное нулю и максимальное значение типа float можно получить с помощью констант
Float.MIN_VALUE - равна 2-149
Float.MAX_VALUE - равна (2-2-23)∙2127
Аналогичные значения для типа double - с помощью констант
Double.MIN_VALUE - равна 2-1074
Double.MAX_VALUE - равна (2-2-52)∙21023.
