Stefan Sokołowski, Podstawy programowania
LABORATORIUM 6


Zadanie 0:

Program
   
   #include<stdio.h>

   int main() {
    if (! 2==3)  printf("\n 2 nie rowna sie 3\n\n");
    else  printf("\n 2 rowna sie 3\n\n");
    return 0;
   }
  
drukuje bzdurę (sprawdzić!). Wyjaśnić dlaczego.


Zadanie 1:

Proszę uruchomić program, który Na przykład, jeśli użytkownik napisze to powinien uzyskać wydruk około 50 dat, postaci: Uwaga:
Program powinien te daty wyliczać, a nie korzystać z jakiegoś już gotowego spisu, ani z jakiejś gotowej biblioteki.

Wskazówka:
Może pomóc zastanowienie się, jak przeliczyć na datę dzień roku o podanym numerze; np. w roku 2025


Zadanie 2:

Jak wiadomo, liczba pierwsza to taka liczba naturalna  p ≥ 2 , która nie posiada żadnego dzielnika naturalnego  d  takiego że  2 ≤ d < p .

Proszę uruchomić program, który Czyli wydruki tego programu dla różnych wartości  n  powinny wyglądać jakoś tak:
  Ile liczb pierwszych (co najmniej 1)?  3

  Spis 3 najmniejszych liczb pierwszych:
    2
    3
    5
       
  Ile liczb pierwszych (co najmniej 1)?  7

  Spis 7 najmniejszych liczb pierwszych:
    2
    3
    5
    7
   11
   13
   17

Przetestować program dla dużych wartości n i porównać wyniki z jakimś dostępnym spisem liczb pierwszych, np. ze spisem w Wikipedii.

Wskazówka:
Naturalnym (choć oczywiście nie jedynym) sposobem rozwiązania tego zadania jest komenda warunkowa if, wewnątrz pętli while, zagnieżdżonej w pętli for. Zewnętrzna pętla for powinna odliczać, ile już liczb pierwszych znaleziono i wyświetlono. Pętla while powinna sprawdzać kolejnego ,,kandydata'' na liczbę pierwszą, czyli czy jakaś liczba mniejsza jest jego dzielnikiem. Komenda if powinna sprawdzać, czy znaleźliśmy dzielnik ,,kandydata'' — jeśli tak, to ,,kandydat'' nie jest liczbą pierwszą i należy wypróbować następnego; a jeśli nie, to sprawdzić następny dzielnik.


Zadanie 3:

Sumy nieskończonych ciągów liczb mogą być skończone (szczegóły: proszę wpisać do wyszukiwarki np. ,,szeregi liczbowe''). Pewne wartości funkcji trudnych do policzenia dają się przedstawić jako nieskończone sumy składników łatwych do policzenia. Na przykład Takie rozkłady na nieskończone sumy wykorzystuje się do przybliżonego obliczania wartości funkcji na liczbach rzeczywistych. Oczywiście w komputerze nie można wykonać nieskończonego sumowania. Ale żeby w ogóle istniała skończona suma, kolejne składniki muszą szybko maleć (powyżej: silnia w mianowniku szybko rośnie), wobec tego dalekie składniki wnoszą niewiele do sumy, więc ich ucięcie wprowadza tylko niewielki błąd.

Proszę napisać i uruchomić program, który Na przykład wydruk programu dla eπ dla 10 składników sumy mógłby wyglądać tak:
  OBLICZANIE EKSPONENSU:
  Ile skladnikow przyblizenia? 10
  argument == 3.14

    l.skladn. | wartosc przyblizenia
 -------------+---------------------
           1  |  1.000000
           2  |  4.140000
           3  |  9.069800
           4  |  14.229657
           5  |  18.280145
           6  |  20.823852
           7  |  22.155058
           8  |  22.752199
           9  |  22.986577
          10  |  23.068349
 -------------+---------------------
  e^ 3.140000 |  23.103867
Począwszy od jakiej liczby składników suma już nie zmienia wartości w ramach wyświetlanej liczby cyfr znaczących?

Wskazówka:
Silnia bardzo szybko rośnie, więc policzenie mianownika dla  n>12  nie będzie możliwe (por. zad. 2 z Laboratorium 3). Proszę znaleźć sposób na obliczanie n-tego składnika sumy bez liczenia silni. Zresztą potęg  xn  również nie trzeba obliczać — trzeba jakoś policzyć cały n-ty składnik w oparciu o znaną wcześniej wartość  n−1 -szego składnika.


Zadanie 4:

W sposób podobny do omówionego w zad.3 wyliczyć wartości przybliżone następujacych funkcji
(a)          (b)


Uwaga:
Argument funkcji trygonometrycznej musi być podany w mierze łukowej, a nie w stopniach. Przelicznik jest taki: przy czym w języku C zamiast π należy pisać M_PI. Na przykład  sin(M_PI/6) = 0.5 , bo  π/6 = 30° .


Zadanie 5:

Dla dużych wartości x program liczący wg wzorów sumacyjnych z zad.4 daje surrealistycznie duże wyniki (wartości sinusa i cosinusa powinny mieścić się między −1.0 a 1.0). Proszę zastanowić się, skąd to się bierze.

Napisać program, który liczy te wartości poprawnie, nawet dla dużych argumentów.


Zadanie 6 domowe:

Ze szkoły wiemy, jak rozwiązać równanie   f(x) = 0   w przypadku, kiedy funkcja  f  jest albo liniowa, albo kwadratowa. Kiedy tak nie jest, problem jest trudniejszy, ale można w dosyć prosty sposób znaleźć przybliżone rozwiązanie równania. Wystarczy znaleźć jakieś dwie liczby  x1  i  x2 , dla których wartości funkcji mają różne znaki, czyli leżą po przeciwnej stronie osi  x . Na poniższych rysunkach jest to zilustrowane dla funkcji Zauważamy (zgadujemy i wyliczamy), że więc funkcja  f  musi gdzieś między 0 a 2 przecinać oś  x . Dzielimy przedział  [0 . . 2]  na pół i sprawdzamy, że  f(1) = −1 , więc funkcja zmienia znak na krótszym przedziale  [0 . . 1] ...; itd. W każdym obrocie pętli dzielimy przedział, na którym funkcja zmienia znak, na pół i w ten sposób coraz ciaśniej ,,osaczamy'' punkt przecięcia funkcji z osią  x , czyli rozwiązanie (jedno z możliwych rozwiązań) równania.

f(0) = 1
f(2) = −1
  f(0) = 1
f(1) = −1
  f(0.5) = 0.125
f(1) = −1
  f(0.5) = 0.125
f(0.75) = −0.453125
     


Wychodzimy z pętli, kiedy długość przedziału stanie się mniejsza niż podana z góry mała liczba rzeczywista wyrażająca żądaną precyzją. Wtedy jako przybliżone rozwiązanie można podać dowolną liczbę z tego przedziału, na przykład jego środek.

Proszę skonstruować program, który Tą samą metodę zastosować do znalezienia przybliżonego rozwiązania równania innego niż podane wyżej; np. do gdzie   x ∈ [−0.5 . . 0.5] ; albo do gdzie   x ∈ (0 . . π/2)  (w C logarytm naturalny nazywa się  log , a tangens nazywa się  tan  — por. tutaj). Oczywiście zacząć trzeba od znalezienia (zgadnięcia) dwóch wielkości  x1  i  x2 , na których funkcja zmienia znak:  f(x1) · f(x2) < 0 .


Do mojej głównej witrynki

Ostatnia modyfikacja: 3 listopada 2024