Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 44, средняя оценка - 4.84
Biblio
2 / 2 / 0
Регистрация: 30.04.2009
Сообщений: 27
#1

Проверка арифметического переполнения для int - C++

30.04.2009, 16:33. Просмотров 6213. Ответов 3
Метки нет (Все метки)

Есть задача (из книги Лафоре ООП в С++, задача 4, глава 8):
Создайте класс Int, основанный на упражнении 1 из главы 6 [ЭТО В ДАННОМ СЛУЧАЕ НЕ ВАЖНО]. Перегрузите четыре целочисленных арифметических операции(+, -, *, /), так, чтобы их можно было использовать для операций с объектами класса Int [УЧЕБНЫЙ КЛАСС, СОЗДАННЫЙ РАНЕЕ]. Если результат какой-либо из операций выходит за границы типа int (в 32-битной системе), имеющие значение от 2147483648 до -2147483647, то операция должна послать сообщение от ошибке и завершить программу. Такие типы данных полезны там, где ошибки могут быть вызваны арифметическим переполнением, которое недопустимо. Подсказка: для облегчения проверки переполнения выполняйте вычисления с использованием типа long double. Напишите программу для проверки этого класса.
Лафоре дает ответ, но 1) он у меня не работает; 2) я не понимаю, что он делает в программе.
Решение Лафоре:
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
//ex8_4.cpp
//работа перегружаемых арифметических операций с типом Int
#include <iostream>
using namespace std;
#include <process.h>         //для exit()
///////////////////////////////////////////////////////////
class Int
    {
    private:
      int i;
    public:
      Int():i(0)             //конструктор без аргументов
        {}
      Int(int ii):i(ii)      //конструктор с одним
                             //аргументом
        {}                   //(из int в Int)
      void putInt()          //вывод Int
        {cout <<i;}
      void getInt()          //чтение Int с клавиатуры
        {cin >>i;}
      operator int()         //операция преобразования
        {return i;}          //(Int в int)
      Int operator +(Int i2) //сложение
        {return checkit(long double(i)+long double(i2));}
      Int operator -(Int i2) //вычитание
        {return checkit(long double(i)-long double(i2));}
      Int operator *(Int i2) //умножение
        {return checkit(long double(i)*long double(i2));}
      Int operator /(Int i2) //деление
        {return checkit(long double(i)/long double(i2));}
      Int checkit(long double answer) //проверка
                                      //результатов
        {
        if(answer >2147483647.0L ||answer <-2147483647.0L )
          {cout <<"\nОшибка переполнения\n ";exit(1);}
        return Int(int(answer));
        }
    };
///////////////////////////////////////////////////////////
int main()
    {
    Int alpha =20;
    Int beta =7;
    Int delta,gamma;
    gamma =alpha +beta;     //27
    cout <<"\ngamma=";gamma.putInt();
    gamma =alpha -beta;      //13
    cout <<"\ngamma=";gamma.putInt();
    gamma =alpha *beta;      //140
    cout <<"\ngamma=";gamma.putInt();
    gamma =alpha /beta;      //2
    cout <<"\ngamma=";gamma.putInt();
    delta =2147483647;
    gamma =delta +alpha;    //ошибка переполнения
    delta =-2147483647;
    gamma =delta -alpha;     //ошибка переполнения
    cout <<endl;
    return 0;
    }
В моей собственной программе перегрузка происходит нормально, но проверку на переполнение сделать не получается.
Моя программа:
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
//Имитация работы класса int. Инициализация объектов, ввод, вывод, перегрузка арифметических операций
#include <iostream>
#include <process.h>         
using namespace std;
class Int
{
    private:
        int n;//поле класса типа int
    public:
        Int() : n(0){/*пустое тело*/}//инициализирущий конструктор. присваивает полю по умолчанию значение ноль
        Int(int d) : n(d){/*пустое тело*/}//конструктор с одни параметром
        void set(int d) { n = d; }//метод инициализирует поле класса целым числом
 
        void output()//метод вывода значения поля на экран
        {
            cout << "Zna4enie polya ravno " << n << endl;
        }
 
        Int operator+(Int);//перегрузка сложения
        Int operator*(Int);//перегрузка умножения
        Int operator-(Int);//перегрузка вычитания
        Int operator/(Int);//перегрузка деления
};
 
 
int main()
{
    Int a, b, c;
    a.output();
    b.output();
    c.output();
    a.set(100000000);
    b.set(2147483647);
    a.output();
    b.output();
    c = a+b;
    cout << "Slojenie "; c.output();
    a.output();
    b.output();
    c = a*b;
    cout << "Umnojenie "; c.output();
    a.output();
    b.output();
    c = a-b;
    cout << "Vichitanie "; c.output();
    a.output();
    b.output();
    c = a/b;
    cout << "Delenie "; c.output();
 
    return 0;
}
 
