powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Числа Фибоначчи без MODEL и явной формулы. Можно ли сделать?
25 сообщений из 58, страница 2 из 3
Числа Фибоначчи без MODEL и явной формулы. Можно ли сделать?
    #34720858
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Volder andrey_anonymous...Решается:
- pipelined/table function (очевидно)...
Вам мало?можно попробовать и не очевидно))
Это уже искусственное запутывание довольно простого кода:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
SQL> create or replace type ane_num_tab is table of number
   2   /

Type created

SQL> create or replace function ane_fibonacci_numb(p_num   number)
   2     return ane_num_tab pipelined is
   3     p1 number :=  1 ;
   4     p2 number :=  0 ;
   5   begin
   6     for i in  1 ..p_num loop
   7       case i
   8       when  1  then pipe row( 0 );
   9       when  2  then pipe row( 1 );
  10       else
  11         p1 := p1 + p2;
  12         p2 := p1 - p2;
  13         pipe row(p1);
  14       end case;
  15     end loop;
  16     return;
  17   end;
  18   /

Function created

SQL> select * from table(ane_fibonacci_numb( 20 ));

COLUMN_VALUE
------------
            0 
            1 
            1 
            2 
            3 
            5 
            8 
           13 
           21 
           34 
           55 
           89 
          144 
          233 
          377 
          610 
          987 
         1597 
         2584 
         4181 

 20  rows selected

SQL> 
...
Рейтинг: 0 / 0
Числа Фибоначчи без MODEL и явной формулы. Можно ли сделать?
    #34720880
Newok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous
Вы размышляете о практической ценности при запрете на использование явного представления числа Фибоначчи как функции от порядкового номера?!
Оригинально

Решается:
- pipelined/table function (очевидно)
- XMLQuery (как показал Elic)
- MODEL

А если отменить непонятный запрет, то решается и вовсе без изысков...

Вам мало?

Андрей, да не размышляю я о практической ценности!! Так, посмотрел на время выполнение... ну повеселило оно меня :)

Я вообще создавал топик с одной целью - узнать как решить эту задачку обычным SQL(т.е. с аналитикой), потому как у самого после длительных раздумий особых идей не возникало. И ещё устойчиво не отпускала мысль, что я вроде бы когда-то уже решал эту задачку аналитикой, только вот совсем забыл как :) (до тех пор, пока в один прекрасный момент не вспомнил, что та задачка была "немного"другой)
...
Рейтинг: 0 / 0
Числа Фибоначчи без MODEL и явной формулы. Можно ли сделать?
    #34720939
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
SQL> create or replace
   2     package fib
   3       is
   4           function get(
   5                        p_n natural
   6                       )
   7             return number;
   8           g_n natural :=  2 ;
   9           g_fib_num natural :=  1 ;
  10           g_prev_fib_num natural :=  1 ;
  11   end;
  12   /

Package created.

SQL> create or replace
   2     package body fib
   3       is
   4       function get(
   5                    p_n natural
   6                   )
   7         return number
   8         is
   9             v_temp natural;
  10         begin
  11             case sign(p_n - g_n)
  12               when  1 
  13                 then
  14                   for v_i in g_n +  1 ..p_n loop
  15                     v_temp := g_fib_num + g_prev_fib_num;
  16                     g_prev_fib_num := g_fib_num;
  17                     g_fib_num := v_temp;
  18                   end loop;
  19                   g_n := p_n;
  20               when - 1 
  21                 then
  22                   for v_i in reverse p_n..g_n -  1  loop
  23                     v_temp := g_prev_fib_num;
  24                     g_prev_fib_num := g_fib_num - g_prev_fib_num;
  25                     g_fib_num := v_temp;
  26                   end loop;
  27                   g_n := p_n;
  28               else
  29                 null;
  30             end case;
  31             return g_fib_num;
  32       end;
  33   end;
  34   /

Package body created.

