Магия. Просто стер все нафиг, скопировал исходники третьей версии, заново сделал все то же самое и программа работает!
Вот работающий код
/*
lab4v4 - calculation of function y=1/sin(x) 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>
using namespace std;
double fac (double n) //Функция факториала.
{
double 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)
{
return pow(-1, n)*pow(x, 2*n+1)/fac(2*n+1);
}
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, n=0, Row=0, MyFunc, Func;
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;
}
if (dx<=0) {
printf ("Шаг должен быть положительным числом. Код ошибки -15.\n");
return -15;
}
if ( abs(x2-x1)<dx ) {
printf ("Шаг dx больше диапазона x. Код ошибки -16.");
return -16;
}
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-ого членов меньше заданного значения точности.
Row+= Row_Member(x, n); //Прибавлять к ряду n-ный член.
n+=1; //Увеличивать номер члена.
}
MyFunc = 1/Row; //Функция, вычисленная с помощью ряда.
Func = 1/sin(x); //Функция, вычисленная с помощью math.h .
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], "-x", 2) == 0 ) x = atof(argv[index+1]);
}
if (x==0) {
printf ("Введено неверное x. Код ошибки -20\n");
return -20;
}
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;
}
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;
}
}
Начинаю работу над пятой версией!
Как-то не по науке double fac (double).
Переписал int fac (int). Вроде в нужных местах поставил static_cast<double>(). В итоге программа печатает шапку таблицы и срывается в бесконечный цикл.
/*
lab4v3 - calculation of function y=1/sin(x) 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>
using namespace std;
int fac (int 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, int n)
{
return pow(-1, n)*pow(x, 2*n+1)/static_cast<double>( fac(2*n+1) );
}
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;
int 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;
}
if (dx<=0) {
printf ("Шаг должен быть положительным числом. Код ошибки -15.\n");
return -15;
}
if ( abs(x2-x1)<dx ) {
printf ("Шаг dx больше диапазона x. Код ошибки -16.");
return -16;
}
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-ого членов меньше заданного значения точности.
Row+= Row_Member(x, n); //Прибавлять к ряду n-ный член.
n++; //Увеличивать номер члена.
}
MyFunc = 1/Row; //Функция, вычисленная с помощью ряда.
Func = 1/sin(x); //Функция, вычисленная с помощью math.h .
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], "-x", 2) == 0 ) x = atof(argv[index+1]);
}
if (x==0) {
printf ("Введено неверное x. Код ошибки -20\n");
return -20;
}
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;
}
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++; //Увеличивать номер члена.
}
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;
}
}
Пожалуйста, укажите, в чем ошибка.
Или лучше скажите, как в Эклипсе ставить брейкпоинты и отслеживать выполнение по строкам. Сам не нашел. Насколько понимаю, Эклипс будет всего лишь фронтендом для gdb.
И еще интересует вопрос. Если уж быть совсем правильным, то нужно написать unsigned int fac (unsigned int n), потому что факториал - это произведение всех натуральных чисел до n включительно.
http://ru.wikipedia.org/wiki/%D0%A4%D0%B0%D0%BA%D1%82%D0%BE%D1%80%D0%B8%D0%B0%D0%BBВ данной программе переменная n "для внутреннего пользования", проблемы с неправильными данными могут быть только от моей криворукости.
Но интересует такой вопрос. Написал в gedit'е маленькую программулину.
#include <cstdio>
int main()
{
unsigned int a;
puts("Введите a");
scanf("%u", &a);
printf("%u\n", a);
return 0;
}
Вот результат:
yaromir@debian-yaromir:~/C++$ g++ -Wall -o unsigned unsigned.cpp
yaromir@debian-yaromir:~/C++$ ./unsigned
Введите a
2
2
yaromir@debian-yaromir:~/C++$ ./unsigned
Введите a
-2
4294967294
yaromir@debian-yaromir:~/C++$
Очень странно. Я думал, что минус просто не влезет в переменную и результатом во втором случае будет просто 2. А получилось непонятное число.
Заранее спасибо за ответы.