C++

advertisement
KURS JĘZYKA C++
– WYKŁAD 14 (3.06.2015)
Narzędzia programistyczne w STL
SPIS TREŚCI
Współczynniki wymierne
 Liczby losowe
 Pomiar czasu
 Wyrażenia regularne
 Lokalizacje

WSPÓŁCZYNNIKI WYMIERNE




W pliku nagłówkowym <ratio> jest zdefiniowany szablon do
tworzenia współczynnika wymiernego, w którym licznik i mianownik
jest przekazany poprzez argumenty szablonu.
Mianownik zawsze musi być niezerowy.
Definicja tego szablonu przypomina liczbę wymierną:
template <intmax_t N, intmax_t D = 1>
class ratio {
public:
typedef ratio<num,den> type;
static constexpr intmax_t num;
static constexpr intmax_t den;
//…
};
Licznik num i mianownik den są automatycznie redukowane do
minimalnych wartości (mianownik będzie dodatni).
WSPÓŁCZYNNIKI WYMIERNE
typedef ratio<25,15> FiveThirds;
cout << FiveThirds::num << "/"
<< FiveThirds::den << endl;
// 5/3
ratio<42,42> one;
cout << one.num << "/" << one.den << endl;
// 1/1
ratio<0> zero;
cout << zero.num << "/" << zero.den << endl;
// 0/1
typedef ratio<7,-3> Neg;
cout << Neg::num << "/" << Neg::den << endl;
// -7/3
WSPÓŁCZYNNIKI WYMIERNE
Obliczenia na współczynnikach można wykonywać w trakcie
kompilacji za pomocą następujących szablonów: ratio_add,
ratio_subtract, ratio_multiply i ratio_divide
(operacje arytmetyczne) oraz ratio_equal,
ratio_not_equal, ratio_less, ratio_less_equal,
ratio_greater i ratio_greater_equal (porównania).
 Przykład:
ratio_add<ratio<2,7>,ratio<2,6>>::type
ratio_equal<ratio<5,3>,ratio<25,15>>::value
 Istnieje też wiele predefiniowanych jednostek ratio<>:
pico, nano, micro, milli, centi, deci, deca, hecto,
kilo, mega, giga, tera, itd.

LICZBY LOSOWE
Narzędzia do generowania liczb losowych są zdefiniowane w
pliku nagłówkowym <random>.
 Do generowania liczb pseudolosowych używane są różne silniki
pseudolosowe i różne rozkłady.
 Generatory liczb losowych posiadają wewnętrzny stan i funkcję,
która oblicza rezultat i wysterowuje generator do następnego
stanu – te dwie charakterystyki stanowią silnik generatora.
 Innym bardzo ważnym mechanizmem są rozkłady wyników –
przedział i gęstość zmiennej losowej.

LICZBY LOSOWE

W STL zdefiniowano kilka szablonów silników do generowania
liczb pseudolosowych:
szablon linear_congruential_engine<> – niska jakość
(wielkość stanu to 1 x sizeof(TYPE)),
 szablon subtract_with_carry_engine<> – średnia jakość
(wielkość stanu to 25 x sizeof(TYPE)),
 szablon mersenne_twister_engine<> – wysoka jakość
(wielkość stanu to 624 x sizeof(TYPE))


Adaptery szablonów silników pseudolosowych:


…
Wewnętrzny stan silnika pseudolosowego jest określony przez
ziarno.
LICZBY LOSOWE

Rozkłady liczb pseudolosowych:


...
…
LICZBY LOSOWE

Przykład utworzenia silnika pseudolosowego:
std::default_random_engine dre;

Przykład wykorzystania silnika pseudolosowego do wygenerowania
liczby całkowitej z określonego zakresu z rozkładem jednostajnym:
std::uniform_int_distribution<int> di(0,9);
int x = di(dre);

Przykład wykorzystania silnika pseudolosowego do wygenerowania
liczby rzeczywistej z określonego zakresu z rozkładem jednostajnym:
std::uniform_real_distribution<double> dr(1,2);
double y = dr(dre);
LICZBY LOSOWE
POMIAR CZASU
Biblioteka standardowa wprowadza narzędzia pomocne w
pomiarze czasu – są one zdefiniowane w pliku nagłówkowym
<chrono> w przestrzeni nazw std::chrono.
 Podstawowe pojęcia:


przedział czasowy (ang. duration) – określona liczba tyknięć w
zadanej jednostce czasowej, na przykład:
3 minuty – 3 tyknięcia minut
 86400 sekund – 1 doba liczona w tyknięciach sekund


punkt czasowy (ang. timepoint) – odległość czasowa od pewnego
ustalonego punku początkowego epoki, na przykład:


New Year’s Midnight 2000 – jest to 1262300400 sekund od początku epoki
unixowej (od 1 stycznia 1970 r)
epoka (ang. epoch) – punkt bieżący zegara.
POMIAR CZASU
POMIAR CZASU


Przedział czasowy reprezentowany przez szablon
std::chrono::duration<> jest liczbą określonych jednostek
czasowych (mierzonych w sekundach).
Przykłady:
std::chrono::duration<int>
twentySeconds(20);
std::chrono::duration<double,std::ratio<60>>
halfAMinute(0.5);
std::chrono::duration<long,std::ratio<1,1000>>
oneMillisecond(1);

W bibliotece standardowej zdefiniowano następujące typy przedziałów
czasowych: nanoseconds, microseconds, milliseconds,
seconds, minutes i hours.

Przykłady:
std::chrono::seconds twentySeconds(20);
std::chrono::hours aDay(24);
POMIAR CZASU
Przedziały czasowe możemy porównywać, dodawać,
odejmować, mnożyć i dzielić przez współczynniki oraz
inkrementować i dekrementować o określoną jednostkę.
 Przykład:
chrono::duration<int,ratio<1,3>> d1(1);
// 1/3 sekundy
chrono::duration<int,ratio<1,5>> d2(1);
// 1/5 sekundy
d1 + d2 /* 8 jednostek z 1/15 sekundy */
d1 < d2 /* false */

POMIAR CZASU




Zegar definiuje epokę i długość tyknięcia zegara.
W bibliotece standardowej zdefiniowane są trzy zegary:
system_clock (z funkcjami to_time_t() oraz
from_time_t()), steady_clock (nigdy nie korygowany) i
high_resolution_clock (dokładny zegar systemowy).
Bieżący czas można uzyskać za pomocą metody now():
auto system_start = chrono::system_clock::now();
Sprawdzenie czy upłynęła co najmniej minuta do startu:
if (system_clock::now() > system_start +
minutes(1))
POMIAR CZASU

Punkt czasowy jest reprezentowany przez obiekt time_point.

Pomiaru czasu można dokonać za pomocą punktów czasowych:
auto t = steady_clock::now();
// ... do something ...
auto d = steady_clock::now()−t;

Konwersja punktu czasowego do postaci kalendarzowej:
std::string asString
(const std::chrono::system_clock::time_point &tp) {
// convert to system time:
std::time_t t =
std::chrono::system_clock::to_time_t(tp);
std::string ts =
std::ctime(&t); // convert to calendar time
ts.resize(ts.size()-1); // skip trailing newline
return ts;
}
Download