Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.97/35: Рейтинг темы: голосов - 35, средняя оценка - 4.97
0 / 0 / 0
Регистрация: 17.12.2011
Сообщений: 67

Длинные числа. Умножение отрицательных

29.03.2015, 17:30. Показов 7873. Ответов 43
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, помогите пожалуйста как сделать, чтобы и отрицательные числа перемножались?
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include <iostream>
#include<conio.h>
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
#include<string.h>
using namespace std;
 
//Ввод данных
void vvod(char *ar, int  &n)
{
    int i=0;
    printf("\n Введите число: ");
    ar[i]=getchar();
    while(ar[i]!='\n') 
    {
        i++;
        ar[i]=getchar();    
    }
    n=i;
    for(i=0; i<n; i++) ar[i]-=48;
}
void write_num(char *ar, int &n)
{
    int i;
    for(i = 0; i < n; i++)
        printf("%d", ar[i]);    
}
 
void umnogenie(char b[], int &n, char c[], int m)
{
    char h[1000];
    int i,j,l,o;
    
    //Обнуляем резултат
    for(i=0; i<n+m; i++)
         h[i]=0;
    //Умножение
    for(i=0; i<m; i++)
    {
     o=0; l=0;
     for(j=n-1; j>=0; j--) 
     {
        h[j+m-i]+=(b[j]*c[m-1-i] + o)%10;
        if(h[j+m-i]>9) 
         {
             l=h[j+m-i]/10;
             h[j+m-i]=h[j+m-i]%10;
         }
        o=(b[j]*c[m-i-1] + o)/10+l;        
        if(j==0) h[j+m-1-i]+=o;
        l=0;
     }
    }
    //Избавляемся от ведущих нулей
    n=n+m;
    while(h[0]==0)
    {
      for(j=0; j<n-1; j++)
         h[j]=h[j+1];
      if(n!=1) n--; else break;
    }
    //Вывод результата
    for(i=0; i<n; i++)
      b[i] = h[i];
}
 
int main()
{ 
    
    setlocale(LC_ALL,"rus");
    int kol;
    char a[1000], b[1000], c[1000], q[1000];
    int d=0;
    int na, nb, nc, nq; // Число цифр
    cout << "============Простейший калькулятор на умножение в 10 СC============\n";
    cout << "\n Калькулятор предназначен для работы только с цифрами. \n Количество вводимых чисел от 2 до 4. \n Длина вводимого числа должна быть в пределе [-1000000000; 1000000000].\n";
    cout << " Ввод чисел осуществляется через клавишу Enter.\n";
    cout << " Выход из программы по нажатию кнопки 1.\n  ";
do{
        while(true)             
        { 
            printf("\n\n Введите количество чисел: ");
            cin >> kol;
            if((kol==2 || kol==3 || kol==4 || kol==1) && cin.peek() == '\n')
            { 
                cin.get();                      
                break;
            }   
            else
            { 
                cout << "\n Операция вычитания возможна только с 2-4 числами. \n Подсказка: Нажмите цифру 2, 3 или 4. Для выхода нажмите 1. \n" << endl;
                cin.clear();    
                while (cin.get() != '\n'){}
            }
        }
    switch(kol) 
    {
        case 1: 
            return 0;
            break;
        case 2:
            vvod(a, na);
            vvod(b, nb);
            umnogenie(a,na,b,nb);
            printf("\n Результат: ");
            write_num(a,na);
            break;
        case 3:
            vvod(a, na);
            vvod(b, nb);
            vvod(c, nc);
            umnogenie(a,na,b,nb);
            umnogenie(a,na,c,nc);
            printf("\n Результат: ");
            write_num(a,na);
            break;
        case 4:
            vvod(a, na);
            vvod(b, nb);
            vvod(c, nc);
            vvod(q, nq);
            umnogenie(a,na,b,nb);
            umnogenie(a,na,c,nc);
            umnogenie(a,na,q,nq);
            write_num(a,na);
            break;
    }
 }while(d!=1);
    printf("\n\n");
    system ("pause");
    return 0;
}
Добавлено через 7 минут
Здравствуйте. Помогите пожалуйста довести программу до ума.
Задача: Калькулятор на умножение в 10 СС. Диапазон вводимых чисел [-2^256; 2^256]. Умножение от 2 до 4 чисел. Вывод в своей системе и в 18 СС.
Как сделать проверку на вводимый диапазон чисел? И не понимаю как сделать, чтобы и с отрицательными числами программа работала.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
29.03.2015, 17:30
Ответы с готовыми решениями:

Длинные числа в c++
Делаю прогу, которая работает с длинными числами, хранятся такие числа у меня в классе, в массиве, состоящем из unsigned short int, в...

Длинные числа в С++
Я так понемаю самое большое число long long тоесть до милиарда???? а если больше! 100000000000000000 такое(целое) как сни работать +1...

Длинные целые числа
Подскажите пожалуйста как разработать поле типа : длинные целые числа ?

43
Модератор
Эксперт CЭксперт С++
 Аватар для sourcerer
