Pull to refresh

Детектирование неопределенностей или история о поющей программе

Начну с истории о поющей программе.
Занимался написанием довольно несложной программы по вычислению суммы конечного ряда и сопоставления её со значением самой функции (sinx в моем случае). Для кошерности программы я пытался вывести рекуррентную формулу, но что-то не выходило, поэтому я выразил факториал обычной рекурсией и не стал замораичваться. Но вот ведь незадача: при увеличении точности, программа при попытке посчитать все числа приходит к неопределлености "-nan". Это было нехорошо и нужно было хотя бы предотвратить появление этой некрасивой величины. Я обратился к своему преподавателю и мы вместе с ним и несколькими однокурсниками думали, как её выловить или «задетектировать». Ни обращение к гуглу на двух языках, ни сравление числа с "-NAN" ни прочие схожие танцы с бубном нам не помогли. Все продолжалось до тех пор, пока один из нас не заметил ритмичность: nan nan nan nan nan… Live is life (если кто-то не понял — это слова популярной песни Opus — Live is life). И тогда все забыли про оптимизацию программы — всем было нужно, чтобы она запела. В тот день нам так и не удалось заставить программу плясать под нашу дудку.

Позже я по-разному пытался «найти» эту неопределенность: сравнивать её с выражением, подсчет которого так же дает неопределенность; сравнивать её с выражением, подсчитанным точно так же как и оно само — все безрезультатно. И в один момент мне пришло решение. Ведь если это неопределенность, то её невозможно с чем-либо сравнить, т.е. если для её детектирования и можно что-то использовать, то только её саму (противоречиво, но не лишино смысла). Любое число по сравнению с неопределенностью обладает разительным и очевидным свойством, которое сразу незаметно: с числом, в отличии от неопределенности, можно проводить любые математическии операции и получить после этого число (если конечное число не выходит за рамки допустимых значений). И вот оно, решение:
if (a-a!=0){
	counter+=1;
}

Я не взял во внимание a/a!=1,a+a=2*a и прочие подобные, потому что при определенных условиях они могут дать осечку.
Таким образом я нашел "-nan", но так же можно найти и любую другую неопределенность, этот метод универсален с данной точки зрения.

Ну и если кому понадобится,мой пограмистский код:
#include <stdio.h>
#include <math.h>
long double fact(double f){
	if (f==0){
		return 1;
	}
	return f*fact(f-1);
}

void main(){
	double x1,x2,y,nan_det,s,dx,eps;

	printf("Введите начальное значение аргумента:");
	scanf("%lf",&x1);
	printf("Введите конечное значение аргумента:");
	scanf("%lf",&x2);
	printf("Введите приращение аргумента:");
	scanf("%lf",&dx);
	printf("Введите точность:");
	scanf("%lf",&eps);

	while(x1<=x2+dx){
		s=0;
		for(int i=0;i<=eps;i++){
			s+=pow(-1,i)*pow(x1,2*i+1)/(fact(2*i+1));
		}
		y=sin(x1);
		printf("x=%lf,\tS=%lf,\ty=%lf\n",x1,s,y);
		x1=x1+dx;
		if(s-s!=0){
			nan_det+=1;
		}
		if(nan_det==5){
			printf("\nLive is life\n\n");
			nan_det=0;
		}
	}
}
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.