Странное поведение программы на C++ ⇐ C++
-
Anonymous
Странное поведение программы на C++
При обратном вызове функции наблюдается странное поведение. Я хочу вычислить корень функции методом биссектрисы. Система, которую нужно решить, включает в себя интеграцию функции, верхний предел которой является функцией другой функции, что не имеет большого значения. Когда я указываю числовое значение, программа завершается хорошо, но если я делаю обратный вызов функции, терминал завершает процесс, и программа работает медленнее. Кстати, это один из моих первых кодов на C++.
Следующий блок кода;
#include #include #include #include структура Ninj_Params{ двойной р; двойной Q0; двойной гамма_м; }; двойной с = 1; двойной эВ = 1,0; двойной МэВ = pow(10,6) * эВ; двойное ме = 0,510998902 * МэВ; двойной е = 8,542 * pow(10,-2); двойной Фм = 1/197,3269602 * 1/МэВ; двойной см = pow(10,13) * fm; двойной Гаусс = 5,788381749 * pow(10,-15) * МэВ * 2 * me/e; двойной метр = pow(10,2) * см; двойная секунда = 299792458*метр; // Функция для поиска корня методом деления пополам двойное сечение пополам (const std::function &func, double a, double b, двойной допуск){ если (func(a) * func(b) >= 0){ printf("Метод деления пополам не может гарантировать сходимость в этом интервале.\n"); вернуть НАН; // Не число, указывающее на ошибку } двойной с = а; while ((b - a) >= допуск) { // Находим среднюю точку в = (а + б)/2; // Проверяем, найден ли корень если (функ(с) == 0,0) перерыв; // Обновляем интервал по знаку функции в средней точке если (func(c) * func(a) < 0) б = с; еще а = с; } вернуть с; } двойная бета (двойная гамма) { return sqrt(1. - pow(Гамма, -2.)); } двойной R (двойной т, двойной Rs, двойной Гамма) { возврат (Rs + бета(Гамма)*c*Гамма*t)*1./см; } двойной B (двойной t, двойной Rs, двойной R0, двойной Гамма, двойной B0, двойной a){ return B0*pow((R(t, Rs, Gamma)*cm)/R0, -a)*1./Gauss; } двойной Q(двойные гаммы, void * args){ Ninj_Params& params = *(Ninj_Params*)args; if(params.gamma_m double{ return Ninj_Gest - Ninj(Q0*1/sec, p, 1e5, gamma_max); }; двойной корень = деление пополам (root2solve, 1e40*1./сек, 1e53*1./сек, 1e-7); вернуть корень*сек; } void TEST_ROOT(двойной t, двойной Rs, двойной R0, двойной Gamma, двойной gamma_m, двойной B0, двойной a){ двойной Nj = 1e47*1/сек; printf("%.5e\n",Q0rate(Nj, t, Rs, R0, Гамма, B0, a)); } интервал основной(){ двойной т = 10*сек; двойной рупий = 1е14*см; двойной R0 = 1e15*см; двойной B0 = 0,3*1e2*Гаусс; двойная Гамма = 300; двойная гамма_м = 1e5; двойное а = 1,0; TEST_ROOT(t, Rs, R0, Гамма, гамма_m, B0, а); } Строка, о которой идет речь, — это 105 (и закомментированная 106). Когда установлено как:
double gamma_max = 1e8*pow(B(t, Rs, R0, Gamma, B0, a), -0,5); вывод (с медленным поведением):
**** 7.957e+06 zsh: убит ./Main
и если изменить на:
double gamma_max = 7.957e+06; программа завершается успешно с ожидаемым значением корня:
% ./Основная **** 7.957e+06 1.50212e+42
При обратном вызове функции наблюдается странное поведение. Я хочу вычислить корень функции методом биссектрисы. Система, которую нужно решить, включает в себя интеграцию функции, верхний предел которой является функцией другой функции, что не имеет большого значения. Когда я указываю числовое значение, программа завершается хорошо, но если я делаю обратный вызов функции, терминал завершает процесс, и программа работает медленнее. Кстати, это один из моих первых кодов на C++.
Следующий блок кода;
#include #include #include #include структура Ninj_Params{ двойной р; двойной Q0; двойной гамма_м; }; двойной с = 1; двойной эВ = 1,0; двойной МэВ = pow(10,6) * эВ; двойное ме = 0,510998902 * МэВ; двойной е = 8,542 * pow(10,-2); двойной Фм = 1/197,3269602 * 1/МэВ; двойной см = pow(10,13) * fm; двойной Гаусс = 5,788381749 * pow(10,-15) * МэВ * 2 * me/e; двойной метр = pow(10,2) * см; двойная секунда = 299792458*метр; // Функция для поиска корня методом деления пополам двойное сечение пополам (const std::function &func, double a, double b, двойной допуск){ если (func(a) * func(b) >= 0){ printf("Метод деления пополам не может гарантировать сходимость в этом интервале.\n"); вернуть НАН; // Не число, указывающее на ошибку } двойной с = а; while ((b - a) >= допуск) { // Находим среднюю точку в = (а + б)/2; // Проверяем, найден ли корень если (функ(с) == 0,0) перерыв; // Обновляем интервал по знаку функции в средней точке если (func(c) * func(a) < 0) б = с; еще а = с; } вернуть с; } двойная бета (двойная гамма) { return sqrt(1. - pow(Гамма, -2.)); } двойной R (двойной т, двойной Rs, двойной Гамма) { возврат (Rs + бета(Гамма)*c*Гамма*t)*1./см; } двойной B (двойной t, двойной Rs, двойной R0, двойной Гамма, двойной B0, двойной a){ return B0*pow((R(t, Rs, Gamma)*cm)/R0, -a)*1./Gauss; } двойной Q(двойные гаммы, void * args){ Ninj_Params& params = *(Ninj_Params*)args; if(params.gamma_m double{ return Ninj_Gest - Ninj(Q0*1/sec, p, 1e5, gamma_max); }; двойной корень = деление пополам (root2solve, 1e40*1./сек, 1e53*1./сек, 1e-7); вернуть корень*сек; } void TEST_ROOT(двойной t, двойной Rs, двойной R0, двойной Gamma, двойной gamma_m, двойной B0, двойной a){ двойной Nj = 1e47*1/сек; printf("%.5e\n",Q0rate(Nj, t, Rs, R0, Гамма, B0, a)); } интервал основной(){ двойной т = 10*сек; двойной рупий = 1е14*см; двойной R0 = 1e15*см; двойной B0 = 0,3*1e2*Гаусс; двойная Гамма = 300; двойная гамма_м = 1e5; двойное а = 1,0; TEST_ROOT(t, Rs, R0, Гамма, гамма_m, B0, а); } Строка, о которой идет речь, — это 105 (и закомментированная 106). Когда установлено как:
double gamma_max = 1e8*pow(B(t, Rs, R0, Gamma, B0, a), -0,5); вывод (с медленным поведением):
**** 7.957e+06 zsh: убит ./Main
и если изменить на:
double gamma_max = 7.957e+06; программа завершается успешно с ожидаемым значением корня:
% ./Основная **** 7.957e+06 1.50212e+42
Мобильная версия