Форум программистов, компьютерный форум CyberForum.ru

Как заставить программу завершаться при делении на ноль? - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 21, средняя оценка - 4.81
Alchem
0 / 0 / 0
Регистрация: 23.09.2009
Сообщений: 10
25.09.2009, 05:39     Как заставить программу завершаться при делении на ноль? #1
Проблема состоит в том, что при решении задач матфизики трудно поставить условия так, чтобы не возникала численная неустойчивость. При неустойчивости искомые переменные очень быстро принимают значения NaN или Inf в зависимости от компилятора. Было бы хорошо если бы программа при этом аварийно завершалась, но в С она продолжает работать. Вот и получается, на ночь программу оставляю считаться, а к утру получаю 2000 файлов из которых половина: "NaN NaN NaN" и приходится искать в какой момент решение разболталось. Подскажите как отловить момент когда переменная уходит в бесконечность?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.09.2009, 05:39     Как заставить программу завершаться при делении на ноль?
Посмотрите здесь:

C++ Найти сумму таких чисел в диапазоне [a;b], у которых остаток от деления на 7 такой же, как и у b при делении на 7.
C++ Как заставить программу управлять программами?
написать программу в Dev-C++ для поиска трехзначных чисел, которые при делении на 47 дают в остатке 43, а при делении на 43 дают в остатке 47 C++
Как заставить программу запустить другую программу C++
C++ Что возвращать при делении на ноль?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
25.09.2009, 05:55     Как заставить программу завершаться при делении на ноль? #2
C
1
2
3
4
5
6
7
#include <errno.h>
#include <string.h>
 
