Ta strona wykorzystuje ciasteczka ("cookies") w celu zapewnienia maksymalnej wygody w korzystaniu z naszego serwisu. Czy wyrażasz na to zgodę?

Czytaj więcej
< All Topics
Print

Operacje na liczbach

Typy liczb

Liczby rzeczywiste zapisywane i wyświetlane są w R w systemie dziesiętnym, a separatorem części ułamkowej jest kropka, nie przecinek.

> 1,3
BŁĄD: nieoczekiwane ',' in "1,"
> 1.3
[1] 1.3

 

Czerwonym kolorem zaznaczone są wszelkie polecenia wpisywane przez użytkownika przy użyciu klawiatury, niebieskim odpowiedzi programu. Polecenia wpisuje się zawsze po czerwonym >. Odpowiedzi są poprzedzone liczbą w nawiasie, która pokazuje pozycję wyświetlanej za nią liczby wśród wszystkich, jakie składają się na odpowiedź. Warto przy tym wiedzieć, że wciskając strzałkę ↑ na klawiaturze przywołujemy wpisane już polecenia i możemy wykonać w nich poprawki.

W komputerze liczby dziesiętne zamieniane są na liczby w systemie dwójkowym i przypisane są im obiekty fizyczne złożone z nienamagnesowanych i namagnesowanych fragmentów pamięci operacyjnej zwanych bitami ułożone w zestawy zwane bajtami. W inny sposób reprezentowane liczby całkowite, inaczej rzeczywiste.

Liczby całkowite zapisywane są w jednym lub kilku bajtach, gdzie pierwszy bit pierwszego bajtu wykorzystywane jest na znak liczby (0 to +, a 1 to -) a pozostałe bity służą do zapisu liczby w systemie dwójkowym.

Liczby rzeczywiste zapisywane są w kilku bajtach, w których pierwszy bit zarezerwowany jest na znak liczby, kolejne bity na tzw. mantysę – liczbę od 1 do 2 (ale mniejszą od 2), a pozostałe na wykładnik (czyli tzw. cechę). Jest to tzw. postać zmiennoprzecinkowa w systemie dwójkowym:
x = ± m*2c. Zapis ten pozwala na operowanie szerokim zakresem liczb i stosowanie wydajnych algorytmów arytmetycznych. Cechuje go jednak pewna niedokładność. Przykładowo nie można zera zapisać w postaci zmiennoprzecinkowej. Zatem pewne obliczenia wykonywane dla liczb całkowitych są dokładniejsze, gdy wykonuje się je dla liczb zapisywanych jako całkowite (typ integer) niż zmiennoprzecinkowe (typ double).

Po wykonaniu różnych operacji na liczbach w systemie dwójkowym program R zamienia je na liczby w systemie dziesiętnym i pokazuje standardowo jako zestaw cyfr. Liczby w zakresie od 0.001 do 99999999 pokazywane są standardowo (z wyjątkami). Mniejsze od 0.0001 i większe 99999999 pokazywane są w postaci zmiennoprzecinkowej o podstawie 10.

> 9999
[1] 9999
> 99999999
[1] 1e+08
> 100000
[1] 1e+05
> 100001
[1] 100001
> 0.0011
[1] 0.0011
> 0.0001
[1] 1e-04

 

Występująca w tym ujęciu litera e nie ma nic wspólnego ze stałą Eulera e=2.71… używaną w matematyce, a oznacza 10 do potęgi, gdzie wykładnikiem jest liczba podana po e wraz ze znakiem.

Często wiemy, że efektem wykonywanych operacji liczbowych jest 0, a program wyświetla liczby postaci 1.34e-17. Jest to związane z liczbą bitów używaną do zapisu mantysy i cechy. Im więcej bitów zajmuje zapis jednej liczby, tym zapis liczb jest dokładniejszy ale pojemność pamięci operacyjnej jest ograniczona i przydzielanie dużo miejsca liczbom (a jest ich zazwyczaj dużo) jest nieopłacalne. Drogą kompromisu wypracowano, że najlepiej spisują się komputery operujące liczbami tzw. double precision. Liczby o podwójnej precyzji w zapisie dziesiętnym operują 16 znaczącymi miejscami po przecinku/kropce, co oznacza, że liczby mniejsze od 10-16 nie różnią się już od 0. Pozwala to zazwyczaj na dość dokładne obliczenia. Pokazuje to także, że dla zmiennych z natury nieujemnych powinniśmy używać takich jednostek, by wyniki pomiarów mieściły się od 1 do 1000 (wtedy błąd obliczeń się minimalizuje).

