Лекция Язык ada проблемы целочисленных тд



Дата14.06.2016
өлшемі0.64 Mb.
#134458
Языки программирования. Лекция 6.

Язык ADA

Проблемы целочисленных тд:

1). Проблема представления

2). Проблема универсальности (насколько система целочисленного тд соответствует машинной архитектуре)

3). Надежность

фиксированное представление тд  неуниверсальность.

Естественный тип данных- natural int ( в Cи#) (то, что в Си называется просто int)

(для грядущих 64-битных архитектур)

Язык ADA

Целочисленный тд


Для языка Ада ключевой пункт – надежность.

В Аде существуют понятия тип и подтип ( очень гибкая концепция типов).

Типы могли выводиться друг из друга ( type T1 is new T- Т1 производный от Т, не путать с наследованием! Т1 наследует все мн-во значений и операций типа Т).

Типы между собой не совместимы полностью!!!



Для Ада: Если

type T1=T, то Т1- новый тип данных.

( для Си++ typedef T T1; T1- просто синоним Т, но не новый тип!)

Но подтипы совместимы.


Пример:

1).


Задача: Несовместимость без знаковых типов с целочисленными:

type CARDINAL is new INTEGER range 0..MAXINT;

I:CARDINAL;

J:INTEGER;

I и J не совместимы!!!!!!!

Т. е. нельзя I+J, I:=J, J:=I и т.д. ( статический контроль).

2).

Задача: Ограничить мн-во значений



Подтипы :

subtype NATURAL is INTEGER range 0..MAXINT;

K:NATURAL;

J:INTEGER;

K:=J; J:=K; K+J(значение- тип integer); -совместимы - квазистатический контроль( во время исполнения, т.к. значение J известно только в момент исполнения) надежность

Например: проверка J на попадание в диапазон.

K:=-1; нельзя, ограничение диапазона – статический контроль.

Вещественные типы данных


1). Плавающие

S*Ma*Bp

S-знак + или –

M-мантисса( n бит) ½<= M <1

(т.к. машина двоичная, для десятичной-1/10<= M <1)

 в терминах двоичной системы 0.b1b2…bn, где bi-биты мантиссы

т.к. ½<= M <1b1=1-нормализованное представление.

Естественно в качестве В( порядок) выбирать 2.


1985- стандарт IEEE 754 базовые правила работы с плавающей арифметикой:

-Мантисса хранится в нормализованном представлении  b1 хранить не обязательно.

-устанавливает представление

32-битное

64-битное

-младшие значения порядка –зарезервированы

-не все значения мантиссы являются одинаково допустимыми
Зарезервированные значения NaN- Not a Number( выдается при ошибке вещественной арифметики) и +, - бесконечность. С ними можно сравнивать и производить ряд операций.
Все производители компьютеров приняли этот стандарт.

Это стандарт поддерживают С# и Java( float ( 32 bit) и double (64 bit))

Си# поддерживает decimal – 128 bit, для работы с SQL. Вообще, SQL оказал большое влияние на С# .

Ада


Для переносимости фиксируем точность:

Type T is digits D; D-значащих разрядов

Type T is digits 6;
[log2 D]+1- число бит в мантиссе

Модельные числа для языка Ада - М*2р с размерностью мантиссы [log2 D]+1

 D<7 32- битная реализация

 D>6 64- битная реализация

Т.о. стандарт Ады определял модельные числа, а задача компилятора- подобрать такую реализацию, что доступна на данном процессоре, чтобы она включала целиком все модельные числа.

Если D велико(например, 50), то компилятор должен сам генерировать все операции с такими числами (стандарт Ады-83). Практика показала, что соответствующие реализации очень накладны.

Современные компиляторы выбирают представления либо float, либо double. Если соответствующих вариантов нет, то компилятор выдает ошибку и дальше это проблема программиста, переделывать программу.

Пример:


Промежуток= 2-n

при р=0 и р=1 – 2n чисел, и т.д. промежуток растягивается, а количество чисел 2n

 большая погрешность при больших числах!
2).Фиксированный тип (delta тип)

type T is delta H range L..R

l, R- константы.

Интервал от L до R с интервалом H (удобен для сеточных функций).


Причины появления такого типа:

1). Фиксированная точность

2). Более компактное хранение(конец 70-х главный ресурс-память)
кол-во чисел= (L-R)/H

Удобен для хранения результатов измерений при оцифровки звука (диапазон и кол-во значений).

Вывод: язык Ада наиболее адекватен для численных математических расчетов Он не стал языком №1, т.к.:


  • сложность яп;

  • соответствующая ниша занята уже фортраном;



Логический тип


Есть во всех яп, которые мы рассматриваем:

- Boolean

- Bool ( Cи#, Cи++)

- True, false

Во всех яп логический тд несовместим со всеми остальными. Т.е. все преобразования – явные.

Но в языке Си++, изначально логического типа не было. Возможное решение:

Typedef bool

#define TRUE 1

#define FALSE 0

Необходимость введения в С++ bool- bool, как описано выше, это не новый тд, а синоним unsigned int.

Т.е.:

Для полноценного тд, существует перекрытие функций:



int f(int)

int f(bool)

Для полноценного тд объявления обеих ф-ий корректно, для описания bool, как показано выше, не корректно.

f(x) – тип х определит функцию, которая будет вызвана.

 необходимость введения полноценного типа bool.
Для совместимости С и С++:

1). Неявное преобразование bool  int