SQL> select rownum -  1  as n,fib.get(rownum -  1 ) fib from dual connect by level <=  15 
   2   /

         N        FIB
---------- ----------
          0            0 
          1            1 
          2            1 
          3            2 
          4            3 
          5            5 
          6            8 
          7           13 
          8           21 
          9           34 
         10           55 

         N        FIB
---------- ----------
         11           89 
         12          144 
         13          233 
         14          377 

 15  rows selected.

SQL> select fib.get( 5 ) from dual
   2   /

FIB.GET( 5 )
----------
          5 

SQL> select fib.get( 10 ) from dual
   2   /

FIB.GET( 10 )
-----------
          55 

SQL> select fib.get( 5 ) from dual
   2   /

FIB.GET( 5 )
----------
          5 

SQL> select fib.get( 5 ) from dual
   2   /

FIB.GET( 5 )
----------
          5 

SQL> select fib.get( 0 ) from dual
   2   /

FIB.GET( 0 )
----------
          0 

SQL> select fib.get( 1 ) from dual
   2   /

FIB.GET( 1 )
----------
          1 

SQL> select rownum +  19  as n,fib.get(rownum +  19 ) fib from dual connect by level <=  5 
   2   /

         N        FIB
---------- ----------
         20         6765 
         21        10946 
         22        17711 
         23        28657 
         24        46368 

SQL> 

SY.
...
Рейтинг: 0 / 0
Числа Фибоначчи без MODEL и явной формулы. Можно ли сделать?
    #34721463
Volder
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andrey_anonymousЭто уже искусственное запутывание довольно простого кода:я ж не спорю - эт так - потренироваться с рекурсией))

PS Вашу pipelined можно упростить - case лишний:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
create or replace function ane_fibonacci_numb(p_num number)
  return ane_num_tab
  pipelined is
  p1 number :=  1 ;
  p2 number :=  0 ;
begin
  for i in  1  .. p_num loop
    pipe row(p2);
    p1 := p1 + p2;
    p2 := p1 - p2;
  end loop;
  return;
end;
...
Рейтинг: 0 / 0
Числа Фибоначчи без MODEL и явной формулы. Можно ли сделать?
    #34722090
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NewokАндрей, да не размышляю я о практической ценности!!
Пусть оправдываются виноватые :)
VolderPS Вашу pipelined можно упростить - case лишний:
Старею :)
SY
Код: plaintext
1.
2.
3.
  15                     v_temp := g_fib_num + g_prev_fib_num;
  16                     g_prev_fib_num := g_fib_num;
  17                     g_fib_num := v_temp;

v_temp вроде не нужна?
...
Рейтинг: 0 / 0
Числа Фибоначчи без MODEL и явной формулы. Можно ли сделать?
    #34722113
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous NewokАндрей, да не размышляю я о практической ценности!!
Пусть оправдываются виноватые :)
VolderPS Вашу pipelined можно упростить - case лишний:
Старею :)
SY
Код: plaintext
1.
2.
3.
  15                     v_temp := g_fib_num + g_prev_fib_num;
  16                     g_prev_fib_num := g_fib_num;
  17                     g_fib_num := v_temp;

v_temp вроде не нужна?

I also cтарею :):

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
create or replace
  package body fib
    is
    function get(
                 p_n natural
                )
      return number
      is
      begin
          case sign(p_n - g_n)
            when  1 
              then
                for v_i in g_n +  1 ..p_n loop
                  g_fib_num := g_fib_num + g_prev_fib_num;
                  g_prev_fib_num := g_fib_num - g_prev_fib_num;
                end loop;
                g_n := p_n;
            when - 1 
              then
                for v_i in reverse p_n..g_n -  1  loop
                  g_prev_fib_num := g_fib_num - g_prev_fib_num;
                  g_fib_num := g_fib_num - g_prev_fib_num;
                end loop;
                g_n := p_n;
            else
              null;
          end case;
          return g_fib_num;
    end;