...
 
    if (errno)
        printf("%s" "\n", strerror(errno);
пример

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
 
main()
{
    double n;
    
    n = strtod("1.5e+1024", NULL);
    printf("%f" "\n", n);
    
    if (errno)
        printf("%s" "\n", strerror(errno));
    
    return 0;
}

вывод

Код
[guest@station src]$ ./test
inf
Numerical result out of range
[guest@station src]$


Добавлено через 1 минуту
а деление на ноль у меня не прошло
Ёрик
45 / 45 / 2
Регистрация: 07.01.2009
Сообщений: 298
25.09.2009, 07:38     Как заставить программу завершаться при делении на ноль? #3
При деление на нуль вызывается прерывание, в любом случае оно не пройдет.Если Вы пишите на С,то там нужно просто проверять вычисления условными операторами. Если на С++, там все легче, есть throw и catch.
M128K145
Эксперт C++
 Аватар для M128K145
8272 / 3491 / 142
Регистрация: 03.07.2009
Сообщений: 10,707
25.09.2009, 08:48     Как заставить программу завершаться при делении на ноль? #4
Ёрик, throw/catch - самый плохой вариант. Если ты знаешь, что возможно делится на ноль, то быстрее проверится ифом, а не генерацией велосипедов под названием "исключения"
Gosha_Dubinin
 Аватар для Gosha_Dubinin
35 / 12 / 3
Регистрация: 06.05.2009
Сообщений: 215
25.09.2009, 08:53     Как заставить программу завершаться при делении на ноль? #5
а я бы поставил просто условие проверки, вывод которого завершал программу....
писать не буду.
Alchem
0 / 0 / 0
Регистрация: 23.09.2009
Сообщений: 10
25.09.2009, 09:25  [ТС]     Как заставить программу завершаться при делении на ноль? #6
accept, попробовал твой код из примера, он исправно генерит ошибку, но мне нужно чтобы ошибку генерило что-то вроде этого:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
 
int main()
{
    double x=5,y=0,z;
    
    z = x/y;
    printf("%f" "\n", z);
 
    if (errno)
    {
        printf("%s" "\n", strerror(errno));
    }
    
    return 0;
}
А вот такой код как раз спокойно пишет 1.#INF00 и продолжает выполняться дальше. errno так и остается равным нулю. Я бы написал что-то вроде If(z == 1.#INF00) но не знаю как вообще в С определена бесконечность, как проверить бесконечна ли z. Компилил через mingw и Visual C++ Express.
M128K145
Эксперт C++
 Аватар для M128K145
8272 / 3491 / 142
Регистрация: 03.07.2009
Сообщений: 10,707
25.09.2009, 09:31     Как заставить программу завершаться при делении на ноль? #7
Попробуй так
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
 
int main()
{
    double x=5,y=0,z;
    
    if(y == 0)
    {
        printf("На ноль делить нельзя");
        exit(0);
    }
    else
    {
        z = x/y;
        printf("%f" "\n", z);
    }  
    return 0;
}
ЗЫ. не компилировал, но смысл я думаю ты понял
-=ЮрА=-
Заблокирован
Автор FAQ
25.09.2009, 10:19     Как заставить программу завершаться при делении на ноль? #8
Я решил сделать програмку с генерацией чисел, т.е. когда 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
#include <windows.h>
#include <stdio.h>
#include <time.h>
 
void main()
{
    srand(time(0));
    printf("Program shows result Param1/Param2\r\n");
    printf("where Param2 - random number\r\n");
    printf("Enter Param1 \t");int Param1;scanf("%d",&Param1);
    int Param2 = rand();
    do
    {
        Param2 = rand();
        while(Param1 < Param2)
            Param2 = rand();
        printf("%.2f\r\n",1.0*Param1/Param2);
        if(Param2 == 0)
        {
            printf("\tParam2 == 0!!!\r\n");
            printf("%s\r\n",strerror(GetLastError()));
        }
    }
    while(Param2 != 0);
    printf("Press NUM1 for new calculations\r\n");
    scanf("%d",&Param1);
    if(Param1 == 1)
        main();
}
Миниатюры
Как заставить программу завершаться при делении на ноль?  
Rififi
 Аватар для Rififi
2330 / 1045 / 43
Регистрация: 03.05.2009
Сообщений: 2,656
25.09.2009, 10:45     Как заставить программу завершаться при делении на ноль? #9
для VC

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
#pragma float_control (except, on)
 
int filter(LPEXCEPTION_POINTERS ptr)
{
    switch (ptr->ExceptionRecord->ExceptionCode)
    {
    case EXCEPTION_FLT_DIVIDE_BY_ZERO: // float
        // ...
        break;
 
    case EXCEPTION_INT_DIVIDE_BY_ZERO: // integer
        // ...
        break;
    }
    return EXCEPTION_EXECUTE_HANDLER;
}
 
 
unsigned current = _controlfp(0, 0);
current &= ~(EM_OVERFLOW | EM_UNDERFLOW | EM_INEXACT | EM_ZERODIVIDE | EM_DENORMAL | EM_INVALID);
_controlfp(current, _MCW_EM);   
 
__try
{
    float c = ... // попытка деления на 0
}
__except(filter(GetExceptionInformation()))
{
    // сообщение об ошибке
}
Alchem
0 / 0 / 0
Регистрация: 23.09.2009
Сообщений: 10
25.09.2009, 11:18  [ТС]     Как заставить программу завершаться при делении на ноль? #10
M128K145, вариант с проверкой знаменателя в данном случае конечно самый лучший, но у меня он не работает по причине сложности вычисляемых уравнений. Так что я остановился на варианте If(z > 1e+200 || z < -1e+200). Если условие выполняется, то из проги выходим. Все равно таких больших чисел в решении не подразумевается.

-=ЮрА=-, то же самое, плюс у тебя на скриншоте видно что printf("%s\r\n",strerror(GetLastError())); выдает "No error". Как ни обидно , деление на ноль не считается ошибкой.

Rififi, ээээ с первого взгляда в коде не разобрался, тут какие-то функции винды используются?
odip
Эксперт C++
 Аватар для odip
7225 / 3287 / 58
Регистрация: 17.06.2009
Сообщений: 14,165
25.09.2009, 18:17     Как заставить программу завершаться при делении на ноль? #11
Visual Studio 2005.

int _isnan(
double x
);

_isnan returns a nonzero value if the argument x is a NAN; otherwise it returns 0.


Но тебе скорее нужен:

int _finite(
double x
);

_finite returns a nonzero value if its argument x is not infinite; that is, if –INF < x < +INF. It returns 0 if the argument is infinite or a NAN.

Добавлено через 3 минуты
Еще есть:

_fpclass
Return status word containing information on floating-point class

_fpieee_flt
Invoke user-defined trap handler for IEEE floating-point exceptions
Alchem
0 / 0 / 0
Регистрация: 23.09.2009
Сообщений: 10
25.09.2009, 19:26  [ТС]     Как заставить программу завершаться при делении на ноль? #12
odip, _finite замечательно работает, огромный респект за помощь.
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
27.09.2009, 09:52     Как заставить программу завершаться при делении на ноль? #13
Цитата Сообщение от Alchem
А вот такой код как раз спокойно пишет 1.#INF00 и продолжает выполняться дальше.
errno реагирует на математические функции и другие
здесь же просто деление на ноль, у меня прога выпадает с ошибкой
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.10.2010, 15:40     Как заставить программу завершаться при делении на ноль?
Еще ссылки по теме:

Написать программу по поиску четырехзначных чисел, дающих при делении на определенное число определенный остаток. C++
C++ Найти все пятизначные числа, которые при делении на A дают в остатке B, а при делении на C дают в остатке D
C++ Как происходит переполнение при делении

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

Или воспользуйтесь поиском по форуму:
Yurasik
 Аватар для Yurasik
0 / 0 / 0
Регистрация: 29.10.2010
Сообщений: 9
31.10.2010, 15:40     Как заставить программу завершаться при делении на ноль? #14
Помогите исправить программу на Борланд С++ 3.1 деление выражения на ноль Expression Syntax Error 5 строка

#include<iostream.h>
#include<math.h>
void main()
{
try
{
float K,d,x,y,a;
cout<<"Vvedite K,d,x\n";
cin>>K>>d>>x;

y=(3*K+d-tan(x))/(fabs(x)+d);
cout<<"y="<<y<<"\n";
a=(fabs(x)+d);
throw 0;}
catch (float a)
{cout<<"a=0"<<a<<"\n";
cout<<"net reshenia"<<"\n";};
}
Yandex
Объявления
31.10.2010, 15:40     Как заставить программу завершаться при делении на ноль?
Ответ Создать тему
Опции темы

Текущее время: 01:28. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru