Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.70/50: Рейтинг темы: голосов - 50, средняя оценка - 4.70
 Аватар для Виктор_Сен
36 / 29 / 2
Регистрация: 01.08.2011
Сообщений: 176

СИ++ и контроль переполнения

10.11.2011, 13:03. Показов 10356. Ответов 20
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Можно ли как-нибудь в VS включить контроль переполнения при математических вычислениях? Чтоб, например, возникало исключение. Или это можно сделать только средствами ассемблера путём контроля флагов?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
10.11.2011, 13:03
Ответы с готовыми решениями:

Отслеживание переполнения
Привет. Подскажите пожалуйста как ловить переполнение переменной типа size_t ( unsigned int )... например, когда человек передает в...

Переполнения безопастны?
Насколько безопасна строчка: for(unsigned int b(UINT_MAX); ++b != UINT_MAX;) или такое нужно писать только так: unsigned int b(0);...

Флаг переполнения
Доброго времени суток! Подскажите, как проверить какую-либо определенную переменную типа double на переполнение (значениe -1.#IND00,...

20
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
10.11.2011, 13:39
Думаю можно и проще чем заюзывать asm приведу пример
C
1
2
3
4
5
6
7
8
int val;
long param;
do
{
     cin>>param;
}
while(INT_MAX < param);
val = (int)param;
0
 Аватар для kazak
3602 / 2743 / 355
Регистрация: 11.03.2009
Сообщений: 6,305
10.11.2011, 14:32
-=ЮрА=-, как это может помочь при контроле выполнения математических операций?
0
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
10.11.2011, 14:34
Виктор_Сен, как вариант - перегрузить операторы для нужных вам типов, и в них выполнять проверки.
1
Заблокирован
10.11.2011, 14:36
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
 
using namespace std;
 
int main()
{
    int x = 10000, y = 100000, result;
    
    cout << "Input two operands!" << endl;
    cin >> x >> y;
     
    result = x*y;
    __asm__ __volatile__ ("jno label");
    cout << "Overflow detected!" << endl; 
    __asm__ ("label:");
    cout << result << endl;
    return 0;
}
в ВС еще проще, он позволяет ассемблерным вставкам обращаться к меткам за пределами ассемблерной вставки, в гсс вроде такой трюк не прокатывает
2
10.11.2011, 14:39

Не по теме:

Еще можно бросить плюсы, взять C#. Там есть checked

0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
10.11.2011, 14:45
Цитата Сообщение от kazak Посмотреть сообщение
-=ЮрА=-, как это может помочь при контроле выполнения математических операций?
- очень просто например нам нужны целочисленные значения, выполняем расчёты с ними например считаем сумму ряда в double sum, а затем смотрим если величина суммы превосходит INT_MAX то выдаём сообщение о переполнении, если же нет то делаем int val = (int)sum Вобщем в стандартных типах можно реализовать всё даже для float лишь бы желание было...
константа INT_MAX и многие другие прописаны в limits.h

Добавлено через 5 минут

Не по теме:

LosAngeles, задание предполагает альтарнативные асму варианты...

Цитата Сообщение от Виктор_Сен Посмотреть сообщение
Можно ли как-нибудь в VS включить контроль переполнения при математических вычислениях?Или это можно сделать только средствами ассемблера путём контроля флагов?
Как я понял с асемблеровским вариантом ТС знаком

0
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
10.11.2011, 14:48
-=ЮрА=-, а если нужно контролировать переполнение в unsigned long long или long long double?
0
237 / 210 / 29
Регистрация: 08.06.2011
Сообщений: 467
10.11.2011, 14:49
Цитата Сообщение от talis Посмотреть сообщение
Виктор_Сен, как вариант - перегрузить операторы для нужных вам типов, и в них выполнять проверки.
Насколько я помню, нельзя перегружать операторы для базовых типов данных.
2
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
10.11.2011, 15:00
Лучший ответ Сообщение было отмечено как решение

Решение

Net_Wanderer, да, поторопился. Извините.

Добавлено через 8 минут
А если сделать шаблонную обёртку, то можно:

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
#include <iostream>
#include <stdexcept>
 
template< typename _Tp >
struct var
{
    _Tp data;
 
    var( const _Tp d ) : data(d) {};
 
    var<_Tp> & operator+=( const var<_Tp> &d )
    {
        data += d;
        return *this;
    }
 
    _Tp & operator*()
    {
        return data;
    }
 
    operator _Tp()
    {
        return data;
    }
};
 
template< typename _Tp >
var< _Tp > & operator+( const var< _Tp > &a, const var< _Tp > &b )
{
    var< _Tp > v( a );
    v += b;
    return v;
}
 
typedef var<int> int_v;
 
int main( )
{
    int_v a = 50;
 
    std::cout << a << '\n';
 
    a = 12 + 8;
 
    std::cout << a << '\n';
 
    return 0;
}
3
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
10.11.2011, 21:42
talis, разумеется, ведь шаблонная обёртка не подпадает под понятие "базовый тип"
0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
11.11.2011, 10:47
Цитата Сообщение от Виктор_Сен Посмотреть сообщение
Можно ли как-нибудь в VS включить контроль переполнения при математических вычислениях? Чтоб, например, возникало исключение.
- ниже простой код не требующий введения классов и преобразований к старшему типу данных, я написал лишь ветвь для сложения, но завершить алгоритм труда не составит(остаётся заполнить лишь 3 case в множественном выборе)
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
#include <iostream>
#include <conio.h>
using namespace std;
 
int main()
{
    char ch;
    bool bFlag;
    int val1, val2;
    char choperator;
    do
    {
        cout<<"\tThis algorithm checking limits in algebraic operations\n";
        cout<<"Enter equation val1 operator val2, val1(2) - INT operator : + - / *\n";
        cout<<"Example 5 + 6\n";
        cout<<" "<<INT_MAX<<" - maximum INT value\n";
        cout<<INT_MIN<<" - minimum INT value\n>";
        bFlag= true;//Çäåñü ýòî ôëàã äëÿ ââîäà
        val1 = 0;val2 = 0;
        while((ch = getchar()) != '\n')
        {
            if(isdigit(ch))
            {
                if(bFlag)
                {
                    if(INT_MAX/10 < val1)
                        cout<<"You trying enter val1 accedes INT_MAX\n";
                    else
                    {
                        val1 *= 10;
                        val1 += ((int)ch - '0');
                    }
                }
                else
                {
                    if(INT_MAX/10 < val2)
                        cout<<"You trying enter val2 accedes INT_MAX\n";
                    else
                    {
                        val2 *= 10;
                        val2 += ((int)ch - '0');
                    }
                }
            }
            else
            {
                if(!isspace(ch))
                    choperator = ch;
                if(bFlag)
                    bFlag = false;
            }
        }
        
        cout<<"\tCalculation of equation\n";
        cout<<val1<<" "<<choperator<<" "<<val2<<" = ";
        bFlag = true;//Òåïåðü ýòî óæå ôëàã äëÿ ìàòîïåðàöèé
        switch(choperator)
        {
        case '+' :
            if(0 <= val1)
            {
                if(INT_MAX - val1 < val2)
                    bFlag = false;
            }
            else
            {
                if(val2 < 0)
                if(val2 < INT_MIN - val1)
                    bFlag = false;
            }
            if(bFlag)
                cout<<(val1 + val2)<<endl;
            else
                cout<<"Result of val1 + val2 out of [-INT_MIN;INT_MAX]\n";
            break;
        case '-' :
            break;
        case '*' :
            break;
        case '/' :
            break;
        default:
            cout<<"You enter unsupported operator\n";
            break;
        }
        cout<<"Press Y-key for new input\n";
    }
    while(toupper(getch()) == 'Y');
    return 0;
}
Миниатюры
СИ++ и контроль переполнения  
0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
11.11.2011, 10:49
PS:
Цитата Сообщение от talis Посмотреть сообщение
-=ЮрА=-, а если нужно контролировать переполнение в unsigned long long или long long double?
- руководствуясь приведенной мной логикой можно контролировать и эти типы...
0
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
11.11.2011, 12:18
-=ЮрА=-, без введения обёрток математическая формула, реализованная вашим способом, станет абсолютно нечитаемой.
0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
11.11.2011, 12:57
Цитата Сообщение от talis Посмотреть сообщение
реализованная вашим способом, станет абсолютно нечитаемой.
- что под этим подразумевалось, чем это не читаемое выражение?
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
cout<<(val1 + val2)<<endl;
Алгоритм просто не даст сложить неправильно и всё
Кстати у вас же ещё ветвь проверки значения нужно здесь дописать
Цитата Сообщение от talis Посмотреть сообщение
var<_Tp> & operator+=( const var<_Tp> &d )
* * {
* * * * data += d;
* * * * return *this;
* * }
, причём от моих условных операторов она абсолютно ничем отличаться не будет. Кроме того мой код потянет даже самый самый начинающий, обвёртка уже предполагает некоторых знаний

Не по теме:

В заключение вот тест Вашего алгоритма

C++
1
2
3
4
5
6
7
8
9
int main( )
{
    int iMAX = INT_MAX;
    int_v a = iMAX;
    std::cout << a << '\n';
    a = iMAX + 8;
    std::cout << a << '\n';
    return 0;
}
- я пока не пишу что он не реализует предполагаемую задачу, т.к. возможно вы именно как обворачивать без обработки исключений представить хотели...

Миниатюры
СИ++ и контроль переполнения  
0
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
11.11.2011, 13:03
-=ЮрА=-, если вы внимательно посмотрите код обёртки, то увидите, что я не включал туда никакого контроля. Реально внутри обёртки должен быть код, подобный вашему (лучше, конечно, ассемблерный вариант). А использование её в программе сведётся как раз к выражениям вида

C++
1
double_v dub = a + 15 * sqrt(b) + c;
Весь этот код проверки будет внутри обёртки и код вычислений станет читабельным. В вашем варианте всё это дело придётся писать перед каждой операцией, причём составные выражения вроде того, которое я привёл выше, будет невозможно сделать.
0
11.11.2011, 13:25

Не по теме:

Цитата Сообщение от talis Посмотреть сообщение
сли вы внимательно посмотрите код обёртки, то увидите, что я не включал туда никакого контроля
- я поэтому и писал.
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
возможно вы именно как обворачивать без обработки исключений представить хотели
, Замечание сделал на случай вдруг ТС ещё не имеет достаточного багажа знаний и напрямую попытается использовать ваш код, это не претензия к вам была:pardon:На счёт остального соглашусь, я делал под начинающего, у вас как должно быть в программе уже набившего руку программиста;)