end;
/

SY.
...
Рейтинг: 0 / 0
Числа Фибоначчи без MODEL и явной формулы. Можно ли сделать?
    #35152147
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Еще одна прямая формула для первых 180 членов
Код: plaintext
1.
2.
3.
4.
5.
SELECT	ROUND(
			 3 . 06524758424985278748642156811189336485  * 
		POWER(	 1 . 61803398874989484820458683436563811772 , LEVEL- 4 )
	) rn
FROM	dual
CONNECT BY LEVEL <  181 
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Числа Фибоначчи без MODEL и явной формулы. Можно ли сделать?
    #38663640
Репетитор-рептилия
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Полюбуйтесь!

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
WITH t_first AS
(
  SELECT 1 i, 1 sum_, 1 n FROM dual
)
, t_next (i, sum_, n) AS
(
  SELECT * FROM t_first
  UNION ALL
  SELECT i + 1, sum_ + n, sum_ FROM t_next
  WHERE i < 100
)
SELECT i, n FROM t_next;
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Числа Фибоначчи без MODEL и явной формулы. Можно ли сделать?
    #39126807
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
SQL> with t as (select rownum id from dual connect by rownum <= 55)
  2  select * from t
  3  match_recognize
  4  (
  5   order by id
  6   all rows per match
  7   pattern ((fib|{-dummy-})+)
  8   define fib as (id = 1 or id = 2 or id = last(fib.id, 1) + last(fib.id, 2))
  9  );

        ID
----------
         1
         2
         3
         5
         8
        13
        21
        34
        55

9 rows selected.
...
Рейтинг: 0 / 0
Числа Фибоначчи без MODEL и явной формулы. Можно ли сделать?
    #39256350
Фотография michael R
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
формула Бине
без рекурсий
...
Рейтинг: 0 / 0
Числа Фибоначчи без MODEL и явной формулы. Можно ли сделать?
    #39256365
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
michael Rформула Бине

Ну-ну :)

Newokбез использования явной формулы?
Elic andrey_anonymousЯ лично не понимаю что такое "явная формула"...Нерекурсивная формула получения i-того члена последовательности.
...
Рейтинг: 0 / 0
Числа Фибоначчи без MODEL и явной формулы. Можно ли сделать?
    #39256375
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous,

Фибоначчи можно сгенерировать на числом SQL
- без каких либо трюков с XML
- без recursive factoring clause
- без model clause
- без pattern matching
- без явной формулы

Этого решения здесь не было пока предложено.
...
Рейтинг: 0 / 0
Числа Фибоначчи без MODEL и явной формулы. Можно ли сделать?
    #39256405
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Собственно вот
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
SQL> with t as
  2   (select rownum - 1 id from dual connect by rownum <= power(2, 15) / 15),
  3  pairs as
  4   (select t1.id id1, t2.id id2
  5      from t t1, t t2
  6     where t2.id between (1 / 2) * t1.id and (3 / 4) * t1.id
  7    union all
  8    select 1, 0 from dual
  9    union all
 10    select 1, 1 from dual)
 11  select rownum lvl, id2 fib
 12    from pairs
 13   start with (id1, id2) in ((1, 0))
 14  connect by prior id1 = id2
 15         and prior (id1 + id2) = id1
 16         and level <= 15;

       LVL        FIB
---------- ----------
         1          0
         2          1
         3          1
         4          2
         5          3
         6          5
         7          8
         8         13
         9         21
        10         34
        11         55
        12         89
        13        144
        14        233
        15        377

15 rows selected.

Очевидно что model и subqery factoring выполняют полноценную генерацию с учетом уже сгенерированных.
pattern matching делает перебор из множества 0...f n ,
connect by делает перебор из множества мощности порядка O(f n 2 ),
где f n - n-ое число Фибоначчи.
...
Рейтинг: 0 / 0
Числа Фибоначчи без MODEL и явной формулы. Можно ли сделать?
    #39256414
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dbms_photoshopandrey_anonymous,

