Дальнейшее развитие ситуации. Одна из лабораторных в этом семестре - "Использование dll." Нужно посчитать функцию с помощью этого же ряда, но ряд запихнуть в отдельную функцию, а эту функцию - в dll. Первоочередная задача - сделать счет ряда в отдельной функции. Решил делать это в любимом родном Линуксе в любимом родном Эклипсе. (Терпеть не могу VS. >_<) Представляю это так: сделать функцию double Row_Member (double x, int n) {}. Код скажет намного лучше меня.
/*
lab4v4 - calculation of function y=(1/sin(x))^2 using Taylor row.
Copyright (C) 2009 Yaromir Shpilevskii yaromir@hotbox.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
//#define my_abs(x) (double)abs((double) x)
double fac (double n) //Функция факториала.
{
int a, b=1;
if (n==0) return 1;
for (a=1; a<=n; a++) b *=a;
return b;
}
double Row_Member (double x, double n)
{
// double n_double=static_cast<double>(n);
double Row_Member = pow(-1, n)*pow(x, 2*n+1)/fac(2*n+1);
return Row_Member;
}
/*double module (double input) //Функция модуля.
{
if (input<0) return -input;
else return input;
}*/
int main(int argc, char* argv[])
{
int mode=0;
for (int index=1; index<argc; index++) {
if ( strncmp(argv[index], "-mode", 5) == 0 ) mode = atoi(argv[index+1]);
}
if (mode==0) {
printf("Использование:\nСинтаксис:\nlab4 -mode 1 -eps [значение] -x1 [значение] -x2 [значение] -dx [значение]\nlab4 -mode 2 -eps1 [значение] -eps2 [значение] -x [значение]\nMode 1: счет в диапазоне значений x от x1 до x2 с шагом dx с фиксированной точностью eps.\nMode 2: счет с фиксированным x в диапазоне точности от eps1 до eps2 с шагом 0.1.");
return -30;
}
double eps, eps1, eps2, x, x1, x2, dx, Row=0, MyFunc, Func;
double n=0;
if (mode==1) {
if (argc!=11) {
printf ("Использование:\nСинтаксис:\nlab4 -mode 1 -eps [значение] -x1 [значение] -x2 [значение] -dx [значение]\nlab4 -mode 2 -eps1 [значение] -eps2 [значение] -x [значение]\nMode 1: счет в диапазоне значений x от x1 до x2 с шагом dx с фиксированной точностью eps.\nMode 2: счет с фиксированным x в диапазоне точности от eps1 до eps2 с шагом 0.1.");
return -31;
}
for (int index=1; index<argc; index++) {
if ( strncmp(argv[index], "-eps", 4) == 0 ) eps = atof(argv[index+1]);
}
if (eps<=0) {
printf ("Точность должна быть положительным числом. Код ошибки -10.\n");
return -10;
}
for (int index=1; index<argc; index++) {
if ( strncmp(argv[index], "-x1", 3) == 0 ) x1 = atof(argv[index+1]);
}
if (x1==0) {
printf ("Введено неверное x1. Код ошибки -11.\n");
return -11;
}
for (int index=1; index<argc; index++) {
if ( strncmp(argv[index], "-x2", 3) == 0 ) x2 = atof(argv[index+1]);
}
if (x2==0) {
printf ("Введено неверное x2. Код ошибки -12.\n");
return -12;
}
if (x1>x2) {
printf ("Начальное x должно быть меньше конечного. Код ошибки -13.\n");
return -13;
}
for (int index=1; index<argc; index++) {
if ( strncmp(argv[index], "-dx", 3) == 0 ) dx = atof(argv[index+1]);
}
if (dx<=0) {
printf ("Шаг должен быть положительным числом. Код ошибки -14.\n");
return -14;
}
printf ("________________________________________________________\n");
printf ("| X | MyFunc(x) | Function(x) | Невязка |\n");
printf ("________________________________________________________\n");
for (x=x1; x<=x2; x+=dx) { //Диапазон иксов.
while ( abs ( Row_Member(x, n+1) - Row_Member(x, n) ) > eps ) { //Пока разность n+1-ого и n-ого членов меньше заданного значения точности.
printf("\n%f\n", Row);
Row+= Row_Member(x, n); //Прибавлять к ряду n-ный член.
n+=1; //Увеличивать номер члена.
}
MyFunc = 1/Row; //Функция, вычисленная с помощью ряда.
Func = 1/sin(x); //Функция, вычисленная с помощью cmath .
printf ("| %7.3f | %12.7f | %12.7f | %12.7f |\n", x, MyFunc*MyFunc, Func*Func, sqrt ( abs ( MyFunc*MyFunc - Func*Func ) ) );
Row=0; n=0; //Обнуление переменных.
}
printf ("________________________________________________________\n");
return 0;
}
if (mode==2) {
if (argc!=9) {
printf ("Использование:\nСинтаксис:\nlab4 -mode 1 -eps [значение] -x1 [значение] -x2 [значение] -dx [значение]\nlab4 -mode 2 -eps1 [значение] -eps2 [значение] -x [значение]\nMode 1: счет в диапазоне значений x от x1 до x2 с шагом dx с фиксированной точностью eps.\nMode 2: счет с фиксированным x в диапазоне точности от eps1 до eps2 с шагом 0.1.");
return -32;
}
for (int index=1; index<argc; index++) {
if ( strncmp(argv[index], "-eps1", 5) == 0 ) eps1 = atof(argv[index+1]);
}
if (eps1<=0) {
printf ("Eps1 должно быть положительным числом. Код ошибки -21.\n");
return -21;
}
for (int index=1; index<argc; index++) {
if ( strncmp(argv[index], "-eps2", 5) == 0 ) eps2 = atof(argv[index+1]);
}
if (eps2<=0) {
printf ("Eps2 должно быть положительным числом. Код ошибки -22.\n");
return -22;
}
if (eps1<eps2) {
printf("Начальное eps должно быть больше конечного. Код ошибки -23.\n");
return -23;
}
for (int index=1; index<argc; index++) {
if ( strncmp(argv[index], "-x", 2) == 0 ) x = atof(argv[index+1]);
}
if (x==0) {
printf ("Введено неверное x. Код ошибки -24\n");
return -24;
}
printf ("__________________________________________________________\n");
printf ("| eps | MyFunc(x) | Function(x) | Невязка |\n");
printf ("__________________________________________________________\n");
for (eps=eps1; eps>=eps2; eps *= 0.1) { //Диапазон точности.
while ( abs ( Row_Member(x, n+1) - Row_Member(x, n) ) > eps ) { //Пока разность n+1-ого и n-ого членов меньше заданного значения точности.
Row+= Row_Member(x, n); //Прибавлять к ряду n-ный член.
n+=1; //Увеличивать номер члена.
}
MyFunc = 1/Row; //Функция, вычисленная с помощью ряда.
Func = 1/sin(x); //Функция, вычисленная с помощью math.h .
printf ("| %8.7f | %12.7f | %12.7f | %12.7f |\n", eps, MyFunc*MyFunc, Func*Func, sqrt ( abs ( MyFunc*MyFunc - Func*Func ) ) );
Row=0; n=0; //Обнуление переменных.
}
printf ("________________________________________________________\n");
return 0;
}
else {
printf("Код режима неверен.\nИспользуйте -mode 1 для счета в диапазоне значений x от x1 до x2 с шагом dx с фиксированной точностью eps.\nИспользуйте -mode 2 для счета с фиксированным x в диапазоне точности от eps1 до eps2 с шагом 0.1.");
return -31;
}
}
Добавил еще пару проверок вводимых переменных, но речь не об этом. Программа считает криво. Считаю, что у меня опять проблемы с неявным приведением типов и полиморфизмом. (бяк, ненавижу >_<) Специально сделал все переменные дабл, но Эклипс, при тыканьи на abs в этих местах
for (x=x1; x<=x2; x+=dx) { //Диапазон иксов.
while ( abs ( Row_Member(x, n+1) - Row_Member(x, n) ) > eps ) { //Пока разность n+1-ого и n-ого членов меньше заданного значения точности.
printf("\n%f\n", Row);
Row+= Row_Member(x, n); //Прибавлять к ряду n-ный член.
n+=1; //Увеличивать номер члена.
}
for (eps=eps1; eps>=eps2; eps *= 0.1) { //Диапазон точности.
while ( abs ( Row_Member(x, n+1) - Row_Member(x, n) ) > eps ) { //Пока разность n+1-ого и n-ого членов меньше заданного значения точности.
Row+= Row_Member(x, n); //Прибавлять к ряду n-ный член.
n+=1; //Увеличивать номер члена.
}
Выдает такое описание:
/* Return the absolute value of X. */
extern int abs (int __x) __THROW __attribute__ ((__const__)) __wur;
т.е. abs определена, как int abs(int), из-за чего происходит такая вещь: если подмодульное выражение от нуля до единицы, то при приведении его к целому получится ноль, что меньше любой бесконечно малой точности, и у меня циклы останавливаются раньше времени, не досчитывая кучу членов ряда.
Вот такие дела. Буду благодарен за любую помощь.
В чем может быть ошибка?
Существует ли какой-нибудь оператор, который в данной программе мог бы однозначно определить полиморфную функцию?
Попробую переписать на C, где нет долбанного полиморфизма, но, емнип, в VS, где потом буду распихивать все это на exe и dll, нет средств разработки на С.
Вот.