2014 dxdy logo

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

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




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

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


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

-- 26.10.2014, 13:34 --

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

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

 
 
 
 Re: С++. Обработка исключений
Сообщение26.10.2014, 12:42 
EtCetera так будет ?
Используется синтаксис C++
double logarithm(double base, double x)
{
    return log(x) / log(base);
}

 
 
 
 Re: С++. Обработка исключений
Сообщение26.10.2014, 12:47 
MAKSUS_87 в сообщении #923079 писал(а):
я так понял base - это основание ?
Да.

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

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

 
 
 
 Re: С++. Обработка исключений
Сообщение26.10.2014, 13:08 
MAKSUS_87 в сообщении #923083 писал(а):
Как в данном случае сгенерировать исключение ?
В данном случае никакой специфики выброса исключений нет.
MAKSUS_87 в сообщении #923083 писал(а):
Я так понимаю здесь нужно акцентировать внимание на то, что x и base должны быть строго больше 0.
Найдите область определения логарифма.

 
 
 
 Re: С++. Обработка исключений
Сообщение26.10.2014, 13:28 
EtCetera
Цитата:
В данном случае никакой специфики выброса исключений нет.

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

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

 
 
 
 Re: С++. Обработка исключений
Сообщение26.10.2014, 13:49 
MAKSUS_87 в сообщении #923101 писал(а):
Хорошо, тогда для какого случая мне нужно реализовать исключение ?
Для случая, когда поданные на вход аргументы не попадают в область определения логарифма.

 
 
 
 Re: С++. Обработка исключений
Сообщение26.10.2014, 14:20 
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 
Для начала напишите реализацию функции double logarithm(double base, double x), в которой будет проверка аргументов и выброс исключения (лучше на каждый из аргументов сделать отдельную проверку и отдельный выброс исключения), а также расчет значения логарифма в случае корректных значений аргументов. Затем уже можно будет приступать к коду, который будет использовать данную функцию и, соответственно, обрабатывать исключения, возникающие при ее работе.
В качестве исключений в данном случае лучше взять готовые классы исключений из стандартной библиотеки (например, std::invalid_argument или std::domain_error) или написать таковые самому. В типичном сценарии использования исключений они бросаются по значению (т.е. использовать динамическую память не нужно).
Использование в качестве логических операторов токенов типа or, подозреваю, может смутить 95% программистов на C++, но если они Вам нравятся, используйте их.
Не знаю, стоит ли на данном этапе упоминать о корректном способе сравнения вещественных чисел...

 
 
 
 Re: С++. Обработка исключений
Сообщение27.10.2014, 10:05 
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 
Ну... хорошим тоном будет почитать вначале документацию по самой функции log. Сама функция может каким-то образом проводить проверку допустимости параметров и как-то сигнализировать о том, что что-то не так. Более того, в данном случае допустимость входных параметров известная только самой функции log. Действительные числа хранятся с ограниченной точностью, поэтому некоторые эффекты могут быть вблизи перечисленных вами особых точек. Поэтому я бы предложил такой сценарий.

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

 
 
 
 Re: С++. Обработка исключений
Сообщение27.10.2014, 11:52 
EtCetera в сообщении #923142 писал(а):
Не знаю, стоит ли на данном этапе упоминать о корректном способе сравнения вещественных чисел...

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

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

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

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

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

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


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

 
 
 
 Re: С++. Обработка исключений
Сообщение27.10.2014, 12:47 
mustitz в сообщении #923436 писал(а):
С учетом денормализованного представления, да и без него?

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

 
 
 [ Сообщений: 15 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group