5288 / 2376 / 342
Регистрация: 20.02.2013
Сообщений: 5,773
Записей в блоге: 20
30.03.2015, 20:01
Студворк — интернет-сервис помощи студентам
flo, а как задание звучит в оригинале (в варианте препода или откуда там задание)?

Добавлено через 45 секунд
Там просто в коде каша какая-то. В неё и лезть-то как-то не хочется. Проще заново всё написать, мне кажется.
0
0 / 0 / 0
Регистрация: 17.12.2011
Сообщений: 67
30.03.2015, 20:21  [ТС]
Я программирование плохо понимаю
Просто попала в бригаду, где люди не программировали, а я занималась этим на 1ом и 2ом курсе и то, только чтобы сделать задание, а не из интереса.
Поэтому участь пала на меня))

Добавлено через 3 минуты
Цитата Сообщение от gru74ik Посмотреть сообщение
flo, а как задание звучит в оригинале (в варианте препода или откуда там задание)?

Добавлено через 45 секунд
Там просто в коде каша какая-то. В неё и лезть-то как-то не хочется. Проще заново всё написать, мне кажется.
Нужно сделать калькулятор на умножение от двух до четырех чисел. Длина числа [-2^256; 2^256], то есть длинная арифметика. Вывод сделать в 10 СС и в 18 СС.
0
Модератор
Эксперт CЭксперт С++
 Аватар для sourcerer
5288 / 2376 / 342
Регистрация: 20.02.2013
Сообщений: 5,773
Записей в блоге: 20
30.03.2015, 20:27
flo, а именно через самописные функции и массивы всё это делать - чья идея? Почему не использовать готовые решения?

Цитата Сообщение от flo Посмотреть сообщение
Я программирование плохо понимаю
Тем более. Скачайте готовое решение (библиотечное умножение длинных чисел из библиотеки boost), всего и делов-то. Зачем эти ужасающие костыли из самописных функций и массивов?
0
 Аватар для MicM
840 / 498 / 325
Регистрация: 29.12.2009
Сообщений: 1,106
30.03.2015, 21:33
Вот, нашел исходник своей старой лабы по длинной арифметике.
Код, конечно, оставляет желать лучшего, ибо он плохой и нехороший.
Много чего, не хватает в нем. Той же обработки ошибок и различных функций.
Это даже будет небольшой обрубок, а не программа по длинным числам
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <iostream>
 
class long_number
{
    static int const size = 1000;
    int a[size];
public:
    long_number()
    {
        for (int i = 0; i < size; i++)
            a[i] = 0;
    }
    long_number(int x)
    {
        int i = size - 1;
        while (x!=0)
        {
            a[i] = x % 10;
            --i;
            x/=10;
        }
        for (int j = i; j > -1; j--)
            a[j] = 0;
    }
    long_number & operator= (long_number arg)
    {
        for (int i = 0; i < size; i++)
            a[i] = arg.a[i];
        return *this;
    }
    long_number operator* (int arg)
    {
        long_number result;
        int q = 0;
        while (arg!=0)
        {
            int k = arg % 10;
            long_number x;
            int m = 0;
            for (int i = size - 1; i > -1; i--)
            {
                int c = a[i] * k + m;
                m = 0;
                x.a[i - q] = c%10;
                m = c/10;
            }
            ++q;
            result = result + x;
            arg/=10;
        }
        return result;
    }
    long_number operator+ (long_number arg)
    {
        long_number result;
        int m = 0;
        for (int i = size - 1; i > 0; i--)
        {
            int k = this->a[i] + arg.a[i] + m;
            result.a[i] = k % 10;
            m = k / 10;
        }
        return result;
    }
    friend std::ostream & operator<< (std::ostream &, long_number &);
};
 
std::ostream & operator<< (std::ostream & stream, long_number & object)
{
    int i = 0;
    while (i < object.size && object.a[i]==0)
        ++i;
    if (i==object.size)
    {
        stream <<0;
    }
    else
    {
        while (i < object.size)
            stream << object.a[i++];
    }
    return stream;
}
 
int main()
{
    long_number a (1);
    for (int i = 1; i < 20; i++)
        a = a * i;
    std::cout << a << std::endl;
}
0
0 / 0 / 0
Регистрация: 17.12.2011
Сообщений: 67
30.03.2015, 21:37  [ТС]
Цитата Сообщение от gru74ik Посмотреть сообщение
flo, а именно через самописные функции и массивы всё это делать - чья идея? Почему не использовать готовые решения?


Тем более. Скачайте готовое решение (библиотечное умножение длинных чисел из библиотеки boost), всего и делов-то. Зачем эти ужасающие костыли из самописных функций и массивов?
Намутила я такую кашу
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include <iostream>
#include<conio.h>
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
#include<string.h>
using namespace std;
 
 
//Ввод данных
void vvod(char *ar, int  &n)
{
    int i=0, j=0,r1=0;
    printf("\n Введите число: ");
    ar[i]=getchar();
    if(ar[i]=='-')
        {   
            ar[0]=r1;
        }
    while(ar[i]!='\n')
    {
        i++;
        ar[i]=getchar();    
    }
    n=i;
    if(ar[0]==0)
    {
    for(i=1; i<n; i++) 
        ar[i]-=48;
    }
    else {
        for(i=0; i<n; i++) 
        ar[i]-=48;
    }
}
void write_num(char *ar, int &n)
{
    int i;
    for(i = 0; i < n; i++)
        printf("%d", ar[i]);    
}
 
