2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему
 
 С++. Обработка исключений
Сообщение26.10.2014, 12:31 


26/11/13
85
Здравствуйте.
Помогите, пожалуйста, разобраться с написанием кода к заданию:
Описать функцию, вычисляющую логарифм по основанию, равному первому аргументу, от числа равного второму аргументу. Функция должна генерировать исключение в случае некорректных данных. В этом случае должно быть выдано соответствующее сообщение и сгенерировано повторное исключение. Создать функцию, находящую методом деления отрезка пополам решение уравнения $xlnx=a$ (здесь $x>0$ - неизвестное). Формальными параметрами функции должны быть числа типа double ⎯ $a$ и точность нахождения корня $\varepsilon$.
Создать программу, использующую эту функцию, перехватывающую все исключения и прекращающую работу в случае возникновения исключений.

Для начала хотелось бы разобраться с первым предложением:
Цитата:
Описать функцию, вычисляющую логарифм по основанию, равному первому аргументу, от числа равного второму аргументу.


Заранее спасибо. :-)

-- 26.10.2014, 13:34 --

P.S. Тему создал не в том разделе. Переместите, пожалуйста. Мои извинения.

 Профиль  
                  
 
 Re: С++. Обработка исключений
Сообщение26.10.2014, 12:39 
Заслуженный участник


28/04/09
1933
Логарифм $\text{---}$ это функция от двух аргументов: $y(a, x)=\log_a x$ ($a$ $\text{---}$ основание логарифма). В C++ это будет выглядеть как-то так:
Используется синтаксис C++
double logarithm(double base, double x)
{
    // Ваш код, вычисляющий логарифм
}

 Профиль  
                  
 
 Re: С++. Обработка исключений
Сообщение26.10.2014, 12:42 


26/11/13
85
EtCetera так будет ?
Используется синтаксис C++
double logarithm(double base, double x)
{
    return log(x) / log(base);
}

 Профиль  
                  
 
 Re: С++. Обработка исключений
Сообщение26.10.2014, 12:47 
Заслуженный участник


28/04/09
1933
MAKSUS_87 в сообщении #923079 писал(а):
я так понял base - это основание ?
Да.

 Профиль  
                  
 
 Re: С++. Обработка исключений
Сообщение26.10.2014, 12:55 


26/11/13
85
EtCetera

Хорошо, что нужно сделать дальше ? Как в данном случае сгенерировать исключение ?
Я так понимаю здесь нужно акцентировать внимание на то, что x и base должны быть строго больше 0.

 Профиль  
                  
 
 Re: С++. Обработка исключений
Сообщение26.10.2014, 13:08 
Заслуженный участник


28/04/09
1933
MAKSUS_87 в сообщении #923083 писал(а):
Как в данном случае сгенерировать исключение ?
В данном случае никакой специфики выброса исключений нет.
MAKSUS_87 в сообщении #923083 писал(а):
Я так понимаю здесь нужно акцентировать внимание на то, что x и base должны быть строго больше 0.
Найдите область определения логарифма.

 Профиль  
                  
 
 Re: С++. Обработка исключений
Сообщение26.10.2014, 13:28 


26/11/13
85
EtCetera
Цитата:
В данном случае никакой специфики выброса исключений нет.

Хорошо, тогда для какого случая мне нужно реализовать исключение ?
Цитата:
Найдите область определения логарифма.

Область определения функции: $(0, +\infty)$ для основания: $(0,1) and (1, +\infty)$

 Профиль  
                  
 
 Re: С++. Обработка исключений
Сообщение26.10.2014, 13:49 
Заслуженный участник


28/04/09
1933
MAKSUS_87 в сообщении #923101 писал(а):
Хорошо, тогда для какого случая мне нужно реализовать исключение ?
Для случая, когда поданные на вход аргументы не попадают в область определения логарифма.

 Профиль  
                  
 
 Re: С++. Обработка исключений
Сообщение26.10.2014, 14:20 