Фибоначчи можно сгенерировать на числом SQL
- без каких либо трюков с XML
- без recursive factoring clause
- без model clause
- без pattern matching
- без явной формулы

Этого решения здесь не было пока предложено.
С точностью до опечатки (обнаруженной и поправленной в последующих сообщениях) - решение, отвечающее указанным критериям, представлено было:
4507502

Но Ваше, на мой взгляд, вполне гармонично дополняет тему разогрева атмосферы дорогостоящим оборудованием, обсуждавшуюся в данном топике :)
...
Рейтинг: 0 / 0
Числа Фибоначчи без MODEL и явной формулы. Можно ли сделать?
    #39256431
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous,

Это конечно не явная формула i-го члена, но формула многочлена. Я решил обойтись без формулировок всех тонкостей формул. :)
Мое решение не для использования где либо а исключительно для демонстрации возможностей SQL.
...
Рейтинг: 0 / 0
Числа Фибоначчи без MODEL и явной формулы. Можно ли сделать?
    #39256466
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dbms_photoshopandrey_anonymous,
Это конечно не явная формула i-го члена, но формула многочлена.
Я решил обойтись без формулировок всех тонкостей формул. :)
Ну... неубедительно :)
В предложенном решении идет такой же поиск полным перебором на том же множестве, разница - лишь в формулировке предиката, который и определяет "формулу".
Таким образом, принимая во внимание, что "без формулировок всех тонкостей формул" задача с ограничением "без применения формул" решена вообще быть не может, предложенное решение либо не является решением в указанных ограничениях, либо эквивалентно ранее предложенному :)
...
Рейтинг: 0 / 0
Числа Фибоначчи без MODEL и явной формулы. Можно ли сделать?
    #39256492
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous"без формулировок всех тонкостей формул" задача с ограничением "без применения формул" решена вообще быть не может
Пожалуй, это слишком сильное утверждение.
Одно решение все-таки есть: импорт таблицы с искомой последовательностью и простые запросы к ней.
Все вопросы на тему "где ты взял таблицу для импорта" отметем как выходящие за scope данной конференции :)
...
Рейтинг: 0 / 0
Числа Фибоначчи без MODEL и явной формулы. Можно ли сделать?
    #39256500
Фотография Валерий Юринский
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В апреле 2012 г. в рамках Олимпиады по Oracle SQL мы предлагали участникам решить такую задачу:

"Используя только таблицу DUAL вычислить и вывести в результат
все числа Фибоначчи в диапазоне от 1 до 1000 (1 <= n_fib <= 1000).
Числа в результате не должны повторяться
и должны быть отсортированы по возрастанию. "


Тогда я потренировался с Recursive Subquery Factoring
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
-- Вычисление чисел Фибоначчи
-- Используется Recursive Subquery Factoring
-- 1 <= N <= 1000
WITH fibon(n, z) AS (
SELECT 1 AS n, 1 as z FROM dual
UNION ALL
SELECT B.m, f.n 
FROM (SELECT rownum+1 m FROM dual CONNECT BY LEVEL < 1000) B
   , fibon F
WHERE F.n+F.z  = B.m
)
--
SELECT n FROM fibon
ORDER BY n;
...
Рейтинг: 0 / 0
Числа Фибоначчи без MODEL и явной формулы. Можно ли сделать?
    #39256515
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Валерий Юринский,

врроде так ещё проще
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
WITH fibon(n, z) AS
(
    SELECT 1 AS n, 1 AS z FROM dual
    UNION ALL
    SELECT n+z, n 
      FROM fibon F
     WHERE n+z < 1000
)
SELECT n FROM fibon
ORDER BY n;

но народ искал что-то другое
...
Рейтинг: 0 / 0
Числа Фибоначчи без MODEL и явной формулы. Можно ли сделать?
    #39256522
Фотография Валерий Юринский
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymxВалерий Юринский,