Int Int::operator+(Int d2)//метод перегрузки сложения
{
    long double m = n+d2.n;
    if(m > 2147483648.0L || m < -2147483647.0L)
    {
        cout << "Perepolneneie!";
        exit(1);
    }
    else return Int(int(m));
}
 
Int Int::operator*(Int d2)//метод перегрузки умножения
{
    long double m = n*d2.n;
    cout << "m ravno " << m << endl;
    if(m > 2147483648.0L || m < -2147483647.0L)
    {
        cout << "Perepolneneie!";
        exit(1);
    }
    else return Int(int(m));
}
 
Int Int::operator-(Int d2)//метод перегрузки вычитания
{
    long double m = n-d2.n;
    if(m > 2147483648.0L || m < -2147483647.0L)
    {
        cout << "Perepolneneie!";
        exit(1);
    }
    else return Int(int(m));
}
 
Int Int::operator/(Int d2)//метод перегрузки деления
{
    long double m = n/d2.n;
    if(m > 2147483648.0L || m < -2147483647.0L)
    {
        cout << "Perepolneneie!";
        exit(1);
    }
    else return Int(int(m));
}
Помогите, пожалуйста. Или подправьте мою программу или исправьте и растолкуйте решение Лафоре.
Заранее спасибо
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.04.2009, 16:33
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Проверка арифметического переполнения для int (C++):

Нахождение среднего арифметического без переполнения - C++
Задача найти среднее арифметическое целых чисел (int). Если просто складывать их и потом делить на количество происходит переполнение... ...

Проверка переполнения double - C++
Добрый день! Подскажите пожалуйста, где можно почитать теорию. Нужно решить задачу, написать функции на С++, которые бы проверяли ...

Как вызвать exception во время переполнения типа int - C++
такая задача, нужно что бы во время присваивания переменной типа int чисел больших чем допустимые вызвалось именно исключение, ибо сейчас у...

