寫了個Oracle轉換函式,發現當資料為負數的時候,無法轉換,因為業務前端入庫的資料是32位,當JAVA進行有符號轉換為INT類型的時候,會產生負數,而我要再次轉換為二進位進行位的判斷,網上找了好多,都不能做有符號數位轉換,因此按照負數的二進位標記法重新寫了個函數:
負數的二進位方法的表示方法:例如 -5
第一步:首先要把5變成101的二進位形式
第二步:再者就是安位取反,(形成前面全是1)010
第三步:在最後加1 形成:11111111 11111111 11111111 11111011
CREATE OR REPLACE FUNCTION NUMBER_2_BIT(V_NUM NUMBER) RETURN VARCHAR IS
V_RTN VARCHAR(2000);
V_N1 NUMBER;
V_N2 NUMBER;
BEGIN
V_N1 := ABS(V_NUM);
--如果為正數
IF SIGN(V_NUM) > 0 THEN
LOOP
V_N2 := MOD(V_N1, 2);
V_N1 := ABS(TRUNC(V_N1 / 2));
V_RTN := TO_CHAR(V_N2) || V_RTN;
EXIT WHEN V_N1 = 0;
END LOOP;
--dbms_output.put_line('正數結果'||V_RTN);
--補全32位高位0
SELECT lpad(V_RTN,32,0)
INTO V_RTN
FROM dual;
--dbms_output.put_line('正數補全結果'||V_RTN);
ELSE
--轉換為二進位同時按位取反
LOOP
V_N2 := MOD(V_N1, 2);
IF V_N2 = 1 THEN
V_N2 := 0;
ELSIF V_N2 = 0 THEN
V_N2 := 1;
END IF;
V_N1 := ABS(TRUNC(V_N1 / 2));
V_RTN := TO_CHAR(V_N2) || V_RTN;
EXIT WHEN V_N1 = 0;
END LOOP;
--dbms_output.put_line('負數結果'||V_RTN);
--補全32位高位1
SELECT lpad(V_RTN,32,1)
INTO V_RTN
FROM dual;
--dbms_output.put_line('負數補全1結果'||V_RTN);
--二進位轉換為10機制,同時+1
SELECT SUM(data1) + 1
INTO V_N1
FROM (SELECT substr(V_RTN, rownum, 1) * power(2, length(V_RTN) - rownum) data1
FROM dual
CONNECT BY rownum <= length(V_RTN));
-- dbms_output.put_line('轉換為十進位數結果'||V_RTN);
----轉換為二進位
LOOP
V_N2 := MOD(V_N1, 2);
V_N1 := ABS(TRUNC(V_N1 / 2));
V_RTN := TO_CHAR(V_N2) || V_RTN;
EXIT WHEN V_N1 = 0;
END LOOP;
--dbms_output.put_line('負數轉換結果'||V_RTN);
--補全32位高位0
SELECT lpad(V_RTN,32,0)
INTO V_RTN
FROM dual;
--dbms_output.put_line('負數補全0結果'||V_RTN);
END IF;
RETURN V_RTN;
END;