Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: Реализовать класс больших целых чисел

Необходимо реализовать класс больших целых чисел.

Так как в типах int и long нет возможности хранить очень большие числовые значения,
состоящие из нескольких десятков знаков и более, нужно реализовать собственный класс
для работы с большими числами.

Большое число можно представить в виде суммы:

X=∑ (от i=0 до n-1)( 10^i*m)*(a i-тый), где m - заранее определенное натуральное число,
a i-тый-целое число, состоящее из не более m цифр.

Пример:

m=3, X=1234567890

X=890*10^0+567*10^3+234*10^6+1*10^9

Таким образом, большое число X можно представить в виде целочисленного массива A=[a i-ого]

Необходимо реализовать класс BigNumber, содержащий следующие члены:
1. Статистическая константа m (ее значения на ваше усмотрение).

2. Массив A чисел, которые определяют большое число(большое число по своему написанию является последовательностью чисел из массива A).

3. Знак числа (+/-, тип bool).

4. Конструктор для инициализации экземпляра класса из строкового написания большого числа (из переменной типа string).

5.Перезагрузка операторов: - (унарный), -(бинарный), +,*,/,==,!=,>,<,<=, >+, также для бинарных
варианты перезагрузки с одним из операндов типа int.

6. Перезагрузка метода ToString() для перевода числа в строковое написание.
Ответ: ЭЭЭЭЭЭЙйй
Вопрос: Работа с очень большими целыми числами

В настоящее время появляется целые положительные числа, размер которых порядка 1,0E+50 и более.
Такие числа можно раздробить и представить в виде массива.
Кто-нибудь имел дело с такими массивами при проведении вычислений между ними? Либо это где-то уже рассмотрено?
Или оставить только цифры высокого порядка и работать с одной ячейкой?
Ответ:
Gennadiy Usov
Видел недавно на странице сообщении о работе с массивом, где хранится вся информация о числе, когда считается N!, и не могу найти.

Со своей стороны попробую сделать простой алгоритм по такому же принципу.

Ничего не понятно, если честно. Давай попроще пример, число 100500 как должно выглядеть по твоему?
Вопрос: Считая что в двух строках находятся очень длинные целые числа, сформировать третью строку - сумму этих чисел

