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

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

17.10.2018, 09:45. Показов 2150. Ответов 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
Ответ Создать тему
Новые блоги и статьи
Модель микоризы: классовый агентный подход 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 считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru