/* atk1 h6t2 -- pyöristys */ #include #include /* määritellään aliohjelmat, jotka suorittavat pyöristyksen. round ottaa pyöristettävän luvun muodollisena argumenttina, ja palauttaa kutsuvalle ohjelmalle pyöristetyn luvun. round_ptr ottaa argumentikseen pyöristettävän luvun muistipaikan osoitteen, ja operoi sen sisältöön, eli suoraan pääohjelmassa määriteltyyn double-tyyppiseen muuttujaan. toinen argumentti molemmissa on haluttu desimaalien määrä */ double round(double,int); void round_ptr(double*,int); main() { double x=3.81819; int n=2; /* round(x,n) ei vaikuta muuttujan x arvoon */ printf("x ~= %.2lf\n",round(x,n)); /* round_ptr(&x,n) korvaa muistipaikan &x sisällön pyöristetyllä arvolla */ x=3.999; round_ptr(&x,n); printf("x ~= %.2lf\n",x); } double round(double x,int n) { /* miten pyöristys n desimaalin tarkkuuteen suoritetaan? kokonaisluvuksi pyöristykseen on olemassa valmiit funktiot floor ja ceil, jotka pyöristävät alas- ja ylöspäin lähimpään kokonaislukuun. olk. x=1.23456. jos x halutaan pyöristää 3 desimaalin tarkkuuteen, lasketaan 10^3*x=1234.56, ja pyöristetään tämä lähimpään kokonaislukuun, ja jaetaan tulos 10^3:lla, ts. ceil(10^3*x)=1234 ja 1234/10^3=1.234. miten päätetään, kumpaa kokonaisluvuksipyöristysfunktiota käytetään? jos ensimmäinen pois jätettävä desimaali on >= 5, nin pyöristetään ylöspäin, muuten alaspäin. tarkastellaan erotusta t=|floor(10^n*x)/10^n - x|. jos t<5*10^(-(n+1)), niin pyöristetään alaspäin, muuten ylöspäin. esim. x=1.23456, n=3. 10^n*x=1234.56 floor(10^n*x)=1234 floor(10^n*x)/10^n=1.234 |floor(10^n*x)/10^n-x|=0.00056 > 5*10^(-4) siis pyöristetään ylöspäin, ts. lasketaan ja palautetaan ceil(10^n*n)/10^n */ double t=fabs(floor(x*pow(10.0,n))/pow(10.0,n)-x); if (t<5.0*pow(10.0,-(n+1))) return floor(x*pow(10.0,n))/pow(10.0,n); else return ceil(x*pow(10.0,n))/pow(10.0,n); } void round_ptr(double* p,int n) { /* p:n arvo on jonkin double-tyyppisen muuttujan muistipaikan osoite. *p antaa sen muistipaikan sisällön, ts. muuttujan arvon */ double t=fabs(floor((*p)*pow(10.0,n))/pow(10.0,n)-(*p)); if (t<5.0*pow(10.0,-(n+1))) /* sijoitetaan muistipaikkaan p */ *p = floor((*p)*pow(10.0,n))/pow(10.0,n); else *p = ceil((*p)*pow(10.0,n))/pow(10.0,n); }