С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
9 / 9 / 0
Регистрация: 16.06.2018
Сообщений: 22

Реализовать операцию вычитания двух длинных целых десятичных чисел

17.10.2018, 09:45. Показов 2154. Ответов 7

Студворк — интернет-сервис помощи студентам
Ребят, помогите найти ошибку в программе.

Задание:
Реализовать операцию вычитания двух длинных целых десятичных чисел.

Код программы:
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
#include "stdafx.h"
#include <iostream>
#include <ctime>
#include <string>
#include <math.h>
using namespace std;
 
int difference(int *x, int *y, int *z, int length)   //функция вычисления разности
{
    for (int ix = 0; ix < (length - 1); ix++)        //проход по всем разрядам числа, начиная с последнего, не доходя до первого
    {
        if (ix < (length - 1))                       //если текущий разряд чисел не первый
        {
            x[ix + 1]--;                             //в следующуем разряде большего числа занимаем 1.
            z[ix] += 10 + x[ix];                     //в ответ записываем сумму значения текущего разряда большего числа и 10-ти
        }
        else                                         //если текущий разряд чисел - первый
            z[ix] += x[ix];                          //в ответ суммируем значение текущего разряда большего числа
 
        z[ix] -= y[ix];                              //вычитаем значение текущего разряда меньшего числа
 
        if (z[ix] / 10 > 0)                          //если значение в текущем разряде двухразрядное
        {
            z[ix + 1]++;                             //переносим единицу в старший разряд
            z[ix] %= 10;                             //в текущем разряде отсекаем ее
        }
    }
    return 0;
}
void cinlong(int *mas, int size, string num)         //функция зеркального сохранения числа в массив
{
    for (int i = 0; i < size; ++i)
    {
        mas[i] = 0;
    }
    int len;
    len = num.length();
    for (int i = 0; i < len; i++)
    {
        mas[len - i] = int(num[i]) - 48;
    }
}
void coutlong(int *mas, int size)                    //функция зеркального вывода числа
{
    int i = size;
    while (mas[i] == 0 && i > 1)
    {
        i--;
    }
    for (int j = i; j >= 1; j--)
    {
        cout << mas[j];
    }
}
 
int main()
{
    setlocale(LC_ALL, "Russian");
    string num1, num2;
    cout << "\n Введите число: ";
    getline(cin, num1);
    cout << " Введите число: ";
    getline(cin, num2);
    int size_a = num1.size();
    int size_b = num2.size();
    int* a = new int[size_a];
    int* b = new int[size_b];
 
    cinlong(a, size_a, num1);
    cinlong(b, size_b, num2);
 
    short k = 3;                                     //если к = 3, значит числа одинаковой длинны
    int length = size_a;
    if (size_a > size_b)
    {
        length = size_a;
        k = 1;                                       //если к = 1, значит первое число длиннее второго
    }
    else
        if (size_b > size_a)
        {
            length = size_b;
            k = 2;                                   //если к = 2, значит второе число длиннее первого
        }
        else                                         //если числа одинаковой длинны, то необходимо сравнить их веса
            for (int ix = 0; ix < length; ix++)      //поразрядное сравнение весов чисел
            {
                if (a[ix] > b[ix])                   // если разряд первого числа больше
                {
                    k = 1;                           //значит первое число длиннее второго
                    break;
                }
                if (b[ix] > a[ix])                   //если разряд второго числа больше
                {
                    k = 2;                           //значит второе число длиннее первого
                    break;
                }
            }
    int size_c = length * 1.5;
    int* c = new int[size_c];
    if (k == 1)                                      //если первое число больше второго,
        difference(a, b, c, length);                 
    if (k == 2)                                      //если второе число больше первого.
        difference(b, a, c, length);                 
    cout << "\n   Разница двух чисел:\n  Ответ: ";
    coutlong(c, size_c);
    cout << endl;
 
    cout << "\n Время работы программы = " << clock() / 1000.0 << "\n\n";  //вывод времени работы программы
    system("pause");
    return 0;
}
Код вычитания я брал с этого сайта: http://cppstudio.com/post/5036/
Ошибка, как я думаю, скорее всего связана либо с массивом "c" (массив с результатом), либо с самой функцией вычитания.
На скриншоте результат работы программы.
Миниатюры
Реализовать операцию вычитания двух длинных целых десятичных чисел  
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
17.10.2018, 09:45
Ответы с готовыми решениями:

