Моя дубинка или дубинка
Привет,
GeoGrebra, C++ и C# все согласны с тем, каким должен быть cosh(16.612). Но когда я использую функцию, которую я написал сам, которая использует алгоритм для вычисления гиперболического Косинуса, я получаю (очень немного) другой результат. Я попытался настроить обработку с плавающей запятой Visual Studio на точную, строгую и быструю, но безрезультатно.
Что же это за проблема?
Это то, о чем все остальные согласны:
cosh(16.612000) = 8193509.0494933873414993
Это мой первый подход:
_cosh(16.612000) = 8193509.0494933854788542
И мой второй:
ecosh(16.612000) = 8193509.0494933798909187
Последний использует cosh(x) = 0.5(e^x + e^(-x))
Вот мой код:
#include <cstdio> #include <iostream> #include <string> long double e = 2.718281828459045090795598298427648842334747314453125L; long double ecosh(long double x) { //return 0.5 * (exp(x) + exp(-x)); return 0.5L * (pow(e, x) + pow(e, -x)); } using namespace std; using decimal = double; constexpr bool b(int i) { return i > 0; } static_assert(b(7), "hej"); auto f = [=](double x) { return sqrt(x*x*x); }; long double fac(long double x) { if ((int)x > 1) return x * fac(x - 1); return 1; } //25/2 + 25/4 - 25/2/2*1.5 + 25/2/2/2*1.5 decimal _sqrt(decimal x, int iterations = 15) { decimal y = x - x / 2 + x / 4; for (int i = 1; i < 49; i++) { y += x / pow(2, i) * 1.5 * pow(-1, i); } return y+0.0000000001; } long double _cosh2(double x) { long double y = 0; for (int i = 1; i < 70; i++) { y += pow(x, (double)(2.0*i)) / fac(2.0*i); } return y+1; } long double _sinh2(double x) { long double y = x; for (int i = 1; i < 70; i++) { y += pow(x, (double)(2.0*i+1)) / fac(2.0*i+1); } return y + 0; } int main(int argc, char** argv) { double r = 4.0; printf("sqrt(%f) = %.25f\n\n", r, _sqrt(r)); printf("sqrt(%f) = %.25f\n\n", r, sqrt(r)); double d = 16.612; printf("_cosh(%f) = %.16f\n cosh(%f) = %.16f\n", d, _cosh2(d), d, cosh(d)); printf("ecosh(%f) = %.16lf\n", d, ecosh(d)); printf("--------------------------------------\n"); printf("e() = %.75lf\ne = %.75f\n", exp(1.0L), e); printf(" %.50f\n", _sinh2(6.125)); printf(" %.50f\n", sinh(6.125)); getchar(); }
Что я уже пробовал:
Я попытался перенастроить Visual Studio 2017.
nv3
Сколько цифр точности вы ожидаете при вычислении типа double?
Dave Kreskowiak
Это не имеет никакого отношения к каким-либо настройкам в Visual Studio. Это все зависит от вашего кода.
Нет, я понятия не имею, что это будет.
[no name]
Вопрос в том, почему вы получаете другой результат, чем другие? Помимо чисто тривиальных ошибок, это тонкий вопрос. Написание математической библиотеки-очень сложная задача, и до сих пор вы смотрели на нее очень поверхностно. Вы ничего не знаете о том, как другие методы вычисляют это внутренне или насколько они сами близки к "правильному" результату. В частности, вы сами, кажется, не провели тщательного анализа. Например, что такое pow ()? Я бы добавил, что результат, который вы получите, будет казаться совершенно адекватным для подтверждения работы алгоритма.
YvesDaoust
Зачем волноваться ? Ваша ценность точна до пятнадцати значимых цифр, максимум, который обеспечивает двойная точность.