#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> //#include <limits.h> const double IZP_E = 2.7182818284590452354; // e const double IZP_PI = 3.14159265358979323846; // pi const double IZP_2PI = 6.28318530717958647692; // 2*pi const double IZP_PI_2 = 1.57079632679489661923; // pi/2 const double IZP_PI_4 = 0.78539816339744830962; // pi/4 double *epsilon=NULL; double *x=NULL; double druhaodmocnina(double neznama, double eps) { //Y0 = X // po�åte�nà aproximace //Yi+1 = 0.5 * (X/Yi + Yi) double y=neznama; if (y==0) return 0; double last=0; if (neznama>0) { do { last=y; y=(neznama/last+last)/2; } while (fabs(y-last)>=eps); } else { fprintf(stderr,"Odmocninu lze vypocitat jen z kladnych cisel!\n"); return NAN; } //printf("%.10le\n",sqrt(*x)); return y; } double sinus(double neznama, double eps) { //sin(X) = X - X3/3! + X5/5! - X7/7! + ... short neg=0; if (neznama<0) { //pokud je zaporny, udelame ho kladny neznama=fabs(neznama); neg++; } if (neznama>IZP_2PI) neznama=fmod(fabs(neznama),IZP_2PI); //poladime konvergenci // printf("%.10le\n",neznama); double neznama2=pow(neznama,2); double y=neznama; double prirustek=neznama; unsigned short k=3; while (fabs(prirustek)>=eps) { prirustek=(-prirustek/(k*(k-1)))*neznama2; k+=2; y+=prirustek; } if (neg!=0) y*=-1; //kdyz byl vstup zapornej, tak se musi "uzapornit" i vystup // printf("%.10le\n",sin(*x)); if (y>1 || y<-1) { fprintf(stderr,"Vysledek je mimo rozsah <-1;1>!\n"); return NAN; } return y; } double kosinus(double neznama, double eps) { return (sinus((IZP_PI_2-neznama), eps)); } double tangens(double neznama, double eps) { //printf("%.10le\n",tan(*x)); double y=sinus(neznama,eps)/kosinus(neznama,eps); if (y==INFINITY) { fprintf(stderr,"Funkce tangens neni pro tuto hodnotu definovana!\n"); return NAN; } return y; } double kotangens(double neznama, double eps) { //printf("%.10le\n",tan(*x)); double y=kosinus(neznama,eps)/sinus(neznama,eps); if (y==INFINITY) { fprintf(stderr,"Funkce kotangens neni pro tuto hodnotu definovana!\n"); return NAN; } return y; } double enax(double neznama, double eps) { //eX = 1 + X + X2/2! + X3/3! + ... short neg=0; if (neznama<0) { neznama=fabs(neznama); neg=1; } double y=neznama+1; double prirustek=neznama; unsigned short k=2; while (fabs(prirustek)>=eps && y!=INFINITY && prirustek!=INFINITY) { prirustek*=(neznama/k); k++; y+=prirustek; } if (y==INFINITY || prirustek==INFINITY) { fprintf(stderr,"Preteceni!\n"); return NAN; } if (neg!=0) y=1/y; //printf("%.10le\n",exp(*x)); return y; } double prirozenylogaritmus(double neznama, double eps) { if (neznama==0) return -INFINITY; if (neznama<0){ fprintf(stderr,"Prirozeny logaritmus lze pocitat jen z cisel vetsich nez 0!\n"); return NAN; } int mocnina=0; while (neznama>=2) { //priblizit se 1 neznama=neznama/10; mocnina++; } while (neznama<=.1 && neznama>0) { //priblizit se 1 neznama=neznama*10; mocnina--; } double z=(neznama-1)/(neznama+1); double zz=z*2; double z2=pow(z,2); double y=zz; unsigned int k=1; double prirustek=y; while (fabs(prirustek)>=eps && prirustek!=INFINITY && y!=INFINITY) { prirustek*=((k*z2)/(k+2)); // printf ("%f\n",prirustek); k+=2; y+=prirustek; } if (mocnina!=0) y+=(mocnina*log(10)); //pokud se musela doladit konvergence (snad nevadi pouziti fce log()) return y; } double odmocninazenax(double neznama, double eps) { double y=druhaodmocnina(enax(neznama,eps),eps); return y; } double sinusprirozenehologaritmu(double neznama, double eps) { double y=sinus(prirozenylogaritmus(neznama,eps),eps); // printf("%.10le\n",sin(log(neznama))); return y; } void napoveda(void) { printf("Pouziti: program -FUNKCE EPSILON\nDale zadavejte vstupy pro zvolenou funkci.\n\nFUNKCE:\nsqrt druha odmocnina\nsin sinus\ncos kosinus (bonus)\ntan tangens (bonus)\ncot kotangens (bonus)\nex mocnina Eulerova cisla\nln prirozeny logaritmus\nsqrtex druha odmocnina z mocniny Eulerova cisla\nsinln sinus z prirozeneho logaritmu\n\nEPSILON:\nPresnost vypoctu. Musi byt vetsi nez 0. Cim blize 0, tim presnejsi vypocet.\n\nSepsal a v hlavni rohli sehral xkalab00.\n"); } int main(int argc, char *argv[]) { if (argc == 1 || (argc == 2 && strcmp("-h", argv[1]) == 0)) { napoveda(); return EXIT_SUCCESS; } if (argc == 3) { //nacteme vstupy epsilon=malloc(sizeof (double)); *epsilon=atof(argv[2]); //nacteme epsilon if (*epsilon<=0) { fprintf(stderr,"Spatne epsilon!\n"); free(epsilon); return EXIT_FAILURE; } } else { fprintf(stderr,"Spatne parametry!\n"); return EXIT_FAILURE; } x=malloc(sizeof (double)); int a=scanf("%lf", x); //nactem vstup while (a!=EOF) { //pokud je v poradku pokracujem if (a!=1) { //pokus se nic nenacetlo fprintf(stderr,"To nebylo cislo!\n"); scanf("%*s"); a=scanf("%lf",x); continue; } //sqrt if (strcmp("-sqrt", argv[1])==0) { double y=druhaodmocnina(*x, *epsilon); if (isnan(y)==0) printf("%.10le\n",y); } //sin if (strcmp("-sin", argv[1])==0) { double y=sinus(*x, *epsilon); if (isnan(y)==0) printf("%.10le\n",y); } //cos (kdyz uz to umi sinus...) if (strcmp("-cos", argv[1])==0) printf("%.10le\n",kosinus(*x,*epsilon)); //tan if (strcmp("-tan", argv[1])==0) { double y=tangens(*x, *epsilon); if (isnan(y)==0) printf("%.10le\n",y); } //cot if (strcmp("-cot", argv[1])==0) { double y=kotangens(*x, *epsilon); if (isnan(y)==0) printf("%.10le\n",y); } //exp if (strcmp("-ex", argv[1])==0) { double y=enax(*x, *epsilon); if (isnan(y)==0) printf("%.10le\n",y); } //log if (strcmp("-ln", argv[1])==0) { double y=prirozenylogaritmus(*x, *epsilon); if (isnan(y)==0) printf("%.10le\n",y); } //sqrt(ex) if (strcmp("-sqrtex", argv[1])==0) printf("%.10le\n",odmocninazenax(*x, *epsilon)); //sin(ln) if (strcmp("-sinln", argv[1])==0) { printf("%.10le\n",sinusprirozenehologaritmu(*x, *epsilon)); } a=scanf("%lf", x); } free(epsilon); free(x); return EXIT_SUCCESS; } //gcc -std=c99 -Wall -W -lm -pedantic proj2.c -o proj2 -O2