Blog programisty w Oracle PL/SQL

Jest to blog eksperymentatora programisty w PL/SQL dla Oracle. Wszystkie kody tutaj zamieszczone mogą być dowolnie wykorzystywane i zmieniane. A jeśli Ktoś z Gości znajdzie błąd, będę niezwykle wdzięczny...
Zapisz

Szukaj na tym blogu

piątek, 1 lipca 2016

Obliczanie liczby pi w SQL

Kolejnym zastosowaniem klauzuli MODEL będzie napisanie prostego zapytania wyliczającego  liczbę pi  ( ludolfinę ) z zadaną dokładnością z wykorzystaniem algorytmu Leibniza
 data:image/png;base64,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
Zapytanie zwraca cztery kolumny, druga to wartość liczby PI obliczona z funkcji arcus sinus, trzecia
to przybliżona wartość pi obliczona ze wzoru Leibniza, czwarta to  moduł różnicy pomiędzy  kolumną drugą a trzecią. Zwiększając dokładność o kolejne rzędy wielkości  odczujemy istotne  wydłużenie działania zapytania. Iterowanie zakończy się w momencie spełnienia jednego z warunków: osiągniemy zakładaną dokładność lub liczba iteracji osiągnie  wartość umieszczona w nawiasie po  słowie kluczowym ITERATE .
Jak możemy się łatwo przekonać obserwując ostatnia kolumnę, jest to algorytm wolnozbieżny, jego zastosowanie  ma tylko charakter edukacyjny, aby pokazać możliwość  obsługi ciągów liczbowych przez iteracyjną klauzulę MODEL ..

SELECT
      d  + 1 "Nr iteracji",
      PI_ASIN "Pi z funkcji asin",
      4 *PI_COMPUTED "Wartość obliczona",
      DIFF "Różnica"
  FROM   (SELECT   0 d  FROM DUAL)
MODEL
   DIMENSION BY ( 0 d)
   MEASURES (
   CAST( 0 AS  NUMBER)  PI_ASIN,
   CAST( 0 AS  NUMBER)  PI_COMPUTED,
   CAST( 0 AS  NUMBER)  DIFF )   
   RULES
      ITERATE (1000000000) UNTIL (ITERATION_NUMBER >1 AND  DIFF [ITERATION_NUMBER ] < 0.01)
       (      
        PI_ASIN[ ITERATION_NUMBER ] =ASIN(1)*2,      
        PI_COMPUTED[ ITERATION_NUMBER]  =
            CASE ITERATION_NUMBER
                                WHEN 0 THEN 1
                    ELSE
                     PI_COMPUTED[ ITERATION_NUMBER -1 ] + POWER( -1, ITERATION_NUMBER) / (2*ITERATION_NUMBER +1)                   
           END,                     
       DIFF [ ITERATION_NUMBER] = ABS(4*PI_COMPUTED[ ITERATION_NUMBER ] - PI_ASIN[ITERATION_NUMBER] ))