Zapis liczby z literą e i wykładnikiem pochodzi z Ameryki i nosi nazwę formatu naukowego (scientific) liczb. Niezbyt podoba się on Europejczykom. Aby zobaczyć, co się kryje za liczbą w formacie naukowym można użyć funkcji format z opcją scientific=FALSE. Wyświetla ona liczby jako zmienne tekstowe, ale jednocześnie jest to już zapis liczby, nie jej wartość. W porzypadku dużych liczb całkowitych wystaczy bezpośrednio za liczbą napisać L

> 0.0000045
[1] 4.5e-06
> format(0.0000045,scientific=FALSE)
[1] "0.0000045"
> 700000000
[1] 7e+08
> format(700000000,scientific=FALSE)
[1] "700000000"
> 700000000L
[1] 700000000

 

Być może teraz, gdy wpisujemy sami liczby funkcja format(), wydaje się zbędna. Stosuje się ją dopiero wtedy, gdy chcemy zobaczyć wyniki obliczeń różnych funkcji w formie bardziej właściwej dla ich umieszczenia np. w pracy dyplomowej.

R wyświetla liczby rzeczywiste z taką dokładnością, by cała liczba składała się od 7 do 9 liczb. Jednak do obliczeń używa wszystkich znaków znaczących jakie są używane. Można to wykryć każąc wyświetlać liczby, jako zmienne tekstowe za pomocą funkcji format() z opcją digit=n lub digits=n, gdzie n jest liczbą cyfr liczby, którą chcemy zobaczyć.

> 0.1101101101101101
[1] 0.1101101
> format(0.1101101101101101,digits=16)
[1] "0.1101101101101101"

 

Opcja digits działa do n=21, ale tylko 16 znaków po kropce jest wyświetlanych przy jej pomocy.

Komputery cechują się ograniczeniami nie tylko dokładności obliczeń (do 16 cyfr po przecinku/kropce), ale też mają ograniczenie na wielkość liczby. Liczby powyżej 1016 nie są już odróżnialne od siebie. Nie ma to charakteru ogólnego. Wszystko zależy od tego, jak dana liczba jest prezentowana w postaci binarnej.

> 10000000000000000
[1] 1e+16
> 10000000000000001
[1] 1e+16
> 10000000000000001-10000000000000000
[1] 0
> 10000000000000002-10000000000000000
[1] 2
> 10000000000000002-10000000000000001
[1] 2

 

Funkcje sprawdzające i określające typ liczby

Każda liczba wpisana do konsoli R jest traktowana jako liczba rzeczywista (co oznacza zapisanie jej w systemie zmiennoprzecinkowym), nawet wtedy gdy ma postać liczby całkowitej. Liczby całkowite także można wpisać do R przy użyciu funkcji as.integer(x). W niektórych sytuacjach zwiększa to dokładność obliczeń. Z dugiej strony liczby całkowite można zmienić na zmiennoprzecinkowe używając funkcji as.double(). Podobne do nich funkcje is.integer() i is.double() dają odpowiedzi TRUE lub FALSE pozwalając na wykrycie typu liczby. Sprawdzanie, czy dany obiekt wogóle jest liczbą, jest możliwe poprzez użycie funkcji is.numeric(), a zamiana czegoś, co wyląda na liczbę, na tę liczbę, wymaga użycia funkcji as.numeric().

> is.integer(7)
[1] FALSE
> is.integer(as.integer(7))
[1] TRUE
> as.integer(10.64)
[1] 10
> is.double(10.64)
[1] TRUE
> is.numeric("7.2")
[1] FALSE
> as.numeric("7.2")
[1] 7.2

 

Typy różnych obiektów wpisanych do R wykrywa się za pomocą funkcji mode(), typeof(), class() i str(). Dla liczba dają one następujące odpowiedzi:

> mode(7)
[1] "numeric"
> typeof(7)
[1] "double"
> class(7)
[1] "numeric"
> str(7)
 num 7
