Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > не обрабатывается исключение


Автор: Pawl 1.1.2012, 15:04
Доброго времени суток (и с Новым Годомsmile)!
Попросил меня товарисч сделать прогу для вычисления корня заданного уравнения методом деления отрезка пополам с пом. рекурсии. Сессия у него! Только не думайте, что я ее сделал вчера или сегодня! smile сделал ее я 2 дня назад, но выбрался на форум с вопросом только сейчас - товарисч о себе напомнил... Ну да не в этом дело! Вот код моей программы:
Код

public class Koren {
    private float root;
    
    public Koren(float a, float b, float e) {
     findRoot(a, b, e);
    }
    
    // функция
    private float f(float x) {
     return x * x - 2;
    }
    //поиск корня
    private void findRoot(float a, float b, float e) {
     float x;
     // если функция не пересекает на отрезке a b ось х, корня нет (он равен NaN)     
     if (f(a) * f(b) >= 0) {
         root = Float.NaN;
         return;
     }
     // делим отрезок пополам и сравниваем значение функции в точке х с точностью
     x = (a + b) / 2;
     // если f(x) больше точности, исследуем новый отрезок, иначе - корень найден
     if (Math.abs(f(x)) >= e) {
            if (f(a) * f(x) > 0) {
                findRoot(x, b, e);
            } else {
                findRoot(a, x, e);
            }
     } else {
         root = x;
     }
    }
    // метод, возвращающий значение корня
    public float getRoot() throws Exception {
        if (root != Float.NaN) {
            return root;            
        }
        
        throw new Exception("No root!");    
    }

    public static void main(String[] args) {
     Koren k = new Koren(2.0f, 3.0f, 0.0001f);      
        try {         
         float r = k.getRoot();
         System.out.println(r);         
        } catch (Exception e) {
         System.out.println(e.getMessage());
        }
    }
}

Как видно, корень тут может быть не числом (NaN), а проблема в следующем: в методе getRoot(), когда корень - не число, выбрасывается Exception, которое, по идее, должно отлавливаться в блоке try catch метода main. Но оно не отлавливается, а на экран вместо него выводится NaN. Конечно, можно выбрасывать исключение сразу в методе findRoot, но мне, если честно, так не хочется. Да и не понятно, почему программа некорректно работает. Если кто доходчиво объяснит, буду благодарен.
Спасибо!

Автор: jk1 1.1.2012, 16:13
С новым годом.

Сравнение чисел с плавающей точкой на точное равенство - плохая идея в большинстве языков. Тем более когда речь идет о NaN. Вот работающий вариант

Код

    public float getRoot() throws Exception {
        if (!Float.isNaN(root)) {
            return root;            
        }       
        throw new Exception("No root!");    
    }

Автор: Pawl 1.1.2012, 16:28
Отлично, спасибо, jk1!
Да, знание таких вот тонкостей приходит с опытом...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)