Длинная арифметика: реализовать операцию сложения длинных чисел
я пыталась сложить два больших числа но при запуске после ввода всё крошится #include &lt;bits/stdc++.h&gt; using...

Написать калькулятор для сложения и вычитания целых однозначных десятичных чисел
Приложение-калькулятор для сложения и вычитания целых однозначных десятичных чисел. В главной форме есть кнопки«0», «1» ., «9», «+», «-»,...

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

7
 Аватар для FFPowerMan
2156 / 1236 / 508
Регистрация: 11.10.2018
Сообщений: 6,240
17.10.2018, 11:30
Введенное число 1 неправильно переписывает в массив "а". Т.е. я полагаю, что ошибка в функции cinlong().

Добавлено через 10 минут
Цитата Сообщение от MysteriousLord Посмотреть сообщение
C++
1
mas[len - i] = int(num[i]) - 48;
- вот ошибка. Должно быть вот так:
C++
1
mas[len - i - 1] = int(num[i]) - 48;
Добавлено через 31 минуту
Цитата Сообщение от MysteriousLord Посмотреть сообщение
if (ix < (length - 1)) * * //если текущий разряд чисел не первый
- но и не второй, да?

Добавлено через 9 минут
Цитата Сообщение от MysteriousLord Посмотреть сообщение
C++
1
z[ix] += 10 + x[ix];  //в ответ записываем сумму значения текущего разряда большего числа и 10-ти
- здесь массив z, который раньше был массивом c не инициализирован, т.е. прибавлять к нему сумму 10 и какого-то числа - это полный бред. Подпрограмму difference нужно полностью перерабатывать, иначе там бредятина полнейшая. Да и не очень хорошей идеей было переворачивать 2 входных числа при переконвертации в массивы целых чисел: a и b. От этого тяжело отлаживать и т.д.
0
27 / 27 / 16
Регистрация: 22.08.2017
Сообщений: 126
17.10.2018, 11:41
Как-то мне тоже понадобилась длинная арифметика. Но использовать GMP было нельзя, так как длинная арифметика нужна была для микроконтроллеров без операционной системы и кучи. Пришлось написать свою библиотеку С++ шаблонов для работы с длинными целыми числами. Вот ссылка:

https://sourceforge.net/projec... position=5

Там в архиве есть и описание на русском языке.
Там есть операции сложения, вычитания, деления, умножения И, ИЛИ, НЕ и еще много чего.
1
9 / 9 / 0
Регистрация: 16.06.2018
Сообщений: 22
22.10.2018, 14:50  [ТС]
Цитата Сообщение от FFPowerMan Посмотреть сообщение
- вот ошибка. Должно быть вот так:
C++Выделить код1
mas[len - i - 1] = int(num[i]) - 48;
Нет, ошибка не в этом, я проверял эту функцию, всё правильно переписывается в массив. Так же я попробовал внести изменения, предложенные вами - результат один и тот же.

Цитата Сообщение от FFPowerMan Посмотреть сообщение
Сообщение от MysteriousLord
if (ix < (length - 1)) * * //если текущий разряд чисел не первый
- но и не второй, да?
Я же брал этот код с сайта), там так и было написано, а как должно работать подобная функция для длинной арифметики я не знаю).

Цитата Сообщение от FFPowerMan Посмотреть сообщение
Сообщение от MysteriousLord
C++Выделить код1
z[ix] += 10 + x[ix]; //в ответ записываем сумму значения текущего разряда большего числа и 10-ти
- здесь массив z, который раньше был массивом c не инициализирован, т.е. прибавлять к нему сумму 10 и какого-то числа - это полный бред. Подпрограмму difference нужно полностью перерабатывать, иначе там бредятина полнейшая. Да и не очень хорошей идеей было переворачивать 2 входных числа при переконвертации в массивы целых чисел: a и b. От этого тяжело отлаживать и т.д.
Я массив "с" объявил фиг знает как), так что я не знаю, как объявлять массив для нормальной работы функции.
Я считаю, что ошибка как раз таки в объявлении массива "z (c)".
0
 Аватар для FFPowerMan