2)true=1, false=0 все логические значения будут сведены к ним. Например, 31.
В С++:

bool b;


int I;

b&&I; можно, т.к. есть bool  int, но компилятор выдаст предупреждение из-за неэффективности.


Проблема тд – Ленивые вычисления

Двуместные операции:

ор1 ор 2

У ряда операций достаточно вычислить только первый аргумент, например:

And, or:

0 and ор=0

1 or ор=1

Следовательно, можно вычислить только 1-ый операнд.


В старых ЯП в целях оптимизации компилятор мог переупорядочивать операнды( увеличение эффективности, например повторное вычисление операнда в выражении)!

ор1 ор 2 op1op2

f(a) f(b) f(a)f(b)

Если ф-ия обладает побочным эффектом, то может возникнуть проблема.

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

1).ор1 and op2 op1 or op2 вычисляют оба операнда, порядок их вычисления зависит от компилятора.

2). Укороченные операции and_if и or_else вычисления слева на право (ленивые операции).

В окончательном варианте 2 не вошли, т.к. были избыточными.


В С все логические операции- ленивые, арифметические- компилятор имеет право устраивать некоторую оптимизацию. В современных языках принят такой же подход.
Пример: while (i<= N) and ( a[i]<> x) do …

And должна быть ленивой, иначе -выход за границу массива!


Порядковые типы

  • диапазоны;

  • перечисления;

1).Перечисления.

Впервые появился в яп Паскаль- явное перечисление значений.

Базовый тип - целочисленный тип данных.

type DaysofWeek= ( Mon, Tue, …, n+1) Mon=0 Tue=1…

daysofWeek i;

i:=3;


i:=Wed; наглядность

i:=8; -нельзя, т.к. 8 выходит за диапазон [0,6] надежность.

В языке Ада компилятор может выбирать базовым типом не целочисленный, а подтип, т.е. столько бит, сколько необходимо для хранения.
В 1988 году появился язык Оберон, но уже без перечислимых типов данных. Вирт посчитал его избыточным для языка, т.к Оберон –ООЯП


  • перечислимые типы усложняют компиляцию программ (многомодульных программ, т.к. когда мы импортируем типы данных  импортировать имена, т.е. для перечислимого типа- импортируем неявно соответствующие константы- очень накладно и могут возникнуть конфликты имен)

  • (основная!!!) перечислимые типы слабо удовлетворяют концепции наследования:

Т<= open (openmode, enum openmode)

поток ввода- вывода, openmode, enum openmode- .режимы открытия


T=> (наследование) T1 у него уже свой open на верхнем уровне надо зафиксировать всевозможные значения, с которым может открываться файл. Детализация идет с более низким уровнем иерархии.
С++:

Иерархия Iostream

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

Ios::имя_константы


В Delphi есть, т.к. перечислимый тип был в Паскале.
1995- Java (перечислимого типа нет, т.к. Java -ООЯП)

static final int Mon=1

Значение final не меняется

Здесь мы уже теряем в надежности

(day_of_week=19;)
1999-C# (перечисления есть)

причина: Понятие перечислимого тд хорошо коррелирует с понятием интерактивной среды разработки (IDE).
инспектор объекта

name

Value








combobox

x

150

Value 1















Value n










В combobox явно перечислены всевозможные значения, которые могут быть.
Классы:

- классы-заготовки для наследования

В системе MFC:

CDialog  CMyDialog

-терминальные классы, предназначенные для использования( в них перечисления очень полезны, т.к. класс расширяться не будет).Компонентное программирование
C# использует парадигмы:

-компонентное программирование

-чисто объектно-ориентированная парадигма
В Паскаль, Модула-2- перечислимые типы такие, как рассказывалось выше.
ADA

1).


type Color is (Red, Green, Blue);

type Т is (Red, ..);

i:= Red; для Ада это не ошибка (зависит от полного контекста, т.е. от типа данных i), для модула-2, Паскаль, С –это ошибка!

2).


procedure P(X: color)

procedure P(X:T)

P(i)- в зависимости от типа i

P(Red)- ошибка, т.к. он не знает что такое red.

Для этого есть конструкция “ указание типа”(указывает) (не “ преобразование типа”(преобразует) !)

общий вид указания типа: Т’е

Р(Color' Red);
В Паскале тип- Boolean, на основе перечислимого типа.
Character- предопределенный перечислимый тип в языке Ада.

type CHARACTER is (‘A’,’B’,’C’,…,‘a’,’b’,’c’,…,’0’,…);


Сравнение перечислений в C# и C++:

Основа перечислимых типов- диапазон 0…N-1

Можно ли преобразовывать перечислимый тип в числа и наоборот?

Кроме С++(по наследству от С) неявно нельзя.

type T=(C1,…,CN)

X:T;


X:=T(8);-явное преобразование числа в константу(квазистатический контроль).

X:=color(i);


В модуле-2:

Val(T,e) Т-имя типа, e- значение.









Достарыңызбен бөлісу:




©dereksiz.org 2022
әкімшілігінің қараңыз

    Басты бет