Matematikai alapok Dr. Iványi Péter
Számok A leggyakrabban használt adat típus Egész számok Valós számok
Bináris számábrázolás Kettes számrendszer Bitek: és Byte: 8 bit 28 64 32 6 8 4 2 bináris decimális = +2+4+8+6+32+64+28 = 255
Egész számok Egész szám (integer): 4 byte (32 bites processzorokon) Maximum: 247483647 Minimum: -247483648
Boolean algebra Bináris számok között műveletek NOT (igazságtábla) A NOT(A) Példa: NOT()
Boolean algebra AND: csak akkor igaz ha mindkét bit igaz A B A AND B Példa: AND
Boolean algebra OR:akkor igaz ha az egyik bit igaz A B A OR B Példa: AND
XOR: exkluzív OR Boolean algebra A B A XOR B Példa: AND
Boolean algebra Bármilyen boolean művelet definiálható AND és OR műveletekkel, például A B A XOR B Csak az igaz eredményeket kell összekapcsolni: (A= AND B=) OR (A= AND B=)
Lebegőpontos számok Folytonos Diszkrét matematika Számok bináris ábrázolása IEEE 754 float: 32 biten van ábrázolva Ez azt jelenti, hogy 2 32 valós számot lehet pontosan reprezentálni Ezzel szemben végtelen sok valós szám van Ábrázolható tartomány: ±.4298464324877e-45 ±3.428234663852886e+38
32 bit: Lebegőpontos számok s : előjel bit ( bit) e :exponenciális kitevő (8 bit) m : mantissza (23 bit) ( ) s m 2 ( e 27) seeeeeeeemmmmmmmmmmmmmmmmmmmmmm 3
Lebegőpontos számok m mantissza: (-22 bit) 2 - =.2 =.2 ugyanaz ezért normalizálva van az érték, mint bináris tört Bináris törtek. = /2 + /4 + /6 = 3/6 =.825 Nem minden szám reprezentálható:. = /6 + /32 + /256 + /52 + /496 + /892 +... vagyis az első 23 bitet használjuk csak, a maradékot eldobjuk...
Lebegőpontos számok Mantissza a tizedes ponttól jobbra levő rész Automatikusan feltételezünk egy -est a tizedes pont előtt.mmmmm... De így hogyan reprezentálhatjuk a zérust: Ha minden bit zérus De akkor hogyan representáljuk. et, hiszen a tizedes pont előtti -et automatikusan feltételezzük
Lebegőpontos számok Megoldás: az exponenciális biteket 27-et módosítjuk e kitevő: (3-23 bit) 5 esetén: 27 + 5 = 32 binárisan -5 esetén 27 5 = 22 binárisan
Lebegőpontos számok Egy példa a lebegőpontos szám ábrázolásra:.85: bits: 3 3-23 22- binary: decimal: 23 39899 2 e-27 ( + m / 2 23 ) = 2-4 ( + 39899/838868) = 4857/3427728 =.85894696763859375
Lebegőpontos számok Speciálisan reprezentált számok: Minusz végtelen (-inf): ha az összes exponenciális bit előjel bit Plusz végtelen (+inf): ha az összes exponenciális bit előjel bit NaN : Not a Number ha az összes exponenciális bit valamelyik mantissza bit
Lebegőpontos számok binary: decimális: binary: decimális:.5
Pontosság és teljesség Két különböző fogalom Pontosság: Az érték mennyire van közel a valódi értékhez Teljesség: Mennyi információ van az adott értékről
Pontosak Egész számok Ha van egy kettes számom és ahhoz egyet hozzáadok, akkor biztos hogy hármat fogok kapni Bármilyen műveletet végzünk és azértelmezési tartományba esik a válasz, akkor mindig pontos értéket kapunk Ugyanakkor nem teljesek, abban az értelemben, hogy nem képesek például a tört részeket reprezentálni
Lebegőpontos számok Fordított helyzet Teljesek: Önkényesen soha nem hagynak el információt a számról Elvileg minden számot tudnak reprezentálni ha elég bit áll rendelkezésre De nem pontosak Kerekítési hiba (Roundoff error) Kioltó hiba (Cancelation error)
Kerekítési hiba #include <stdio.h> int main() { double x =.3; double x2 =. +. +.; double x3 =.5; double x4 =. +. +. +. +.; } printf("%.2f\n", x2); if(x == x2) printf("egyenlo\n"); else printf("nem egyenlo\n"); printf("%.2f\n", x4); if(x3 == x4) printf("egyenlo\n"); else printf("nem egyenlo\n"); return();
A futtatás eredménye: Kerekítési hiba $ num3.exe.3444 nem egyenlo.5 egyenlo
Kerekítési hiba Négyzetgyök számítása Newton módszerrel double EPSILON =.; double t = c; while (t*t - c > EPSILON) t = (c/t + t) / 2.; Azt várjuk hogy mindig: t 2 c >
Kerekítési hiba #include <stdio.h> int main() { double eps =.; double c = 4.; /* bemenet */ double t = c; while(t*t - c > eps) { t = (c/t + t) / 2.; } printf("%f\n", t); return(); }
Kerekítési hiba c=4. c=. a program a helyes eredményt adja esetén a program végtelen ciklusba kerül A program elvileg akkor ér véget ha t 2 valójában t 2 < c esetén áll le. = c,de Ugyanakkor a folytonos matematika garantálja, hogy ez nem következhet be!!! Oka: kerekítési hiba
Lebegőpontos számok Kernighan és Plauger: A lebegőpontos számok olyanok mint egy kupac homok. Amikor elmozdítunk egy kicsit, el is veszítünk egy kicsit és csak piszok marad a kezünkben.
#include <stdio.h> Kioltó hiba int main() { double x =.4; double x2 =.; double y =.4; double y2 =.; double z = (y - y2) / (x - x2); printf("%f\n", z); return(); }
Kioltó hiba A várt eredmény:.4 /.4 =. A kapotteredmény.5
Stabilitás Egy matematikai probléma jól kondicionált ha a bemeneti paraméterek kis változására az eredmény is mértékben változik. Egy algoritmus numerikusan stabil ha bemeneti paraméterek kis változására az eredmény is kis mértékben változik. A művészet és tudomány az, hogy numerikusan stabil algoritmusokat találjunk jól kondicionált problémák megoldására.
Stabilitás A pontosság függ a probléma kondicionáltságától és az algoritmus stabilitásától. Pontatlanságot okozhat, ha: Stabil algoritmust alkalmazunk rosszul kondicionált problémára; vagy Instabil algoritmust alkalmazunk jól kondicionált problémára
Instabilitás Probléma: az f(x) = exp(x) függvény Jól kondicionált probléma Algoritmus: a Taylor sorozat első négy elemét használjuk g(x) = + x + x 2 / 2 + x 3 / 3 f() = 2.78282 g() = 2.666667
Instabilitás Ha x < akkor az algoritmus instabil!!! De ha az e -x függvény Taylor sorát vesszük az már stabil lesz.
Rosszul kondicionáltság x n 2 = ( R + ) xn R ( xn ) Vegyük a fenti egyenletet Kezdő érték: x =.5 R=3 iterációt futtatunk A műveleteket többféleképpen csoportosítjuk
Rosszul kondicionáltság n (R+)x-R(xx) (R+)x-(Rx)x ((R+)-(Rx))x x + R(x-xx) pontos 5.67567955.637469566.599878799.6528942.62236944.6727.94574394.2564956763.42823334.74288654 Négy különböző értéket kaptunk!!! Az összeadás, szorzás, kivonás stabil, de A probléma rosszul kondicionált. Ha R >2.57 az egyenlet kaotikus!
Mit fog kinyomtatni az alábbi kód? #include <stdio.h> int main() { double a = 2345.; double b = e-6; printf("%d", a + b == a); } return ; /* Eredmeny: */
Mit fog kinyomtatni az alábbi kód? #include <stdio.h> int main() { double d; for (d =.; d <=.5; d +=.) /* 4 értéket nyomtat */ { printf("%f\n", d); } printf("\n"); for (d =.; d <=.5; d +=.) /* 5 értéket nyomtat */ { printf("%f\n", d); } } return ;
Számoljuk ki: 4 4 9x y + 2y 2 #include <stdio.h> int main() { double x = 864; double y = 887; double r; r = 9*x*x*x*x - y*y*y*y + 2*y*y; printf("result: %f\n", r); } return ; /* Eredmény: 2. Helyes:. */
Mit fog kinyomtatni az alábbi kód? #include <stdio.h> int main() { long x = 677727; /* 2^24 + */ float y = 677727; printf("%ld\n", x); printf("%f", y); return ; } /* Eredmeny: 677727 nem lehet float-ként ábrázolni: 677726. */
Mit csinál a következő ciklus? int count = ; for (float x =.f; x < 2.f; x = x +.f) count++; printf( %d, count); int count2 = ; for (double x =.; x < 2.; x = x +.) count2++; printf( %d, count2); /* első ciklus végtelen ciklus lesz: 677726.f +.f = 677726.f a második ciklus működik */
Hibák az életben
Ariane 5 European Space Agency év, 7 billió dollárba került a fejlesztés 996 június 4-én felrobbant A rakéta és terhének összértéke: 5 millió dollár Ok: Szoftver, numerikus hiba
Ariane 5 Az irányító rendszer 36.7 másodperccel a fellövés után a rakéta oldal irányú sebességét reprezentáló számot próbálta konvertálni, egy 64 bites számot 6 bites formátumra A rendszert leállítja magát, mert érvénytelen adatot kap. A másodleges rendszer is leáll, hiszen ugyanaz a szoftver. Az irányító rendszer így hibás utasítást ad, mintha egy nem létező fordulatot kellene kompenzálni. A rakéta hirtelen irányt váltott (bár nem volt rá szükség) Olyan erők ébredtek melyre az önmegsemmisítés bekapcsolt 39 másodperccel a fellövés után
Patriot rakéta 99 február 25, Öböl háború Patriot nem tudta eltalálni az iraki Scud rakétát 28 katona halt meg és sérült meg Ok: Szoftver, numerikus hiba
Patriot rakéta Az egy tized másodpercekben mért időt a rendszer / el szorozta meg hogy másodpercekben kapja meg az időt Az adatot 24 biten reprezentálta / et nem lehet pontosan reprezentálni binárisan, így a 24. bit utáni rész levágódik. Ez egy kerekítési hiba. Sokszor elvégezve a szorzást a hiba növekszik: órás üzem esetén az eltérés:.34 másodperc
Patriot rakéta Scud sebessége:.676 m/s Így több mint fél kilómétert tesz meg a Scud.34 másodperc alatt