Задание из Яндекс контест на квадратное уравнение

177
01 октября 2018, 15:30

Проверка ЯндексКонтест выдает ошибку при 3 проверке программы, самостоятельно ошибку найти не могу.Вот условие:

Формат ввода Входной файл содержит три целых числа a, b и c, не превосходящих по модулю 10^9, — коэффициенты уравнения ax2 + bx + c = 0.

Формат вывода В первой строке вывода требуется указать число различных решений этого уравнения. Далее выведите корни уравнения с точностью до 6 знаков после запятой, по одному в строке. Корни должны следовать в порядке возрастания.

Если корней бесконечно много, выведите ровно одно число, -1.

Вот код:

using namespace std; 
int main () { 
double a,b,c,d,x1,x2;
 cin>>a>>b>>c; 
    if((c==0 && b==0 && a==0)) cout<<-1; 
    else if((b==0 && c==0)||(a==0 && c==0)) cout<<1<<"\n"<<0;
    else { 
  d=b*b-4*a*c; 
  b=-b; 
 a=a*2; 
if(d==0) cout<<1<<"\n"<<b/a; 
else if(d<0) cout<<0; 
 else if(d>0){ 
 cout<<2<<"\n"; 
 x1=(b+sqrt(d))/a; 
x2=(b-sqrt(d))/a; 
 if(x1<x2) {cout<<setprecision(7)<<x1<<"\n"<<setprecision(7)<<x2;} 
else {cout<<setprecision(7)<<x2<<"\n"<<setprecision(7)<<x1;} } 
return 0; 
 }}
Answer 1

Я не знаю, содержат ли тестовые данные такие входы, на которых будет проявляться явление "catastrophic cancellation", приводящее к катастрофической потере точности в арифметике с плавающей точкой, но тем не менее:

В ситуации, когда корней два, более правильной техникой нахождения этих корней в арифметике с плавающей точностью будет

double d = b * b - 4 * a * c; 
double q = b >= 0 ? (-b - sqrt(d)) / 2  : (-b + sqrt(d)) / 2; 
double x1 = q / a;
double x2 = c / q;

Такой вариант намного более устойчив к catastrophic cancellation (https://ru.stackoverflow.com/a/493642/182825)

Например, на входных данных

a = 1, b = -1000000000, c = 1

(что находится в пределах диапазона задания) мой вариант дает решение

x1 = 1000000000, x2 = 1.0000000000000000623e-09

а ваш вариант дает

x1 = 1000000000, x2 = 0

Как видите, погрешность на x2 в вашем случае существенно выше, хотя и в пределах требуемой точности.

Также у вас, вроде бы, не рассмотрен случай a = 0, b = 0, c != 0.

Answer 2
  1. 0*x2 + 0*x + 7 = 0
  2. Дробные числа не стоит сравнивать на равенство.
    Безопасно ли сравнение == для типа double?
READ ALSO
Работа с БД MS Access в С++ [закрыт]

Работа с БД MS Access в С++ [закрыт]

Нужен совет каким образом сохранить список людей в БДК примеру если использовать MS Access, что необходимо сделать для доступа к БД из C++ VS17? Какая...

182
Получить адрес функции

Получить адрес функции

Пробовал получать адрес функции по-разному:

146
Подключение библиотеки в qt creator

Подключение библиотеки в qt creator

На ubuntu установлена библиотека GStreamerХочу подключить ее к своему проекту в Qt Creator но не знаю как, библиотека была загружена через консоль

160
Convert time to int

Convert time to int

Как преобразовать дату/время в количество секунд чтобы хранить в int32?

199