учебники, программирование, основы, введение в,

 

Простые типы данных

Переменные и константы
Будем называть объектом данных один или несколько однотипных элементов данных, рассматриваемых программой как одно простое или составное целое.
Объекту данных присущи такие атрибуты, как тип, адрес памяти, присвоенное значение, имя.
Переменные и константы - это объекты данных. При создании переменной или константы им назначается имя, называемое иногда идентификатором. В отличие от переменной, атрибут "значение" объекта данных "константа" не может быть изменен в процессе выполнения программы.
Объявление объектов данных
Перед использованием в программе любой объект данных должен быть объявлен. Однако некоторые языки допускают неявное объявление. Так, в языке FORTRAN компилятор определяет тип используемой, но предварительно не объявленной переменной по первому символу имени, а в языке Perl неявное объявление переменной происходит при присваивании ей начального значения. Некоторые языки выполняют неявное объявление переменных, используемых в качестве счетчиков циклов.
Оператор объявления сообщает компилятору информацию об идентификаторах и типах данных, назначаемых объектам данных, и о предполагаемом времени жизни этих объектов (глобальная или локальная переменная, переменная - член класса, статическая переменная и т.п.).
При объявлении объекта данных в зависимости от типа этого объекта и языка программирования возможно выделение памяти под этот объект при объявлении или при последующем создании этого объекта.
В языке C++ для объявления новых имен в текущей области видимости предназначаются операторы объявления.
Например: int i, j; float m, n;
Оператор объявления в языке C++ может указываться в любом допустимом месте программы.
В языке C++ каждый оператор объявления завершается символом конца оператора (точка с запятой). В операторе объявления может объявляться несколько объектов данных одного типа, перечисляемых через запятую. Любой оператор объявления начинается с ключевого слова или идентификатора, указывающего тип объявляемого объекта.
Объявляемыми объектами данных могут быть названия типов и имена объектов.
Объявление определяет имя внутри области видимости. Имя, объявляемое внутри блока, класса, функции или пространства имен, является локальным. Блок в языке C++ заключается в фигурные скобки. Если вне блока существуют глобальные имена, обозначаемые теми же идентификаторами, то они становятся скрыты внутри блока и к ним следует обращаться, используя оператор разрешения области видимости ::.
Например:
int i1;      // Объявление глобальной
// переменной
void metod1() {
int i1;    // Объявление локальной
// переменной
i1=22;     // Доступ к локальной
// переменной метода
::i1=44;   // Доступ к глобальной
// переменной
{ int i1;  // Объявление локальной
// переменной
i1=33;   // Доступ к локальной
// переменной блока
}
i1=44;       // Доступ к глобальной
// переменной
В языке C++ объявления применяются для создания нового имени, используемого в приложении (имя может указывать не только объект данных). Объявления позволяют:

  • специфицировать класс памяти, тип и область действия объекта;
  • инициализировать объект начальным значением;
  • назначать имена константе (при объявлении перечислимого типа);
  • объявлять новый тип (class, struct и union);
  • определять синоним существующего типа (typedef);
  • специфицировать шаблон классов или функций (template);
  • специфицировать пространство имен (namespace);
  • специфицировать класс памяти, тип и область действия подпрограммы.

Отметим, что термин объявление означает только указание, каким образом объявляемое имя будет интерпретироваться компилятором.
В языке C++ при каждом объявлении локального объекта под него выделяется память.
Например:
// Объявление и инициализация
// локального объекта в цикле

do { char char1 = _getch();
if( (char1 == NULL ) continue;
return (char1);
} while( 1 );
Удаление объекта, который был объявлен в цикле, происходит после каждой итерации, при выходе из блока или при передаче управления в точку, расположенную выше объявления этого объекта.
Процедура удаления объекта в языке C++ может включать не только удаление объекта из памяти (освобождение памяти), но и выполнение деструкторов (для объектов типа класса).
В языке Java объявления переменной могут указываться в любом допустимом месте программы.
Например:
boolean b1=true;  
// Оператор присваивания
// задается символом =
char  c1='N';
int int1=123;
Имена могут иметь следующие элементы языка Java:

  • пакет, определяемый оператором package;
  • тип, вводимый определением класса или интерфейса;
  • поле, являющееся переменной типа класса или типа интерфейса;
  • группа методов типа класса или типа интерфейса;
  • переменная, являющаяся формальным параметром метода;
  • переменная, являющаяся локальной переменной блока;
  • метка оператора.

Если имя или выражение означает переменную или значение простого типа, тогда тип этой переменной или значения называется типом имени или выражения.
В языке Object Pascal оператор объявления может указываться только в области объявлений, определяемой ключевым словом var.
Например:
var
ch1: Char;  
{Оператор объявления в
языке Object Pascal}
begin
ch1 := Chr(65);     
{ Оператор присваивания
задается символами :=}
end;

http://localhost:3232/img/empty.gifТипы данных

Тип данных назначается объекту данных при его объявлении и определяет: значения, которые может принимать объект данного типа; операции, которые используются для манипуляции над объектами заданного типа.
Современные языки программирования, как правило, могут иметь набор простых типов, являющихся встроенными в данный язык программирования, и средства для создания производных типов.
Объектно-ориентированные языки программирования позволяют определять типы класса.
Реализация простых типов данных заключается в способе представления значений данного типа в компьютере и в наборе операций, поддерживаемых для данного типа.
Типы данных языка C++
Тип данных определяет размер памяти, выделяемой под переменную данного типа при ее создании.
C++ поддерживает следующие типы данных:

  • базовые типы. Базовые типы указываются зарезервированными ключевыми словами, и их не надо определять.
  • производные типы. Переменные этих типов создаются как с использованием базовых типов, так и типов классов. Это структуры, объединения, указатели, массивы.
  • типы класса. Экземпляры этих типов называются объектами.

Базовые типы языка C++ можно подразделить на две группы: целочисленные и вещественные. Существует еще ключевое слово void, которое используется для описания типа подпрограмм, не имеющих возвращаемого значения, или при указании параметров подпрограмм неизвестного типа.


char
signed char

Символьный тип. Диапазон значений от -128 до 127.
Содержит один символ или строку символов. Каждый символ представляется одним байтом. Компилятор различает как отдельные следующие типы: char, signed char и unsigned char.

unsigned char

Символьный тип. Диапазон значений от 0 до 255.
Каждый символ представляется одним байтом (значение в диапазоне от 0 до 255).

short
signed short

Целый тип. Диапазон значений от -32768 до 32767.
Сокращенное обозначение типа short int. Длина этого типа вне зависимости от используемого компилятора всегда больше или равна длине значения типа char и меньше или равна длине значения типа int.

unsigned short

Беззнаковый целый тип. Диапазон значений от 0 до 65535.

int
signed int

Целый тип. Диапазон значений от -2147483648 до 2147483647.
Длина этого типа вне зависимости от используемого компилятора всегда больше или равна длине значения типа short int.
В общем случае размер типа int языка C++ зависит от конкретной реализации.

unsigned int

Беззнаковый целый тип. Диапазон значений от 0 до 4294967259.

__intn

Целый тип, размер в битах которого определяется значением n, и может быть равным 8, 16, 32 или 64 битам.

long
signed long

Целый тип. Диапазон значений от -2147483648 до 2147483647.
Сокращенное обозначение типа long int.

unsigned long

Беззнаковый целый тип. Диапазон значений от 0 до 4294967259

float

Тип данных с плавающей точкой. Диапазон значений от 3.4Е-38 до 3.4Е+38.

double

Тип данных с плавающей точкой двойной точности. Диапазон значений от 1.7Е-308 до 1.7Е+308.
Длина типа double вне зависимости от используемого компилятора всегда больше или равна длине типа float и короче или равна длине типа long double.

long double

Тип данных с плавающей точкой двойной точности, длина которого равна длине значений типа double.
Типы double и long double имеют одинаковое представление, но компилятор трактует их как различные типы.

Размер памяти, выделяемой под каждый тип данных языка C\C++, в некотором смысле зависит от используемой платформы и компилятора. Однако все компиляторы гарантируют, что для типа short памяти всегда выделяется меньше или столько же, сколько и для типа int, а тип long всегда "длиннее" или равен типу int.
Символьные типы char и unsigned char представляют значение символа, реализуемое одним байтом. Для использования символов в кодировке Unicode язык C++ предоставляет тип wchar_t, в котором под каждый символ отводятся два байта.
Ключевое слово typedef языка C++ позволяет объявить новое имя существующего типа.
Например:
typedef int my_integer;
my_integer i1=0;
Создание псевдонима для типа значительно облегчает процесс изменения типа переменных в уже отлаженном коде.
Символьным литералом или символьной константой называется символ, заключенный в одинарные кавычки. Целые литералы представляют целочисленные константы в десятичном, восьмеричном или шестнадцатеричном виде.
Восьмеричные литералы начинаются с символа 0, а шестнадцатеричные - с символов 0x.
После литерала может быть указан суффикс, определяющий его тип: U - unsigned int, L - long int.
Например:
00      // Восьмеричное значение, равное 0
oxffff  // Шестнадцатеричное значение,
// равное 65535
10L    // Значение типа long int
При записи шестнадцатеричных литералов каждый знак может принимать значение от 0 до 15. Для записи значений от 10 до 15 принято использовать следующие символы: a - 10, b - 11, c - 12, d - 13, e - 14 и f - 15.
Литералы с плавающей точкой могут записываться в двух формах: вещественной и экспоненциальной.
Например:
1.53
32.24e-12     
// Экспоненциальная форма записи литерала
Литералы с плавающей точкой могут использоваться для инициализации значений переменных вещественного типа (float, double или long double).

http://localhost:3232/img/empty.gifhttp://localhost:3232/img/empty.gifПреобразование типов в языке C++

Язык C++ позволяет выполнять преобразование значения одного типа в значение другого типа. Преобразование типа может быть явным и неявным. Явное преобразование называется приведением типов.
Для явного приведения типов можно использовать две формы записи:

  • без указания дополнительной информации для преобразования типа (перед преобразуемой переменной в скобках указывается имя типа, к которому она приводится).

Например:

std::cout <<"strlen="<<(long)strlen(pArr1);

  • с указанием дополнительной информации для преобразования типа (используются операторы static_cast, dynamic_cast, reinterpret_cast и const_cast).

Например:

std::cout <<"strlen="<<static_cast<long>(
strlen(pArr2));
Вторая форма явного преобразования типов более предпочтительна, поскольку несет в себе дополнительную информацию, позволяющую сократить число возможных ошибок.
Дополнительная информация о приводимом типе может быть указана следующими операторами:

  • static_cast - выполняет преобразование родственных типов;
  • const_cast - выполняет приведение константных выражений;
  • dynamic_cast - используется для динамического преобразования типа, реализуемого на этапе выполнения;
  • reinterpret_cast - выполняет преобразование не связанных между собой типов.

Преобразование типов выполняется для значений переменных при вычислении выражений и оказывает влияние на тип результата. Преобразование типов не изменяет типа самих переменных, участвующих в выражении.
Типы данных языка Object Pascal
Все переменные и константы, используемые в программе, всегда принадлежат какому-либо типу. Вызов функции также возвращает значение определенного типа.
Типы данных языка Object Pascal можно разбить на следующие группы:

  • базовые типы данных:
    • целочисленный тип;
    • действительный тип;
    • логический тип;
    • символьный тип;
    • строковый тип;
  • производные типы данных;
  • простые типы данных:
    • порядковый тип;
    • перечислимый тип;
  • структурированные типы данных:
    • множества;
    • массивы;
    • записи;
    • файлы;
    • объектный тип (тип класса);
    • тип ссылки на класс;
  • указатели;
  • процедурный тип данных.

В язык Object Pascal включены следующие базовые типы данных:

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

Тип

Диапазон значений

Формат

Integer

-2147483648..2147483647

signed 32-bit

Cardinal

0..4294967295

unsigned 32-bit

Shortint

-128..127

signed 8-bit

Smallint

-32768..32767

signed 16-bit

Longint

-2147483648..2147483647

signed 32-bit

Int64

-263..263-1

signed 64-bit

Byte

0..255

unsigned 8-bit

Word

0..65535

unsigned 16-bit

Longword

0..4294967295

unsigned 32-bit

  • Действительные типы

Тип

Диапазон значений

Размер в байтах

Real

5.0 * 10-324 .. 1.7 * 10308

8

Real48

2.9 * 10-39 .. 1.7 * 1038

6

Single

1.5 * 10-45 .. 3.4 * 1038

4

Double

5.0 * 10-324 .. 1.7 * 10308

8

Extended

3.6 * 10-4951 .. 1.1 * 104932

10

Comp

-263+1 .. 263 -1

8

Currency

-922337203685477.5808.. 922337203685477.5807

8

  • Для указания значения действительного типа можно использовать экспоненциальный формат (например, значение 1.3Е-5 эквивалентно 1.3*10-5).
  • Логические типы

Тип

Диапазон значений

Размер в байтах

Boolean

True или False

1

ByteBool

True или False

1

WordBool

True или False

2

LongBool

True или False

4

  • Символьные типы

Тип

Диапазон значений

Размер в байтах

Char

ANSI-символ

1

AnsiChar

ANSI-символ

1

WideChar

Unicode-символ

2

  • Строковые типы

Тип

Максимальная длина

Размер в байтах

string

Определяется директивой компилятора $H

ShortString

255 символов

От 2 до 256 байт

AnsiString (длинная строка)

~231 символов

От 4 байт до 2 Гбайт

WideString (Символы Unicode)

~230 символов

От 4 байт до 2 Гбайт

Для строковых переменных выполняются следующие правила:

  • строки могут быть постоянной или переменной длины: при объявлении строки можно указать только идентификатор или идентификатор и в квадратных скобках длину строки;
  • значение строки указывается в одинарных кавычках или как последовательность ASCII-символов, перед каждым из которых ставится знак #;
  • доступ к символу строки можно выполнять по индексу, указываемому в квадратных скобках (например, MyString[7] := 'n';).

Например:
var
S1: string;
{Объявление строковой переменной
произвольной длины}
S2: string[2];
{Объявление строковой переменной
длиной 2 символа}
Строки типа AnsiString также называют длинными строками (long string), представляющими динамически размещаемые строки, длина которых ограничена только доступной памятью. Такие строки используют 1-байтовое представление ANSI-символов.
Реально переменная типа AnsiString является указателем, состоящим из 4 байт. Если строка пустая (ее длина равна 0), то указатель равен nil и для хранения строки никакой памяти не выделяется. Если строка не является пустой, то данная переменная указывает на динамически размещаемый блок памяти, содержащий значение строки, на 32-битовое значение длины строки и на 32 битовое значение счетчика ссылок на строку.
Несколько идентификаторов строк могут ссылаться на одну строку. При этом им не будет выделяться дополнительная память, а только будет выполняться увеличение счетчика ссылок.

http://localhost:3232/img/empty.gifhttp://localhost:3232/img/empty.gifКонстанты в языке Object Pascal

Объявление переменных выполняется в секции, начинающейся с ключевого слова var. Ключевое слово const предназначено для объявления констант.
Константами могут быть простые значения или значения типа записи, массива, функции и указателя.
При объявлении константного указателя его сразу необходимо инициализировать.
Инициализация константного указателя может быть выполнена тремя способами:

  • определением адреса глобальной переменной с использованием оператора @;
  • указанием адреса равного nil;
  • заданием значения константы типа PChar или PWideChar.

Например:
const PI: ^Integer = @i1; 
{ i1 - переменная типа Integer}
const StrNew: PChar = 'NewConst';
const PFunc: Pointer = @MyFunc;              
Типы данных языка Java

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

  • простые типы;
  • ссылочные типы.

Язык Java позволяет использовать следующие простые типы:

  • числовые типы

целые типы:

    • byte (8-битовое значение) диапазон значений от -128 до 127
    • short (16-битовое значение) диапазон значений от -32768 до 32767.
    • int (32-битовое значение) диапазон значений от -2147483648 до 2147483647
    • long (64-битовое значение) диапазон значений от -9223372036854775808 до 9223372036854775807

типы значений с плавающей точкой:

    • float (32-битовое значение)
    • double (64- битовое значение)
  • символьный тип
    • char (16-битовое значение Unicode)
  • логический тип
    • boolean (значение true или false)

Например:
// Объявление переменных
boolean b1=true;
float   fN1=74.3F;
float fN2=(float)(fN1+2);
double dN1=14573.74;
double dN2= 81.2E-2;
Значение одного целого типа может быть приведено к значению другого целого типа.
Приведение целых типов к логическому и обратно выполнять нельзя.
Язык Java предусматривает для целочисленных значений следующие операторы:

  • операторы сравнения
    • = равно
    • != не равно
  • операторы отношения
    • < меньше
    • <= меньше или равно
    • > больше
    • >= больше или равно
  • унарные операторы
    • + положительное значение
    • - отрицательное значение
  • бинарные операторы
    • + и += сложение (x=x+y эквивалентно записи x+=y)
    • - и -= вычитание (x=x-y эквивалентно записи x-=y)
    • * и *= умножение (x=x*y эквивалентно записи x*=y)
    • / и /= деление (x=x/y эквивалентно записи x/=y)
    • % и %= остаток от деления
  • префиксный и постфиксный оператор приращения и декремента
    • ++ приращение (увеличение значения на 1 до вычисления выражения (++x) или после (x++))
    • -- декремент
  • операторы сдвига
    • << сдвиг влево
    • >> сдвиг вправо с распространением знака
    • >>> сдвиг вправо без учета знака (слева происходит заполнение нулями)
  • унарный логический оператор
    • ~ отрицание (побитовое дополнение)
  • бинарные логические операторы
    • & логическое И (AND)
    • | логическое ИЛИ (OR)
    • ^ логическое исключающее ИЛИ (XOR)

Если оба операнда имеют целочисленный тип, то операция рассматривается как целочисленная. Если один из операндов имеет тип long, то операция выполняется с использованием 64-битового представления: при этом любой другой операнд будет расширен до типа long и результат будет также иметь тип long. В противном случае операции выполняются, используя 32-битовое представление (любой операнд, не являющийся int, первоначально расширяется до типа int) и результат будет иметь тип int.
Логические значения представляются одним битом и обозначаются константами true и false
В языке Java нельзя прямо выполнить приведение типа int к типу boolean, но можно конвертировать значение int, используя следующий синтаксис языка: int x != 0, где любое не нулевое значение x даст в результате true, а нулевое значение даст false. Для преобразования значения типа boolean в целое следует выполнить условный оператор: bool x ? 1:0.
Для логических значений в языке Java предусмотрены следующие операторы:

  • == и !=
  • !, &, |, и ^
  • && и ||.

Типы данных языка C#
В языке C# нет базовых типов - все типы реализуются как классы библиотеки NET Framework. Однако язык C# имеет набор встроенных типов, которые рассматриваются как псевдонимы типов в пространстве имен System. Например, тип string - это псевдоним типа System.String, а тип int - псевдоним типа System.Int32.
C# поддерживает следующие встроенные типы:

  • bool - псевдоним класса System.Boolean;
  • byte - псевдоним класса System.Byte;
  • sbyte - псевдоним класса System.SByte;
  • char - псевдоним класса System.Char;
  • decimal - псевдоним класса System.Decimal;
  • float - псевдоним класса System.Single
  • double - псевдоним класса System.Double;
  • int - псевдоним класса System.Int32;
  • uint - псевдоним класса System.UInt32;
  • long - псевдоним класса System.Int64;
  • ulong - псевдоним класса System.UInt64;
  • object - псевдоним класса System.Object;
  • short - псевдоним класса System.Int16;
  • ushort - псевдоним класса System.UInt16;
  • string - псевдоним класса System.String.

Все встроенные типы подразделены на группы:

  • целочисленные типы (int, long, ulong);
  • вещественные типы (float, double);
  • логический тип (bool);
  • символьные типы (char, string);
  • объектный тип (object).

Иерархия классов NET Framework имеет один общий корень - класс System.Object.
Все типы разделяются на две категории:

  • размерные типы;
  • ссылочные типы.

При создании переменной размерного типа под нее в стеке выделяется определенный объем памяти, соответствующий типу этой переменной. При передаче такой переменной в качестве параметра выполняется передача значения, а не ссылки на него. Значение размерного типа не может быть равным null. К размерным типам относятся целочисленные и вещественные типы, структуры, перечислимые типы.
При создании переменной ссылочного типа память под созданный объект выделяется в куче. Ссылка всегда указывает на объект заданного типа.
В языке C# все массивы являются объектами. Базовым классом массива является класс Array пространства имен Systems.
Язык C# позволяет создавать следующие массивы:

  • одномерные массивы;
  • многомерные массивы;
  • невыровненные массивы.

Массивы относятся к ссылочным типам.
Одномерный массив можно создать одним из следующих способов:

  • отдельно объявить массив без указания размерности. Например:
  • int[] myArr1;
  • создать уже объявленный массив с одновременной его инициализацией. Например:
  • myArr1 = new int[] {1, 2, 3, 4};  
  • отдельно объявить массив с указанием размерности и соответственно созданием объекта. Например:
  • int[] myArr2 = new int [4];
  • объявить массив с одновременной его инициализацией (с указанием оператора new). Например:
  • int[] myArr3 = new int[] {1, 2, 3, 4};
  • string[] sColor = new string[] {
  •     "Yellow","Blue","Red"};
  • объявить массив с одновременной его инициализацией (короткая форма). Например:
  • int[] myArr4 = {1, 2, 3, 4};

Отметим, что нельзя выполнять инициализацию массива в форме myArray5 = {1, 2}; для предварительно объявленного или уже созданного массива.
При создании многомерных массивов их размерность определяется числом запятых плюс один, указанных в квадратных скобках после типа массива. Формы создания многомерного массива аналогичны формам создания одномерного массива.
Например:
int[,] iArr1 = new int[8,2];
Невыровненный массив реализуется как массив массивов.
Например, массив из трех элементов, каждый из которых содержит двумерный массив, может быть описан следующим образом:
int[][,] iJaggedArr1 = new int [3][,]
{ new int[,] { {1,1}, {8,8} },               
// первый элемент массива
new int[,] { {5,5}, {6,6}, {7,7} }, 
// второй элемент массива
new int[,] { {0,0}, {0,0}, {0,0} }  
// третий элемент массива
};
Операторы new должны использоваться для создания каждого массива: первое вхождение оператора new создает одномерный массив, каждый из трех элементов которого также является массивом, а три следующих вхождения оператора new создают элементы как двумерные массивы.
В обычных массивах индексы элементов представляют собой подряд идущие целочисленные значения. Библиотека NET Framework предоставляет класс Collections.Hashtable, позволяющий создавать хэшированные массивы.
Например:

Collections.Hashtable hArr =  new
Collections.Hashtable();
hArr["i"] = 175;    
// Значение индекса указывается
// типом string

http://localhost:3232/img/empty.gifПредставление целых и вещественных типов данных

Представление целочисленных и вещественных значений в памяти компьютера в большинстве случаев реализуется аппаратным способом с учетом возможностей конкретного процессора. Также аппаратно реализуется примитивный набор операций над этими значениями. Применение операций, реализуемых аппаратно, значительно более эффективно, чем использование программно реализуемых операций. Поэтому компиляторы по возможности формируют код, в котором применяется аппаратная реализация примитивных операций (таких, как сложение, вычитание, умножение и деление).
Целочисленное значение типа integer, записанное как "signed 32-bit", может иметь в памяти компьютера следующее представление:
Целочисленное значение типа shortint, записанное как " signed 8-bit ", может иметь в памяти компьютера следующее представление:
Максимально допустимое значение, которое можно записать в 7 бит - это восьмеричное число 177, которое в десятичном исчислении равно 127 (1778=1*82+7*81+7*80=12710).
Таким образом, диапазон допустимых значений для каждого целочисленного типа данных определяется как стандартом языка, так и возможностями аппаратуры.
В некоторых языках программирования представление целочисленного значения включает еще и хранение дескриптора этого значения. При этом дескриптор может храниться как в одной ячейке со значением, так и в различных ячейках. В первом случае наличие дескриптора значительно уменьшает диапазон допустимых значений, а также, как правило, замедляет процесс выполнения арифметических операций (операции над частью ячейки памяти не поддерживаются аппаратно).
При хранении дескриптора и значения в разных ячейках (этот способ представления используется для языка LISP) одновременно с дескриптором хранится и указатель физического расположения значения.
Вещественные типы аппаратно могут иметь два представления: вещественные числа с фиксированной точкой и вещественные числа с плавающей точкой. Как правило, по умолчанию компиляторы преобразуют вещественные значения в экспоненциальный формат (формат с плавающей точкой), если синтаксис языка явно не указывает применение формата с фиксированной точкой.
Вещественное значение с плавающей точкой может иметь в памяти компьютера следующее представление:
Для представления вещественных чисел с плавающей точкой и вещественных чисел двойной точности с плавающей точкой стандартом IEEE 754 определены 32- и 64-битовые представления соответственно.
В разряды мантиссы записываются значащие цифры, а в разряды экспоненты заносится показатель степени. Положительные значения содержат в знаковом бите числа - 0, а отрицательные значения - 1.
При обозначении чисел с плавающей точкой приняты следующие соглашения: знаковый разряд обозначается буквой s, экспонента - e, а мантисса - m.
В языке Java значения с плавающей точкой могут объявляться следующими базовыми типами:

  • float диапазон значений от +3.40282347E+28 до +1.40239846E-45 (32 бита)
  • double диапазон значений от +1.79769313486231579E+308 до +4.9406545841246544E-324 (64 бита).

Полной ненулевой формой значения типа float является форма s·m·2e, где s это +1 или -1 (знаковый бит числа), m является положительным значением, меньшим, чем 224 (мантисса), и e является целым в пределах от -149 до 104 включительно (экспонента).
Полной ненулевой формой значения типа double является форма s·m·2e, где s это +1 или -1, m является положительным значением, меньшим, чем 253, и e является целым в пределах от -1045 до 1000 включительно.
Положительным нулевым значением и отрицательным нулевым значением являются 0.0 и -0.0 (0.0 == -0.0 дает в результате true), но некоторые операторы различают эти "эквивалентные" значения, например, 1.0/0.0 равно положительной бесконечности, а 1.01/-0.0 - отрицательной бесконечности.
В языке Java приняты следующие правила приведения вещественных типов:

  • любые значения любого типа с плавающей точкой могут быть приведены к любому другому значению числового типа;
  • любые значения любого типа с плавающей точкой могут быть приведены к значению типа char и наоборот;
  • приведение невозможно между значениями типа boolean и значениями с плавающей точкой.

Если оба операнда имеют тип float, или один имеет тип float, а другой - целый тип, то результат будет иметь тип float.
Если же хотя бы один из операндов имеет тип double (устанавливаемый по умолчанию), то другой операнд также приводится к типу double и результат будет иметь тип double.
Операции со значениями с плавающей точкой не выдают исключений.
При вычислениях значений с плавающей точкой следует учитывать правила округления. Так например, для значений с плавающей точкой выражение1.0*10 не равно значению 10. Это иллюстрирует следующий пример на языке Java:
public class MyFloatSumma  
{ public static void main(String[] args)
{
float f1 = (float) 1.0;     
// Число с плавающей точкой
float fSum = 0;     
// Переменная для записи результата
final static float myDeltaFloat =
(float) 0.00001;
// Дельта для "усечения"
// мусора мантиссы

// Способ вычисления - простое
// суммирование и сравнение
for (byte i=0; i<10; i++)
fSum = fSum + (float) 0.1;
// Цикл от 0 до 10

if (f1 == fSum)
// Сравнение (float) 1.0 и
// полученной суммы
System.out.println("Числа равны");
else
System.out.println("Числа различны");
// Правильный способ вычисления -
// с "усечением" мусора мантиссы
fSum = 0; 
for (byte i=0; i<10; i++) 
fSum = fSum + (float) 0.1;
if (Math.abs(fSum - f2) < myDeltaFloat)
System.out. println("Числа одинаковы");
else
System.out. println("Числа различны");
}
}

 
На главную | Содержание | < Назад....Вперёд >
С вопросами и предложениями можно обращаться по nicivas@bk.ru. 2013 г.Яндекс.Метрика