Реферат Курсовая Конспект
Позволяет пользователю дать новое имя некоторому типу - раздел Информатика, Лекция 2. Замечание. Typedef И #define =Ty...
|
Лекция 2.
Замечание. typedef и #define
=typedef позволяет пользователю дать новое имя некоторому типу:
typedef тип новое_имя [размерность];
Введенное новое имя можно использовать также, как имена стандартных типов. typedef unsigned int Uint;
Uint k, I, j;
=Директива #defineявляется директивой препроцессора и определяет некоторую подстановку в тексте программы, выполняемую препроцессором.#defineиспользуется для определения:
· символических констант: #define имя текст_подстановки
Каждое вхождение имени заменяется на текст_подстановки.
#define VER 1 {в С++ лучше писпользовать const ….}
· символов, управляющих условной компиляцией: #define имя
#define HEADER_INCLUDED
Используется вместе с директивами #ifdef и #ifndef .
7 6 5 4 3 0
16-ый код: 40 0С 00 00 00 00 00 00
Число –3.5: С0 0С 00 00 00 00 00 00
Диапазон чисел, представимых в формате с плавающей точкой (тип double): |X|min<=|X|<=|X|max и X=0 1<=P’<=2046 (для чисел X ≠0)
|M|min*2pmin <=|X| <=|M|max*2pmax и X=0
1*2-1022<=|X| <=(2-2-52)*21023 и X=0
10k<=|X| <=10L lg2=0.30103
k= –1022*lg 2= –307.65266= -308+0.34734
L= 1024* lg 2=1024*0.30103=308.25472
2.2*10-308<=|X| <=1.7*10308 и X=0
__[\\\\\\\\] _____|_____[\\\\\\\\]______
–Xmax -Xmin 0 Xmin Xmax
Точность чисел, представленных в формате с плавающей точкой: часто вместо числа Х в МС хранится его приближение Х*. Погрешность вносится из-за хранения приближенного значения мантиссы.
Абсолютная погрешность числа Х*:
|X – X*| = ∆( Х*) = |MX –MX*|*2px = 2-52*2px
т.е. абсолютная погрешность числа зависит от порядка числа. Обычно для формата с плавающей точкой определяют относительную погрешность Х* : d(Х*)
Для пользователя более важным является практический вопрос: сколько значащих цифр десятичного представления числа гарантированно сохраняются при таком формате хранения числа. Есть приближенное правило для определения этого количества К цифр при q=2:
m двоичных разрядов мантиссы соответствуют К десятичным цифрам:
К»[m / 3.32]; Для типа double К=[53/3.32]=15.96, т.е. для значения типа
doubleсохраняется в памяти 15-16 десятичных знаков.
Выполнение операций над числами, представленными с плавающей точкой (говорят- в плавающей арифметике).
Пусть X = Mx×2Px ,а Y = My×2Py
a)Сложение (вычитание) чисел:
Z = X ± Y = Mx×2Px ± My×2Py
={1шаг–выравнивание порядков к большему; пусть Px >Py}
= 2Px×(Mx ± My×2Py–Px)
={2 шаг–сдвиг мантиссы My на |Py–Px| разрядов}
= 2Px×mz
= {3шаг–сложение(вычитание) мантисс, получается мантисса mz}.
= Mz ×2Pz
Возможны случаи:
· 1 £ |mz| < 2 Þ операция закончена, Mz = mz ; Pz = Px ;
· 2 £ |mz|, но |mz| <4
Þ выполняется нормализация результата сдвигом мантиссы вправо на 1 разряд с коррекцией порядка (+1);
· |mz| <1 Þ выполняется нормализация результата сдвигом мантиссы влево на t разрядов с коррекцией порядка (–t).
з pх 1.ххххх
– з py 1.xxyyy пусть pх == py
з pх 0.00zzz При вычитании близких чисел
з pz 1.zz??? происходитпотеря точности
б)Умножение :
Z = X × Y = Mx×2Px × My×2Py = Mx×My×2Px+Py == Mz ×2Pz , где Mz = Mx×My ; Pz = Px+Py; т.е. при умножении чисел их мантиссы перемножаются, а порядки складываются. При умножении двух мантисс может получиться результат такой, что потребуется сдвиг мантиссы вправо, но не более, чем на один разряд, тогда нужна коррекция порядка (+1).
в)Деление :
т.е. при делении чисел их мантиссы делятся, а порядки вычитаются. При делении двух мантисс может потребоваться для полученной мантиссы сдвиг влево, но не более, чем на один разряд с коррекцией порядка (–1).
Особые ситуации плавающей арифметики.
1. Переполнение порядка при выполнении операций плавающей арифметики;
2. некорректность деления в плавающей арифметике: деление на число с нулевой мантиссой;
3. потеря значимости: Pz ¹0, а Mz = 0;
4. исчезновение порядка: Pz < Pmin , а Mz ¹ 0.
Две последние ситуации не являются аварийными, они обычно приводят к тому, что результат Z заменяется нулём – это машинный нуль.
Int i, j , m;
i=0; //индекс байта строки u.
q.a = n; //значение n помещается в объединение q
m=L<<3 –1; //индекс последнего бита строки s.
Do
{unsigned char x;
x=q.u[i++]; //запись в x очередного i-го байта из u
for( j=0; j<8; j++) // цикл формирует биты от 0 до7
{s[m--] = (x&1)+'0'; // i-го байта строки s.
x=x>>1;
}
}
while (i<L);
s[L<<3]=0; //нуль символ в конец строки s.
}
//Внутреннее 16-ричное представление целого.
void hexkod (tip n, char s[ ])
{int i,m;
unsigned char x;
char alf[ ]="0123456789ABCDEF";//алфавит 16-ой системы счисления
i=0; m=L<<1 –1;
do
{x=q.u[i++];
s[m--]=alf[x&15]; // младшая 16-ричная цифра i-го байта u
s[m--]=alf[(x>>4)]; // старшая 16-ричная цифра i-го байта u
}
while (i<L);
s[L<<1]=' '; //нуль символ в конец строки s.
}
int main ()
{double x;
char t[L<<3+1];
cout<< "n double—x= ";
cin>> x;
binkod(x,t); cout<< x<< ": n"<<t<<endl;
hexkod (x,t); cout<< x<< ": "<<t<<endl;
return 0;
}
Выполнение этой программы
double—-x= 3.5
3.5:
3.5: 400C000000000000
Замечание 1. Этот способ доступа к значению типа tip (с union ) может быть применён для значения другого простого типа, например, int. Это более универсальный способ. Для использования этой программы для типа int достаточно изменить одно предложение:
typedef int tip;
В главе «Битовые операции» для получения внутреннего кода данных типа int был рассмотрен другой способ с использованием битовых операций и операций сдвига. Тот способ не приемлем для вещественных данных, так как для них не определены битовые операции и операции сдвига.
Замечание 2. Шаблон функции.
Поскольку алгоритм вывода внутреннего кода данного можно использовать для данных разных типов, возникает желание сделать тип параметром этого алгоритма. В языке С++ есть средство параметризации – шаблоны. С помощью шаблона функции можно определить алгоритм, которому конкретный тип передаётся в виде параметра на этапе компиляции, при этом компилятор генерирует код функции, соответствующий этому типу. Это называется инстанцированием шаблона. Тип параметра для инстанцирования задаётся при вызове функции либо явным образом, либо определяется автоматически по типу аргумента. Код функции при повторном вызове с тем же параметром не создаётся снова.
Простейшая функция-шаблон с параметром tip имеет вид:
template <class tip> заголовок_функции
{/*тело функции*/}
Пример шаблона функции с параметром tip для получения строки внутреннего двоичного кода данного этого типа.
#include <iostream>
Using namespace std;
template <class tip>
void binkod (tip n,char s[])
{//функция формирует строку s с двоичным представлением //вещественного данного n.
const int L=sizeof(tip); // размер типа в байтах
union {
Tip a;
unsigned char u[L];
}q;
Int i,j,m;
i=0; //индекс байта строки u.
q.a=n; //значение n помещается в объединение q
m=L<<3–1; //индекс бита строки s.
Do
{unsigned char x;
x=q.u[i++]; //запись в x очередного байта из u
for( j=0;j<8;j++) // цикл формирует биты от 0 до7
{s[m--]=(x&1)+'0'; // m-го бита строки s.
x=x>>1;
}
}
while (i<L);
s[L<<3]=0; //нуль символ в конец строки s.
}
template <class tip>
void hexkod(tip n,char s[])
{//Внутреннее 16-ричное представление целого.
const int L=sizeof(tip);
union {
Tip a;
unsigned char u[L];
}q;
Int i,m;
Unsigned char x;
char alf[]="0123456789ABCDEF";
q.a=n;
i=0; m=L<<1–1;
Do
{x=q.u[i++];
s[m--]=alf[x&15];
s[m--]=alf[(x>>4)];
}
while (i<L);
s[L<<1]=' ';
}
Int main ()
{const int Q=sizeof(long double);
Int n;
Double u;
Float v;
1023: 00000000000000000000001111111111
FF
-3.5: 1100000000001100000000000000000000000000000000000000000000000000
-3.5: C00C000000000000
2.5: 01000000001000000000000000000000
2.5: 40200000
1: 00000001
1: 01
//вывод 16-го кода с использованием манипуляторов
– Конец работы –
Используемые теги: Позволяет, пользователю, Дать, новое, имя, некоторому, типу0.102
Если Вам нужно дополнительный материал на эту тему, или Вы не нашли то, что искали, рекомендуем воспользоваться поиском по нашей базе работ: Позволяет пользователю дать новое имя некоторому типу
Если этот материал оказался полезным для Вас, Вы можете сохранить его на свою страничку в социальных сетях:
Твитнуть |
Новости и инфо для студентов