void umnogenie(char b[], int &n, char c[], int m)
{
    char h[1000];
    int i,j,l,o;    
    //Обнуляем результат
    for(i=0; i<n+m; i++)
         h[i]=0;
    //Умножение
    for(i=0; i<m; i++)
    {
     o=0; l=0;
     for(j=n-1; j>=0; j--) 
     {
        h[j+m-i]+=(b[j]*c[m-1-i] + o)%10;
        if(h[j+m-i]>9) 
         {
             l=h[j+m-i]/10;
             h[j+m-i]=h[j+m-i]%10;
         }
        o=(b[j]*c[m-i-1] + o)/10+l;        
        if(j==0) h[j+m-1-i]+=o;
        l=0;
     }
    }
    //Избавляемся от ведущих нулей
    n=n+m;
    while(h[0]==0)
    {
      for(j=0; j<n-1; j++)
         h[j]=h[j+1];
      if(n!=1) n--; else break;
    }
    //Вывод результата
    for(i=0; i<n; i++)
      b[i] = h[i];
}
 
int main()
{ 
    
    setlocale(LC_ALL,"rus");
    int kol;
    int k=0;
    char a[1000], b[1000], c[1000], q[1000];
    int d=0;
    int na, nb, nc, nq; // Число цифр
    cout << "============Простейший калькулятор на вычитание в 10 СC============\n";
    cout << "\n Калькулятор предназначен для работы только с цифрами. \n Количество вводимых чисел от 2 до 4. \n Длина вводимого числа должна быть в пределе [-2^256; 2^256].\n";
    cout << " Ввод чисел осуществляется через клавишу Enter.\n";
    cout << " Выход из программы по нажатию кнопки 1.\n  ";
do{
        while(true)             
        { 
            printf("\n\n Введите количество чисел: ");
            cin >> kol;
            if((kol==2 || kol==3 || kol==4 || kol==1) && cin.peek() == '\n')
            { 
                cin.get();                      
                break;
            }   
            else
            { 
                cout << "\n Операция вычитания возможна только с 2-4 числами. \n Подсказка: Нажмите цифру 2, 3 или 4. Для выхода нажмите 1. \n" << endl;
                cin.clear();    
                while (cin.get() != '\n'){}
            }
        }
    switch(kol) 
    {
        case 1: 
            return 0;
            break;
        case 2:
            vvod(a, na);
            vvod(b, nb);
            if(a[0]==0 && b[0]==0)
            printf("\n Результат: ");
            else printf("\n Результат: -");
            umnogenie(a,na,b,nb);
            write_num(a,na);
            break;
        case 3:
            vvod(a, na);
            vvod(b, nb);
            vvod(c, nc);
            if((a[0]==0 && b[0]!=0 && c[0]==0) || (a[0]!=0 && b[0]==0 && c[0]==0) ||(a[0]==0 && b[0]==0 && c[0]!=0)||(a[0]!=0 && b[0]!=0 && c[0]!=0))
                printf("\n Результат: ");
            else printf("\n Результат: -");
            umnogenie(a,na,b,nb);
            umnogenie(a,na,c,nc);
            write_num(a,na);
            break;
        case 4:
            vvod(a, na);
            vvod(b, nb);
            vvod(c, nc);
            vvod(q, nq);
            if((a[0]==0 && b[0]==0 && c[0]!=0 && q[0]!=0) || (a[0]==0 && b[0]!=0 && c[0]==0 && q[0]!=0) ||(a[0]==0 && b[0]!=0 && c[0]!=0 && q[0]==0)||(a[0]!=0 && b[0]==0 && c[0]==0 && q[0]!=0)||(a[0]!=0 && b[0]==0 && c[0]!=0 && q[0]==0)||(a[0]!=0 && b[0]==0 && c[0]!=0 && q[0]==0)||(a[0]!=0 && b[0]!=0 && c[0]==0 && q[0]==0)||(a[0]==0 && b[0]==0 && c[0]==0 && q[0]==0))
                printf("\n Результат: ");
            else printf("\n Результат: -");
            umnogenie(a,na,b,nb);
            umnogenie(a,na,c,nc);
            umnogenie(a,na,q,nq);
            write_num(a,na);
            break;
    }
 }while(d!=1);
    printf("\n\n");
    system ("pause");
    return 0;
}
Зато теперь работает с отрицательными числами .
Осталось проверить на корректность вводимых чисел и чтобы они были в диапазоне от -2^256; +2^256
0
Модератор
Эксперт CЭксперт С++
 Аватар для sourcerer