вроде так ещё проще
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
WITH fibon(n, z) AS
(
    SELECT 1 AS n, 1 AS z FROM dual
    UNION ALL
    SELECT n+z, n 
      FROM fibon F
     WHERE n+z < 1000
)
SELECT n FROM fibon
ORDER BY n;

но народ искал что-то другоеТогда Recursive Subquery Factoring было новым и малоизвестным... :-)

Народ всегда ищет что-то другое, но в итоге ест, то, что ему дают...
...
Рейтинг: 0 / 0
Числа Фибоначчи без MODEL и явной формулы. Можно ли сделать?
    #39256533
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymousdbms_photoshopandrey_anonymous,
Это конечно не явная формула i-го члена, но формула многочлена.
Я решил обойтись без формулировок всех тонкостей формул. :)
Ну... неубедительно :)
В предложенном решении идет такой же поиск полным перебором на том же множестве, разница - лишь в формулировке предиката, который и определяет "формулу".
Таким образом, принимая во внимание, что "без формулировок всех тонкостей формул" задача с ограничением "без применения формул" решена вообще быть не может, предложенное решение либо не является решением в указанных ограничениях, либо эквивалентно ранее предложенному :)Это шутка? Сумма двух предыдущих это определение!
Ограничение i-го члена сверху и то, что предыдущий попадает в интервал 1/2...3/4 следующего было придумано за пару минут.
Перебор идет не на том же множестве, а на значительно большем, что я уже описал.
Если охота позанудствовать можно делать это сколько угодно, но сути это не меняет.

Валерий ЮринскийВ апреле 2012Валерий ЮринскийТогда Recursive Subquery Factoring было новым и малоизвестным... :-)Если вспомнить когда вышла 11.2 можно понять насколько это заявление нелепо.
Что для кого-то новшество, для многих других давно пройденный этап.

PS. Еще из решений на чистом SQL не был предложен вариант с XML.
То что было предложено здесь - ПЯТНИЧНАЯ ЗАДАЧА - рекурсия в SQL без MODEL :) очевидно с ипользованием PL/SQL и не катит.
...
Рейтинг: 0 / 0
Числа Фибоначчи без MODEL и явной формулы. Можно ли сделать?
    #39256541
Фотография Валерий Юринский
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dbms_photoshopВалерий ЮринскийВ апреле 2012Валерий ЮринскийТогда Recursive Subquery Factoring было новым и малоизвестным... :-)Если вспомнить когда вышла 11.2 можно понять насколько это заявление нелепо.
Что для кого-то новшество, для многих других давно пройденный этап.Да, и симметрично:

Что для кого-то давно пройденный этап, для многих других новшество.

У каждого свои новшества и пройденные этапы... :-)
...
Рейтинг: 0 / 0
Числа Фибоначчи без MODEL и явной формулы. Можно ли сделать?
    #39256573
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dbms_photoshopСумма двух предыдущих это определение!
А разве это как-то противоречит моим тезисам?
В общем и целом - мысль не понял.
...
Рейтинг: 0 / 0
Числа Фибоначчи без MODEL и явной формулы. Можно ли сделать?
    #39256579
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous,

Не вижу дальнейшего смысла расжевывать отличия "явной формулы" от определения чисел Фибоначчи.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Числа Фибоначчи без MODEL и явной формулы. Можно ли сделать?
    #39487801
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymxЕще одна прямая формула для первых 180 членов
Код: plsql
1.
2.
3.
4.
5.
6.
SELECT	ROUND(
			3.06524758424985278748642156811189336485 * 
		POWER(	1.61803398874989484820458683436563811772, LEVEL-4)
	) rn
FROM	dual
CONNECT BY LEVEL < 181


хитрец :)
ты откуда вынул последнюю пятерку в 3.06524758424985278748642156811189336485?
Руками подбирал?

вот еще вариант для на пользовательском вычислении степени.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
create or replace package sqlru_pwr is

