IEEE с плавающей точкой
Большинство языков будут обрабатывать ваш конкретный пример без исключений или типов объединений, потому что IEEE с плавающей точкой включает представление для NaN.В Java используйте Double.NaN:
public static double quadratic(double a, double b, double c, int polarity) {
double x = b*b - 4*a*c;
// When x < 0, Math.sqrt(x) retruns NaN
if (x < 0) {
return Double.NaN;
}
return (-b + Math.sqrt(x) * polarity) / (2*a);
}
, который производит ваш точный вывод, который вы хотели:
x = 4.0
x = 3.0
x = NaN
x = NaN
Исключения
Исключения - старый способ решения Javaпохожие проблемы:
public static double quadratic(double a, double b, double c, int polarity) {
double x = b*b - 4*a*c;
// When x < 0, Math.sqrt(x) returns NaN
if (x < 0) {
throw new Exception("NaN")
}
return (-b + Math.sqrt(x) * polarity) / (2*a);
}
Вот ваш клиентский код для исключения.
a=1; b=-7; c=12;
// x = 4.0
try {
System.out.println("x = " + quadratic(a, b, c, 1));
} catch (Exception iae) {
System.out.println("Oopsie: " + iae.getMessage());
}
// x = 3.0
try {
System.out.println("x = " + quadratic(a, b, c, -1));
} catch (Exception iae) {
System.out.println("Oopsie: " + iae.getMessage());
}
// "invalid" coefficients.
a=4; b=4; c=16;
// Oopsie: NaN
try {
System.out.println("x = " + quadratic(a, b, c, 1));
} catch (Exception iae) {
System.out.println("Oopsie: " + iae.getMessage());
}
// Oopsie: NaN
try {
System.out.println("x = " + quadratic(a, b, c, -1));
} catch (Exception iae) {
System.out.println("Oopsie: " + iae.getMessage());
}
Типы объединения
Чтобы действительно передавать или возвращать несвязанные типы в или из метода,вам нужны типы Union, которые Java на самом деле не поддерживает.Но Paguro предоставляет Union Types , которые вы можете использовать в Java следующим образом (используя Or):
public static Or<Double,String> quadratic(double a, double b,
double c, int polarity) {
double x = b*b - 4*a*c;
// When x < 0, Math.sqrt(x) retruns NaN
if (x < 0) {
return Or.bad("NaN");
}
return Or.good((-b + Math.sqrt(x) * polarity) / (2*a));
}
@Test public void testQuadradic() {
double a, b, c;
a=1; b=-7; c=12;
// x = Good(4.0)
System.out.println("x = " + quadratic(a, b, c, 1));
// x = 3.0
System.out.println(
(String) quadratic(a, b, c, -1)
.match(good -> "x = " + good,
bad -> "Oopsie: " + bad));
// "invalid" coefficients.
a=4; b=4; c=16;
// x = Bad("NaN")
System.out.println("x = " + quadratic(a, b, c, 1));
// Oopsie: NaN
System.out.println(
(String) quadratic(a, b, c, -1)
.match(good -> "x = " + good,
bad -> "Oopsie: " + bad));
}
Заключение
Для вашего конкретного примера просто используйте Floating Point.Для более общего решения я считаю типы объединения более полезными, чем исключения.Вы можете использовать типы объединения в качестве аргументов для метода, который может принимать два разных входа, которые не имеют общего интерфейса или предка.Они также более дружественны к функциональному программированию.