5288 / 2376 / 342
Регистрация: 20.02.2013
Сообщений: 5,773
Записей в блоге: 20
01.04.2015, 21:24
Цитата Сообщение от MicM Посмотреть сообщение
Почему бы boost не использовать?
Цитата Сообщение от flo Посмотреть сообщение
Если бы я знала как
Как-то так.
0
0 / 0 / 0
Регистрация: 17.12.2011
Сообщений: 67
01.04.2015, 22:36  [ТС]
Всем спасибо!
Сделала по своему, по примитивному))
НО осталась одна проблемка на корректность ввода числа. Нужно чтобы программа не давала вводить буквы символы(кроме знака '-'). Я попыталась сделать, но программа пропускает, например, такое число 333gggg.
Где ошибка?
Вот функция проверки на ввод, чтобы вводились только числа
C++
1
2
3
4
5
6
7
8
9
bool isNumber (char *str, int size)
{
    for (int i = 0; i < size; i++)
    {
        if (!(str[i] >= '0' && str[i] <='9')) return false; 
        else return true;
    }
    return true;
}
Вот функция ввода числа
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
void vvod(char *ar, int  &n)
{
    int i=0, j=0,r1=0;
 
        printf("\n Введите число: ");
        ar[i]=getchar();
        if(ar[i]=='-')
        {   
            ar[0]=r1;
        }
        while(ar[i]!='\n')
        {
            i++;
            ar[i]=getchar();    
        }
        n=i;
    if(ar[0]==0)
    {
        for(i=1; i<n; i++) 
        ar[i]-=48;
    }
    else {
            for(i=0; i<n; i++) 
            ar[i]-=48;
         }
}
и кусочек int main():

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
int main()
{ 
    
    setlocale(LC_ALL,"rus");
    int kol;
    int k=0;
    bool l=true;
    bool u=true;
    char a[1000], b[1000], c[1000], q[1000];
    int d=0;
    int na, nb, nc, nq; // Число цифр
    cout << "============Простейший калькулятор на вычитание в 10 СC============\n";
    cout << "\n Калькулятор предназначен для работы только с цифрами. \n Количество вводимых чисел от 2 до 4. \n Длина вводимого числа должна быть в пределе [-2^256; 2^256].\n";
    cout << " Ввод чисел осуществляется через клавишу Enter.\n";
    cout << " Выход из программы по нажатию кнопки 1.\n  ";
    do{
        while(true)             
        { 
            printf("\n\n Введите количество чисел: ");
            cin >> kol;
            if((kol==2 || kol==3 || kol==4 || kol==1) && cin.peek() == '\n')
            { 
                cin.get();                      
                break;
            }   
            else
            { 
                cout << "\n Операция вычитания возможна только с 2-4 числами. \n Подсказка: Нажмите цифру 2, 3 или 4. Для выхода нажмите 1. \n" << endl;
                cin.clear();    
                while (cin.get() != '\n'){}
            }
        }
    switch(kol) 
    {
        case 1: 
            return 0;
            break;
        case 2:
            while(true)
            {
                vvod(a, na);
                //l=bolshe(a,na);
                u=isNumber (a,na);
                if (!u) 
                    printf ("Ошибка! Введите число в установленном диапазоне  [-2^256; 2^256].\n");
                else break;
            }
В case 2 вызываю проверку

Добавлено через 4 минуты
А можно еще как-нибудь вставить эту проверку в саму функцию ввода числа? а не в главную
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,874
01.04.2015, 22:39
Цитата Сообщение от flo Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
bool isNumber (char *str, int size)
{
   for (int i = 0; i < size; i++)
    {
      if (!(str[i] >= '0' && str[i] <='9')) return false; 
      else return true;
    }
  return true;
}
в результате проверяем только один символ и прямо из цикла выходим или false или true
C++
1
2
3
4
5
6
7
8
9
10
11
12
bool isNumber (char *str, int size)
{
  for (int i = 0; i < size; i++)
   {
      if(i==0&&*str[]=='-')
        continue;
        if (str[] <'0' || str[i]>'9')
           return false; 
 
     }
 return true;
}
0
0 / 0 / 0
Регистрация: 17.12.2011
Сообщений: 67
01.04.2015, 23:35  [ТС]
ValeryS,
Так тоже пропускает числа типа 5455jjjj, т.е когда после чисел идут буквы, он считывает как число.

Добавлено через 6 минут
Так тоже пропускает числа типа 5455jjjj, т.е когда после чисел идут буквы, он считывает как число.
В общем, пропускает, где вообще есть число. Даже такое - gklgdksjg44485kgkg
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,874
01.04.2015, 23:45
Цитата Сообщение от flo Посмотреть сообщение
Так тоже пропускает числа типа 5455jjjj,
ну во первых пропускать ничего не должно, поскольку не компилируется
у меня там ошибки при копировании получились, вот исправленная версия
C++
1
2
3
4
5
6
7
8
9
10
11
12
bool isNumber (char *str, int size)
{
  for (int i = 0; i < size; i++)
   {
      if(i==0&&str[i]=='-')
        continue;
        if (str[i] <'0' || str[i]>'9')
           return false;
 
     }
 return true;
}
все работает
смотри вызов функции
0
0 / 0 / 0
Регистрация: 17.12.2011
Сообщений: 67
02.04.2015, 01:07  [ТС]
ValeryS,
Все изначально было сделано, как у тебя
А всё равно пропускает ошибки)
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,874
02.04.2015, 06:40
Цитата Сообщение от flo Посмотреть сообщение
vvod(a, na);
* * * * * * * * //l=bolshe(a,na);
* * * * * * * * u=isNumber (a,na);
в функции vvod символы уже перестают быть символами
Цитата Сообщение от flo Посмотреть сообщение
ar[i]-=48;
следовательно нет смысла проверять на равенство символам в isNumber
0
0 / 0 / 0
Регистрация: 17.12.2011
Сообщений: 67
02.04.2015, 11:56  [ТС]
Цитата Сообщение от ValeryS Посмотреть сообщение
в функции vvod символы уже перестают быть символами
следовательно нет смысла проверять на равенство символам в isNumber
А если до этого момента сделать? Но так тоже коряво работает
Не уже ли ни как не проверить
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
void vvod(char *ar, int  &n)
{
    int i=0, j=0,r1=0;
    bool u=true;
     while(true)
     {
        printf("\n Введите число: ");
        ar[i]=getchar();
        if(ar[i]=='-')
        {   
            ar[0]=r1;
        }
        while(ar[i]!='\n')
        {
            i++;
            ar[i]=getchar();    
        }
        n=i;
        u=isNumber (ar,n);
        if (u) 
                    printf ("Ошибка! Введите число в установленном диапазоне  [-2^256; 2^256].\n");
                else break;
 
     }
    if(ar[0]==0)
    {
        for(i=1; i<n; i++) 
        ar[i]-=48;
    }
    else {
            for(i=0; i<n; i++) 
            ar[i]-=48;
         }
}
Добавлено через 1 час 18 минут
я попробовала так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
bool isNumber (char *str, int size)
{
   for (int i = 0; i < size; i++)
   {
      if(i==0&&str[i]=='-')
        continue;
        if (str[i] <'0' || str[i]>'9')
            {
                printf ("Ошибка! Введите число в установленном диапазоне  [-2^256; 2^256].\n");
        return false;
        }
     }
 return true;
}
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
void vvod(char *ar, int  &n)
{
    int i=0, j=0,r1=0;
    bool u=true;
     while(true)
     {
        printf("\n Введите число: ");
        ar[i]=getchar();
        if(ar[i]=='-')
        {   
            ar[0]=r1;
        }
        while(ar[i]!='\n')
        {
            i++;
            ar[i]=getchar();    
        }
        n=i;
        u=isNumber (ar,n);
        if(u)
        break;  
     }
    if(ar[0]==0)
    {
        for(i=1; i<n; i++) 
        ar[i]-=48;
    }
    else {
            for(i=0; i<n; i++) 
            ar[i]-=48;
         }
}
Если мы введем первое число 235ааааа - то будет ошибка.
Затем, если введу 3333333 - то снова ошибка.
Я прочитала, что нужно использовать cin.sync(); и cin.clear() только не понимаю как
0
0 / 0 / 0
Регистрация: 17.12.2011
Сообщений: 67
03.04.2015, 15:45  [ТС]
помогите, пожалуйста)
0
0 / 0 / 0
Регистрация: 17.12.2011
Сообщений: 67
05.04.2015, 02:38  [ТС]
Всё исправила, тема больше не актуальна)
Всем спасибо за ответы, очень помогли)