Вообщем, задание вот такое:
Даны две символьные строки, состоящие только из цифр (длина каждой более 10 символов). Считая, что в этих строках находятся очень длинные целые числа, сформировать третью строку – сумму этих чисел.
Я сделала, но часть программы работает неверно,
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <conio.h> 
#include <iostream>
#include <cstdio>  
using namespace std;
int main() {
      char a[100];
      int mp, n_a,n_b,n_c, maxx, min, i, S;
      char n;
      char c[100];
      cout<<"Stroka 1: "<<endl;
      scanf("%s", a);
      char b[100];
          cout<<"Stroka 2: "<<endl;
      scanf("%s", b);
      n_a=strlen(a);
      n_b=strlen(b);
          printf("Dlina 1 stroki: %d", n_a);
      printf("Dlina 2 stroki: %d", n_b);
      if (n_a>n_b) {
        maxx=n_a; 
        min=n_b; 
        n_c=n_a;
        n='a';
      }
      else {maxx=n_b; min=n_a; n_c=n_b; n='b'; }
      n_c=maxx+1;
      mp=0;
      for (i=1; i<min+1; i++)
      {
        S=mp+(a[n_a-i]-48)+(b[n_b-i]-48);
        mp=S/10;
            c[maxx-i]=S%10+48;
      }
 
иииии  дальше... [B]вот эта часть уже как то не так работает[/B]
      if(n=='a')
        for (i=maxx - min; i>=0; i--)
        {
            c[maxx-i-1-min]=(mp+a[n_b-i]-48)%10;
            mp=(c[n_c-i]-48)/10+48;
        
        }
      else
        for (i=min; i<maxx-min; i++)
        {
                c[maxx-i-1-min]=(mp+b[n_b-i]-48)%10;
                mp=(c[n_c-i]-48)/10+48;
            
        }
        c[0]=mp+48;
    cout<<"Summa 1 i 2 stroki ravna : "<<c<<endl;
    _getch();
    return 0;
}
Могу объяснить алгоритм, блин ну никак исправить не могу((((
Ответ:
C++
1
2
3
4
5
6
7
cout << "\n\nSumma 1 i 2 stroki ravna : " ;
if ( n_b < n_a)
for (int p = 0; p < n_a;p++)
cout <<  c [p]<<endl;
else
for (int d = 0; d < n_b; d++)
cout <<  c[d] << endl; 
Вопрос: Создать Библиотеку для работы с массивами целых чисел

Создать библиотеку для работы с массивами целых чисел.. В библиотеку включить
1)метод поиска максимального элемента массива.,
2)метод поиска минимального элемента массива и метод обмена значениями максимального и минимального элементов массива..
3)В программе предусмотреть создание и печать массива, обмен значениями максимального и минимального элементов и печать нового массива..
Ответ: Zorroo, смотри, можешь взять в качестве основы. У меня это класс "Матрица" (т.е. двумерный массив). Там, в принципе, несложно переделать в одномерный массив. Тебе останется написать только функцию-член обмена значений. Что-нибудь типа:
Код C++
1
Item swap(Item first, Item second);
Потом в качестве параметров в эту функцию просто подставляй вызов find_max_value() и find_avg_value() и она будет менять местами максимальный и минимальный элементы.
Вопрос: Работа с очень большими целыми числами

Для криптографии необходимо возводить числа в большую степень, в результате чего это число выходит за диапазон допустимых значений, unsigned long long int не спасает! меня вы устроил вариант long double, но тип данных должен быть строго целочисленный, т.к. это число нужно будет делить по модулю! может есть библиотека с такими типами данных? если есть то как с ней работать?
Ответ: Воспользоваться CryptoAPI не вариант?
Вопрос: Длинная арифметика(вычитание длинных целых чисел)

Добрый вечер! Очень нужна помощь. Мне нужно написать программы для сложения больших целых чисел(разрядности около 200), вычитания и что-то вроде обобщения, то есть, программу, которая складывала бы положительные с положительными, отрицательные с отрицательными и отрицательные с положительными. У меня есть готовая программа для сложения, которую я хочу переделать для вычитания, точнее, уже чуть переделала, но для самого элементарного случая. Возникает загвоздка со случаями, когда уменьшаемое меньше вычитаемого и когда нужно занимать десяток из предыдущего разряда. На пальцах я все понимаю, а вот как и куда в коде вставить эти проверки, ну никак не соображу, бьюсь уже несколько недель... Перелопатила весь интернет, а толку мало, чаще всего написано так, что я не понимаю, ибо не сильна в программировании, к сожалению. Прошу не судить строго, сама понимаю, что задание по сути простое, но никак не осилю, а очень надо) Буду благодарна за любую помощь)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <iostream>
using namespace std;
char * razn(char *a, char *b) {
  int len1 = strlen(a); // количество разрядов первого числа
  int len2 = strlen(b); // количество разрядов второго числа
  char *c;
  int t;
  int razr = 0; // перенос в следующий разряд
 // int k = len1 > len2 ? len1 : len2; // количество разрядов результата
  int k;
  t = 0;
  k = max(len1, len2);
  c = new char[k + 2];
  k++;
  c[k] = '\0'; // завершающий нуль-символ результата
  k--;
  /*for (int i=len1-1, j = len2-1; i>=0, j>=0; i--, j--)
  {
      if (a[i] < b[j])
      {
          t = 0; 
          break;
      }
      if (a[i] >= b[j])
      {
          t = 1;
          break;
      
  }*/
  char umens, vich, raz;
  for (int i = len1 - 1, j = len2 - 1; i >= 0 || j >= 0; i--, j--) {
     /* if (i < 0)
       sum1 = 0;
      else sum1  = a[i] - '0';*/
     umens = i < 0 ? 0 : a[i] - '0'; // если разряд отсутствует, взять 0 //dig1=0 else dig1=a[i]-'0';
     /* if (i < 0)
       sum2 = 0;
      else sum2  = b[j] - '0';*/
     vich = j < 0 ? 0 : b[j] - '0'; // иначе преобразовать символ в цифру
     raz = umens - vich + razr; // сложить две цифры разрядов и перенос
    if (raz > 9) { // если сумма разрядов >9
      raz = raz - 10; // отнять 10
      razr = 1; // и сгенерировать перенос в следующий разряд
    }
    else razr = 0; // переноса нет
    c[k] = raz + '0'; // преобразовать цифру в символ
    k--; // перейти к следующему разряду
  }
  if (razr == 0) return &c[1]; // в старшем разряде результата пусто
  else {
    c[k] = razr + '0'; // заполнить старший разряд результата
    return c;
  }
}
int main() {
  char a[203];
  char b[203];
  cout << "a = ";
  cin >> a;
  //cin.getline(a, 1000);
  cout << "b = ";
  cin >> b;
  //cin.getline(b, 1000);
  cout << a << "-" << b << "=" << razn(a, b) << endl;
  //cin.get();
  return 0;
}
Ответ: A+B, A-B я написал это не просто так. В первом случае вычисляется сумма положительного и положительного числа, во втором случае вычисляется разница положительного и положительного числа(писать минус перед числом не надо)