-- применения процедуры возведения в степень
----------------------------

-- возводим в степень способом русских крестьян (алгоритм Ахмеса)
-- cdterms_test_dbr.Power
Function Power( px in number
              , pn In Pls_integer -- целая степень
              ) Return Number Deterministic Parallel_Enable;
----------------------------

-- дублировние строки pc_valx в количестве pn раз на бюазе возведения в степень
Function Replicate(pc_valx in Varchar2, pn In Pls_integer -- количестов дублирований (степень)
                  ) return Varchar2 Deterministic Parallel_Enable;       
----------------------------

-- вычисление чисел Фибоначчи на парах по Степанову. 
Function dkas_fib_p(pn In Number -- номер числа
                 ) Return Number Deterministic Parallel_Enable;
----------------------------

-- вычисление чисел Фибоначчи на парах по Степанову. (Возведение пар в степень)
-- follow Donald Knuth & Alex Stepanov ( see Sean Parent demonstration for full matrix version)
-- 193 - номер последнего числа, которое может быть правильно вычислено в PL/SQL (=9663391306290450775010025392525829059713).
-- 9999999999999999999999999999999999999999 - число до которого работает без ошибок целочисленная арифметика в PL/SQL
-- 193-е число Фибоначчи - самое большое, не превышающее этого значения.
Function dkas_fib_p(pn In Number -- номер числа
                 ) Return Number Deterministic Parallel_Enable;

End sqlru_pwr;
/
create or replace package body sqlru_pwr
-------------------------------------------------------------------------------------
-- для варианта вычисления чисел Фибоначчи на парах по Степанову
TYPE T_FIB_PARE is record(m0 Number, m1 Number);
--------------------------------------------------------------------------------------

-- единица для чисел по умножению
Function mlt_Identity_Element(pv_type in Number) return number 
  Is
Begin
  Return 1.0;
End;
------------------------

-- единица для пары Степанова, производящей числа Фибоначчи
Function mlt_Identity_Element(pv_type in T_FIB_PARE) return T_FIB_PARE Deterministic
  Is
  cmtx_fib_identity  T_FIB_PARE;
Begin
  cmtx_fib_identity.m0 := 0;
  cmtx_fib_identity.m1 := 1;
  Return cmtx_fib_identity;
End;   
------------------------

-- единица для строк по конкатенации
Function mlt_Identity_Element(pv_type in Varchar2) return Varchar2 Deterministic
  Is
Begin
  Return '';
End;
------------------------

-- операция крестьянского алгоритма для чисел по умножению
Function mult_op(x in Number, y in Number) return Number deterministic
  is
Begin
  Return x*y;
End;    
------------------------

-- операция крестьянского алгоритма для строк по конкатенации
Function mult_op(x in Varchar2, y in Varchar2) return Varchar2 deterministic
  is
Begin
  Return x||y;
End;  
------------------------  

-- операция крестьянского алгоритма  для "Фибоначевой пары" по умножению
Function mult_op(x in T_FIB_PARE, y in T_FIB_PARE) Return T_FIB_PARE
Is 
  r_result T_FIB_PARE;
Begin
  -- followed by Alex Stepanov
  r_result.m0 := x.m0 * (y.m1 + y.m0) + x.m1 * y.m0;
  r_result.m1 := x.m0 * y.m0 + x.m1 * y.m1;
  Return r_result;
End;
------------------------

-- Определение нечетного числа - для нечетного числа возвратим 1
Function Odd_i(iparam In Pls_Integer ) return pls_integer Deterministic Parallel_Enable
Is
    ci_One constant Pls_integer := 1;
Begin
    Return Bitand(iparam,ci_One);
End;   
--------------------------

-- целочисленная половина (для уменьшения степени вдвое на шаге крестьянского алгоритма)
Function Half(iparam In Pls_Integer ) Return Pls_integer 
is
Begin
  -- ограничимся положительными значенями, иначе бы потребовался печальный Trunc
  Return Floor(iparam/2); 
