2009-04-22 3 views
7

shift의 대체 연산자가 PL/SQL에 있습니까? bitand 함수가 있지만, binary_integer -type 인수 만 받아들입니다.PL/SQL의 시프트 연산자

정말로 긴 숫자의 하위/상위 비트를 확인해야한다면 어떻게해야합니까?

C에는 <<>> 연산자가 있습니다. PL/SQL에서 어떻게 구현할 수 있습니까?

답변

3

여기 내 자신의 LPAD/RPAD 솔루션입니다.

나는 Tom Kyte package을 기본으로 확장했습니다. 간단하게 (변화를 곱하여

create or replace function bin_shift_right 
( p_bin in varchar2, 
    p_shift in number default null) return varchar2 
is 
    l_len number; 
    l_shift number; 
begin 
    l_shift := nvl(p_shift, 1); 
    l_len := length(p_bin); 
    if (l_len <= 0) then 
     return null; 
    end if; 
    if (l_shift > l_len) then 
     l_shift := l_len; 
    end if; 

    return lpad(substr(p_bin, 1, l_len - l_shift), l_len, '0'); 
end bin_shift_right; 

create or replace function shright 
( p_num in number, 
    p_shift in number default null) return number 
is 
begin 
    if (trunc(p_num) <> p_num OR p_num < 0) then 
     raise PROGRAM_ERROR; 
    end if; 
    return nvl(to_dec(bin_shift_right(to_bin(p_num), p_shift), 2), 0); 
end shright; 
/

그리고 테스트

SQL> 
SQL> select shright(123) from dual; 

SHRIGHT(123) 
------------ 
      61 

SQL> 
SQL> select shright(123, 2) from dual; 

SHRIGHT(123,2) 
-------------- 
      30 

SQL> 
SQL> select shright(123, 10) from dual; 

SHRIGHT(123,10) 
--------------- 


SQL>/
5

Oracle 버전 8부터 데이터베이스에 Java 코드를 사용할 수 있습니다. PL/SQL에서 자바 코드에 대한 래퍼를 정의 할 수 있습니다. 예 :

PACKAGE BODY JAVA_CODE 
IS 
    function bitshift_left(x in number, 
         n in number) return number 
    is language java name 'com.foo.Bitshift(java.lang.Integer, 
              java.lang.Integer) return java.lang.Integer'; 
END JAVA_CODE; 

Java 코드에서 shift 연산자를 사용할 수 있습니다. 조금 어색하지만,이 방법으로 작동 할 수 있습니다.

Oracle XE에서는 '무료'버전의 Java에 대한 지원이 없으므로 슬프게도 불가능합니다.

+0

감사합니다. 나는 pl/SQL 방식으로 몇 분 안에 게시 할 것입니다. – drnk

6

다음 대답은 불가지론 엔디안되지 않고 내 표현이 리틀 엔디안 형식을 기반으로 ...

당신은 이동할 수있는 비트 왼쪽으로) 또는 인수를 2로 나누어 x의 제곱으로 나눕니다. 여기서 x는 이동할 비트 수입니다. 예를 들어, I는 숫자 (255 : 11111111)의 하위 바이트를 이동해야하는 경우 I는 다음과 같은 동작을 수행 할 왼쪽으로 16 비트 : I의 값을 전환 할 경우, 반대로

select 255 * power(2,16) from dual; 
-- the result will be (16711680:111111110000000000000000) 

을 16,711,680 오른쪽으로 16 비트 다음을 수행합니다.

select 16711680/power(2,16) from dual; 
-- the result will be (255:11111111)