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

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

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

Поможем написать учебную работу

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

Предоплата всего

от 25%

Подписываем

договор

Выберите тип работы:

Скидка 25% при заказе до 2.1.2025

Лабораторная работа №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. филосн проф проректор по учебной работе Курганского госуниверситета; shlutinbs@mil
2. СОЦИАЛЬНО КУЛЬТУРНЫЙ СЕРВИС И ТУРИЗМ Специализация 100201 Туризм Моск
3. Саянской складчатой области Полезные ископаемые Металлогеническая специализация
4. Реферат- Валеология
5.  Таблица 1 Исходные данные показатель обозначение
6. Аналіз напруженого стану складених тонкостінних оболоно
7. ЛЕКЦИЯ 3 маркетинговые исследования
8. Бюджетный дефицит и государственный долг
9. Бухгалтерский баланс и его роль в управлении предприятием и оценка финансового положения
10. Общая характеристика уголовного законодательства связанного с незаконным оборотом наркотических средств
11. Медицина Пророка.
12. Синтетичний та аналітичний облік фінансових результатів від звичайної діяльності підприємства
13.  Нормирование труда в основном производстве строительства
14. Діагностика модемів Укладач- Стахів В
15. Лекция 1 Общие понятия экономической теории 1
16. В.Н. Шилов Политическая система Росси
17. НАЧНИ СВОЕ ДЕЛО 1
18. В его состав входят- леса земли покрытые лесом либо предназначенные для лесоразведывания нелесные земли
19. Детский крестовый поход 1212 года
20. Гляжу на будущность с тоской