Как устранить ошибки «не удается найти символ»? - PullRequest
1 голос
/ 28 сентября 2019

Я пытаюсь решить сложное математическое выражение, используя Java на Netbeans, однако у меня есть две проблемы: «не могу найти символ (переменную)», и результат, который я получаю, всегда равен «NaN».

Но когда я попробовал 'double x = 0;'вместо 'двойной х;'мой код работает, но я всегда получаю ответ «NaN».Я также попытался инициализировать переменную при сканировании 'double x = scan.nextDouble ();'но это тоже не работает.

Затем я понял, что большая часть кода, который я печатаю, который включает в себя сложную математику, должна иметь '= 0;'для переменных, которые будут найдены компилятором.

Итак, мой реальный вопрос: в чем разница между «double x = 0»?и «двойной х;»Почему первое работает в математических выражениях, а второе не может быть обнаружено компилятором?

Ненужная информация ниже

    //The code I made for my homework
    double ans, num, den, x, y;
    //double x = 0;
    //double y = 0;

    //variable x and y might not have been initialized
    num = Math.cbrt( ((2 * Math.pow(x,4) * y) + (2 * x * Math.pow(y,4) )) );
    den = (4 * x * Math.pow(y, ((2 * x) + (2 * y))));   

    ans = num / den;

    System.out.print("x: ");
    x = scan.nextDouble();
    System.out.print("y: ");
    y  = scan.nextDouble();
    System.out.println("\n The answer is " + ans); 

У меня есть математическое выражение ((\ root (3) ((2x ^ (4) y + 2xy)^ (4))))) / (4xy ^ (2x + 2y))

Я ожидаю вывод

x: 2 y: 3

Ответ0.096157 ...

Вместо этого я получаю результат «переменные x и y, возможно, не были инициализированы», а в другом сценарии я получаю результат «Ответ - NaN».Я думаю, смогу ли я использовать переменные для каждого термина, чтобы решить его.

РЕДАКТИРОВАТЬ: Я УСПЕШНО СДЕЛАН ДЕЛЕНИЕМ ДВОЙ, удалив 'double x = 0;'Я исключил возможность «NaN».Вместо этого я объявляю и присваиваю значения переменным одновременно.

    System.out.print("x: ");
    double x = scan.nextDouble();
    System.out.print("y: ");
    double y  = scan.nextDouble();


    //preparation
    //double term1, term2, term3, term4, term5, term6, exp; //x, y;
    //double x = 0;
    //double y = 0;

    //variable x and y might not have been initialized
   //double term1 = (Math.cbrt(2 * Math.pow(x,4) * y));
   //double term2 = (Math.cbrt(2 * x * Math.pow(y,4)));
   //double term3 = (4 * x);
   //double term4 = (2 * x); 
   //double term5 = (2 * y);
  // double exp = term4 + term5;
   //double term6 = (Math.pow(y,exp)); 
   //double num = (Math.cbrt((2 * Math.pow(x,4) * y) + (2 * x * Math.pow(y, 4))));
   //double den = term3 * term6; 
   double num = (2 * Math.pow(x,4) * y) + (2 * x * Math.pow(y,4) );
   double den = (4 * x * Math.pow(y, ((2 * x) + (2 * y))));


   double ans = Math.cbrt(num / den);

   System.out.println("\n The answer is " + ans);

Ответы [ 3 ]

1 голос
/ 28 сентября 2019

Локальным переменным должно быть присвоено значение перед тем, как на них будут ссылаться.Поскольку ваш код выполняется сверху вниз, вычисления будут выполнены до того, как x и y будут инициализированы для пользовательских значений ввода.Вот почему в ваших вычислениях говорится, что «переменная не может быть инициализирована».

Ваше заблуждение может заключаться в том, что эти строки определяют некое «отношение» между x, y, num, den:

num = Math.cbrt( ((2 * Math.pow(x,4) * y) + (2 * x * Math.pow(y,4) )) );
den = (4 * x * Math.pow(y, ((2 * x) + (2 * y))));

ans = num / den;