Остальное может сами дополните

Добавлено через 9 минут
Сообщение от Lizavetka
почему с строках 13 и 19 (там, где сложение) вычитается именно 48? А для вычитания, почему maxsize=10002?
Это для перевода символьных чисел в целочисленный массив чисел, например ASCII код 1 это 49 вычитаем 48 получаем 1,
для 5 ASCII код равен 53 вычитаем 48 получаем 5.

maxsize можете выбрать сами но чтоб в массиве умещался
Вопрос: Работа с файлом целых чисел

Дан файл f, компоненты которого являются целые числа. Определить:
1)Количество чётных чисел среди компонент
2)Количество квадратов нечётных чисел среди компонент.
Ответ: Спасибо!
Вопрос: Класс очень больших чисел

Добрый день!

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

И дан код-образец, который нужно модифицировать:

Код

// verylong.h
// описатель класса сверхбольших целых чисел
#include <iostream>
#include <string.h> // для strlen()и т. п.
#include <stdlib.h> // для ltoa()
using namespace std;
const int SZ = 1000; // максимальное число разрядов
class verylong
{
private:
char vlstr[SZ]; // число как строка
int vlen; // длина строки verylong
verylong multdigit(const int) const; // прототипы
verylong mult10(const verylong) const;// скрытых
// функций
public:
verylong() : vlen(0) // конструктор без аргументов
{ vlstr[0] = '\0'; }
verylong(const char s[SZ]) // конструктор (1 аргумент)
{ strcpy(vlstr, s); vlen = strlen(s); } // для строки
verylong(const unsigned long n) // конструктор (1 арг.)
{ // для long int
ltoa(n, vlstr, 10); // перевести в строку
strrev(vlstr); // перевернуть ее
vlen = strlen(vlstr); // найти длину
}
void putvl() const; // вывести число
void getvl(); // получить число от пользователя
verylong operator+(const verylong); // сложить числа
verylong operator*(const verylong); // умножить
};


Код

// verylong.cpp
// реализация обработки данных типа verylong
#include "verylong.h" // заголовочный файл для verylong
//---------------------------------------------------------
void verylong::putvl() const // вывод на экран verylong
{
char temp[SZ];
strcpy(temp, vlstr); // создать копию
cout << strrev(temp); // перевернуть копию
} // и вывести ее
//---------------------------------------------------------
void verylong::getvl() // получить сверхбольшое число от
// пользователя
{
cin >> vlstr; // получить строку от пользователя
vlen = strlen(vlstr); // найти ее длину
strrev(vlstr); // перевернуть ее
}
//---------------------------------------------------------
verylong verylong::operator+(const verylong v)
// сложение
{
char temp[SZ];
int j;
// найти самое длинное число
int maxlen = (vlen > v.vlen) ? vlen : v.vlen;
int carry = 0; // установить в 1, если сумма >= 10
for(j = 0; j < maxlen; j++) // и так для каждой позиции
{
int d1 = (j > vlen - 1) ? 0 : vlstr[j]-'0'; // получить
// разряд
int d2 = (j > v.vlen - 1) ? 0 : v.vlstr[j]-'0';// и еще
int digitsum = d1 + d2 + carry; // сложить разряды
if(digitsum >= 10) // если перенос, то
{ digitsum -= 10; carry = 1; } // увеличить сумму на 10
else // установить перенос в 1
carry = 0; // иначе перенос = 0
temp[j] = digitsum + '0';// вставить символ в строку
}
if(carry == 1) // если перенос в конце,
temp[j++] = '1'; // последняя цифра = 1
temp[j] = '\0'; // поставить ограничитель строки
return verylong(temp); // вернуть временный verylong
}
//---------------------------------------------------------
verylong verylong::operator*(const verylong v)// умножение
{ // сверхбольших чисел
verylong pprod; // произведение одного разряда
verylong tempsum; // текущая сумма
for(int j = 0; j < v.vlen; j++)// для каждого разряда аргумента
{
int digit = v.vlstr[j]-'0'; // получить разряд
pprod = multdigit(digit); // умножить текущий на него
for(int k = 0; k < j; k++) // умножить результат на
pprod = mult10(pprod); // степень 10-ти
tempsum = tempsum + pprod; // прибавить произведение к
// текущей сумме
}
return tempsum; // вернуть полученную текущую сумму
}
//---------------------------------------------------------
verylong verylong::mult10(const verylong v) const // умножение аргумента
// на 10
{
char temp[SZ];
for(int j = v.vlen - 1; j >= 0; j--)// сдвинуться на один разряд
temp[j + 1] = v.vlstr[j]; // выше
temp[0] = '0'; // обнулить самый младший разряд
temp[v.vlen + 1] = '\0'; // поставить ограничитель строки
return verylong(temp); // вернуть результат
}
//---------------------------------------------------------
verylong verylong::multdigit(const int d2) const
{ // умножение числа на
char temp[SZ]; // аргумент (цифру)
int j, carry = 0;
for(j = 0; j < vlen; j++) // для каждого разряда
{ // в этом сверхбольшом
int d1 = vlstr[j]-'0'; // получить значение разряда
int digitprod = d1 * d2; // умножить на цифру
digitprod += carry; // добавить старый перенос
if(digitprod >= 10) // если возник новый перенос,
{
carry = digitprod / 10; // переносу присвоить значение старшего разряда
digitprod -= carry * 10;// результату - младшего
}
else
carry = 0; // иначе перенос = 0
temp[j] = digitprod + '0';// вставить символ в строку
}
if(carry != 0) // если на конце перенос,
temp[j++] = carry + '0'; // это последний разряд
temp[j] = '\0'; // поставить ограничитель
return verylong(temp); // вернуть сверхбольшое число
}


