2014-12-11 6 views
5

Я хочу рассчитать объем сферы с помощью программы Java. Итак, я использовалjava 2 различные проблемы с формулой

double result = 4/3*Math.PI*Math.pow(r,3); 

Эта формула дает неправильные ответы.

программа Как Java выбрать 4/3, но если я изменить его на

double result= Math.PI*Math.pow(r,3)*4/3; 

это дает мне правильный ответ. Кто-нибудь знает что происходит?

+0

1. форматирование, 2.целочисленное деление (4/3) и 3. порядок работы в java. Убедитесь, что эти три вещи проверены. –

+2

Я просто исправил ваш формат и большую часть фразы. В следующий раз, пожалуйста, найдите время, чтобы сделать ваш вопрос презентабельным и читаемым. Используйте знаки пунктуации, символы верхнего регистра, где необходимо, и используйте теги кода, чтобы они были правильно подсвечены. – brimborium

ответ

3

Разница в результатах обусловлена ​​приоритетом оператора. В Java умножение и деление имеют одинаковый приоритет и поэтому оцениваются слева направо.

Итак, ваш первый пример эквивалентен

double result = (4/3)*Math.PI*Math.pow(r,3); 

Здесь, 4/3 является деление двух целых чисел, и в Java, в таких случаях выполняется целочисленное деление, с результатом 1. Для того, чтобы решить эту проблему , вы должны явно убедиться, что один или оба из операндов является двойной:

double result = (4.0/3.0)*Math.PI*Math.pow(r,3); 

Ваш второй пример, однако, эквивалентно

double result = (Math.PI*Math.pow(r,3)*4)/3; 

Здесь часть Math.PI*Math.pow(r,3)*4 оценивается как двойная, и поэтому у нас больше нет целочисленного деления, и вы получаете правильный результат.

+0

Это наиболее сложный ответ. -> +1 – brimborium

5

Это связано с порядком, в котором кастинг происходит на Java (или C, если на то пошло).

Подробная информация о приоритете оператора приведена в http://introcs.cs.princeton.edu/java/11precedence/.

В первом случае, поскольку операторы умножения и деления вычисляются слева направо, первая операция java интерпретирует 4/3. Поскольку оба операнда являются целыми, java вычисляет целочисленное деление, результат которого равен 1.

В вашем втором случае первой операцией является двойное умножение: (Math.PI Math.pow (r, 3)). , Вторая операция умножает двойную (Math.PI Math.pow (r, 3)) на целое число (4). Это выполняется путем литья 4 в двойное и двойное умножение. Наконец, java должен разделить двойной (Math.PI * Math.pow (r, 3) * 4) на целое число (3), которое java выполняет как двойное деление после литья 3 в double. Это дает вам результат, которого вы ожидаете.

Если вы хотите, чтобы исправить свой первый ответ, литая 3 удвоится первым:

4/ (double)3 

и вы получите результат, который вы ожидаете.

+1

Есть ли преимущество '(double) 3' вместо' 3.0'? – brimborium

+1

Нет, что я знаю с программной точки зрения. Но я склонен использовать явное (двойное) обозначение каста, потому что не раз я был сожжен, забыв «.». при изменении значения константы позже. Например. Сначала у меня есть фрагмент кода с чем-то вроде double x = 3.14/2; и позже мне нужно изменить свою формулу, скажем, на двойной x = 3.0/2; но я могу случайно написать double x = 3/2; особенно с длинной формулой. Если (двойной) есть, он остается там, чтобы обеспечить литье независимо от того, что это за значение. Это гарантия, которую мне нравится. – Lolo

+0

Обычно я всегда использую '.', поэтому я бы делал' x = 3.14/2.0' в первую очередь. И я думаю, что это более читаемо, чем прямое изложение. – brimborium

2

4/3 является разделение между двумя int, так что Java предполагает, что результат является также int (в данном случае, это приводит к значению 1). Измените его на 4.0/3.0, и с вами все будет в порядке, потому что 4.0 и 3.0 интерпретируются как double Java.

double result = 4.0/3.0 * Math.PI * Math.pow(r,3); 
Смежные вопросы