отличие библиотек <math.h> и <cmath> и вопросы точности

163
24 октября 2018, 11:50

вопрос 1:

Подскажите, отличаются ли C++ библиотеки <math.h> и <cmath> чем-то принципиально (кроме новых функций)?

вопрос 2:

Иногда возникают задачи вычисления над близкими значениями, например exp(-(log(x) - a)*(log(x) - a)), в результате даже long double перестаёт помогать и приходится вводить какие-то масштабирующие коэффициенты, чтобы повысить точность, что не очень хорошо.

Может дело в том, что функции exp, log программно-написанные, а не из ALU? Как вообще люди решают такие проблемы?

Answer 1

<cmath> - это по большому счету <math.h>, только завернутая в пространство имен std. Или <math.h> - вытащенные из std функции <cmath>...

Проблемы с точностью вычислений связаны с ограниченной точностью представлений чисел с плавающей точкой. Библиотечные функции использовали свои "программно-написанные" функции разве что во времена 80386, когда еще было математический сопроцессор - было удовольствие не на каждой машине. Дело не в этом, а в том, что как ни старайтесь, но законы математики не перепрыгнуть, и действительно надо прибегать к математическим преобразованиям для таких вычислений - вплоть до того, что часто изменение последовательности суммирований существенно меняет результат.

Кстати, некоторые компиляторы при long double все равно используют обычный double - например, Visual C++. Проверьте, что там у вас...

Answer 2

Для длинной арифметики классика жанра это GMP. Но вообще-то так, чтобы было мало long double это должна быть ОЧЕНЬ специфическая задача. Особенно теперь, когда платформа x86 стала 64-х разрядной.

READ ALSO
Как в QT5 в QTableWidget из делегата изменить значение в ячейке из другой колонки?

Как в QT5 в QTableWidget из делегата изменить значение в ячейке из другой колонки?

Задача следующая: ComboBoxDelegate задает точность и шаг приращения в другой колонке той же строки, но с DoubleSpinBoxDelegateПроблема в том, что если изменить...

162
Вызов перегруженной функции - Segmentation fault

Вызов перегруженной функции - Segmentation fault

При вызове Func() заполняется buffer данными из сокета, после происходит их конвертация в класс DerivedЕсли после конвертаци вызвать функию Foo(), то происходит...

153