1
Заблокирован
11.11.2011, 14:30
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
/**
    OVERFLOW_ASSERT(label) macro
        throw exception if OF == 1 || CF == 1
    params:
        label - name of label for compiler, so avoid of using the same name twice!
    return:
        code for MSVC or code for g++
*/
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
    #define OVERFLOW_ASSERT(label) \
    __asm { JNO label }; \
    __asm { JNC label }; \
    throw std::overflow_error("This is SPARTAAAA!"); \
label:
#elif defined(__GNUG__)
    #define OVERFLOW_ASSERT(label) \
    __asm__ ("JNO label" \
            "JNC label"); \
    throw std::overflow_error("This is SPARTAAAA!"); \
    __asm__ ("label:");
#endif
 
 
 
template< typename _Tp >
struct var
{
    _Tp data;
 
    var( const _Tp d ) : data(d) {};
 
    var<_Tp> & operator+=( const var<_Tp> d )
    {
        data += d.data;
        OVERFLOW_ASSERT(addition)
        return *this;
    }
 
    var<_Tp> & operator*=( const var<_Tp> d )
    {
        
        data *= d.data;
        OVERFLOW_ASSERT(multiplication)
        return *this;
    }
 
    _Tp & operator*()
    {
        return data;
    }
 
    operator _Tp()
    {
        return data;
    }
};
Добавлено через 9 минут
talis, кстати говоря в чём смысл 44 строки в твоём листинге? там же built-in оператор используется, и как бы нельзя проверить переполнение, а то я уже было обрадовался
1
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
11.11.2011, 14:41
LosAngeles, да, спасибо. Должно быть так:

