Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Visual C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.05.2012, 03:38   #1
bombozavr
Новичок
Джуниор
 
Регистрация: 18.05.2012
Сообщений: 3
По умолчанию большие числа, нужны идеи.

Здравствуйте. Требуется написать программу "реализация сложения и вычитания очень больших чисел ( 2^32 и больше)". "Мы" написали умножение, и теперь не знаем как переделать на сложение и вычитание. Прошу помочь. Спасибо заранее.
bombozavr вне форума Ответить с цитированием
Старый 18.05.2012, 03:43   #2
bombozavr
Новичок
Джуниор
 
Регистрация: 18.05.2012
Сообщений: 3
По умолчанию

вот что вышло. кину 2 сообщениями.


Код:
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <NTL/ZZ.h>
NTL_CLIENT
#define N 512//кол-во символов в числе
#define O 10000//максимальное число в элем массива будет О-1
using namespace std;
void menu();
void vivod(const unsigned int* chislo1,int size);//ф-я вывода
void zapis(unsigned int* chislo,char* num1, int size, int dl);//перевод строки в число
void umn(const unsigned int* chislo1,const unsigned int* chislo2,unsigned int* rez,int raz1,int raz2,int size);//умножение
// Приложение А.1. основная функция программы
void main() 
{
	srand(time(NULL));
	cout<<"You are welcome!"<<endl;
	menu();
	cout<<"Good Bye!"<<endl;

}
// Приложение А.2. функция выполняет считывание "больших чисел"
void zapis(unsigned int* chislo,char* num, int size, int dl)
{
	int n=strlen(num)/dl + 1;//нашли скок ячеек будет занято в массиве
	int j;
	for(j=0;j<=size-n;++j)//обнулили все ячейки которые будут пустыми
		chislo[j]=0;
	char* pt=num+strlen(num)-dl;//указатель на то откуда будем число распознавать
	j=size-1;//счетчик дабы знать куда записывать
	while(pt>num)//пока наш указатель не станет за началом строки
	{
		chislo[j]=atoi(pt);//распознаем йотый элем числа
		pt[0]='\n';//изменяем конц строки
		--j;//уменьшаем йот т.к. до этого записали в йотый элем массива число
		pt=pt-dl;//берем указатель на след 4 символа
	}
	chislo[j]=atoi(num);//т.к. невсегда будет число символов кратно 4, и последние символа 1-3 символа в цикле не записываются, то эта строчка записывает эти символы
}
// Приложения А.3. функция выполняет умножение "больших чисел" по "классическому алгоритму"
void umn(const unsigned int* chislo1,const unsigned int* chislo2,unsigned int* rez,int raz1,int raz2,int size) 
{
	int j=0,i=0;
	unsigned int k=0;
	if((chislo1[raz1]==0 && raz1==size-1) || (chislo1[raz2]==0 && raz2==size-1))
		return;
	for(j=size-1;j>=raz1;--j)//пока не дойдем до посл элем 1го числа
	{
		k=0;//разряд переноса
		for(i=size-1;i>=raz2;--i)//пока не дойдем до посл элем 2го числа
		{
			unsigned int t=(chislo1[j]*chislo2[i]+k+rez[-size+i+j+1]);//йотую ячейку перемножаем с итой то что было до этого в той ячейке в которую записываем
			rez[-size+i+j+1]=t%O;//записываем по модулю О
			k=t/O;//находим К
		}
		rez[j-size+raz2]=k;//записываем его
	}
}
// Приложение А.4. функция вывода "больших чисел".
void vivod(const unsigned int* chislo1,int size)//
{
	int raz1=0;
	while(!chislo1[raz1]&&raz1!=size-1)//ищем ненулевой элем 1й
		++raz1;
	cout<<chislo1[raz1];
	for(int i=raz1+1;i<size;++i)//начинаем с него и до конца
		printf("%04u",chislo1[i]);
	cout<<endl;//вывели число, перешли на новую строку
}
//приложение А.5. функция меню.
void menu()
{
	char m;
	do
	{
		cout<<"Multiply - 1."<<endl;
		cout<<"Test with 1000 numbers 512bit - 2."<<endl;
		cout<<"Exit - else."<<endl;
		cin>>m;
		if(m=='1')
		{
			char num1[N];//создали куда записывать число мы будем
			int dl=4;//количество цифр в 1й ячейке, т.к. 9999 - макс число, то дл==4
			cout<<"Enter first digit: "<<endl;
			cin>>num1;//ввели число
			if(strlen(num1)>255)
			{
				cout<<"Too Big NUMBER\n";
				continue;
			}
			int r1=strlen(num1);//кол-во символов в нем
			int i=0;//счетчик
			int size=(N-1)/dl + 1;//количество интов что бы записать число
			unsigned int* dg1 = new unsigned int [size];//создали массив
			zapis(dg1,num1,size,dl);//записали число
			cout<<"Enter second digit: "<<endl;
			cin>>num1;//ввели другое число
			if(strlen(num1)>255)
			{
				cout<<"Too Big NUMBER\n";
				continue;
			}
			int r2=strlen(num1);//узнали размер его
			unsigned int* dg2 = new unsigned int [size];//создали массив что бы записать 2е число
			unsigned int* rez = new unsigned int [size];//массив для результата
			for(i=0;i<size;++i)//
				rez[i]=0;//обнулили массив для рез.
			zapis(dg2,num1,size,dl);//записали 2е число
			int raz1=0,raz2=0;//переменные что бы узнать скок ячеек занятов в массиве
			while(raz1!=size-1&&!(dg1[raz1]))
				++raz1;//узнаем скок занято в 1м числе
			while(raz2!=size-1&&!(dg2[raz2]))
				++raz2;//узнаем скок во 2м числе
			umn(dg1,dg2,rez,raz1,raz2,size);//умножаем
			cout<<"Resultat:\n";
			vivod(rez,size);//выводим рез.
			delete[]dg1;//удаляем все
			delete[]dg2;
			delete[]rez;
		}
		else if(m=='2')//если выбрали проверку
		{
			int s=512/32;//размер проверяемых значений в битах
			FILE* fNumbers=fopen("C:\NUMBERS1.txt","wt");//открыли файл
			if(!fNumbers)
			{
				cout<<"ERROR";
				return;
			}
			unsigned int test;
			for(int j=0;j<1000;++j)//генерируем и записываем
			{
				test=((rand()<<16)|rand())%O;
				fprintf(fNumbers,"%u",test);
				for(int i=1;i<s;++i)
				{
					test=((rand()<<16)|rand())%O;
					fprintf(fNumbers,"%04u",test);
				}

Последний раз редактировалось ACE Valery; 18.05.2012 в 12:13.
bombozavr вне форума Ответить с цитированием
Старый 18.05.2012, 03:44   #3
bombozavr
Новичок
Джуниор
 
Регистрация: 18.05.2012
Сообщений: 3
По умолчанию

Код:
fprintf(fNumbers,"\n");
			}
			cout<<"First numbers created!\n";//сделали
			fclose(fNumbers);//закрыли файл
			fNumbers=fopen("C:\NUMBERS2.txt","wt");//открыли файл
			if(!fNumbers)
			{
				cout<<"ERROR";
				return;
			}	
			for(int j=0;j<1000;++j)//генерируем и записываем
			{
				test=((rand()<<16)|rand())%O;
				fprintf(fNumbers,"%u",test);
				for(int i=1;i<s;++i)
				{
					test=((rand()<<16)|rand())%O;
					fprintf(fNumbers,"%04u",test);
				}
				fprintf(fNumbers,"\n");
			}
			cout<<"Second numbers created!\n";//сделали
			fclose(fNumbers);//закрыли файл
			char num[N];//строка для чтения чисел
			int dl=4;//количество цифр в числе
			int size=(N-1)/dl + 1;//размер
			unsigned int* dg1 = new unsigned int [size];//3 переменных
			unsigned int* dg2 = new unsigned int [size];
			unsigned int* rez = new unsigned int [size];
			int raz1,raz2,raz;
			FILE* fNumbers1=fopen("C:\NUMBERS1.txt","rt");//открываем файлы
			fNumbers=fopen("C:\NUMBERS2.txt","rt");
			FILE* fRes=fopen("C:\RES.txt","wt");
			for(int j=0;j<1000;++j)//считываем записываем умножаем выводим
			{
				raz1=0;
				raz2=0;
				for(int i=0;i<size;++i)
				{
					rez[i]=0;
					dg1[i]=0;
					dg2[i]=0;
				}	
				fscanf(fNumbers1,"%s",num);//считываем
				zapis(dg1,num,size,dl);	//записываем
				fscanf(fNumbers,"%s",num);//считываем
				zapis(dg2,num,size,dl);//записываем
				while(raz1!=size-1&&!(dg1[raz1]))
					++raz1;
				while(raz2!=size-1&&!(dg2[raz2]))
					++raz2;
				umn(dg1,dg2,rez,raz1,raz2,size);//умножаем
				raz=0;
				while(raz!=size-1&&!(rez[raz]))
					++raz;
				fprintf(fRes,"%u",rez[raz]);//выводим
				for(int i=raz+1;i<size;++i)
					fprintf(fRes,"%04u",rez[i]);
				fprintf(fRes,"\n");
			}
			cout<<"Resultat created!\n";//сделили
			fclose(fRes);//закрыли все
			fclose(fNumbers1);
			fclose(fNumbers);
			ZZ tdg1,tdg2,tres;//класс ЗЗ создали для проверки
			fNumbers1=fopen("C:\NUMBERS1.txt","rt");//открыли файлы
			fNumbers=fopen("C:\NUMBERS2.txt","rt");
			ofstream b_file("C:\RES1.txt");
			for(int i=0;i<1000;++i)//считываем записываем умножаем выводим
			{
				fscanf(fNumbers1,"%s",num);//считываем
				tdg1 = to_ZZ(num);//записываем
				fscanf(fNumbers,"%s",num);//считываем
				tdg2 = to_ZZ(num);//записываем
				tres=tdg1*tdg2;
				b_file<<tres<<'\n';//выводим
			}
			fclose(fNumbers1);//закрыли
			fclose(fNumbers);
			b_file.close ();
			fNumbers1=fopen("C:\RES1.txt","rt");//открыли для проверки
			fNumbers=fopen("C:\RES.txt","rt");
			char num1[N];
			int c=0;//количество несовпадений
			for(int i=0;i<1000;++i)
			{
				fscanf(fNumbers1,"%s",num1);//считываем
				fscanf(fNumbers,"%s",num);//считываем
				if(strcmp(num,num1))//сравниваем
				{
					++c;//увеличиваем несовпадения
					cout<<i<<endl<<num<<endl<<num1<<endl;//вывод несовпавших
				}
			}
			cout<<"Koli4estvo nesovpadeniy ravno:\t"<<c<<endl;//вывели количество несовпавших
			fclose(fNumbers1);//закрыли
			fclose(fNumbers);
		}
	}while(m=='1' || m=='2');//возврат в меню
}

Последний раз редактировалось ACE Valery; 18.05.2012 в 12:13.
bombozavr вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Всем фантазерам сюда - нужны ИДЕИ. abzhapparovmaxat Свободное общение 35 08.11.2011 08:12
Нужны идеи zumm Свободное общение 42 17.06.2010 06:45
Нужны любые идеи как создать фильтр Color blindness для bitmap! SkAndrew Мультимедиа в Delphi 19 05.04.2009 17:15
Файл и много картинок в нём. Нужны идеи Аццкий прогер Мультимедиа в Delphi 5 17.03.2009 14:09
Интересная задача. Нужны идеи ее решения KnDmPetr Паскаль, Turbo Pascal, PascalABC.NET 11 05.03.2008 18:43