End;    
------------------------

-- возводим в степень способом русских крестьян (алгоритм Ахмеса)
-- (для чисел - как демонстрация и для проверки правильности работы алгоритма.)
-- версии для других типов данных образуются из этой путем копирования и замены типов входных параметров 
-- и им соответствующих локальных переменных.
-- follow Alex Stepanov
Function Power_rpa( px in number
              , pn In Pls_integer -- целая степень
              ) return number Deterministic Parallel_Enable
Is
  
  degree Pls_integer;
  x_lc Number;
  mresult Number;
Begin
  PRAGMA INLINE(mlt_Identity_Element,'YES');
  If pn = 0 Then return mlt_Identity_Element(px); End If;
  degree := pn; 
  x_lc := px;
  PRAGMA INLINE(Odd_i,'YES');
  While Odd_i(degree) = 0 
  Loop
    PRAGMA INLINE(Half,'YES');
    degree := Half(degree);
    
    PRAGMA INLINE(mult_op,'YES');
    x_lc := mult_op(x_lc, x_lc);
  End Loop; 
  mresult := x_lc;
  
  PRAGMA INLINE(Half,'YES');
  degree := Half(degree);
  
  While degree != 0
  Loop
    x_lc := mult_op(x_lc, x_lc);
    PRAGMA INLINE(Odd_i,'YES');
    If Odd_i(degree) != 0
      Then
        PRAGMA INLINE(mult_op,'YES');        
        mresult := mult_op(mresult, x_lc);
    End If;
    PRAGMA INLINE(Half,'YES');
    degree := Half(degree);
  End Loop;
  Return mresult; 
End;                
------------------------

-- возведение в степень (дублирование) строки
-- (аналог replicate или repeat в "других языках", в интерфейсе пакета публикуется как Replicate)
-- copy-past версии для чисел с заменой типов параметра, результата и локальных переменных
-- (возведение в степень способом русских крестьян (алгоритм Ахмеса))
Function Power_rpa( px in Varchar2
              , pn In Pls_integer -- целая степень
              ) return Varchar2 Deterministic Parallel_Enable
Is
  SUBTYPE T_MAXSTRING IS Varchar2(32767);
  degree Pls_integer;
  x_lc T_MAXSTRING;
  mresult T_MAXSTRING;
Begin
  PRAGMA INLINE(mlt_Identity_Element,'YES');
  If pn = 0 Then return mlt_Identity_Element(px); End If;
  degree := pn; 
  x_lc := px;
  PRAGMA INLINE(Odd_i,'YES');
  While Odd_i(degree) = 0 
  Loop
    PRAGMA INLINE(Half,'YES');
    degree := Half(degree);
    
    PRAGMA INLINE(mult_op,'YES');
    x_lc := mult_op(x_lc, x_lc);
  End Loop; 
  mresult := x_lc;
  
  PRAGMA INLINE(Half,'YES');
  degree := Half(degree);
  
  While degree != 0
  Loop
    x_lc := mult_op(x_lc, x_lc);
    PRAGMA INLINE(Odd_i,'YES');
    If Odd_i(degree) != 0
      Then
        PRAGMA INLINE(mult_op,'YES');        
        mresult := mult_op(mresult, x_lc);
    End If;
    PRAGMA INLINE(Half,'YES');
    degree := Half(degree);
  End Loop;
  Return mresult; 
End;   
------------------------

-- возведение в степень для пар Фибоначчи (по Степанову)
-- (возведение в степень способом русских крестьян (алгоритм Ахмеса))
Function Power_rpa( px in T_FIB_PARE
              , pn In Pls_integer -- целая степень
              ) return T_FIB_PARE  Deterministic Parallel_Enable
Is
  
  degree Pls_integer;
  x_lc T_FIB_PARE;
  mresult T_FIB_PARE;