2156 / 1236 / 508
Регистрация: 11.10.2018
Сообщений: 6,240
22.10.2018, 17:24
Цитата Сообщение от MysteriousLord Посмотреть сообщение
Нет, ошибка не в этом, я проверял эту функцию, всё правильно переписывается в массив. Так же я попробовал внести изменения, предложенные вами - результат один и тот же.
- ну конечно, я вообще-то в дебаггере смотрел и точно помню картинку: "0, 5, 4, 3, 2" - когда должно быть: "5, 4, 3, 2, 1", для числа 12345. Нужно уметь программы писать, Вы - не умеете. Господи, зачем Вы вообще сделали обратный порядок чисел? - Бред какой-то.
А результат один и тот же, кстати, оттого, что там еще куча ошибок и все криво и косо сделано. Нужно все переделывать и числа неплохо бы в нормальный порядок поставить.

Добавлено через 7 минут
Цитата Сообщение от MysteriousLord Посмотреть сообщение
Я массив "с" объявил фиг знает как), так что я не знаю, как объявлять массив для нормальной работы функции. Я считаю, что ошибка как раз таки в объявлении массива "z (c)".
- что значит как объявлять массив? Если обнуление в инициализации, то так:
C++
1
int c[20] = {0};
В Мэйне или в функции его нужно циклом проходить по каждому элементу и обнулять. Учите C++ тогда.
0
9 / 9 / 0
Регистрация: 16.06.2018
Сообщений: 22
23.10.2018, 11:00  [ТС]
Цитата Сообщение от FFPowerMan Посмотреть сообщение
Сообщение от MysteriousLord
Нет, ошибка не в этом, я проверял эту функцию, всё правильно переписывается в массив. Так же я попробовал внести изменения, предложенные вами - результат один и тот же.
- ну конечно, я вообще-то в дебаггере смотрел и точно помню картинку: "0, 5, 4, 3, 2" - когда должно быть: "5, 4, 3, 2, 1", для числа 12345. Нужно уметь программы писать, Вы - не умеете. Господи, зачем Вы вообще сделали обратный порядок чисел? - Бред какой-то.
А результат один и тот же, кстати, оттого, что там еще куча ошибок и все криво и косо сделано. Нужно все переделывать и числа неплохо бы в нормальный порядок поставить.
Я студент, я тока учусь писать программы, так что не оскорбляйте меня. Обратный порядок записи - "зеркальный массив", нужен для длинной арифметики, чтобы удобнее было работать с числами, про это куча тем на этом же форуме. Так же я писал, что функцию разности я взял с сайта: http://cppstudio.com/post/5036/, так что прежде, чем писать, что я не умею писать программы и у меня код кривой - посмотрите сайт, который я скинул, и пишите там в комментариях, что у них код кривой и они писать программы не умеют. Откуда вы взяли такую картинку? Придумали из ниоткуда? Чтобы лишний раз меня упрекнуть в неумении писать программы? Вот вы пишите бред как раз таки.

Цитата Сообщение от FFPowerMan Посмотреть сообщение
Сообщение от MysteriousLord
Я массив "с" объявил фиг знает как), так что я не знаю, как объявлять массив для нормальной работы функции. Я считаю, что ошибка как раз таки в объявлении массива "z (c)".
- что значит как объявлять массив? Если обнуление в инициализации, то так:
C++Выделить код1
int c[20] = {0};В Мэйне или в функции его нужно циклом проходить по каждому элементу и обнулять. Учите C++ тогда.
Объявлять массив просто так я умею, я имел в виду объявление массива для функции, чтобы, когда вызываешь функцию, где есть массив в аргументе и где этот массив инициализируется, она могла нормально вызваться, без ошибок.