> mode(as.integer(7))
[1] "numeric"
> typeof(as.integer(7))
[1] "integer"
> class(as.integer(7))
[1] "integer"
> str(as.integer(7))
 int 7

 

Funkcje zaokrąglające liczby rzeczywiste

Przekształcenie danej rzeczywistej na liczbę całkowitą za pomocą funkcji as.integer() powoduje obcięcie jej części ułamkowej. Jest to rodzaj zaokrąglania liczby rzeczywistej w dół. Do zaokrąglania liczb rzeczywistych służy ponadto 5 specjalnych funkcji:

  • ceiling() zaokrąglenie w górę – najmniejsza liczba całkowita większa od argumentu,
  • floor() zaokrąglenie w dół – największa liczba całkowita mniejsza od argumentu,
  • trunc() obcina część liczby po kropce (to samo co floor()),
  • round() klasyczne zaokrąglenie do danej liczby miejsc po przecinku, którą określa się opcją digits=n,
  • signif() zaokrąglenie liczby do 5 miejsc po przecinku.
> # Zaokrąglenia
> ceiling(7.3)
[1] 8
> floor(7.3)
[1] 7
> trunc(7.3)
[1] 7
> round(7.3333)
[1] 7
> round(7.3333,digits=2)
[1] 7.33
> round(7.3393,2)
[1] 7.34
> signif(2.334564345)
[1] 2.33456

 

Opcja digits=n w funkcji round() może być skrócona do wymienienia tylko do n – liczby miejsc po przecinku.

 

Działania na liczbach

Praca z bazami danych i arkuszami kalkulacyjnymi w zasadzie wyeliminowała konieczność używania kalkulatorów. Jednak od czasu do czasu pojawia się konieczność wyliczenia wartości konkretnych działań i by to robić nie trzeba wychodzić z programu R. Wręcz przeciwnie. Wykonanie prostych działań jest w R bardzo proste. Składnia najprostszych działań jest prawie w 100% zgodna z matematyką.

Działania (suma, różnica, iloczyn, iloraz oraz potęgowanie dwóch liczb) są dobrze wszystkim znane. Są to funkcje dwuargumentowe, które zapisuje się za pomocą znaków wstawianych między liczby. W R stosuje się następujące symbole: “+”, “-“, “*”, “/”, “^”, zwane operatorami arytmetycznymi.

># dodawanie i odejmowanie
> 1+1
[1] 2
> 1.6+7.3
[1] 8.9
> 1.6-7.3; 4.5-2.32
[1] -5.7
[1] 2.18
> 10-
+ 5
[1] 5

 

Komunikaty wyjaśniające można wpisywać po znaku #. Nie są one interpretowane przez program.

W jednej linijce można napisać wiele działań, pod warunkiem, że rozdzieli się je średnikiem. Średnik wpisany na końcu każdego polecenia nie generuje błędu, ale jest tak traktowany jak przejście do nowej linijki.

Naciśnięcie klawisza enter przy nie zakończonej instrukcji powoduje pojawienie się znaku +, po którym należy dokończyć działanie. Znak plus na początku linijki oznacza łączenie jej z częścią instrukcji znajdującą w linijce wyżej i nie jest dodawaniem. W przypadku działań może to być mylące.

># mnożenie i dzielenie
> 1*1
[1] 1
> 1.6*7.3
[1] 11.68
> 1.6/7.3
[1] 0.2191781
> 3-1*2
[1] 1
> (3-1)*2
[1] 4
> 1.6/0
[1] Inf
> 1/Inf
[1] 0
> 1/INF
BŁĄD: nie znaleziono obiektu 'INF'
> 1/inf
BŁĄD: nie znaleziono obiektu 'inf'
> 0/0
[1] NaN
> Inf/Inf
[1] NaN > 2(10-3)(41+2)
BŁĄD: próba zastosowania nie-funkcji
> 2*(10-3)*(41+2)
[1] 602

 

Program R zna pojęcie nieskończoności: Inf, które może być używane w działaniach. Największą liczbą odróżnialną przez R od Inf jest 2^1023=8.988466e+307. Natomiast 2^1024=Inf. Działania nieokreślone powodują generowanie wielkości NaN, która może być używana tak jak liczba. Zawsze jednak wszelkie działania z jej użyciem dają w wyniku NaN. Operowanie taką rozbudowaną strukturą liczb powoduje, że rzadko generowane są błędy.

Nie jest natomiast zrozumiałe dla R zwyczajowe pomijanie znaku mnożenia *, gdy mnożymy wyrażenia w nawiasach.

># potęgowanie i pierwiastkowanie
> 9^2
[1] 81
> 9^0.5
[1] 3
> 10^-1
[1] 0.1
> -10^-2
[1] -0.01
> (-10)^-2
[1] 0.01
> (-1)^0.5
[1] NaN
> 0^Inf
[1] 0
> 0.5^Inf
[1] 0
> 1^Inf
[1] 1
> 1.1^Inf
[1] Inf

 

 

Dzielenie z resztą

Poza wymienionymi operatorami arytmetycznymi są także:

  • %% reszta z dzielenia liczby całkowitej przez liczbę całkowitą,
  • %/% największa liczba całkowita, która pomnożona przez dzielnik jest mniejsza od dzielnej.

Te dwa działania wymagają przypomnienia sobie ze szkoły zasad dzielenia liczb całkowitych z uzyskiwaniem reszty. W R takie działania zostały uogólnione na dowolne liczby rzeczywiste.

> 25%/%3
[1] 8
> 25.5%%3
[1] 1.5
> 11%/%3.5
[1] 3
> 11%%3.5
[1] 1.5
> -1%/%3
[1] -1
> -1%%3
[1] 2
> -25.72%/%3.4
[1] -8
> -25.72%%3.4
[1] 1.48

 

Dla liczb K i L zawsze spełnione jest równanie K = (K %/% L)*L + K %% L. Liczba K %% L jest nieujemna i mniejsza od L.

Kolejność działań

Kolejność wykonywania działań jest taka sama, jak przyjęto to w matematyce. Potęgowanie przed mnożeniem i dzieleniem, mnożenie i dzielenie przed dodawaniem i odejmowaniem. Jeżeli wykonywane działania są równoważne – wykonywane są w kolejności od lewej do prawej. Wyjątkiem jest potęgowanie. Zmiana kolejności działań wymaga używania nawiasów. Służą do tego zawsze nawiasy półokrągłe.

># kolejność wykonywania działań
> 81-2-4
[1] 75
> (81-2)-4
[1] 75
> 81-(2-4)
[1] 83
> 44*2/13*100
[1] 676.9231
> 44*(2/13)*100
[1] 676.9231
> 44*2/(13*100)
[1] 0.06769231
> 3^2^0.5
[1] 4.728804
> (3^2)^0.5
[1] 3
> 3^(2^0.5)
[1] 4.728804
> 3*(2+7*(3+4))
[1] 153
> 3*[2+7*(3+4)]
Error: unexpected '[' in "3*["

 

Choć używanie nawiasów kwadratowych często daje bardziej czytelne wyrażenie matematyczne dla ludzkiego oka, nie jest ono zrozumiałe dla R. Nawiasy kwadratowe maja w R zupełnie inne zastosowanie.

Relacje między liczbami

Podobny charakter do działań mają relacje. Są to operatory “= =”, “!=”, “<“, “<=”, “>”, “>=” umieszczane między liczbami, których wartością jest “prawda” (TRUE) albo “fałsz” (FALSE). Znaczenia tych relacji łatwo się domyślić:

  • == równość liczb,
  • != nierówność liczb
  • < liczba z lewej jest mniejsza od prawej,
  • <= liczba z lewej jest mniejsza lub równa liczbie z prawej,
  • > liczba z lewej jest większa od liczby z prawej,
  • >= liczba z lewej jest większa lub równa liczbie z prawej.
> 3==3
[1] TRUE
> 3==2
[1] FALSE
> 3!=3
[1] FALSE
> 3!=2
[1] TRUE
> 3>2
[1] TRUE
> 3<2
[1] FALSE
> 3>3
[1] FALSE
> 3>=3
[1] TRUE
> 8*3>=8^3
[1] FALSE

 

Warto zwrócić uwagę na to, że “=” nie jest relacją równości, jest nią “= =”.

> 7=7
Błąd w poleceniu '7 = 7':niepoprawna (do_set) lewa strona do przypisania
> 7==7
[1] TRUE

