create table t ( x number, b1 int, b2 int, b3 int, b4 int, b5 int, b6 int );
insert into t values ( 123456 , 195,13,35,57, null, null );
insert into t values ( 12345.6 , 195,2,24,46,61, null );
insert into t values ( 1234.56 , 194,13,35,57, null, null );
insert into t values ( 123.456 , 194,2,24,46,61, null );
insert into t values ( -123456 , 60,89,67,45,102, null );
insert into t values ( -12345.6 , 60,100,78,56,41,102 );
insert into t values (-1234.56 , 61,89,67,45,102, null );
insert into t values (-123.456 , 61,100,78,56,41,102 );
column dmp format a35
column b1_bin format a8
column b1_1scomp format a8
column nums format a20
column nums2 format a20
ops$tkyte@ORA9IR2> select x,
2 dmp,
3 exp e,
4 sign || substr(nums,1,2*exp)||'.'||substr(nums,2*exp+1) nums2
5 from (
6 select x,
7 dmp,
8 sign,
9 exp,
10 b2||b3||b4||b5||b6 nums,
11 b2, b3, b4, b5, b6
12 from (
13 select x,
14 dmp,
15 sign,
16 b1_bin,
17 b1_1scomp,
18 case when sign = '+' then bitand(b1,to_dec('01111111',2))-64
19 when sign = '-' then to_dec( substr( b1_1scomp, 2), 2 )-64
20 end exp,
21 to_char( decode( sign, '+', b2-1, decode(b2,102,null,100-(b2-1)) ), 'fm00') b2,
22 to_char( decode( sign, '+', b3-1, decode(b3,102,null,100-(b3-1)) ), 'fm00') b3,
23 to_char( decode( sign, '+', b4-1, decode(b4,102,null,100-(b4-1)) ), 'fm00') b4,
24 to_char( decode( sign, '+', b5-1, decode(b5,102,null,100-(b5-1)) ), 'fm00') b5,
25 to_char( decode( sign, '+', b6-1, decode(b6,102,null,100-(b6-1)) ), 'fm00') b6
26 from (
27 select x,
28 dmp,
29 decode( bitand(b1,to_dec('10000000',2)), 0, '-', '+' ) sign,
30 b1, b2, b3, b4, b5, b6, b1_bin, b1_1scomp
31 from (
32 select x, dump(x) dmp, b1, b2, b3, b4, b5, b6,
33 lpad(to_bin(b1),8,'0') b1_bin,
34 translate(lpad(to_bin(b1),8,'0'),'01','10') b1_1scomp
35 from t
36 )
37 )
38 )
39 )
40 /
X DMP E NUMS2
---------- ----------------------------------- -- --------------------
123456 Typ=2 Len=4: 195,13,35,57 3 +123456.
12345.6 Typ=2 Len=5: 195,2,24,46,61 3 +012345.60
1234.56 Typ=2 Len=4: 194,13,35,57 2 +1234.56
123.456 Typ=2 Len=5: 194,2,24,46,61 2 +0123.4560
-123456 Typ=2 Len=5: 60,89,67,45,102 3 -123456.
-12345.6 Typ=2 Len=6: 60,100,78,56,41,102 3 -012345.60
-1234.56 Typ=2 Len=5: 61,89,67,45,102 2 -1234.56
-123.456 Typ=2 Len=6: 61,100,78,56,41,102 2 -0123.4560
8 rows selected.
there is the utter destruction/construction of a number :)
In the inner most query we have:
32 select x, dump(x) dmp, b1, b2, b3, b4, b5, b6,
33 lpad(to_bin(b1),8,'0') b1_bin,
34 translate(lpad(to_bin(b1),8,'0'),'01','10') b1_1scomp
35 from t
that gets the data, all of the bytes -- and byte one in binary and the one's compliment.
http://asktom.oracle.com/~tkyte/hexdec/index.html
next we figure out the sign:
27 select x,
28 dmp,
29 decode( bitand(b1,to_dec('10000000',2)), 0, '-', '+' ) sign,
30 b1, b2, b3, b4, b5, b6, b1_bin, b1_1scomp
if the high bit of byte 1 is on -- postive, else negative....
then we:
13 select x,
14 dmp,
15 sign,
16 b1_bin,
17 b1_1scomp,
18 case when sign = '+' then bitand(b1,to_dec('01111111',2))-64
19 when sign = '-' then to_dec( substr( b1_1scomp, 2), 2 )-64
20 end exp,
21 to_char( decode( sign, '+', b2-1, decode(b2,102,null,100-(b2-1)) ), 'fm00') b2,
22 to_char( decode( sign, '+', b3-1, decode(b3,102,null,100-(b3-1)) ), 'fm00') b3,
23 to_char( decode( sign, '+', b4-1, decode(b4,102,null,100-(b4-1)) ), 'fm00') b4,
24 to_char( decode( sign, '+', b5-1, decode(b5,102,null,100-(b5-1)) ), 'fm00') b5,
25 to_char( decode( sign, '+', b6-1, decode(b6,102,null,100-(b6-1)) ), 'fm00') b6
that uses the sign to interpret the first byte. If positive, the exponent is going to be the last 7 bits minus 64, else it is the last 7 bits of the ones compliment minus 64.
Also, we pad out each byte to be a 2 character "number". If positive, we subtract 1, if negative -- and not 102 (flag byte), then it is 100 MINUS the byte minus 1...
Then we:
6 select x,
7 dmp,
8 sign,
9 exp,
10 b2||b3||b4||b5||b6 nums,
put the number back together... and lastly:
ops$tkyte@ORA9IR2> select x,
2 dmp,
3 exp e,
4 sign || substr(nums,1,2*exp)||'.'||substr(nums,2*exp+1) nums2
stick the exponent back in. QED.