Код

// vl_app.cpp
// вычисляет факториалы больших чисел
#include "verylong.h" // заголовочный файл verylong
int main()
{
unsigned long numb, j;
verylong fact = 1; // инициализировать verylong
cout << "\n\nВведите число: ";
cin >> numb; // ввод числа типа long int
for(j = numb; j > 0; j--)// факториал — это numb *
fact = fact * j; // numb-1 * numb-2 *
cout << "Факториал = "; // numb-3 и т. д.
fact.putvl(); // вывести значение факториала
cout << endl;
return 0;
}


Помогите, пожалуйста, решить задачу! Буду очень благодарна за помощь!

Это сообщение отредактировал(а) LittleMonkey - 25.5.2015, 12:53
Ответ:
Добрый день!

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

И дан код-образец, который нужно модифицировать:

Код

// verylong.h
// описатель класса сверхбольших целых чисел
#include <iostream>
#include <string.h> // для strlen()и т. п.
#include <stdlib.h> // для ltoa()
using namespace std;
const int SZ = 1000; // максимальное число разрядов
class verylong
{
private:
char vlstr[SZ]; // число как строка
int vlen; // длина строки verylong
verylong multdigit(const int) const; // прототипы
verylong mult10(const verylong) const;// скрытых
// функций
public:
verylong() : vlen(0) // конструктор без аргументов
{ vlstr[0] = '\0'; }
verylong(const char s[SZ]) // конструктор (1 аргумент)
{ strcpy(vlstr, s); vlen = strlen(s); } // для строки
verylong(const unsigned long n) // конструктор (1 арг.)
{ // для long int
ltoa(n, vlstr, 10); // перевести в строку
strrev(vlstr); // перевернуть ее
vlen = strlen(vlstr); // найти длину
}
void putvl() const; // вывести число
void getvl(); // получить число от пользователя
verylong operator+(const verylong); // сложить числа
verylong operator*(const verylong); // умножить
};


Код