Begin
  If pn = 0 Then return mlt_Identity_Element(px); End If;
  degree := pn;  
  x_lc := px;
  While Odd_i(degree) = 0 
  Loop
    degree := Half(degree);
    x_lc := mult_op(x_lc, x_lc);
  End Loop; 
  mresult := x_lc;
  degree := Half(degree);
  
  While degree != 0
  Loop
    x_lc := mult_op(x_lc, x_lc);
    If Odd_i(degree) != 0
      Then
        mresult := mult_op(mresult, x_lc);
    End If;
    degree := Half(degree);
  End Loop;
  Return mresult; 
End;                
------------------------

-- возведение числа в целочисленную степень
Function Power(px in Number
             , pn In Pls_integer -- целая степень
              ) return Number  Deterministic Parallel_Enable
is
 
Begin
  IF COALESCE(sign(px), 2) in (0,2) THEN Return px; END IF;
  Return CASE sign(pn)
         WHEN 1 THEN Power_rpa(px, pn)
         WHEN 0 THEN Power_rpa(px, pn)
         WHEN -1 THEN -- отрицательная степень
           1/Power_rpa(px, abs(pn))
         ELSE -- Null в показателе степени
           Cast(Null as number)  
         END;
    
End;
------------------------

-- дублировние строки pc_valx в количестве pn раз
Function Replicate(pc_valx in Varchar2, pn In Pls_integer -- количестов дублирований (степень)
                  ) return Varchar2 Deterministic Parallel_Enable
Is
Begin
  PRAGMA INLINE(Power_rpa,'YES');
  Return Power_rpa(pc_valx, pn);
End; 
------------------------

-- вычисление чисел Фибоначчи на парах по Степанову. (Возведение пар в степень)
-- follow Donald Knuth & Alex Stepanov ( see Sean Parent demonstration for full matrix version)
-- 193 - номер последнего числа, которое может быть правильно вычислено в PL/SQL (=9663391306290450775010025392525829059713).
-- 9999999999999999999999999999999999999999 - число до которого точно работает целочисленная арифметика в PL/SQL
-- 193-е число Фибоначчи - самое большое, не превышающее этого значения.
Function dkas_fib_p(pn In Number -- номер числа
                 ) Return Number Deterministic Parallel_Enable
Is
  Alex_Pare T_FIB_PARE; -- нижняя строка производящей матрицы 2x2 (см. Д. Кнут) ((1,1),(1,0))
  is_negativ_pwr boolean; -- знак степени
Begin
  -- начальное значение пары
  Alex_pare.m0 := 1;
  Alex_pare.m1 := 0;
  
  If pn = 0 Then Return 0; End If;
  is_negativ_pwr := (sign(pn) = -1);
  
  Return Case is_negativ_pwr
          When False Then  
            power_rpa(Alex_Pare, pn ).m0
          When True Then
            case Odd_i(abs(pn)) when 1 then 1 else -1 end * power_rpa(Alex_Pare, abs(pn) ).m0
          Else Cast(Null as Number)
          End;
  
End;                      
                   
  
end sqlru_pwr;
/
ALTER PACKAGE sqlru_pwr COMPILE BODY PLSQL_OPTIMIZE_LEVEL = 2;
SELECT level as rn,
  to_char( sqlru_pwr.dkas_fib_p(level), 'TM9') as fib2
  , -level
  , to_char( sqlru_pwr.dkas_fib_p(-level), 'TM9') as nega_fib2
  , sqlru_pwr.Replicate('-sql.ru-',level) as repl_demo
  , to_char(sqlru_pwr.Power(2, level), 'TM9') as pwr
  , to_char(sqlru_pwr.Power(2, -level), 'TM9') as nega_pwr
FROM  dual
CONNECT BY LEVEL < 194;

...
Рейтинг: 0 / 0
25 сообщений из 58, страница 2 из 3
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Числа Фибоначчи без MODEL и явной формулы. Можно ли сделать?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]