Я новичок в Java и пытаюсь реализовать алгоритм для нахождения корней кубического уравнения. Проблема возникает, когда я вычисляю дискриминант и пытаюсь проверить, где он падает относительно нуля.
Если вы запустите его и введете цифры "1 -5 8 -4", вы получите следующий вывод:
1 -5 8 -4
p=-0.333333, q=0.074074
disc1=0.001372, disc2=-0.001372
discriminant=0.00000000000000001236
Discriminant is greater than zero.
Я знаю, что проблема возникает из-за того, что вычисления с двойными числами не точны. Обычно дискриминант должен быть равен 0, но в конечном итоге он будет выглядеть примерно как 0,00000000000000001236.
Мой вопрос: каков наилучший способ избежать этого? Должен ли я проверить, находится ли число между эпсилонами окрестности нуля? Или есть лучший и более точный способ?
Заранее благодарю за ответы.
import java.util.Scanner;
class Cubical {
public static void main(String[] args) {
// Declare the variables.
double a, b, c, d, p, q, gamma, discriminant;
Scanner userInput = new Scanner(System.in);
a = userInput.nextDouble();
b = userInput.nextDouble();
c = userInput.nextDouble();
d = userInput.nextDouble();
// Calculate p and q.
p = (3*a*c - b*b) / (3*a*a);
q = (2*b*b*b) / (27*a*a*a) - (b*c) / (3*a*a) + d/a;
// Calculate the discriminant.
discriminant = (q/2)*(q/2) + (p/3)*(p/3)*(p/3);
// Just to see the values.
System.out.printf("p=%f, q=%f\ndisc1=%f, disc2=%f\ndiscriminant=%.20f\n", p, q, (q/2)*(q/2), (p/3)*(p/3)*(p/3), (q/2)*(q/2) + (p/3)*(p/3)*(p/3));
if (discriminant > 0) {
System.out.println("Discriminant is greater than zero.");
}
if (discriminant == 0) {
System.out.println("Discriminant is equal to zero.");
}
if (discriminant < 0) {
System.out.println("Discriminant is less than zero.");
}
}
}