Добавлено через 8 часов 19 минут
Появилась новая проблема
Перевод с 18 СС полученного результата.
Нашла функию деления длинного числа на короткое. Но она невсегда корректно работает:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void perevod_v_18(char a[], int n)
{
    char rez[200];
    int i;
    int p=0;
    int ost=0;
                for(i=0;i<n;i++)
                {
                    rez[i] = (a[i] + ost * 10);
                    ost = rez[i] % 18;
                    rez[i] = rez[i] / 18;
                    p++;
                }   
                printf("%d",ost);
                printf("\n"); 
                for(i=1;i<p;i++)
                printf("%d",rez[i]);        
}
Непонятно, что с этим дальше делать. Если есть способ какой-то полегче, то рада буду услышать.
0
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
05.04.2015, 02:51
Цитата Сообщение от flo Посмотреть сообщение
Непонятно, что с этим дальше делать. Если есть способ какой-то полегче, то рада буду услышать.
У тебя получается костыль на костыле и костылем погоняет.

Ну как полегче?
1) Берешь библичную длинную арифметику и делаешь все с ее помощью.
При таком варианте не придется особенно со всем париться.

2) Делаешь нормальную длинную арифметику самостоятельно.
Тогда можно воспользоваться алгоритмами для длинной арифметики (в том числе и деление),
описанные во втором томе (вроде) Кнута.

Цитата Сообщение от flo Посмотреть сообщение
Нашла функию деления длинного числа на короткое.
Это нечто напоминает деление числа в столбик, но с каким пор в столбик мы начинаем делить с начала числа?
0
0 / 0 / 0
Регистрация: 17.12.2011
Сообщений: 67
05.04.2015, 12:56  [ТС]
Конечно, я же ничего не понимаю в программировании! Поэтому и выходит такая неразбериха.

