Слайд 16
Некоторые полезные советы при работе с вещественными числами
Слайд 17
Когда имеешь дело с вещественными числами в первую
очередь нужно подумать нельзя ли от них избавиться и
перейти к целым.
Пример 1: Нам нужно сравнить два числа вида a/b, где а и b целые числа
Слайд 18
Неправильный выбор: If ((double)a/b < (double)с/d)
Правильный выбор: If (a *
d < c * b)
Исключение: Когда a * d или
c * b не помещаются в целочисленный тип
Слайд 19
Пример 2: Нам нужен цикл до sqrt(n) включительно.
Неправильный выбор:
for(int i = 0; i
for(int i = 0; i * i <= n; i++)
Слайд 20
Пример 3: Сравнить расстояния между точками a,b и c,d
int
d1 = sqr(a.x-b.x) + sqr(a.y-b.y); int d2 = sqr(c.x-d.x) +
sqr(c.y-d.y); Вместо: if (sqrt(d1) < sqrt(d2))
Лучше: if (d1 < d2)
Слайд 21
Если всё-таки приходится работать с вещественными числами, то
всегда нужно стараться уменьшить погрешность вычислений
Пример 1: b/a + c/a
+ … = (b + c + …)/a;
Слайд 22
Пример 2: У нас есть прямоугольный треугольник, мы знаем
длины его сторон a,b,c и один из углов A.
Нужно найти sin(B)
Не лучший выбор: sinb = sin(pi - A);
Можно так: sinb = b/c;
Слайд 23
Если у нас возможно равенство вещественных чисел, то
их всегда нужно сравнивать по eps abs(a - b)
eps <=> a == b
Eps должен быть меньше требуемой точности, но больше лучшей точности. Обычно выбирают eps = 1e-9;
А вообще вопрос точности при работе с вещественными типами это философский вопрос ☺
Слайд 24
При работе с бинпоиском, если нам нужно найти
число с какой-то точностью, то почти всегда лучше это
делать итерационно
Пример: Нам нужно найти корень функции с заданной точностью