C++
1
a = int_v(12) + 8;
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
11.11.2011, 15:01
Лучший ответ Сообщение было отмечено как решение

Решение

Цитата Сообщение от Виктор_Сен Посмотреть сообщение
Можно ли как-нибудь в VS включить контроль переполнения при математических вычислениях? Чтоб, например, возникало исключение. Или это можно сделать только средствами ассемблера путём контроля флагов?
О каких переполнениях идёт речь?

Если речь идёт о целочисленных переполнениях, то в современных процессорах вроде бы нет возможности сделать так, чтобы возникало прерывание при переполнении. Возможно только пощупать соответствующие целочисленные флаги непосредственно после выполнения операции, а потому нужно весь кусок (который вычисляет операцию и вызывает прерывание) полностью писать на ассемблере

Если же речь идёт о плавающих вычислениях, то оно как правило процессорами поддерживается, потому что прерывания требуются по стандарту ieee-754. Для этого есть стандартные функции типа http://linux.die.net/man/3/feenableexcept но они, насколько я знаю, входят в стандарт Си99
4
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
11.11.2011, 15:01
Помогаю со студенческими работами здесь

Защита от переполнения
Ребят помоги создать защиту от переполнения через функцию scanf_s и убрать нолики в конечном ответе, вот код: #include &lt;stdio.h&gt; ...

Ошибка переполнения массива
Здравствуйте. Задача легкая,нужно создать массив из 1000000 элементов,и найти 1000001,и вывести сообщение что не найден такой элемент. Но...

Ошибка переполнения буфера
При первом запуске програма работает, после второго появляеться ошибка переполнения буфера. В чем дело?#include &lt;iostream&gt; #include...

Как отловить переполнения?
Есть проект dll, в в нём экспортируемая функция, возвращающая BOOL, требуется при переполнении любой вещественной операции в теле этой...

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


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru