Wykonywanie działań na liczbach wiąże się często z koniecznością użycia różnego rodzaju funkcji matematycznych, jak na przykład pierwiastek, logarytm czy funkcje trygonometryczne. Dostęp do nich uzyskujemy poprzez konkretyzację pakietu rodzajowego ada.numerics.generic_ elementary_functions dla typu liczbowego, dla którego będziemy używać tych funkcji. Konkretyzacja dla typu float jest już "gotowa" - jest to pakiet ada.numerics.elementary_functions. Zdefiniowane są w nim następujące funkcje: sqrt(x) (pierwiastek kwadratowy), log(x) (logarytm naturalny x), log(x,p) (logarytm x przy podstawie p), exp(x) (e do potęgi x), funkcje trygonometryczne - sin, cos, tan, cot, a także arcsin, arccos, arctan, arccot, sinh, cosh, tanh, coth, arcsinh, arccosh, arctanh, arccoth - wszystkie operujące na argumentach typu float, oraz potęga o podstawie i wykładniku typu float. W jego pakiecie rodzicielskim - ada.numerics zadeklarowane są ponadto dwie stałe - e i pi. Oto przykładowe programy:
-- uzycie funkcji matematycznych
--
-- pierwszy program z tej serii
--
-- w trojkacie o podanych trzech bokach
-- obliczamy wysokosc
with ada.text_io,ada.numerics.generic_elementary_functions;
use ada.text_io;
procedure pr8 is
package flt_io is new ada.text_io.float_io(float);
use flt_io;
package fun_mat is new
ada.numerics.generic_elementary_functions(float);
a,b,c,h,p,pole:float;
begin
put_line("Podaj boki trojkata : ");
put("a : ");get(a);new_line;
put("b : ");get(b);new_line;
put("c : ");get(c);new_line(2);
put_line(" UWAGA !!! ");
put("Nie sprawdzam, czy taki trojkat moze w ogole istniec!");
new_line(3);
-- obliczamy pole trojkata za wzoru Herona
p:=(a+b+c)/2.0;
pole:=fun_mat.sqrt(p*(p-a)*(p-b)*(p-c));
-- wykorzystujemy obliczone pole do znalezienia wysokosci
put("wysokosc opuszczona na bok a : ");
h:=2.0*pole/a;
put(h,5,3,0);
new_line;
put("wysokosc opuszczona na bok b : ");
h:=2.0*pole/b;
put(h,5,3,0);
new_line;
put("wysokosc opuszczona na bok c : ");
h:=2.0*pole/c;
put(h,5,3,0);
end pr8;
Kolejny przykład:
-- uzycie funkcji matematycznych
--
-- drugi program z tej serii
--
-- podajemy przyprostokatne trojkata
-- obliczamy dlugosc przeciwprostokatnej
with ada.text_io,ada.numerics.generic_elementary_functions;
use ada.text_io;
procedure pr9 is
package flt_io is new ada.text_io.float_io(float);
use flt_io;
package fun_mat is new
ada.numerics.generic_elementary_functions(float);
a,b,c : float;
begin
put_line("Podaj dlugosci przyprostokatnych trojkata : ");
put("a : ");get(a);new_line;
put("b : ");get(b);new_line;
new_line(3);
c:=fun_mat.sqrt(a**2+b**2);
put("przeciwprostokatna c : ");
put(c,5,3,0);
end pr9;
I jeszcze jeden przyklad - tym razem funkcje trygonometryczne:
-- Program sprawdzajacy, czy tzw. jedynka trygonometryczna
-- rzeczywiscie daje 1.
-- Pojawiaja sie tu funkcje matematyczne, a wiec
-- konkretyzacja pakietu rodzajowego
-- ada.numerics.generic_elementary_functions
-- oraz typ float.
-- Trzeci program z serii "uzycie funkcji matematycznych".
with text_io,ada.numerics.generic_elementary_functions;
use text_io;
procedure pr10 is
package fun_mat is new
ada.numerics.generic_elementary_functions(float);
use fun_mat;
package flt_io is new text_io.float_io(float);
use flt_io;
x,jedynka:float;
begin
put_line("Podaj dowolna liczbe rzeczywista x");
put_line("obliczymy sin(x)^2 + cos(x)^2 ");
put("x = ");
get(x);
jedynka:=sin(x)**2+cos(x)**2;
new_line(3);
put_line("obliczamy tzw. jedynke trygonometryczna.....");
put("otrzymalismy ");put(jedynka,exp=>0);
new_line;
set_col(10);
put("....no i co Ty na to?...");
end pr10;
W programie pr10 pojawiła się po raz pierwszy instrukcja
set_col(n);
powodująca ustawienie kursora w kolumnie o podanym numerze. Stanowi ona część pakietu ada.text_io.
Czwarty przykład dotyczący funkcji matematycznych ilustruje użycie stałych zadeklarowanych w pakiecie ada.numerics:
-- program z uzyciem stalych ada.numerics.pi
-- i ada.numerics.e.
-- Uzywamy pakietow ada.numerics.elementary_functions
-- oraz ada.float_text_io zamiast konkretyzacji
-- pakietow rodzajowych w czesci deklaracyjnej programu.
--
-- Czwarty program z serii funkcje matematyczne
with ada.text_io,ada.numerics,ada.numerics.elementary_functions;
with ada.float_text_io;
use ada.text_io,ada.float_text_io;
use ada.numerics,ada.numerics.elementary_functions;
procedure pr11 is
begin
new_line(2);
put("liczba pi wynosi ");
put(ada.numerics.pi);
new_line;
put("liczba e wynosi ");
put(ada.numerics.e);
new_line;
put("logarytm naturalny liczby e : ");
put(log(e));
new_line;
put("logarytm naturalny liczby 10 : ");
put(log(10.0));
new_line;
put("logarytm przy podstawie 10 liczby 10 : " );
put(log(10.0,10.0));
new_line;
put("2 ^ 3.1 = ");
put(2.0**3.1);
end pr11;
Typy liczbowe i ich zakresy
Dotychczas zapoznaliśmy się z typami integer i float. Nie są to jedyne predefiniowane typy liczbowe. Dostępne są na przykład typy natural i positive (są to właściwie podtypy typu a), a także (w większości implementacji) typy całkowite i zmiennoprzecinkowe o szerszych bądź węższych zakresach - short_short_integer, short_integer, long_integer, long_long_integer, short_float, long_float i long_long_ float. Jakie są ich zakresy? Do tej pory nie znamy zresztą również zakresów typów integer i float. Żądaną informację uzyskamy wykonując poniższy program:
-- program przedstawia typy liczbowe (podstawowe)
-- oraz ich zakresy
-- pojawiaja sie atrybuty typow
with ada.text_io;
use ada.text_io;
procedure pr12 is
package flo_io is new ada.text_io.float_io(long_float);
package fl_io is new ada.text_io.float_io(float);
package floa_io is new ada.text_io.float_io(long_long_float);
package f_io is new ada.text_io.float_io(short_float);
package int_io is new ada.text_io.integer_io(integer);
package inte_io is new ada.text_io.integer_io(long_integer);
package integ_io is new
ada.text_io.integer_io(long_long_integer);
package in_io is new ada.text_io.integer_io(short_integer);
package i_io is new
ada.text_io.integer_io(short_short_integer);
begin
put_line("Mamy nastepujace typy liczbowe : ");
set_col(5);
put_line("1. short_float - typ zmiennoprzecinkowy
o zakresie : ");
set_col(20);
f_io.put(short_float'first);
put(" .. ");f_io.put(short_float'last);
new_line;
set_col(5);
put_line("2. float - typ zmiennoprzecinkowy o zakresie : ");
set_col(20);
fl_io.put(float'first);put(" .. ");fl_io.put(float'last);
new_line;
set_col(5);
put_line("3. long_float - typ zmiennoprzecinkowy
o zakresie : ");
set_col(20);
flo_io.put(long_float'first);
put(" .. ");flo_io.put(long_float'last);
new_line;
set_col(5);
put_line("4. long_long_float - typ zmiennoprzecinkowy
o zakresie : ");
set_col(20);
floa_io.put(long_long_float'first);
put(" .. ");floa_io.put(long_long_float'last);
new_line;
set_col(5);
put_line("5. short_short_integer - typ calkowity
o zakresie : ");
set_col(20);
i_io.put(short_short_integer'first);
put(" .. ");i_io.put(short_short_integer'last);
new_line;
set_col(5);
put_line("6. short_integer - typ calkowity o zakresie : ");
set_col(20);
in_io.put(short_integer'first);
put(" .. ");in_io.put(short_integer'last);
new_line;
set_col(5);
put_line("7. integer - typ calkowity o zakresie : ");
set_col(20);
int_io.put(integer'first);
put(" .. ");int_io.put(integer'last);
new_line;
set_col(5);
put_line("8. long_integer - typ calkowity o zakresie : ");
set_col(20);
inte_io.put(long_integer'first);
put(" .. ");inte_io.put(long_integer'last);
new_line;
set_col(5);
put_line("9. long_long_integer - typ calkowity
o zakresie : ");
set_col(20);
integ_io.put(long_long_integer'first);
put(" .. ");integ_io.put(long_long_integer'last);
new_line;
put_line("oraz nastepujace podtypy typu integer :");
set_col(5);
put("1. positive - typ calkowity o zakresie : ");
int_io.put(positive'first);
put(" .. ");int_io.put(positive'last);
new_line;
set_col(5);
put("2. natural - typ calkowity o zakresie : ");
int_io.put(natural'first);
put(" .. ");int_io.put(natural'last);
new_line;
end pr12;
W celu otrzymania najmniejszej i największej liczby danego typu użyliśmy tzw. atrybutów typów - typ'first i typ'last wypisujących pierwszy (najmniejszy) i ostatni (największy) element należący do danego typu. Jak widać, podtyp positive obejmuje liczby od 1 do integer'last, a natural - od 0 do integer'last. Istnieją jeszcze inne atrybuty typów, które poznamy nieco później. Zauważmy ponadto, że w celu wyprowadzania liczb dokonaliśmy w części deklaracyjnej programu dużej ilości konkretyzacji. Dla typów całkowitych (dla każdego oddzielnie) konkretyzujemy pakiet ada.text_io.integer_io, a dla typów zmiennoprzecinkowych - ada.text_io.float_io. Zauważmy też, że positive i natural nie wymagały odrębnego pakietu, zadowalając się pakietem przeznaczonym dla ich typu bazowego - integer.
|