Но на самом деле это не так.Они просто делают вычисления и устанавливают переменную с левой стороны на результат.Однако на данный момент значения x и y еще не известны, поскольку строки x = ... и y = ... еще не запущены.

Что если вы добавите double x = 0и double y = 0 наверху?Это решает ошибку компилятора.Теперь можно выполнить расчет, но он будет использовать x = 0 и y = 0.Это вся информация, которую он получил в тот момент, так как строки, где вы получаете пользовательский ввод, еще не были запущены.

Что вам нужно сделать, это переместить строки, которые читают пользовательский ввод, перед вычислениями:

System.out.print("x: ");
x = scan.nextDouble();
System.out.print("y: ");
y  = scan.nextDouble();

num = Math.cbrt( ((2 * Math.pow(x,4) * y) + (2 * x * Math.pow(y,4) )) );
den = (4 * x * Math.pow(y, ((2 * x) + (2 * y))));

ans = num / den;
System.out.println("\n The answer is " + ans);

Кроме того, чтобы получить ожидаемый результат 0.096157 ..., вам нужен корень куба для применения ко всей дроби, а не только к числителю:

num = (2 * Math.pow(x,4) * y) + (2 * x * Math.pow(y,4) );
den = (4 * x * Math.pow(y, ((2 * x) + (2 * y))));

ans = Math.cbrt(num / den);
1 голос
/ 28 сентября 2019

Итак, мой реальный вопрос: в чем разница между double x = 0; и double x;

Первый из них объявляет x и дает ему начальное значение.

Последний объявляет x и не дает ему начальное значение.Вы можете дать x значение позже, но вы должны сделать это для всех путей, которые ведут к любому использованию переменной.Например:

double x;
if (Math.pow(2, 2) >= 0.0) {
    x = 0.0;
} else {
    x = 1.0;
}
System.out.println(x);   // OK

против

double x;
if (Math.pow(2, 2) >= 0.0) {
    x = 0.0;
}
System.out.println(x);   // ERROR

Последнее является ошибкой компиляции, поскольку существует возможный путь через код, где можно использовать x до его инициализации.

Теперь любой, кто обладает знаниями по математике в старшей школе, может сказать вам, что квадрат целого числа всегда будет больше или равен нулю, и поэтому ветвь else никогда не будет выбрана.Однако компилятор Java этого не знает и выдаст вам ошибку компиляции.(Действительно, не разрешено не давать вам ошибку компиляции. Я не буду вдаваться в подробности: они есть в JLS, если вам не безразлично.)


Почему первый работает в математических выражениях, но последний не может быть обнаружен компилятором?

Теперь это интересный вопрос.

Ответ в том, что = имеет принципиально иное значение в языках программирования и математических уравнениях.

В языке программирования, таком как Java, a = b; означает «присвоить (установить) текущее значение a текущему значению b».

В математическом уравнении a = b означает «для всех мест, где используются эти a и b переменные, значение a равно значению b.».Это в основном ограничение на возможные значения a и b.

Еще один способ думать об этом состоит в том, что в математике переменная в уравнении представляет собой набор возможных значений.Уравнение ограничивает множество значений;например, a = sqrt(4) равносильно тому, что a обозначает {x | x * x == 4}, что совпадает с множеством {-2, +2}.

Теперь у математики есть случаи, когда запись ошибочна.Например, a = a + 1 эквивалентно тому, что a обозначает {x | x == x + 1} ..., что является пустым набором.

(примечание, которое я использовал выше, не то, чтоклассические математики и формальные методы, которые обычно используют люди. К сожалению, это довольно сложно объяснить, если вы не взяли некоторые предметы / единицы математики университетского уровня. Или единицы формальных методов в курсе компьютерных наук.)


Наконец, вот такие общие вопросы и ответы, которые касаются других ваших ошибок компиляции и времени выполнения:

0 голосов
/ 28 сентября 2019

Локальным переменным, включая примитивы, не назначены значения по умолчанию, и их необходимо инициализировать явно.Вы должны установить начальные значения для x и y, иначе компилятор протестует.

Почему локальные переменные, включая примитивы, всегда должны инициализироваться в Java?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...