Добавлено через 2 часа 45 минут
Уже понятно, что этот случай мне не подходит. Так как 18 > base.
0
0 / 0 / 0
Регистрация: 17.12.2011
Сообщений: 67
15.04.2015, 23:38  [ТС]
Вот сотворила я сие чудо, может кто подсказать, как оптимизировать умножение отрицательных чисел?
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
#include <iostream>
#include <string>
using namespace std;
 
//Проверка на диапазон числа 2^256
bool RangeForNumber(char a[], int n)
{
    int i;
    int nt;//длина числа 2^256
    char t[85]={1,1,5,7,9,2,0,9};//Cоздание массива числа 2^256
    for(i=8;i<78;i++)//дополняем нулями до конца длины числа
        t[i]=0;
    nt=7+i;//длина числа=85
    if (n==86 && a[0]==0)//рассмотрим случай, если введено первое отрицательное
        for (i=0;i<n;i++)
            if (t[i]>a[i+1]) return false;
            else if (a[i+1]>t[i]) return true;
    if (n>nt) return true;
        else if (nt>n) return false;
    else
      for (i=0; i<n; i++)
      if (a[i]>t[i]) return true;
      else if (t[i]>a[i]) return false;
    return false;
}
 
//Проверка на ввод посторонних символов
bool isNumber (char *str, int size)
{
   for (int i = 0; i < size; i++)
   {
       if(i==0 && str[i]!='-')
        continue;
        if (str[i] <'0' || str[i]>'9' )
            return true;
     }
 return false;
}
//Преобразование в тип string
string IsCHARtoSTRING(char *a, int na)
{
    char *temp;
    string t;
    int w;
    temp = new char[na];
    for(w = 0; w < na; ++w) 
        temp[w] = a[w] + 48;
    t = string(temp, na);
    return t;
}
 
//Ввод длинного числа
void InputNumbers(char *ar, int  &n)
{
    int i=0, j=0;
    int r1=0; // если введен минус
    bool l = true;
    bool u = true;
    while(true)
    {
        int i=0, j=0,r1=0;
        cout << "\n Введите число: ";
        ar[i]=getchar();
        if(ar[i]=='-')
        {   
            ar[0]=r1;
        }
        while(ar[i]!='\n')
        {
            i++;
            ar[i]=getchar();    
        }
        n=i;
        l= isNumber(ar,n);
        u= RangeForNumber(ar,n);
        if (l||u) 
            cout <<"\n Некорректное значение. Повторите ввод. \n";
        else break; 
    }
    if(ar[0]==0)
    {
        for(i=1; i<n; i++) 
        ar[i]-=48;
    }
    else {
            for(i=0; i<n; i++) 
            ar[i]-=48;
         }
}
//Вывод длинного числа
void OutputNumbers(char *ar, int &n)
{
    int i;
    for(i = 0; i < n; i++)
        printf("%d", ar[i]);    
}
 
//Умножение длинных чисел
void Multiplication(char b[], int &n, char c[], int m)
{
    
    char h[200];
    int i,j,l,o;
    //Обнуляем результат
    for(i=0; i<n+m; i++)
         h[i]=0;
    //Умножение
    for(i=0; i<m; i++)
    {
     o=0; l=0;
     for(j=n-1; j>=0; j--) 
     {
        h[j+m-i]+=(b[j]*c[m-1-i] + o)%10;
        if(h[j+m-i]>9) 
         {
             l=h[j+m-i]/10;
             h[j+m-i]=h[j+m-i]%10;
         }
        o=(b[j]*c[m-i-1] + o)/10+l;        
        if(j==0) h[j+m-1-i]+=o;
        l=0;
     }
    }
    //Избавляемся от ведущих нулей
    n=n+m;
    while(h[0]==0)
    {
      for(j=0; j<n-1; j++)
         h[j]=h[j+1];
      if(n!=1) n--; else break;
    }
    //Вывод результата
  
       for(i=0; i<n; i++)
        b[i] = h[i];
    
    
}
 
//Перевод в систему счисления по основанию 18
string into18system(string a)
{
    string rez = a; 
    string result;              
    
    unsigned int i = 0;
    int ost = 0;        
 
    string div;                 
        
    while (!rez.empty())
    {
        for (i = 0; i < rez.size(); i++)
        {
            ost = ost * 10 + (int)rez[i] - 48;
            
            if (ost < 18)
            {
                if (div.size() != 0)
                {
                    div.append("0");
                }
            }
            else
            {
                div = div + (char)(ost / 18 + 48);
                ost = ost % 18;
            }
        }
        if (ost > 9)
        {
            result = (char)(ost + 55) + result;
        }
        else
        {
            result = (char)(ost + 48) + result;
        }
        rez = div;
        div.erase();
        ost = 0;
    }
    return (result);
}
 