Error LNK2019: unresolved external symbol "public: __thiscall Vector<int>::Vector<int>(int,int,int)" (?0?$Vec - C++
Вот есть заголовочный файл // Заголовочный файл Vector.h #ifndef VECTOR_H #define VECTOR_H #include &lt;iostream&gt; using...

Преобразовать int в const int для установки размера массива - C++
Добрый вечер всем! Столкнулся с такой нестандартной проблемой. Нужно преобразовать значения типа int в const int, чтоб константная...

Написать функцию SUM (int M, int N) / С++ для начинающих - C++
Написать функцию SUM (int M, int N), которая вычисляет и возвращает сумму всех чисел кратных 3 и 9 в пределах от M и N включительно ....

3
NickA
35 / 34 / 2
Регистрация: 28.04.2009
Сообщений: 67
30.04.2009, 17:16 #2
C++
1
2
3
4
5
6
7
8
9
10
Int Int::operator+(Int d2)//метод перегрузки сложения
{
    long double m = n+d2.n; // << -- нужно сперва преобразовать n и d2.n к типу long double, после чего выполнять действие, если этого не делать, то операция выполняется с переполнением, например (int)2147483648+(int)1=(int)-2147483647
    if(m > 2147483648.0L || m < -2147483647.0L)
    {
        cout << "Perepolneneie!";
        exit(1);
    }
    else return Int(int(m));
}
Ну скажем так:
C++
1
2
3
4
5
6
7
8
9
10
Int Int::operator+(Int d2)//метод перегрузки сложения
{
    long double m = (long double)n+(long double)d2.n; 
    if(m > 2147483648.0L || m < -2147483647.0L)
    {
        cout << "Perepolneneie!";
        exit(1);
    }
    else return Int(int(m));
}
в остальных операциях аналогично
1
rrrFer
Заблокирован
30.04.2009, 17:25 #3
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
//ex8_4.cpp
//работа перегружаемых арифметических операций с типом Int
#include <iostream>
using namespace std;
#include <process.h>         //для exit()
///////////////////////////////////////////////////////////
class Int
    {
    private:
      int i;
    public:
      Int():i(0)             //конструктор без аргументов
        {}
      Int(int ii):i(ii)      //конструктор с одним
                             //аргументом
        {}                   //(из int в Int)
      void putInt()          //вывод Int
        {cout <<i;}
      void getInt()          //чтение Int с клавиатуры
        {cin >>i;}
      operator int()         //операция преобразования
        {return i;}          //(Int в int)
      Int operator +(Int i2) //сложение
        {return checkit(long double(i)+long double(i2));}
      Int operator -(Int i2) //вычитание
        {return checkit(long double(i)-long double(i2));}
      Int operator *(Int i2) //умножение
        {return checkit(long double(i)*long double(i2));}
      Int operator /(Int i2) //деление
        {return checkit(long double(i)/long double(i2));}
      Int checkit(long double answer) //проверка
                                      //результатов
        {
        if(answer >2147483647.0L ||answer <-2147483647.0L )
          {cout <<"\nOwu6ka nepenoJIHeHu9I\n ";system("pause");exit(1);}
        return Int(int(answer));
        }
    };
///////////////////////////////////////////////////////////
int main()
    {
    Int alpha =20;
    Int beta =7;
    Int delta,gamma;
    gamma =alpha +beta;     //27
    cout <<"\ngamma=";gamma.putInt();
    gamma =alpha -beta;      //13
    cout <<"\ngamma=";gamma.putInt();
    gamma =alpha *beta;      //140
    cout <<"\ngamma=";gamma.putInt();
    gamma =alpha /beta;      //2
    cout <<"\ngamma=";gamma.putInt();
    delta =2147483647;
    gamma =delta +alpha;    //ошибка переполнения
    delta =-2147483647;
    gamma =delta -alpha;     //ошибка переполнения
    cout <<endl;
    system("pause");
    return 0;
    }
вот так у меня работает нормально(добавил system("pause"); для задержки перед выходом и выходом в случае ошибки
а что тут растолковывать?
операторы +-/*, перед возвращением результата вызывают функциж проверки переполеннеия
C
1
2
3
4
5
6
7
8
 Int operator +(Int i2) //сложение
        {return checkit(long double(i)+long double(i2));}
      Int operator -(Int i2) //вычитание
        {return checkit(long double(i)-long double(i2));}
      Int operator *(Int i2) //умножение
        {return checkit(long double(i)*long double(i2));}
      Int operator /(Int i2) //деление
        {return checkit(long double(i)/long double(i2));}
а она принимает число в long double- ши ре чем int и в случае переполлнения программа выводит сообщение и завершаетсмя, если ошибки нет, то возвращает то число, которое ей передали:
C++
1
2
3
4
5
6
7
 Int checkit(long double answer) //проверка
                                      //результатов
        {
        if(answer >2147483647.0L ||answer <-2147483647.0L )
          {cout <<"\nОшибка переполнения\n ";exit(1);}
        return Int(int(answer));
        }
PS/ извиняюсь за орфографию - чуток не в настроении
0
Biblio
2 / 2 / 0
Регистрация: 30.04.2009
Сообщений: 27
30.04.2009, 17:35  [ТС] #4
Цитата Сообщение от rrrFer Посмотреть сообщение
вот так у меня работает нормально(добавил system("pause"); для задержки перед выходом и выходом в случае ошибки
У меня все равно не работает. Выдает ошибки:
\8.04 otv\main.cpp||In member function `Int Int::operator+(Int)':|
\8.04 otv\main.cpp|24|error: expected primary-expression before "long"|
\8.04 otv\main.cpp||In member function `Int Int::operator-(Int)':|
\8.04 otv\main.cpp|26|error: expected primary-expression before "long"|
\8.04 otv\main.cpp||In member function `Int Int::operator*(Int)':|
\8.04 otv\main.cpp|28|error: expected primary-expression before "long"|
\8.04 otv\main.cpp||In member function `Int Int::operator/(Int)':|
\8.04 otv\main.cpp|30|error: expected primary-expression before "long"|
||=== Build finished: 4 errors, 0 warnings ===|

Компилирую в Codbloks, компилятор gcc.

Для
Цитата Сообщение от NickA Посмотреть сообщение
NickA
Спасибо большое, все заработало! Приведение типов я все еще никак не освою... Буду работать дальше
0
30.04.2009, 17:35
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.04.2009, 17:35
Привет! Вот еще темы с ответами:

Проверка баланса скобок арифметического выражения, введенного с клавиатуры - C++
Составить программу проверки баланса скобок арифметического выражения , введенного с клавиатуры.

Проверка на Int - C++
Не знаю как реализовать проверку на ввод только Int c возможностью исправления(т.е. пока не будет введен Int будет выскакивать сообщение с...

Проверка на int - C++
int main(void) { int vop; setlocale(LC_ALL, &quot;Russian&quot;); int mas1, mas2, mas3, outmas; int ke1, ke2, ke3; do { ...

проверка на int - C++
добрый день! не работает проверка на int . подскажите в чем проблема? bool bFlag; do { cout&lt;&lt;&quot;Enter an integer...


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

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru