Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Перехват ошибок: try / catch 
:(
    Опции темы
Martin_8
Дата 3.12.2006, 20:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 93
Регистрация: 16.10.2006
Где: Минск

Репутация: нет
Всего: нет



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

Код

#include <iostream.h>
#include <conio.h>
#include <math.h>

float run1 (float);
float run2 (float);

void main(void)
{
    float a,r1,r2;
    cout<<"Vvedite znacenie a:"<<endl;
    cin>>a;

    try // блок контроля
    {
        r1=run1(a);
        r2=run2(a);
        //cout<<"Znacenie z1="<<run1(a)<<endl;
        //cout<<"Znacenie z2="<<run2(a)<<endl;
        cout<<"Znacenie z1="<<r1<<endl;
        cout<<"Znacenie z2="<<r2<<endl;

        cout<<"Oshibok ne vozniklo"<<endl;
        getch();
    }
    catch(...) // блок обработки
    {
        cout<<"Oshibka !!!   Deleie no 0 "<<endl;
        getch();
    }
}

float run1(float x)
{
    float z1=0,a=0,b=0;
    a=sqrt(pow((3)*x+(2),2)-24*x);
    b=3*sqrt(x)-2/sqrt(x);
    return z1=a/b;
}

float run2(float x)
{
    return -sqrt(x);
}

PM   Вверх
Daevaorn
Дата 3.12.2006, 20:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Martin_8, стандартные try/catch не ловят деление на ноль( как и многое другое ). Для таких вещей есть os-specific решения. Для Windows например:
Код

#include <iostream>
#include <windows.h>

using namespace std;

int main()
{
    __try
    {
        int a = 10;
        int b = 0;
        b;
        int c = a / b ;
    }
    __except( ::GetExceptionCode() == EXCEPTION_INT_DIVIDE_BY_ZERO )
    {
        cout << "Very bad!\n";    
    }
                return 0;
}

PM MAIL WWW   Вверх
Martin_8
Дата 3.12.2006, 20:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 93
Регистрация: 16.10.2006
Где: Минск

Репутация: нет
Всего: нет



Daevaorn, А применительно к консольному приложению, в моём случаи, как это должно выгладить?
PM   Вверх
MAKCim
Дата 3.12.2006, 21:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата

Для таких вещей есть os-specific решения.

Я бы даже сказал архитектурно специфичные


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Daevaorn
Дата 3.12.2006, 21:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Цитата(Martin_8 @  3.12.2006,  21:54 Найти цитируемый пост)
 А применительно к консольному приложению, в моём случаи, как это должно выгладить? 

дописываешь #include <windows.h>
try меняешь на __try
catch меняешь на __except( ::GetExceptionCode() == EXCEPTION_INT_DIVIDE_BY_ZERO )

PM MAIL WWW   Вверх
UnrealMan
Дата 3.12.2006, 21:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Насколько я помню, деление на ноль значений с плавающей точкой никаких ошибок (в т.ч. SEH) не вызывает (результирующим значением будет +/–бесконечнось или неопределённость)

Цитата(Daevaorn @  3.12.2006,  20:51 Найти цитируемый пост)
EXCEPTION_INT_DIVIDE_BY_ZERO 

По-моему, это как бы для целочисленного деления (явно же написано: EXCEPTION_INT_DIVIDE_BY_ZERO).

Martin_8, проверяй делитель на равенство нулю и в случае нулевого значения генерируй собственное исключение.

Это сообщение отредактировал(а) UnrealMan - 3.12.2006, 21:43
PM MAIL   Вверх
MAKCim
Дата 3.12.2006, 21:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



UnrealMan, 
правильно помнишь
в Intel Architecture все операции с плавающей точкой выполняются FPU
все, что происходит при делении на 0 - установка ZE в регистре состояния SR


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Daevaorn
Дата 3.12.2006, 22:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Цитата(UnrealMan @  3.12.2006,  22:37 Найти цитируемый пост)
Насколько я помню, деление на ноль значений с плавающей точкой никаких ошибок (в т.ч. SEH) не вызывает 

Microsoft говорит обратное:
http://msdn.microsoft.com/library/default....l/floapoint.asp
Другое дело, что это не работает. Не понятно почему.
Цитата(UnrealMan @  3.12.2006,  22:37 Найти цитируемый пост)
По-моему, это как бы для целочисленного деления (явно же написано: EXCEPTION_INT_DIVIDE_BY_ZERO).

Да, но есть и константа EXCEPTION_FLT_DIVIDE_BY_ZERO.

PM MAIL WWW   Вверх
Anikmar
Дата 3.12.2006, 23:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 59



Думаю это связано с тем, что в float операндах бессмыслено проверять делитель на 0 - тут может возникнуть ошибка и при ненулевых значениях, например если делится достаточно большое (почти пределеное) число на 0.0001 (последнее нулем не является).
Поэтому и ограничились ошибкой переполнения, которую и надо ловить...
PM MAIL ICQ   Вверх
UnrealMan
Дата 4.12.2006, 11:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Цитата(Daevaorn @  3.12.2006,  22:12 Найти цитируемый пост)
Microsoft говорит обратное:

Ну значит, я ошибся :-)

Цитата(Anikmar @  3.12.2006,  23:20 Найти цитируемый пост)
Думаю это связано с тем, что в float операндах бессмыслено проверять делитель на 0 

Небессмысленно – по крайней мере в ряде случаев.

Цитата(Anikmar @  3.12.2006,  23:20 Найти цитируемый пост)
тут может возникнуть ошибка и при ненулевых значениях, например если делится достаточно большое (почти пределеное) число на 0.0001 (последнее нулем не является).

Верно. И я бы такое обрабатывал примерно так (как дополнение к обработке нулевого знаменателя):

Код
float result = a/b;
if (result && result==result/2) // можно сделать такую проверку и отдельной функцией
    throw E_InvalidFloatValue();

хотя можно и явно сравнивать с бесконечностями:

Код
if (result==std::numeric_limits<float>::infinity() ||
    result==-std::numeric_limits<float>::infinity())

PM MAIL   Вверх
Anikmar
Дата 4.12.2006, 12:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 59



Исключение должно возникнуть уже в данной строке (если b = 0 или близко к  нему):
float result = a/b;

Я работаю на Билдере, при плавающих точках возникают два вида исключений:
Если делитель = 0 - то деление на 0, а если близко к 0 - то переполнение.
Их можно отловить с помощью try ... catch

как в других средах, если честно не знаю.
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0553 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.