int main()
{ 
    setlocale(LC_ALL,"rus");
    int kol;
    int k=0;
    bool neg=true;
    char a[100], b[100], c[100], q[100];
    string t;
    int d=0;
    int na, nb, nc, nq; // Длина чисел
    cout << "============Простейший калькулятор на вычитание в 10 СC============\n";
    cout << "\n Калькулятор предназначен для работы только с цифрами. \n Количество вводимых чисел от 2 до 4. \n Длина вводимого числа должна быть в пределе [-2^256; 2^256].\n";
    cout << " Ввод чисел осуществляется через клавишу Enter.\n";
    cout << " Выход из программы по нажатию кнопки 1.\n  ";
    do{
        while(true)             
        { 
            cout << "\n\n Введите количество чисел: ";
            cin >> kol;
            if((kol==2 || kol==3 || kol==4 || kol==1) && cin.peek() == '\n')
            { 
                cin.get();                      
                break;
            }   
            else
            { 
                cout << "\n Операция вычитания возможна только с 2-4 числами. \n Подсказка: Нажмите цифру 2, 3 или 4. Для выхода нажмите 1. " << endl;
                cin.clear();    
                while (cin.get() != '\n'){}
            }
        }
        
    switch(kol) 
    {
        case 1: 
                return 0;
            break;
        case 2:
                InputNumbers(a, na);
                InputNumbers(b, nb);
                if(a[0]==0 && b[0]==0 || (a[0]!=0 && b[0]!=0))
                {
                    cout << "\n Результат: ";
                    neg=false;
                }
                else 
                    cout << "\n Результат: -";
                Multiplication(a,na,b,nb);
                OutputNumbers(a,na);
                t=IsCHARtoSTRING(a,na);
                if(neg)
                    cout << "\n Результат в 18 СС: -";
                else 
                    cout << "\n Результат в 18 СС: ";
                cout << into18system(t) << endl;
            break;
        case 3:
                InputNumbers(a, na);
                InputNumbers(b, nb);
                InputNumbers(c, nc);
                if((a[0]==0 && b[0]!=0 && c[0]==0) || (a[0]!=0 && b[0]==0 && c[0]==0) ||(a[0]==0 && b[0]==0 && c[0]!=0)||(a[0]!=0 && b[0]!=0 && c[0]!=0))
                {
                    cout << "\n Результат: ";
                    neg=false;
                }
                    else cout << "\n Результат: -";
                Multiplication(a,na,b,nb);
                Multiplication(a,na,c,nc);
                OutputNumbers(a,na);
                t=IsCHARtoSTRING(a,na);
                if(neg)
                    cout << "\n Результат в 18 СС: -";
                else 
                    cout << "\n Результат в 18 СС: ";
                cout << into18system(t) << endl;
            break;
        case 4:
                InputNumbers(a, na);
                InputNumbers(b, nb);
                InputNumbers(c, nc);
                InputNumbers(q, nq);
                if((a[0]==0 && b[0]==0 && c[0]!=0 && q[0]!=0) || (a[0]==0 && b[0]!=0 && c[0]==0 && q[0]!=0) ||(a[0]==0 && b[0]!=0 && c[0]!=0 && q[0]==0)||(a[0]!=0 && b[0]==0 && c[0]==0 && q[0]!=0)||(a[0]!=0 && b[0]==0 && c[0]!=0 && q[0]==0)||(a[0]!=0 && b[0]==0 && c[0]!=0 && q[0]==0)||(a[0]!=0 && b[0]!=0 && c[0]==0 && q[0]==0)||(a[0]==0 && b[0]==0 && c[0]==0 && q[0]==0) || (a[0]!=0 && b[0]!=0 && c[0]!=0 && q[0]!=0))
                {
                    cout << "\n Результат: ";
                    neg=false;
                }
                    else cout << "\n Результат: -";
                Multiplication(a,na,b,nb);
                Multiplication(a,na,c,nc);
                Multiplication(a,na,q,nq);
                OutputNumbers(a,na);
                t=IsCHARtoSTRING(a,na);
                if(neg)
                    cout << "\n Результат в 18 СС: -";
                else 
                    cout << "\n Результат в 18 СС: ";
                cout << into18system(t) << endl;
            break;
 
    }
 }while(d!=1);
    system ("pause");
    return 0;
}
0
1394 / 1023 / 325
Регистрация: 28.07.2012
Сообщений: 2,813
16.04.2015, 00:11
Цитата Сообщение от flo Посмотреть сообщение
как оптимизировать умножение отрицательных чисел?
То, что сейчас есть похоже на кустарную школьную поделку.
Что можно сделать:
Посмотреть какой подход используется в нормальных проектах и сделать по аналогии.
Когда я когда-то писал свою длинную арифметику, то вдохновлялся вот этим. Хоть основная идея, заключающаяся в разделении знаковой и беззнаковой арифметики, там хорошо выражена, но некоторые операции там сделаны неэффективно, в частности умножение и деление. Их лучше всего реализовывать по Кнуту. В дальнейшем умножение можно улучшить методом Карацубы или вовсе при помощи Фурье.