Znak “=” stosuje się jako instrukcje przypisania wartości jakiemuś obiektowi i zostanie opisany później.

Funkcje matematyczne

Funkcje matematyczne znane są dobrze z lekcji matematyki. Najczęściej są to funkcje jednoargumentowe przekształcające liczbę x na y wyliczaną według określonego algorytmu. Zawsze jednak wynik jest wyliczany tylko z pewną dokładnością. W dodatku popełniany błąd nie jest taki sam dla różnych wartości argumentów. Niekiedy ta sama funkcja pojawia się w różnych wariantach wynikających z zastosowania innych algorytmów i innych rodzajach popełnianych błędów.

Najczęściej używane funkcje matematyczne możemy z podzielić na podstawowe, wykładnicze, logarytmiczne, trygonometryczne, cyklometryczne (odwrotne do trygonometrycznych), hiperboliczne oraz specjalne.

Funkcje podstawowe to:

  • abs(x) wartość bezwzględna (wartość absolutna, moduł) liczby,
  • sqrt(x) pierwiastek kwadratowy liczby.
> abs(-3.2345)
[1] 3.2345
> sqrt(32768.2)
[1] 181.0199
> 32768.2^0.5
[1] 181.0199
> sqrt(0)
[1] 0
> sqrt(-1)
[1] NaN
Komunikat ostrzegawczy:
W poleceniu 'sqrt(-1)': wyprodukowano wartości NaN

 

Funkcja sqrt(x) jest dokładnie tym samym, co x^0.5. Czasem, w niektórych wyrażeniach, jej używanie daje bardziej przejrzystą formułę. Do wyliczania innych funkcji potęgowych i pierwiastkowych stosuje się zapis x^a.

Przy obliczaniu funkcji matematycznych odstępy wstawiane przed lub po nawiasach są pomijane.

> sqrt(4)
[1] 2
> sqrt   (4)
[1] 2
> sqrt(    4   )
[1] 2

 

Wyliczanie funkcji wykładniczych można sprowadzić do obliczeń a^x. Jednak częstość stosowania funkcji wykładniczych, których podstawą jest stała e (podstawa logarytmu naturalnego, liczba Eulera, liczba Nepera równa w przybliżeniu 2.718281828459) spowodował, że wyróżniono dwie funkcje wyliczające ex:

  • exp(x) funkcja ex,
  • expm1(x) funkcja ex-1 wyliczona z większą dokładnością niż exp(x)-1 dla liczb bliskich 0.
> exp(1)
[1] 2.718282
> exp(0.000000000001)-1
[1] 1.000089e-12
> expm1(0.000000000001)
[1] 1e-12

 

W R nie ma zaimplementowanej stałej e. Aby posługiwać się tą wartością należy używać exp(1).

