Будь умным!


У вас вопросы?
У нас ответы:) SamZan.net

Лабораторная работа 41

Работа добавлена на сайт samzan.net:


Лабораторная работа №4.

 

«Моделирование процессов преобразования информации в сопроцессоре».

 

Арифметический сопроцессор (FPU) – устройство, непосредственно подключенное к центральному процессору (CPUIntel и предназначенное для выполнения операций над числами в формате с плавающей точкой (вещественные числа) и длинными целыми числами.

Арифметический сопроцессор значительно (в десятки раз) ускоряет вычисления, связанные с вещественными числами. Он может вычислять такие функции как синус, косинус, логарифмы и т.д.

Очень важно понимать, как работает сопроцессор. Также очень важно понимать форматы его данных.

Данных сопроцессора храняться  в 8-ми регистрах (ST0-ST7) во внутреннем формате (long double для C/C++, extended для Pascal). Прикладные  программы читают эти данные из регистров и корректно декодируют.

Аналогичным процессам и посвящена данная лабораторная работа.

 

ОСНОВНЫЕ СВЕДЕНИЯ.

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

(знак)(мантисса)*10(знак)(порядок)

Например: -1.35*10-5

Здесь знак – это минус (унарный плюс недопустим!), мантисса – 1.35, порядок - -5. Как видите, порядок тоже может иметь знак. Вспомним также такое понятие, как нормализованное представление чисел:

если целая часть мантиссы числа состоит из одной, не равной нулю цифры, то число с плавающей точкой называется нормализованным.

Преимущество использования нормализованных чисел состоит в том, что для фиксированной разрядной сетки числа (для фиксированного количества цифр в числе) такие числа имеют наибольшую точность. Кроме того, нормализованное представление исключает неоднозначность – каждое число с плавающей точкой может быть представлено различными (ненормализованными) способами:

123.5678*10= 12.35678*10= 1.235678*10= 0.1235678*108

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

(знак)(мантисса)Е(знак)(порядок).

Например, -5.35Е-2 означает число –5.35*10-2. Такое представление называется научной нотацией.

Сопроцессор фирмы Intel может работать с вещественными числами  в трех форматах:

·       одинарной точности

·       двойной точности

·       расширенной точности

или

·       float

·       double

·       long double

для языка C/C++

·       single

·       double

·       extended

для Pascal/Delphi

Следует отметить, что тип real не поддерживается сопроцессором и его использование в программах нежелательно ввиду потерь времени на преобразование информации к форматам, поддерживаемым сопроцессором и обратно.

Числа в формате данных сопроцессора занимают соответственно 4, 8 и 10 байтов:

 

            1 бит         8 бит                   23 бита

 

 


             1 бит             11 бит                  52 бита

 

 


            1 бит                15 бит                                           64 бита

 

 


На рисунке приведены числа одинарной, двойной и расширенной точности соответственно.

В любом представлении старший бит «Зн» определяет знак вещественного числа:

0 – положительное число

1 – отрицательное число

Обратите внимание: в отличие от целых чисел, вещественные представляются в прямом коде.

Все равные по абсолютному значению положительные и отрицательные числа отличаются только этим битом. В остальном числа с равным знаком полностью симметричны.

Арифметический сопроцессор работает с нормализованными числами, поэтому поле мантиссы содержит мантиссу нормализованного числа.

Здесь используется двоичное представление чисел. Сформулируем определение нормализованного числа для этого случая:

если целая часть мантиссы числа в двоичном представлении равна 1, то число с плавающей точкой называется нормализованным.

Так как для нормализованного двоичного числа целая часть всегда равна единице, то эту единицу можно не хранить. Именно так и поступили разработчики сопроцессора – в форматах одинарной и двойной точности числа целая часть мантиссы не хранится. Таким образом экономится один бит памяти.

Для наглядности представим мантиссу числа в такой форме:

n.nnnnnnn

Здесь символом ‘n’ обозначается либо 0, либо 1. Нормализованные числа в крайней левой позиции содержат 1, поэтому их можно представить в виде:

1.nnnnnnn

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

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

Поле порядка – это степень двойки, на которую умножается мантисса, плюс смещение, равное 127 для одинарной точности, 1023 для двойной, 16383 для расширенной.

Для того, чтобы определить абсолютное значение числа с плавающей точкой, можно воспользоваться следующими формулами:

·       одинарная точность: 1.(цифры мантиссы)*2(Р-127)

·       двойная точность: 1.(цифры мантиссы)*2(Р-1023)

·       расширенная точность: 1.(цифры мантиссы)*2(Р-16383)

Знак числа, как уже говорилось, определяется старшим битом.

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

1  01111110  11000000000000000000000

Для этого числа знак равен 1 (отрицательное число), порядок – 126, мантисса – 11 (в двоичной системе счисления, то есть 0.11 в двоичном виде или 2-1 + 2-2 = 0.5+0.25+0.75 в десятичном). С учетом целой части, это число равно:

-1.11*2(126-127) = - (2+0.5+0.25) * 2-1 = -1.75*0.5= -0.875

Вообще, двоичная мантисса вида 1.nnnnnnnnnn означает следующее:

2 + n*2-1+n*2-2+…+n*2-k

Следует учесть, что не все десятичные числа могут быть разложены в конечный ряд по степеням двойки, например 0.1

 

ЗАДАНИЕ НА ЛАБОРАТОРНУЮ РАБОТУ.

Необходимо реализовать программу, выполняющую конверсию введенного с клавиатуры десятичного числа с плавающей точкой в формат сопроцессора и обратное преобразование (вводится двоичное представление, программа выдает соответствующее десятичное число). Ввод осуществляется с клавиатуры, вывод на экран.

Программа должна поддерживать все три типа данных сопроцессора.

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

 

program chek;

a : extended;

b : array [1..10] of byte absolute a;

begin

 for i:=1 to 10 do

  dec2bin(a[i]);

 endfor

end;

 

program dec2bin(a:byte);

begin

 for i:=1 to 8 do

  write(a mod 2);

  a:=a div 2;

 end;

end;

 

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

 

Пример внешнего вида программы:

Введите число: -0.875

 

Знак: 1

 

Порядок: 01111110 (126d, 7E)

 

 

 

 

 

 

Мантисса: 11000000000000000000000 (0.75d, 0.44h)

 

 

 

 

 

Решение.

#include <iostream>

#include <memory>

#include <math.h>

#include <vector>

#include <conio.h>

#include <algorithm>

#include <string>

using namespace std;

typedef unsigned char byte;

void float2bin(float, byte *, const int = 32);

void double2bin(double, byte*, const int = 64);

void longdouble2bin(long double, byte*, const int = 80);

bool check_float(float, byte* , const int = 32);

bool check_double(double, byte*, const int = 64);

//проверка 80битного представления числа нет, поскольку компиляторы MS VC++ и gcc не поддерживают 80битные long double

//в MS VC++ long double = double, в gcc 12 байт(96 бит)

void print_binary(byte*, const int);

void bit4_bin2hex(vector<byte>&);

void print_binary(byte*, const int);

int bin2integer_part(vector<byte>&);

void integer_part2bin(int, vector<byte>&);

//функции обратного преобразования

float bin2float(byte* , const int );

double bin2double(byte* , const int );

long double bin2longdouble(byte* , const int );

template <class T>

void real_part2bin(T number, vector<byte>& binout, int digits)   

{

if(number == 0.0)

 return;

 

for(int i = 0; i < digits && number != 0.0; i++)     

{

 number *= 2;             

 if(number >= 1)

 {

  binout.push_back(1);

  number -= 1.0;

 }

 else

  binout.push_back(0);

}

}

template <class T>

T bin2real_part(vector<byte>& binary)          

{

T number = 0;

for(int i = 0; i < (int)binary.size() ; i++)       

{

 number += pow(2.0, -1*(i + 1)) * (T)binary[(int)binary.size() - i - 1 ];

 }

 return number;

}

//функция для ввода массива 0 и 1 в вектор байт

void input_vector_bin(vector<byte>&, const int);

//интерфейсы

bool input_binary_interface(byte*, const int);

void work_with_binary();

void work_with_float_numbers();

int main()

{

setlocale(0, "Russian");

int select;

do{

 cout << "Машинное представление вещественных чисел" <<endl;

 cout << "1 - преобразование десятичных вещественных чисел в формат сопроцессора"<<endl;

 cout << "2 - преобразование двоичного машинного представления в десятичное исчисление"<<endl;

 cin >>select;

}while(select != 1 && select !=2);

if( select == 1)

 work_with_float_numbers();

else

 work_with_binary();

 

_getch();

}

void float2bin(float number, byte *bin, const int arr_size )

{

const int count_poryadok = 8;        

const int count_mantissa = 23;        

const int add_por = 127;         

memset(bin, 0, sizeof(byte)*arr_size);      

if(number == 0.0)           

{

 return;

}

if(number < 0)            

 bin[arr_size - 1] = 1;

number = fabs(number);

int offset = 0;            

vector<byte> real_part_bin;         

vector<byte> poryadok;          

if(number >= 1.0)           

{

 int int_part = (int)number;        

 vector<byte> int_part_bin;        

 integer_part2bin(int_part, int_part_bin);    

 offset += int_part_bin.size() - 1;      

 int por = add_por + offset;        

 integer_part2bin(por, poryadok);      

 copy(poryadok.begin(), poryadok.end(), bin + count_mantissa);

 copy(int_part_bin.begin(), int_part_bin.end() - 1, bin + (count_mantissa - offset));

 number -= (int) number;         

 real_part2bin(number, real_part_bin, count_mantissa - offset);//и его двоичное представление

 reverse(real_part_bin.begin(), real_part_bin.end()); //полученное представление записываем в обратном порядке

 copy(real_part_bin.begin(), real_part_bin.end(), bin + (count_mantissa - offset - (int)real_part_bin.size()));

               

 }

 else //если целой части нет

{

 const int size = add_por;          

 real_part2bin(number, real_part_bin, size);      

 reverse(real_part_bin.begin(), real_part_bin.end());   

 while(real_part_bin.back() == 0 && (int)real_part_bin.size() != 1)

 {

  offset--;             

  real_part_bin.pop_back();         

 }

 if(real_part_bin.back() == 0)         

  return;

 real_part_bin.pop_back();          

 offset--;              

 if(real_part_bin.size() > count_mantissa)      

 {

  copy(real_part_bin.begin() + ((int)real_part_bin.size() - count_mantissa) , real_part_bin.end(), bin);

 }else               

 {

  copy(real_part_bin.begin(), real_part_bin.end(), bin + (count_mantissa - (int)real_part_bin.size()));

 }

 int por = add_por + offset;          

 integer_part2bin(por, poryadok);        

 copy(poryadok.begin(), poryadok.end(), bin+count_mantissa);  //записываем в результат.

}

 

 

 

}

void double2bin(double number, byte *bin, const int arr_size)

{

const int count_poryadok = 11;        

const int count_mantissa = 52;        

const int add_por = 1023;         

memset(bin, 0, sizeof(byte)*arr_size);      

if(number == 0.0)           

{

 return;

}

if(number < 0)            

 bin[arr_size - 1] = 1;

number = fabs(number);

int offset = 0;            

vector<byte> real_part_bin;         

vector<byte> poryadok;          

if(number >= 1.0)           

{

 int int_part = (int)number;        

 vector<byte> int_part_bin;        

 integer_part2bin(int_part, int_part_bin);    

 offset += int_part_bin.size() - 1;      

 int por = add_por + offset;        

 integer_part2bin(por, poryadok);      

 copy(poryadok.begin(), poryadok.end(), bin + count_mantissa);

 copy(int_part_bin.begin(), int_part_bin.end() - 1, bin + (count_mantissa - offset));

 number -= (int) number;         

 real_part2bin(number, real_part_bin, count_mantissa - offset);//и его двоичное представление

 reverse(real_part_bin.begin(), real_part_bin.end()); //полученное представление записываем в обратном порядке

 copy(real_part_bin.begin(), real_part_bin.end(), bin + (count_mantissa - offset - (int)real_part_bin.size()));

               

 }

 else //если целой части нет

{

 const int size = add_por;          

 real_part2bin(number, real_part_bin, size);      

 reverse(real_part_bin.begin(), real_part_bin.end());   

 while(real_part_bin.back() == 0 && (int)real_part_bin.size() != 1)

 {

  offset--;             

  real_part_bin.pop_back();         

 }

 if(real_part_bin.back() == 0)         

  return;

 real_part_bin.pop_back();          

 offset--;              

 if(real_part_bin.size() > count_mantissa)      

 {

  copy(real_part_bin.begin() + ((int)real_part_bin.size() - count_mantissa) , real_part_bin.end(), bin);

 }else               

 {

  copy(real_part_bin.begin(), real_part_bin.end(), bin + (count_mantissa - (int)real_part_bin.size()));

 }

 int por = add_por + offset;          

 integer_part2bin(por, poryadok);        

 copy(poryadok.begin(), poryadok.end(), bin+count_mantissa);  //записываем в результат.

}

}

void longdouble2bin(long double number, byte *bin, const int arr_size)

{

const int count_poryadok = 15;        

const int count_mantissa = 64;        

const int add_por = 16383;         

memset(bin, 0, sizeof(byte)*arr_size);      

if(number == 0.0)           

{

 return;

}

if(number < 0)            

 bin[arr_size - 1] = 1;

number = fabs(number);

int offset = 0;            

vector<byte> real_part_bin;         

vector<byte> poryadok;          

if(number >= 1.0)           

{

 int int_part = (int)number;        

 vector<byte> int_part_bin;        

 integer_part2bin(int_part, int_part_bin);    

 offset += int_part_bin.size() - 1;      

 int por = add_por + offset;        

 integer_part2bin(por, poryadok);      

 copy(poryadok.begin(), poryadok.end(), bin + count_mantissa);

 copy(int_part_bin.begin(), int_part_bin.end() - 1, bin + (count_mantissa - offset));

 number -= (int) number;         

 real_part2bin(number, real_part_bin, count_mantissa - offset);

 reverse(real_part_bin.begin(), real_part_bin.end());

 copy(real_part_bin.begin(), real_part_bin.end(), bin + (count_mantissa - offset - (int)real_part_bin.size()));

               

}

else

{

 const int size = add_por;          

 real_part2bin(number, real_part_bin, size);      

 reverse(real_part_bin.begin(), real_part_bin.end());   

 while(real_part_bin.back() == 0 && (int)real_part_bin.size() != 1)

 {

  offset--;             

  real_part_bin.pop_back();         

 }

 if(real_part_bin.back() == 0)         

  return;

 real_part_bin.pop_back();          

 offset--;              

 if(real_part_bin.size() > count_mantissa)      

 {

  copy(real_part_bin.begin() + ((int)real_part_bin.size() - count_mantissa) , real_part_bin.end(), bin);

 }else               

 {

  copy(real_part_bin.begin(), real_part_bin.end(), bin + (count_mantissa - (int)real_part_bin.size()));

 }

 int por = add_por + offset;          

 integer_part2bin(por, poryadok);        

 copy(poryadok.begin(), poryadok.end(), bin+count_mantissa);  //записываем в результат.

}

}

bool check_float(float number, byte* bin, const int arr_size)

{

 

__int32 numb = *(int *)&number;          

__int32 checker = 0x1;            

bool return_value = true;           

 cout << "Проверка полученного двоичного представления с машинным представлением float"<<endl;

 cout << "Полученное число: "<<endl;

for(int i = 0; i < arr_size; i++)         

{

 cout << (int)bin[i];

}

cout << endl << "Машинное представление: "<<endl;

 

for(int i = 0; i < 32; i++)           

{

 if(numb & checker)

  cout << 1;

 else

  cout << 0;

 checker = checker << 1;

}

checker = 0x1;

for(int i = 0; i < arr_size; i++)         

{

 

 if(bin[i] == 0 && (numb & checker))        

  return_value = false;

 if(bin[i] == 1 && !(numb & checker))

  return_value = false;

 checker = checker << 1;

}

return return_value;

}

bool check_double(double number, byte* bin, const int arr_size)

{

__int64 numb = *(__int64 *)&number;         

__int64 checker = 0x1;

bool return_value = true;

 cout << "Проверка полученного двоичного представления с машинным представлением double"<<endl;

 cout << "Полученное число: "<<endl;

for(int i = 0; i < arr_size; i++)

{

 cout << (int)bin[i];

}

cout << endl << "Машинное представление: "<<endl;

 

for(int i = 0; i < arr_size; i++)

{

 if(numb & checker)

  cout << 1;

 else

  cout << 0;

 checker = checker << 1;

}

checker = 0x1;

for(int i = 0; i < arr_size; i++)

{

 

 if(bin[i] == 0 && (numb & checker))

  return_value = false;

 if(bin[i] == 1 && !(numb & checker))

  return_value = false;

 checker = checker << 1;

}

return return_value;

}

//

void bit4_bin2hex(vector<byte>& tetrada)          

{

 if(tetrada[3] == 0 && tetrada[2] == 0 && tetrada[1] == 0 && tetrada[0] == 0)//перебираем все возможные значения

 cout << 0;

if(tetrada[3] == 0 && tetrada[2] == 0 && tetrada[1] == 0 && tetrada[0] == 1)

 cout << 1;

if(tetrada[3] == 0 && tetrada[2] == 0 && tetrada[1] == 1 && tetrada[0] == 0)

 cout << 2;

if(tetrada[3] == 0 && tetrada[2] == 0 && tetrada[1] == 1 && tetrada[0] == 1)

 cout << 3;

if(tetrada[3] == 0 && tetrada[2] == 1 && tetrada[1] == 0 && tetrada[0] == 0)

 cout << 4;

if(tetrada[3] == 0 && tetrada[2] == 1 && tetrada[1] == 0 && tetrada[0] == 1)

 cout << 5;

if(tetrada[3] == 0 && tetrada[2] == 1 && tetrada[1] == 1 && tetrada[0] == 0)

 cout << 6;

if(tetrada[3] == 0 && tetrada[2] == 1 && tetrada[1] == 1 && tetrada[0] == 1)

 cout << 7;

if(tetrada[3] == 1 && tetrada[2] == 0 && tetrada[1] == 0 && tetrada[0] == 0)

 cout << 8;

if(tetrada[3] == 1 && tetrada[2] == 0 && tetrada[1] == 0 && tetrada[0] == 1)

 cout << 9;

if(tetrada[3] == 1 && tetrada[2] == 0 && tetrada[1] == 1 && tetrada[0] == 0)

 cout << 'A';

if(tetrada[3] == 1 && tetrada[2] == 0 && tetrada[1] == 1 && tetrada[0] == 1)

 cout << 'B';

if(tetrada[3] == 1 && tetrada[2] == 1 && tetrada[1] == 0 && tetrada[0] == 0)

 cout << 'C';

if(tetrada[3] == 1 && tetrada[2] == 1 && tetrada[1] == 0 && tetrada[0] == 1)

 cout << 'D';

if(tetrada[3] == 1 && tetrada[2] == 1 && tetrada[1] == 1 && tetrada[0] == 0)

 cout << 'E';

if(tetrada[3] == 1 && tetrada[2] == 1 && tetrada[1] == 1 && tetrada[0] == 1)

 cout << 'F';

}

void print_binary(byte* bin, const int arr_size)      

{

if(arr_size == 32)             

{

 cout << "Знак: "<< (int)bin[31] <<endl;       

 vector<byte> por(bin + 23, bin + 31);       

 cout << "Порядок: " ;

 for(int i = (int)por.size() - 1; i >= 0; i--)     

  cout << (int)por[i];

 cout << " ( ";

 vector<byte> tetrada;

 for(int i = 8; i > 0; i -= 4)         

 {

  tetrada.clear();

  tetrada.insert(tetrada.begin(), por.begin() + (i - 4), por.begin() + i);

  bit4_bin2hex(tetrada);

 }

 tetrada.clear();            

 cout << "h, "<< bin2integer_part(por) << "d )"<<endl;   //выводим в десятичном виде

 por.clear();

 cout << "Мантисса: ";           

 vector<byte> mantissa(bin, bin + 23);

 for(int i = (int)mantissa.size() - 1; i >= 0; i--)

  cout << (int)mantissa[i];

 cout << " ( 0.";

 mantissa.insert(mantissa.begin(), 0);       

 for(int i = 24; i > 0; i -= 4)         

 {

  tetrada.clear();

  tetrada.insert(tetrada.begin(), mantissa.begin() + (i - 4), mantissa.begin() + i);

  bit4_bin2hex(tetrada);

 }

 cout << "h, "<< bin2real_part<float>(mantissa) << "d )"<<endl; //выводим в десятичном виде

 

}

if(arr_size == 64)             

{

 cout << "\nЗнак: "<< (int)bin[63] <<endl;

 vector<byte> por(bin + 52, bin + 63);

 cout << "Порядок: " ;

 for(int i = (int)por.size() - 1; i >= 0; i--)

  cout << (int)por[i];

 cout << " ( ";

 por.push_back(0);

 vector<byte> tetrada;

 for(int i = 12; i > 0; i -= 4)

 {

  tetrada.clear();

  tetrada.insert(tetrada.begin(), por.begin() + (i - 4), por.begin() + i);

  bit4_bin2hex(tetrada);

 }

 tetrada.clear();

 por.pop_back();

 cout << "h, " << bin2integer_part(por) << "d )"<<endl;

 por.clear();

 cout << "Мантисса: ";

 vector<byte> mantissa(bin, bin + 52);

 for(int i = (int)mantissa.size() - 1; i >= 0; i--)

  cout << (int)mantissa[i];

 cout << " \n(0.";

 for(int i = 52; i > 0; i -= 4)

 {

  tetrada.clear();

  tetrada.insert(tetrada.begin(), mantissa.begin() + (i - 4), mantissa.begin() + i);

  bit4_bin2hex(tetrada);

 }

 cout << "h, " << bin2real_part<double>(mantissa) << "d)"<<endl;

}

if(arr_size == 80)

{

 cout << "\nЗнак: "<< (int)bin[79] <<endl;

 vector<byte> por(bin + 64, bin + 79);

 cout << "Порядок: " ;

 for(int i = (int)por.size() - 1; i >= 0; i--)

  cout << (int)por[i];

 cout << " ( ";

 por.push_back(0);

 vector<byte> tetrada;

 for(int i = 16; i > 0; i -= 4)

 {

  tetrada.clear();

  tetrada.insert(tetrada.begin(), por.begin() + (i - 4), por.begin() + i);

  bit4_bin2hex(tetrada);

 }

 tetrada.clear();

 por.pop_back();

 cout << "h, " << bin2integer_part(por) << "d)"<<endl;

 

 por.clear();

 cout << "Мантисса: ";

 vector<byte> mantissa(bin, bin + 64);

 for(int i = (int)mantissa.size() - 1; i >= 0; i--)

  cout << (int)mantissa[i];

 cout << " \n(0.";

 for(int i = 64; i > 0; i -= 4)

 {

  tetrada.clear();

  tetrada.insert(tetrada.begin(), mantissa.begin() + (i - 4), mantissa.begin() + i);

  bit4_bin2hex(tetrada);

 }

 cout << "h, " << bin2real_part<long double>(mantissa) << "d)"<<endl;

 

}

}

float bin2float(byte* bin, const int arr_size)     

{

const int count_poryadok = 8;        

const int count_mantissa = 23;        

const int add_por = 127;

float number = 0;           

vector<byte> mantissa(bin, bin + count_mantissa);   

vector<byte> poryadok(bin + count_mantissa, bin + count_mantissa + count_poryadok);

number = bin2real_part<float>(mantissa) + 1;    

if(bin[count_poryadok + count_mantissa])     

 number *= -1.0;

number *= pow(2.0, bin2integer_part(poryadok) - add_por);

return number;

}

double bin2double(byte* bin, const int arr_size)    

{

const int count_poryadok = 11;        

const int count_mantissa = 52;        

const int add_por = 1023;

double number = 0;

vector<byte> mantissa(bin, bin + count_mantissa);

vector<byte> poryadok(bin + count_mantissa, bin + count_mantissa + count_poryadok);

number = bin2real_part<double>(mantissa) + 1;

if(bin[count_poryadok + count_mantissa])

 number *= -1.0;

number *= pow(2.0, bin2integer_part(poryadok) - add_por);

return number;

}

long double bin2longdouble(byte* bin, const int arr_size)  

{

const int count_poryadok = 15;       

const int count_mantissa = 64;        

const int add_por = 16383;

long double number = 0;

vector<byte> mantissa(bin, bin + count_mantissa);

vector<byte> poryadok(bin + count_mantissa, bin + count_mantissa + count_poryadok);

number = bin2real_part<long double>(mantissa) + 1;

if(bin[count_poryadok + count_mantissa])

 number *= -1.0;

number *= pow(2.0, bin2integer_part(poryadok) - add_por);

return number;

}

int bin2integer_part(vector<byte>& binary)      

{

int number = 0;

for(int i = 0; i < (int)binary.size(); i++)

{

 number += (int)pow((double)2, i)*(int)binary[i];  

}

return number;

}

void integer_part2bin(int number, vector<byte>& binout)

{

if(number == 0)

 return;

while(number != 1)

{

 binout.push_back((byte)(number % 2));

 number /= 2;

}

binout.push_back(1);       

}

void input_vector_bin(vector<byte>& bin, const int need_size)  

{

string inp;              

cin >> inp;              

for(int i = (int)inp.length() - 1; i >= 0; i--)     

{

 if(inp[i] == '0')

  bin.push_back(0);

 if(inp[i] == '1')

  bin.push_back(1);

}

if((int)bin.size() != need_size)        

 bin.clear();

}

bool input_binary_interface(byte* bin, const int arr_size)   

{

if(arr_size == 32)            

{

 vector<byte> buffer;          

 cout << "Введите знак(1 цифра)"<<endl;

 input_vector_bin(buffer, 1);

 if(buffer.empty())           

 {

  cout << "Знак должен быть 0 или 1 (1 знак)" << endl;

  return false;

 }

 bin[31] = buffer[0];          

 buffer.clear();            

 cout << "Введите порядок(8 цифр)" <<endl;

 input_vector_bin(buffer, 8);        

 if(buffer.empty())           

 {

  cout << "Порядок должен состоять из 8 знаков" << endl;

  return false;

 }

 copy(buffer.begin(), buffer.end(), bin + 23);    

 buffer.clear();            

 cout << "Введите мантиссу(23 цифры)" <<endl;

 input_vector_bin(buffer, 23);

 if(buffer.empty())

 {

  cout << "Мантисса должна состоять из 23 знаков" << endl;

  return false;

 }

 copy(buffer.begin(), buffer.end(), bin);

 buffer.clear();

 

}

if(arr_size == 64)            

{

 vector<byte> buffer;

 cout << "Введите знак(1 цифра)"<<endl;

 input_vector_bin(buffer, 1);

 if(buffer.empty())

 {

  cout << "Знак должен быть 0 или 1 (1 знак)" << endl;

  return false;

 }

 bin[63] = buffer[0];

 buffer.clear();

 cout << "Введите порядок(11 цифр)" <<endl;

 input_vector_bin(buffer, 11);

 if(buffer.empty())

 {

  cout << "Порядок должен состоять из 8 знаков" << endl;

  return false;

 }

 copy(buffer.begin(), buffer.end(), bin + 52);

 buffer.clear();

 cout << "Введите мантиссу(52 цифры)" <<endl;

 input_vector_bin(buffer, 52);

 if(buffer.empty())

 {

  cout << "Мантисса должна состоять из 52 знаков" << endl;

  return false;

 }

 copy(buffer.begin(), buffer.end(), bin);

 buffer.clear();

}

if(arr_size == 80)

{

 vector<byte> buffer;

 cout << "Введите знак(1 цифра)"<<endl;

 input_vector_bin(buffer, 1);

 if(buffer.empty())

 {

  cout << "Знак должен быть 0 или 1 (1 знак)" << endl;

  return false;

 }

 bin[79] = buffer[0];

 buffer.clear();

 cout << "Введите порядок(16 цифр)" <<endl;

 input_vector_bin(buffer, 16);

 if(buffer.empty())

 {

  cout << "Порядок должен состоять из 8 знаков" << endl;

  return false;

 }

 copy(buffer.begin(), buffer.end(), bin + 64);

 buffer.clear();

 cout << "Введите мантиссу(64 цифры)" <<endl;

 input_vector_bin(buffer, 64);

 if(buffer.empty())

 {

  cout << "Мантисса должна состоять из 64 знаков" << endl;

  return false;

 }

 copy(buffer.begin(), buffer.end(), bin);

 buffer.clear();

}

return true;

}

void work_with_binary()              

{

 int select;                

 cout << "Работа с введенными бинарными числами"<<endl;

 cout << "Введите разрядность вводимого числа(1 - 32 бит, 2 - 64 бит, 3 - 80 бит):"<<endl;

 do{

 cin>> select;

}while(select != 1 && select != 2 && select != 3);      

byte *bin;                

bool input_success ;             

switch(select)

{

case 1:

 bin = new byte[32];             

 input_success = input_binary_interface(bin, 32);     

 if(!input_success)

  return;

 print_binary(bin, 32);            

 cout << "Число в десятичном исчислении: "<< bin2float(bin, 32) <<endl;  

 break;

case 2:                 

 bin = new byte[64];

 input_success = input_binary_interface(bin, 64);

 if(!input_success)

  return;

 print_binary(bin, 64);

 cout << "Число в десятичном исчислении: "<< bin2double(bin, 64) <<endl;

 break;

default:

 bin = new byte[80];

 input_success =  input_binary_interface(bin, 80);

 if(!input_success)

  return;

 print_binary(bin, 80);

 cout << "Число в десятичном исчислении: "<< bin2longdouble(bin, 80) <<endl;

 break;

}

delete[] bin;               

}

void work_with_float_numbers()

{

 int select;

 cout << "Работа с вещественными числами"<<endl;

 cout << "Введите тип вводимого числа:\n1 - одинарной точности(float)\n2 - двойной точности(double)\n3 - расширенной точности(long double)):"<<endl;

 do{

 cin>> select;

}while(select != 1 && select != 2 && select != 3);

byte *bin;                

float fl_number;              

double db_number;

long double ld_number;

cout << "Введите вещественное число:"<<endl;

 switch(select)

{

case 1:

 bin = new byte[32];             

 cin >> fl_number;             

 float2bin(fl_number, bin);           

 print_binary(bin, 32);            

 if(check_float(fl_number, bin, 32))         

  cout << "\nВерно!"<<endl;

 else

  cout << "\nНеверно!!"<<endl;

 break;

case 2:                 

 bin = new byte[64];

 cin >> db_number;

 double2bin(db_number, bin);

 print_binary(bin, 64);

 if(check_double(db_number, bin, 64))

  cout << "\nВерно!"<<endl;

 else

  cout << "\nНеверно!!"<<endl;

 break;

 break;

default:

 bin = new byte[80];

 cin >> ld_number;

 longdouble2bin(ld_number, bin);

 print_binary(bin, 80);

 break;

}

delete[] bin;              

}




1. это одно из важнейших условий успешной целенаправленной деятельности учащихся и обучающей деятельности уч
2. Статья- Исследование реакции сердечно-сосудистой системы на использование различных циклических средств подготовки
3. Disneylnd Resort Pri
4. Бухгалтерский учет в системе управления организацией Основная цель бухгалтерского учета в системе упр
5. это набор механических отношений и действовать она должна подобно механизму- алгоритмизированное эффекти
6. послабивши болти кріплення кронштейна натяжного ролика зняти зношений ремінь
7. Памятка консультанту выставочного стенда
8. Александр Сергеевич Пушкин (лицейские годы поэта)
9. уровень показателей за соответствующие отрезки времени исходя из принятого масштаба
10. догмат про особисту вірі який виник під впливом Святого Духа
11. ТЕМА 20 ТУРИЗМ КАК ВИД РЕКРЕАЦИИ И ЕГО ВЛИЯНИЕ НА ПРИРОДУ ПЛАН 1
12.  2003 г. 2003 г
13. Задание ’1. Исследовать функцию и построить график.html
14. Тема 2 Основные понятия
15. тема норм права регулирующая трудовые и иные непосредственно связанные с ними отношения
16. Тема 1 Элементы теории множеств Множество совокупность набор какихлибо предметов объектов
17. Контрольная работа- Организация банкета-кофе на 24 человека
18. Гражданское право
19. Оценка стоимости ремонта автотранспортных средств и ущерба от их повреждения
20. 1Предмет экономической теории