Повторная настройка уравнения с плавающей точкой - PullRequest
3 голосов
/ 27 мая 2009

Хотелось бы узнать, есть ли способ повысить точность вычисления уклона. (Это возникло несколько месяцев назад здесь ).

Кажется, изменив:

float get_slope(float dXa, float dXb, float dYa, float dYb) {
    return (dXa - dXb)/(dYa - dYb);
}

до

float get_slope(float dXa, float dXb, float dYa, float dYb) {
    return  dXa/(dYa - dYb) - dXb/(dYa - dYb);
}

может быть улучшением. Предложения?

Редактировать: Мне нужна точность, а не эффективность.

Ответы [ 3 ]

5 голосов
/ 27 мая 2009

Приведите их к double внутри функции.


Когда вы столкнетесь с проблемами, очевидно, что знаменатель близок к нулю, очевидно. Ваш склон будет приближаться к бесконечности. Так что многое зависит от того, что вы хотите сделать на склоне. Иногда, если вы знаете, что ваша дельта y будет близка к нулю, вы можете вычислить обратную величину наклона и использовать ее вместо этого. Вы даже можете определить, какое из них меньше - абсолютное значение deltax или deltay и вернуть наклон или 1 / наклон. Также посмотрите на atan2 ().


Если вы знаете, что ввод в десятичном виде, и вы хотите, чтобы вывод также был десятичным, вы можете преодолеть потерю точности, присущую преобразованию чисел с плавающей запятой в двоичную и обратно, выполнив все вычисления с использованием десятичной библиотеки. Я помню, как мне было приятно, когда я использовал Atari BASIC для десятичных вычислений, поскольку он использовал режим BCD 6502.

1 голос
/ 27 мая 2009

Если вы не возражаете сжечь некоторые дополнительные циклы, вы можете получить большую точность, выполнив цикл.

Рассчитать наклон отрезка между A и B.

Вычислить наклон отрезка между {(Xa - (Xa -Xb)), (Ya - (Ya -Yb)} и {(Xb + (Xa-Xb)), (Yb + (Ya - Yb) )} ... В основном A - наклон и B + наклон.

Затем сравните полученные уклоны. Если разница слишком велика (выберите желаемый порог), продолжайте движение и в конце усредните все склоны.

Это может помочь сгладить аномалии, вызванные арифметикой с плавающей запятой, для очень маленьких склонов.

1 голос
/ 27 мая 2009

Я думаю, что у вас есть опечатка. Вы, наверное, имеете в виду

return  dXa/(dYa - dYb) - dXb/(dYa - dYb);

Я бы сказал, что первая форма, которую вы дали, имеет более высокую точность. Если dXa и dXb близки и велики, то перед вычитанием вы потеряете точность в двух делениях.

...