Soy nuevo en Java y he estado tratando de implementar un algoritmo para encontrar las raíces de una ecuación cúbica. El problema surge cuando calculo el discriminante e intento verificar dónde cae en relación con cero.Comparando un doble contra cero
Si lo ejecuta e introducir los números "1 8 -5 -4", la salida es el siguiente:
1 -5 8 -4
p=-0.333333, q=0.074074
disc1=0.001372, disc2=-0.001372
discriminant=0.000000000000000
Discriminant is greater than zero.
Sé que el problema surge debido a los cálculos con los dobles no son precisos. Normalmente el discriminante debe ser 0, pero termina siendo algo así como 0.000000000000000.
Mi pregunta es, ¿cuál es la mejor manera de evitar esto? ¿Debo verificar si el número cae entre un barrio épsilon de cero? ¿O hay una forma mejor y más precisa?
Gracias de antemano por sus respuestas.
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.");
}
}
}
@hattenn: Para el OP, la segunda sugerencia de Peter es el camino a seguir. –
¿Qué valor es mejor para ERROR? –
@LunaKong el error depende del contexto. Podría ser 1e-12 hasta 1e-3 o podría necesitar ser otra cosa. –