Почему коренным результатом квадратного уравнения является NaN? (Ява)

2

Зачем выписывать Корни NaN и NaN в консоли? Я читал о NaN, но я не нашел правильного решения, как я могу исправить ошибки... Я пробовал кастинг, чтобы удвоить дискриминантный и корни, но не работает. Может кто-нибудь мне помочь, где и что мне нужно переписать?

public static void main(String args[]) {
    Scanner sc = new Scanner(System.in);
    Pattern newlineOrSpace = Pattern.compile(System
            .getProperty("line.separator")
            + "|\\s");
    sc.useDelimiter(newlineOrSpace);
    System.out.print("Enter a, b, c: ");
    double a = sc.nextDouble();
    double b = sc.nextDouble();
    double c = sc.nextDouble();
    // System.out.format("a = %f, b = %f, c = %f", a, b, c);

    double root1;
    double root2;
    double discriminant;
    discriminant = Math.sqrt(b * b - 4 * a * c);
    if (discriminant > 0) {
        System.out.println("There are no real roots ");
    } else {
        root1 = (-b + discriminant) / (2 * a);
        root2 = (-b - discriminant) / (2 * a);
        System.out.println("The roots are " + root1 + " and " + root2);
    }
  • 0
    Я выйду на конечности и угадаю, что a очень маленький, может быть, даже ноль. Что бы вы хотели, чтобы функция делала в этом случае?
  • 0
    Какой вклад вы даете?
Показать ещё 1 комментарий
Теги:
math

4 ответа

7

Math.sqrt(x) возвращает NaN, когда x отрицательный, который затем распространяется через остальную часть вашего кода. Вы должны проверить отрицательные числа, прежде чем принимать квадратный корень:

discriminant = b * b - 4 * a * c;
if (discriminant < 0) {
    System.out.println("There are no real roots ");
} else {
    root1 = (-b + Math.sqrt(discriminant)) / (2 * a);
    root2 = (-b - Math.sqrt(discriminant)) / (2 * a);
    System.out.println("The roots are " + root1 + " and " + root2);
}
  • 1
    Я бы порекомендовал проверить условия вроде a = 0; один корень равен нулю, а другой - -c / b. Легко сделать, и оба реальны. Есть более вырожденные случаи, чтобы искать, чем просто нулевой определитель.
  • 0
    Могу ли я просто предложить использовать Math.abs () для отрицательных чисел? Например, я хочу рассчитать расстояние и не волнует, является ли число отрицательным или положительным.
5

Во-первых, позвольте мне избавиться от пользовательского ввода в качестве причины для этого - гораздо проще, если короткая, но полная программа содержит все необходимые нам данные:

public class Test {
    public static void main(String args[]) {
        showRoots(2.0, 10.0, 2.0);
        showRoots(10.0, 1.0, 1.0);
    }

    private static void showRoots(double a, double b, double c) {
        double discriminant = Math.sqrt(b * b - 4 * a * c);
        if (discriminant > 0) {
            System.out.println("There are no real roots ");
        } else {
            double root1 = (-b + discriminant) / (2 * a);
            double root2 = (-b - discriminant) / (2 * a);
            System.out.println("The roots are " + root1 + " and " + root2);
        }
    }
}

Это показывает два случая - один, где действительно есть корни, но программа утверждает, что нет - и одна, где действительно нет реальных корней, но программа выводит их как NaN. Когда вы берете квадратный корень отрицательного числа, результатом является NaN, поэтому это отображается.

Итак, проблема в том, как вы имеете дело с дискриминантом. Существуют реальные корни, если b 2 - 4ac неотрицательно, но вы уже взяли квадратный корень в этой точке и изменили характер условия.

Итак, это должно быть:

private static void showRoots(double a, double b, double c) {
    double discriminant = b * b - 4 * a * c;
    if (discriminant < 0) {
        System.out.println("There are no real roots ");
    } else {
        double discriminantRoot = Math.sqrt(discriminant);
        double root1 = (-b + discriminantRoot) / (2 * a);
        double root2 = (-b - discriminantRoot) / (2 * a);
        System.out.println("The roots are " + root1 + " and " + root2);
    }
}

Уроки для изучения:

  • Когда вы хотите продемонстрировать проблему, это помогает сохранить ее минимальной; использование жестко закодированных значений - хороший способ сделать это.
  • Соблюдайте порядок операций - в этом случае вы пытались судить о чем-то, используя неправильное значение, потому что вы слишком рано использовали квадратный корень
  • Будьте осторожны с условиями и независимо от того, получаете ли вы их в правильном направлении

РЕДАКТОР. Как отмечено в комментариях, также есть несколько особых случаев, в том числе, когда a равно 0, что в противном случае привело бы к делению на 0.

  • 0
    Я бы порекомендовал проверить условия вроде a = 0; один корень равен нулю, а другой - -c / b. Легко сделать, и оба реальны. Есть более вырожденные случаи, чтобы искать, чем просто нулевой определитель.
  • 0
    @duffymo: добавлена заметка, спасибо.
1

Вы получаете это, когда ваш дискриминант отрицательный. Как и для a = 1, b = 2, c = 3. Delta = 2 * 2 -4 * 1 * 3 = 4 - 12 = -8

Java не может вычислить квадратный корень отрицательного числа, он не знает о мнимом числе i.

1

Do

double discriminant = b * b - 4 * a * c; 
if (discriminant >= 0) {
    discriminant = Math.sqrt(discriminant);  
    root1 = (-b + discriminant) / (2 * a);          
    root2 = (-b - discriminant) / (2 * a);          
    System.out.println("The roots are " + root1 + " and " + root2);      
} 
else {
    System.out.println("There are no real roots ");  
} 

Ещё вопросы

Сообщество Overcoder
Наверх
Меню