26/11/13
85
EtCetera
начал так, не знаю что должно быть в catch (честно говоря и не уверен, что правильно написал в try)
Используется синтаксис C++
void del()
{
     cout <<"Please enter the values 'base' and 'b'" << endl;
     try
     {
          double base, b;
          if ((base==0) or (b=0) or (base==1) or (base<0) or (b<0)) throw "Error!";
          double rez  = log(b)/log(base)
          cout << rez << endl;    
     }
     catch

Подскажите, пожалуйста, как исправить.

 Профиль  
                  
 
 Re: С++. Обработка исключений
Сообщение26.10.2014, 15:05 
Заслуженный участник


28/04/09
1933
Для начала напишите реализацию функции double logarithm(double base, double x), в которой будет проверка аргументов и выброс исключения (лучше на каждый из аргументов сделать отдельную проверку и отдельный выброс исключения), а также расчет значения логарифма в случае корректных значений аргументов. Затем уже можно будет приступать к коду, который будет использовать данную функцию и, соответственно, обрабатывать исключения, возникающие при ее работе.
В качестве исключений в данном случае лучше взять готовые классы исключений из стандартной библиотеки (например, std::invalid_argument или std::domain_error) или написать таковые самому. В типичном сценарии использования исключений они бросаются по значению (т.е. использовать динамическую память не нужно).
Использование в качестве логических операторов токенов типа or, подозреваю, может смутить 95% программистов на C++, но если они Вам нравятся, используйте их.
Не знаю, стоит ли на данном этапе упоминать о корректном способе сравнения вещественных чисел...

 Профиль  
                  
 
 Re: С++. Обработка исключений
Сообщение27.10.2014, 10:05 


24/05/09

2054
1. Нет ввода чисел, вы их объявляете, и нигде не вводите - в результате в переменных случайный мусор. Если уж хотите проверить программу и не заморачиваться пока вводом, присваивайте сразу значения:

Используется синтаксис C++
double base = 10;
double b = 20;


2.
Используется синтаксис C++
 if ((base==0) or (b=0) or (base==1) or (base<0) or (b<0)) throw "Error!";


Оператор "b = 0" присвоит переменной b значение 0 и выдаст true, поэтому у вас всегда будет выскакивать ошибка. Для сравнения нужно "b == 0"

3. Есть сомнения в правильности проверки на ошибки. Ошибка будет вылетать, если выполняется одно из условий:

base = 0
b = 0
base = 1
base < 0
b < 0

Это то, что вы хотели?

 Профиль  
                  
 
 Re: С++. Обработка исключений
Сообщение27.10.2014, 10:57 


10/04/12
705
Ну... хорошим тоном будет почитать вначале документацию по самой функции log. Сама функция может каким-то образом проводить проверку допустимости параметров и как-то сигнализировать о том, что что-то не так. Более того, в данном случае допустимость входных параметров известная только самой функции log. Действительные числа хранятся с ограниченной точностью, поэтому некоторые эффекты могут быть вблизи перечисленных вами особых точек. Поэтому я бы предложил такой сценарий.

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

 Профиль  
                  
 
 Re: С++. Обработка исключений
Сообщение27.10.2014, 11:52 
Заслуженный участник


11/05/08
32166
EtCetera в сообщении #923142 писал(а):
Не знаю, стоит ли на данном этапе упоминать о корректном способе сравнения вещественных чисел...

Поскольку от этих чисел берутся именно логарифмы -- требование их положительности и необходимо, и более чем достаточно (другое дело, что нет никакой необходимости проверять отдельно их ненулёвость). А вот требование нееденичности основания лучше заменить проверкой перед делением того, не является ли знаменатель нулём. И этого вполне достаточно, т.к. числитель не слишком велик (не более скольки-то там тысяч), а знаменатель, если уж он ненулевой, то не слишком мал (порядок не более пары десятков), так что переполнение при делении никак не может случиться.

-- Пн окт 27, 2014 13:04:08 --

mustitz в сообщении #923405 писал(а):
Действительные числа хранятся с ограниченной точностью, поэтому некоторые эффекты могут быть вблизи перечисленных вами особых точек.

Соответственно, вряд ли "вблизи" возможны какие-то эффекты. Т.е. я хоть и не знаю никакой документации, но очень трудно представить себе какой-либо другой алгоритм вычисления логарифма, кроме умножения порядка на логарифм от нормализованной мантиссы. И откуда здесь взяться артефактам?...

Хотя да, одна проблема есть: она в том, что $e>1$. Поэтому если $x=1.000...0001_b$, то само это число не равно единице, а вот логарифм от него может оказаться и нулевым. Но именно поэтому и лучше проверять не само основание, а его логарифм.

 Профиль  
                  
 
 Re: С++. Обработка исключений
Сообщение27.10.2014, 12:39 


10/04/12
705
ewert в сообщении #923420 писал(а):
Хотя да, одна проблема есть: она в том, что $e>1$. Поэтому если $x=1.000...0001_b$, то само это число не равно единице, а вот логарифм от него может оказаться и нулевым. Но именно поэтому и лучше проверять не само основание, а его логарифм.


А при делении не может возникнуть бесконечность? С учетом денормализованного представления, да и без него? А главное, зачем забивать голову лишним и углубляться в особенности машинної арифметики?

 Профиль  
                  
 
 Re: С++. Обработка исключений
Сообщение27.10.2014, 12:47 
Заслуженный участник


11/05/08
32166
mustitz в сообщении #923436 писал(а):
С учетом денормализованного представления, да и без него?

Без него -- в данном случае никак не может, и я объяснил, почему. А нормализацией, в принципе, завершается любая машинная операция. Иначе слишком часто программы глючили бы в самых безобидных ситуациях.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 15 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group