Częstość stosowania funkcji logarytmicznych spowodowała, że zaimplementowano do R najwięcej ich rodzajów:

  • log(x, b) logarytm z x o podstawie b,
  • log(x) logarytm naturalny z x,
  • logb(x, b) logarytm z x o podstawie b (wyliczany przy użyciu starszego algorytmu),
  • logb(x) logarytm naturalny z x (wyliczany przy użyciu starszego algorytmu),
  • log10(x) logarytm z x o podstawie 10 (efektywniejszy niż log(x,10),
  • log2(x) logarytm z x o podstawie 2 (efektywniejszy niż log(x,2),
  • log1p(x) logarytm naturalny z x+1 wyliczany z większą dokładnością dla liczb bliskich 0.
> log(1.0000000000002)
[1] 2.000622e-13
> log1p(0.0000000000002)
[1] 2e-13

 

W R zaimplementowano następujące funkcje trygonometryczne:

  • cos(x) funkcja cosinus, jej argumentem jest x wyrażone w radianach,
  • sin(x) funkcja sinus, jej argumentem jest x wyrażone w radianach,
  • tan(x) funkcja tangens, jej argumentem jest x wyrażone w radianach,
  • cospi(x) funkcja cosinus od argumentu pomnożonego przez π,
  • sinpi(x) funkcja sinus od argumentu pomnożonego przez π,
  • tanpi(x) funkcja tangens od argumentu pomnożonego przez π.

Oprócz tego możemy operować stałą π=3.1416 zapisywaną jako pi.

> pi
[1] 3.141593
> format(pi,digits=20)
[1] "3.1415926535897931"
> sin(pi)
[1] 1.224606e-16
> sinpi(1)
[1] 0
> tan(0.5*pi)
[1] 1.633124e+16
> tanpi(0.5)
[1] NaN
Komunikat ostrzegawczy:
W poleceniu 'tanpi(0.5)': wyprodukowano wartości NaN

 

Funkcjami odwrotnymi do funkcji trygonometrycznych są funkcje cyklometryczne. W R jest ich 4:

  • acos(x) funkcja arcus cosinus dla x z przedziału [0,π], zwraca kąty w radianach,
  • asin(x) funkcja arcus sinus dla x z przedziału [-π/2,π/2], zwraca kąty w radianach,
  • atan(x) funkcja arcus tangens dla x z przedziału [-π/2,π/2], zwraca kąty w radianach,
  • atan2(y, x) kąt między prostą łączącą (0,0) z punktem (x,y) a półosią dodatnią 0X, atan2(y,x)=atan(y/x).
> asin(0.5)
[1] 0.5235988
> acos(0.5)
[1] 1.047198
> atan(3/4)
[1] 0.6435011
> atan2(3,4)
[1] 0.6435011

 

W praktycznych zastosowaniach matematyki, trochę bardziej w fizyce niż w biologii, ważną rolę odgrywają funkcje hiperboliczne. Są to kombinacje funkcji exponencjalnych o następujących wzorach:

  • cosh(x) cosinus hiperboliczny równy (ex+e-x)/2,
  • sinh(x) sinus hiperboliczny równy (ex-e-x)/2,
  • tanh(x) tangens hiperboliczny równy (ex-e-x)/(ex+e-x).
> sinh(0.1)-sin(0.1)
[1] 0.0003333334
> cosh(0.01)-cos(0.01)
[1] 1e-04

 

Funkcje odwrotne do funkcji hiperbolicznych noszą nazwę funkcji polowych z racji tego, że ich wartości są równe polom powierzchni pewnych fragmentów hiperboli jednostkowej x2-y2=1.

  • acosh(x) polowy cosinus hiperboliczny równy ln(x+(x2-1)1/2),
  • asinh(x) polowy sinus hiperboliczny równy ln(x+(x2+1)1/2),
  • atanh(x) polowy tangens hiperboliczny ½ln((1+x)/(1-x)).

Wymienione dotąd funkcje klasyfikowane są przez matematyków jako funkcje elementarne. W R ponadto zaimplementowano szereg funkcji definiowanych w matematyce poprzez wzory całkowe, o których wiadomo, że nie da się ich wyrazić w prostszy sposób. Nazywa się je zazwyczaj funkcjami specjalnymi.

  • beta(a, b) funkcja beta,
  • lbeta(a, b) logarytm z wartości bezwzględnej beta,
  • gamma(x) funkcja gamma,
  • lgamma(x) logarytm z wartości bezwzględnej gamma,
  • digamma(x) pierwsza pochodna funkcji lgamma,
  • trigamma(x) druga pochodna funkcji lgamma,
  • psigamma(x, deriv=n) n-ta pochodna funkcji lgamma(), gdzie n może być równe 0, 1, 2,… i dowolnie duże,
  • choose(n, k) uogólnienie symbolu Newtona dla liczb rzeczywistych wyliczane za pomocą funkcji beta,
  • lchoose(n, k) logarytm funkcji choose,
  • factorial(x) uogólnienie silni dla liczb rzeczywistych wyliczane za pomocą funkcji gamma,
  • lfactorial(x) logarytm funkcji factorial.
> 1*2*3*4*5
[1] 120
> factorial(5)
[1] 120
> 1*2*3*4*5*6
[1] 720
> factorial(6)
[1] 720
> gamma(5)
[1] 24
> gamma(6)
[1] 120
> gamma(7)
[1] 720

 

Wymienione funkcje specjalne pojawiają się głównie w statystyce we wzorach gęstości rozkładów ciągłych. Zastępują wyrażenia z silniami i wzorami Newtona czyniąc skomplikowane wzory łatwiejszymi do zapisania i zrozumienia.

Tags:
Spis treści