P.S.: Вместо того, чтобы упрекать меня, и спрашивать у Господа( ?) ), лучше возьмите и нормально мне помогите, такой помощи, как ваша мне не нужна.
P.S.S.: И научитесь внимательно читать, что пишут в вопросе, а не только шапку и код.
P.S.S.S.: Я и так изучаю C++, так как я студент, и вас не смутило, что тема создана в разделе - "C++ для начинающих"? Вы слепой что ли?
0
 Аватар для FFPowerMan
2156 / 1236 / 508
Регистрация: 11.10.2018
Сообщений: 6,240
23.10.2018, 11:14
Цитата Сообщение от MysteriousLord Посмотреть сообщение
C++
1
2
3
4
for(int i = 0; i < len; i++)
{
    mas[len - i] = int(num[i]) - 48;
}
- вот ошибка. Еще раз говорю. Доказательство. Я ввел число(которое тут будет num) 12345. Соответственно там(в Мэйне) ввелась строка "12345". Здесь Вы ее переворачиваете. Первая итерация этого цикла: Переменная len = 5. В левой части присвоения будет mas[5-0] - в квадратных скобках получаем mas[5] - но к 5 члену нельзя обращаться по правилам C++, потому что его просто нету, есть только члены 0-4 массива. - Теперь понятна ошибка или будете дальше спорить? А исправляется эта ошибка вычитанием 1, как я уже показал в своем сообщении №2.
Зачем ВЫ меня отсылаете на сайт. Там тоже люди могут ошибаться. А своей головы у Вас нет, чтобы думать?
0
9 / 9 / 0
Регистрация: 16.06.2018
Сообщений: 22
23.10.2018, 13:27  [ТС]
Цитата Сообщение от FFPowerMan Посмотреть сообщение
C++Выделить код1
2
3
4
for(int i = 0; i < len; i++)
{
mas[len - i] = int(num[i]) - 48;
}
- вот ошибка. Еще раз говорю. Доказательство. Я ввел число(которое тут будет num) 12345. Соответственно там(в Мэйне) ввелась строка "12345". Здесь Вы ее переворачиваете. Первая итерация этого цикла: Переменная len = 5. В левой части присвоения будет mas[5-0] - в квадратных скобках получаем mas[5] - но к 5 члену нельзя обращаться по правилам C++, потому что его просто нету, есть только члены 0-4 массива. - Теперь понятна ошибка или будете дальше спорить? А исправляется эта ошибка вычитанием 1, как я уже показал в своем сообщении №2.
Зачем ВЫ меня отсылаете на сайт. Там тоже люди могут ошибаться. А своей головы у Вас нет, чтобы думать?
Цитата Сообщение от MysteriousLord Посмотреть сообщение
- вот ошибка. Должно быть вот так:
C++Выделить код1
mas[len - i - 1] = int(num[i]) - 48;
Нет, ошибка не в этом, я проверял эту функцию, всё правильно переписывается в массив. Так же я попробовал внести изменения, предложенные вами - результат один и тот же.
Я уже писал, что это не работает.
Миниатюры
Реализовать операцию вычитания двух длинных целых десятичных чисел  
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
23.10.2018, 13:27
Помогаю со студенческими работами здесь

Цифры двух десятичных целых чисел!
Ребята,помогите решить пожалуйста задачку на паскале. даны цифры двух десятичных целых чисел:А3А2А1 и Б2Б1,где А1 и Б1-число единиц,А2 и...

Найти произведение двух длинных целых чисел
Здравствуйте. Я плохо знаю русский. Извините за этого. Я еще новичок в C++ программирование. В олимп есть токая задача...

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

Даны цифры двух десятичных целых чисел
Даны цифры двух десятичных целых чисел: трехзначного a3a2a1 и двузначного b2b1, где a1 и b1 — число единиц, а2 и b2, — число десятков, a3 —...

Реализовать операцию деления целых чисел через вычитание
Реализовать операцию деления целых чисел через вычитание. В результате операции деления должны получаться частное и остаток.


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru