Pobierz Programowanie Proceduralne i więcej Prezentacje w PDF z Matematyka tylko na Docsity! Reprezentacja symboli w komputerze. Liczby całkowite i zmiennoprzecinkowe. Programowanie Proceduralne 1 Bity i kody binarne • Bit (binary digit) najmniejsza ilość informacji {0, 1}, wysokie/niskie napięcie • Kod binarny - grupa bitów reprezentująca zbiór symboli 1b → 2 symbole {0, 1} 2b → 4 symbole {00, 01, 10, 11} 8b → 256 = 28 symboli n bitów → 2n symboli • Do zakodowania n symboli potrzeba co najmniej dlog2 ne bitów • Ile bitów potrzeba do zakodowania alfabetu polskiego? Programowanie Proceduralne 2 Systemy pozycyjne xn−1xn . . . x0 = n−1∑ i=0 xia i a - baza (podstawa) systemu Dziesiętny 46532(10) = 4 · 104 + 6 · 103 + 5 · 102 + 3 · 101 + 2 · 100 Dwójkowy (binarny) 10011(2) = 1 · 24 + 0 · 23 + 0 · 22 + 1 · 21 + 1 · 20 = 19(10) Ósemkowy (oktalny) 351(8) = 3 · 82 + 5 · 81 + 1 · 80 = 233(10) Szesnastkowy (heksadecymalny) 3FC(16) = 3 · 162 + 15 · 161 + 12 · 160 = 1020(10) A=10, B=11, C=12, D=13, E=14, F=15 Programowanie Proceduralne 5 Konwersje podstawy 1111110101111110(2) = FD7E(16) = 176576(8) = 64894(10) binarny na szesnastkowy 1 cyfrze odpowiadają 4 bity 1111 1101 0111 1110 F D 7 E binarny na ósemkowy 1 cyfrze odpowiadają 3 bity 1 111 110 101 111 110 1 7 6 5 7 6 Programowanie Proceduralne 6 Liczby ósemkowe i szesnastkowe w C 1 #include <s t d i o . h> 2 3 int main ( ) 4 { 5 int a = 10 ; /∗ dec ∗/ 6 int b = 010 ; /∗ oct ∗/ 7 int c = 0x10 ; /∗ hex ∗/ 8 9 printf ("dec: %d %d %d\n" , a , b , c ) ; 10 printf ("oct: %o %o %o\n" , a , b , c ) ; 11 printf ("hex: %x %x %x\n" , a , b , c ) ; 12 13 return 0 ; 14 } dox.c Programowanie Proceduralne 7 1 int zmien_podstawe ( int x , int ∗t , int p ) 2 { 3 int i=0; 4 5 while ( x != 0 ) 6 { 7 t [ i ] = x % p ; 8 x = x / p ; 9 i = i + 1 ; 10 } 11 return i ; 12 } dec2all.c Operator / dla liczb całkowitych dzieli bez reszty! Programowanie Proceduralne 10 Naturalny kod binarny (NKB) bn−1 . . . b1b0 = n−1∑ i=0 bi · 2i • liczby bez znaku • zakres [0, 2n − 1] • unsigned int • unsigned char • operacje arytmetyczne przeprowadza się podobnie jak w systemie dziesiętnym • John Napier, XVI w. Programowanie Proceduralne 11 Liczba całkowita ze znakiem w komputerze U2, kod uzupełnień do dwóch bn−1 . . . b1b0 = −bn−1 · 2n−1 + n−2∑ i=0 bi · 2i • liczby ze znakiem • najstarszy bit bn−1 odpowiada za znak • zakres [ −2n−1, 2n−1 − 1 ] • int, char • operacje arytmetyczne przeprowadza się podobnie jak w NKB • Pascal, uzupełnienie do 10, XV w. Programowanie Proceduralne 12 Stało i zmiennopozycyjny kod Kod stałoprzecinkowy 3, 14(10) = 3 · 100 + 1 · 10−1 + 4 · 10−2 11, 001(2) = 1 · 21 + 1 · 20 + 0 · 2−1 + 0 · 2−2 + 1 · 2−3 = 3, 125(10) Zapis zmiennoprzecinkowy L = m · pc c - cecha p - podstawa (baza) m - mantysa 3, 14 · 100 = 0, 0314 · 102 = 314 · 10−2 Normalizacja 1 ¬ |m| < p Programowanie Proceduralne 15 Liczby zmiennopozycyjne IEEE-754 pojedyncza precyzja (single precision), float x = (−1)s · 1.m · 2(c−127) s = 0 1.m = ( 1 + ∑23 i=1 b23−i · 2−i ) = 1 + 2−2 = 1.25 2(c−127) = 2(124−127) = 2−3 = 0.125 Podobne rozwiązanie stosował Konrad Zuse, 1936 r. Programowanie Proceduralne 16 http: // en. wikipedia. org/ wiki/ Single-precision_ floating-point_ format Zakres i precyzja Pojedyncza precyzja • zakres ±3.4 · 1038 • precyzja 7 cyfr dziesiętnych Podwójna precyzja (double precision) • double cecha 11 bitów, mantysa 52 bity, bias 1024 • zakres ±1.8 · 10308 • precyzja 15 cyfr znaczących Programowanie Proceduralne 17 Niedokładność reprezentacji 1 #include <s t d i o . h> 2 3 int main ( ) 4 { 5 float x = 0 . 1 ; 6 7 if (x == 0.1 ) printf ("OK, %f jest rowne 0.1\n" , x ) ; 8 else printf ("Nie OK, %f nie jest rowne 0.1\n" , x ) ; 9 10 return 0 ; 11 } prec.c • Niektóre liczby nie będą dokładnie reprezentowane • Liczb zmiennoprzecinkowych nie należy przyrównywać do dokładnych wartości. Lepiej |a− b| < ε Programowanie Proceduralne 20 Niedokładność reprezentacji 1 #include <s t d i o . h> 2 3 int main ( ) 4 { 5 float x = 0 . 1 ; 6 7 if (x == 0.1 ) printf ("OK, %f jest rowne 0.1\n" , x ) ; 8 else printf ("Nie OK, %f nie jest rowne 0.1\n" , x ) ; 9 10 return 0 ; 11 } prec.c • Niektóre liczby nie będą dokładnie reprezentowane • Liczb zmiennoprzecinkowych nie należy przyrównywać do dokładnych wartości. Lepiej |a− b| < ε Programowanie Proceduralne 21 Niedokładność reprezentacji 1 #include <s t d i o . h> 2 #include <math . h> 3 #define EPS 0.000001 4 5 int main ( ) 6 { 7 float x = 0 . 1 ; 8 9 if ( fabs (x−0.1) < EPS ) 10 printf ("OK, %f jest rowne 0.1\n" , x ) ; 11 else 12 printf ("Nie OK, %f nie jest rowne 0.1\n" , x ) ; 13 14 return 0 ; 15 } prec2.c Programowanie Proceduralne 22 Limity dla obliczeń zmiennopozycyjnych w C 1 #include <s t d i o . h> 2 #include <float . h> 3 4 int main ( ) 5 { 6 printf ("Limity typu float\n" ) ; 7 printf ("Najwieksza wartosc : %e\n" , FLT_MAX ) ; 8 printf ("Najmniejsza dodatnia : %e\n" , FLT_MIN ) ; 9 printf ("Epsilon maszynowy : %e\n" , FLT_EPSILON ) ; 10 11 return 0 ; 12 } float.c Najwieksza wartosc : 3.402823e+38 Najmniejsza dodatnia : 1.175494e-38 Epsilon maszynowy : 1.192093e-07 Programowanie Proceduralne 25 Inne możliwe problemy • nadmiar (overflow) - przekroczenie zakresu (+Inf, -Inf) • niedomiar (underflow) - zaokrąglenie bardzo małej liczby do 0 • redukcja cyfr przy odejmowaniu bardzo bliskich sobie liczb • dodawanie (lub dodawanie) dużej i małej liczby • kolejność operacji może mieć wpływ na wynik (a+ b) + c 6= a+ (b+ c) • zaokrąglenia, np. liczby 0.1 nie można dokładnie reprezentować w systemie binarnym • 25 luty 1991 r., wojna w zatoce perskiej, awaria systemu antyrakietowego Patriot (zegar rakiety tykał co 0.1 s.), zginęło 28 amerykańskich żołnierzy a 100 zostało rannych. Programowanie Proceduralne 26 Przykład: szereg harmoniczny Problem: wyznaczyć sumę pierwszych n elementów szeregu harmonicznego n∑ i=1 1 n = 1 + 1 2 + 1 3 + . . . −−−→ n→∞ ∞ Programowanie Proceduralne 27 1 int miejsca_zerowe ( float a , float b , float c , float ∗x1 , float ∗x2 ) 2 { 3 float delta ; 4 5 delta = b∗b − 4∗a∗c ; 6 7 if ( fabs ( delta ) < EPS ) 8 { 9 ∗x1=−b/a /2 ; 10 ∗x2=∗x1 ; 11 return 1 ; 12 } 13 14 if ( delta >= EPS ) 15 { 16 delta=sqrt ( delta ) ; 17 ∗x1 = −(b−delta ) /(2∗a ) ; 18 ∗x2 = −(b+delta ) /(2∗a ) ; 19 return 2 ; 20 } 21 return 0 ; 22 } miejscazerowe.c Programowanie Proceduralne 30 Problemy z odejmowaniem • możliwe błędy, gdy jeden z pierwiastków bliski 0, tzn b ≈ √ ∆ x1 = −b+ √ ∆ 2a x2 = −b− √ ∆ 2a • np.: a = 1, b = −100, c = 1 =⇒ √ ∆ ≈ 99.979997999 • x1=99.99000e+01, x2=1.000214e-02 • w(x1)=0.000000e+00, w(x2)=-1.136065e-04 Programowanie Proceduralne 31 Problemy z odejmowaniem • możliwe błędy, gdy jeden z pierwiastków bliski 0, tzn b ≈ √ ∆ x1 = −b+ √ ∆ 2a x2 = −b− √ ∆ 2a • Jeśli problem jest trudny - najlepiej zmienić problem • wzory Viete’a { x1 + x2 = − ba x1x2 = c a • x1=9.999000e+01, x2=1.000100e-02 • w(x1)=0.000000e+00, w(x2)=0.000000e+00 Programowanie Proceduralne 32