// verylong.cpp
// реализация обработки данных типа verylong
#include "verylong.h" // заголовочный файл для verylong
//---------------------------------------------------------
void verylong::putvl() const // вывод на экран verylong
{
char temp[SZ];
strcpy(temp, vlstr); // создать копию
cout << strrev(temp); // перевернуть копию
} // и вывести ее
//---------------------------------------------------------
void verylong::getvl() // получить сверхбольшое число от
// пользователя
{
cin >> vlstr; // получить строку от пользователя
vlen = strlen(vlstr); // найти ее длину
strrev(vlstr); // перевернуть ее
}
//---------------------------------------------------------
verylong verylong::operator+(const verylong v)
// сложение
{
char temp[SZ];
int j;
// найти самое длинное число
int maxlen = (vlen > v.vlen) ? vlen : v.vlen;
int carry = 0; // установить в 1, если сумма >= 10
for(j = 0; j < maxlen; j++) // и так для каждой позиции
{
int d1 = (j > vlen - 1) ? 0 : vlstr[j]-'0'; // получить
// разряд
int d2 = (j > v.vlen - 1) ? 0 : v.vlstr[j]-'0';// и еще
int digitsum = d1 + d2 + carry; // сложить разряды
if(digitsum >= 10) // если перенос, то
{ digitsum -= 10; carry = 1; } // увеличить сумму на 10
else // установить перенос в 1
carry = 0; // иначе перенос = 0
temp[j] = digitsum + '0';// вставить символ в строку
}
if(carry == 1) // если перенос в конце,
temp[j++] = '1'; // последняя цифра = 1
temp[j] = '\0'; // поставить ограничитель строки
return verylong(temp); // вернуть временный verylong
}
//---------------------------------------------------------
verylong verylong::operator*(const verylong v)// умножение
{ // сверхбольших чисел
verylong pprod; // произведение одного разряда
verylong tempsum; // текущая сумма
for(int j = 0; j < v.vlen; j++)// для каждого разряда аргумента
{
int digit = v.vlstr[j]-'0'; // получить разряд
pprod = multdigit(digit); // умножить текущий на него
for(int k = 0; k < j; k++) // умножить результат на
pprod = mult10(pprod); // степень 10-ти
tempsum = tempsum + pprod; // прибавить произведение к
// текущей сумме
}
return tempsum; // вернуть полученную текущую сумму
}
//---------------------------------------------------------
verylong verylong::mult10(const verylong v) const // умножение аргумента
// на 10
{
char temp[SZ];
for(int j = v.vlen - 1; j >= 0; j--)// сдвинуться на один разряд
temp[j + 1] = v.vlstr[j]; // выше
temp[0] = '0'; // обнулить самый младший разряд
temp[v.vlen + 1] = '\0'; // поставить ограничитель строки
return verylong(temp); // вернуть результат
}
//---------------------------------------------------------
verylong verylong::multdigit(const int d2) const
{ // умножение числа на
char temp[SZ]; // аргумент (цифру)
int j, carry = 0;
for(j = 0; j < vlen; j++) // для каждого разряда
{ // в этом сверхбольшом
int d1 = vlstr[j]-'0'; // получить значение разряда
int digitprod = d1 * d2; // умножить на цифру
digitprod += carry; // добавить старый перенос
if(digitprod >= 10) // если возник новый перенос,
{
carry = digitprod / 10; // переносу присвоить значение старшего разряда
digitprod -= carry * 10;// результату - младшего
}
else
carry = 0; // иначе перенос = 0
temp[j] = digitprod + '0';// вставить символ в строку
}
if(carry != 0) // если на конце перенос,
temp[j++] = carry + '0'; // это последний разряд
temp[j] = '\0'; // поставить ограничитель
return verylong(temp); // вернуть сверхбольшое число
}


Код

// vl_app.cpp
// вычисляет факториалы больших чисел
#include "verylong.h" // заголовочный файл verylong
int main()
{
unsigned long numb, j;
verylong fact = 1; // инициализировать verylong
cout << "\n\nВведите число: ";
cin >> numb; // ввод числа типа long int
for(j = numb; j > 0; j--)// факториал — это numb *
fact = fact * j; // numb-1 * numb-2 *
cout << "Факториал = "; // numb-3 и т. д.
fact.putvl(); // вывести значение факториала
cout << endl;
return 0;
}


Помогите, пожалуйста, решить задачу! Буду очень благодарна за помощь!

Это сообщение отредактировал(а) LittleMonkey - 25.5.2015, 12:53
Вопрос: очень большое целое число

Для криптографии нужно возводить числа в большую степень, в результате чего получается очень большое число. Меня бы устроило long double, но тип данных нужен целочисленный, т.к. это число нужно делить по модулю, даже unsigned long long int не спасает!
Ответ: Тут нужна библиотека для работы с числами произвольной длины. Например .
Вопрос: Нахождение суммы большего и меньшего из 3-х введенных целых чисел

Написать программу нахождения суммы большего и меньшего из 3-х введенных целых чисел. Программа должна иметь дружественный интерфейс. Ответ нужно записать так:
Сумма большего и меньшего из чисел 5, 10, -10 равна 0.
Ответ:
Код Pascal
1
2
3
4
5
6
7
8
9
10
11
var a,b,c,mn,mx,s:integer;
begin
writeln('Введите 3 целых числа');
readln(a,b,c);
if a<b then mn:=a else mn:=b;
if c<mn then mn:=c;
if a>b then mx:=a else mx:=b;
if c>mx then mx:=c;
s:=mn+mx;
write('Сумма большего и меньшего из чисел ',a,', ',b,', ',c,' = ',s);
end.