Другие языки программирования и технологии

Почему при вводе маленьких значений коэффициентов программа на c++ не работает

Если ввожу
a = 0.0004
b = 0.0012
c = 0.0009
То программа пишет что нет корней, хотя на самом деле имеется один корень
А какой тип у твоих переменных?
Ilyos Shokirbayev
Ilyos Shokirbayev
11 157
Лучший ответ
Значит что-то не так в расчёте дискриминанта

D = b^2 - 4ac = (0.0012)^2 - 4·0.0004*0.0009 = 0.00000144 - 0.00000144 = 0
ТС
Тимур Сираев
80 178
Потому же, почему и неверно 0.1 + 0.2 == 0.3 (проверьте, это по-началу кажется забавным, ведь очевидно, что математически верно).

Это потеря точности в вещественных числах компьютера.
В примере с вашими коэффициентами дискриминант получается равным -2.1176e-22 (если использовать тип double), что не равно нулю, хотя и очень близко.
Проверьте свою программу отладкой: выведите значение дискриминанта, убедитесь, что он не 0.

Такая потеря точности подводит к правилу сравнения вещественных чисел с заданной точностью.
Например, если заданны 2 вещественные переменные (double a, b;) и нужно их сравнить, вместо if(a == b) корректнее написать if(fabs(a - b) < 0.000000001). Так же это маленькое число, компенсирующее погрешность можно записать коротко: 1e-9 (т. е. -1 * 10^-9). В зависимости от необходимой точности в задаче это значение может меняться. Так же, в коде оставлять «магические константы» плохо, поэтому в C делают #define EPS (1e-9), а в C++ – const double eps = 1e-9.
Само сравнение можно выделить в функцию-компаратор для улучшения читабельности кода. Компаратор возвращает значение целое значение: 0, когда a равно b; значение меньше нуля (-1), когда a < b и значение больше нуля (1), когда a > b. Вот пример такой функции:
const double eps = 1e-9;
inline int fcompare(double a, double b)
{
if(fabs(a - b) < eps) return 0;
else return a < b ? -1 : 1;
}

С такими поправками код сработает:
https://pastebin.com/xHp6AxTL
Дмитрий Каменев У проблемы, оказалось, даже сайт есть:
http://0.30000000000000004.com/

По этой ссылке можно посмотреть и другие решения:
https://ru.stackoverflow.com/questions/399420/Безопасно-ли-сравнение-для-типа-double
Ilyos Shokirbayev Мой ответ не должен был стать лучшим, когда есть этот, но именно из-за такой несправедливости я и прекратила тут отвечать. Очень сочувствую.