Добавлено через 2 минуты
Цитата Сообщение от flo Посмотреть сообщение
умножение отрицательных чисел
Умножение отрицательных чисел почти ничем не отличается от умножения положительных.
Число - это набор "цифр" и знак числа. Перемножаешь в начале "цифры", после этого определяешь знак произведения.

Добавлено через 1 минуту
Цитата Сообщение от flo Посмотреть сообщение
char h[200];
Длинная арифметика не считалась бы длинной, если бы была ограничена только 200-ми цифрами.

Добавлено через 1 минуту
Цитата Сообщение от flo Посмотреть сообщение
string into18system(string a)
Если научиться делить длинные числа и при этом находить остаток от деления,
то перевод в произвольную СС можно осущяствлять прям как в школе учили.

Добавлено через 3 минуты
Весь прикол в том, что хоть человеку 10СС понятнее, но компьютеру роднее 2СС.
Или даже если быть точнее, то СС по основанию 2^32 для архитектуры x86 и 2^64 для архитектуры x64.
Так что было бы логичным длинную арифметику делать именно для таких СС, а для вывода чисел на экран пользоваться переводом из одной СС в другую.
0
0 / 0 / 0
Регистрация: 17.12.2011
Сообщений: 67
16.04.2015, 00:16  [ТС]
Цитата Сообщение от nonedark2008 Посмотреть сообщение
если бы была ограничена только 200-ми цифрами.
По заданию сказано числа длинной от -2^256 до 2^256.
Цитата Сообщение от nonedark2008 Посмотреть сообщение
похоже на кустарную школьную поделку
Изначально делалось, чтобы сделать, а не поразить кого-нибудь своим искусством программирования) Тем более и знаний особых нету и времени.
Мне подсказали идею, я реализовала, но в главной функции хотелось бы избежать таких громоздких проверок(

Еще на сие творение нужно тесты реализовать, это вообще беда, смутно вериться, что мой код вообще можно затестить
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
16.04.2015, 00:16

Длинные числа, 3 в 100 степени
Не получается написать такую так как консоль не поддерживает такое количество цифр.

Как сравнить длинные числа через list?
Знаю, как это сделать с помощью vector, а вот с list, увы нет. Вот код с попощью vector, может немного надо поменять: int...

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

Определить наибольший общий делитель двух многоразрядных чисел (длинные числа)
Определить наибольший общий делитель двух многоразрядных чисел. Для хранения многоразрядного числа использовать динамический...

Длинные числа
Здравствуйте, прошу помогите переделать умножение и деление, неправильно работает например 555*3 или 1000 / 3 Отблагодарю


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Многофункциональное здание: как одно здание порождает конфликты требований, которые никто не планировал (мат мет мод 29)
anaschu 23.06.2026
Многофункциональное здание: как одно здание порождает конфликты требований, которые никто не планировал Материалы для обсуждения с МГСУ · 2026 Рисунки внутри приложенного ворд файла. Что за. . .
28. Конкретное развертывание плана номер 1 из поста номер 27
anaschu 22.06.2026
Можно ли из модели получить конкретные строительные требования? Честно — напрямую из текущей модели такие ответы не получить. Но цепочка логики есть, и она не такая длинная. Где разрыв . . .
27. Планы на разработку функциональных требований к строительству внутри модели пищеблока (или не только его?)
anaschu 22.06.2026
Что уже реализовано и даёт конфликты «бесплатно» Самый простой конфликт уже работает — конфликт за ресурс-работника. Заданий больше, чем доступных поваров → очередь в queue1. Это прямое отражение. . .
26. мед мат модель.Какие типы конфликтов функциональных требований можно рассчитать через ДЕС-моделирование (СМО) в AnyLogic?
anaschu 22.06.2026
Что ДЕС/ СМО умеет считать напрямую: Конфликты за ресурсы (очереди, узкие места). Несколько типов агентов (повара, учителя, рабочие, пациенты) претендуют на один ресурс (лифт, вход, коридор,. . .
25 модель здравосохранения и функциональных требований к пищеблоку: конфликты функциональных требований.
anaschu 22.06.2026
Есть ли данные о том, какие функциональные/ эксплуатационные требования или их сочетания труднее всего учитывать при проектировании зданий? Да, такие данные есть, и они хорошо описаны и в российской,. . .
Remote Connection Manager
DevAlt 21.06.2026
Написал для себя небольшую прилагу: https:/ / github. com/ altbodhi/ ReConMan По итогу пришел к мысли, что DU не дружат с существующими технологиями. От сериализации до отображения в реляционную. . .
Администрация Хабра удаляет новые энергоэфективные алгоритмы, которые не западной школы кода, и вовсе никак не сгенерированы
Hrethgir 20.06.2026
Делается это, как замечено, при правках - при объявлении концептуальных отличий в алгоримах. Делается это, по линейке событий - после дополнения публикации основными отличиями от основных западных. . .
Процесс ориентированная диалектика (не новость - просто системное обновление, философия).
Hrethgir 20.06.2026
Однажды один участник в своём блоге, на этом форуме, сделал запись "О языках замолвите слово". Понимая, что язык - важная вещь, я решил хорошо подумать, прежде чем сказать, и сказал то, что вы видите. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru