我有一个64位整数id
,我想显示最左边的32位。这可以使用Shift operators in PL/SQL完成。
实际上,这两行给出了相同的结果:
-- 1- not using a hex mask
select to_char(id / power(2, 32), 'XXXXXXXXXXXXXXXX', 'XXXXXXXX') from dual;
-- 2- using a hex mask
select to_char( bitand(id, to_number('ffffffff00000000', 'XXXXXXXXXXXXXXXX') / power(2, 32), 'XXXXXXXXXXXXXXXX', 'XXXXXXXX') from dual;
但是,我不明白为什么第一行有效,因为id
未转换为十六进制或二进制。
似乎没有必要使用位掩码,但我不明白为什么。
没有它,是不是意味着十进制数除以2^32
?在某些情况下,这不应该给出浮动数字吗?
由于
答案 0 :(得分:2)
嗯,我真的不知道怎么解释这个,我会试着用一个例子。我真的不明白为什么六角面具是不必要的。
第一个命令只取一个数字并将其除以power(2, 32)
这相当于将数字向右移动32位。
如果要将数字向右移1位,只需将其除以2即可
要将数字向右移2位,请将其除以2 * 2(power(2,2)
)
要将数字向右移3位,请将其除以2 * 2 * 2(power(2,3)
)
......
要将数字向右移32位,请将其除以2 * .... * 2(power(2,32)
)。
一些简单的例子 - 假设我们有一个数字12345(十进制)
12345(十进制)= 10011010010(二进制)
如果我们将这个数字向右移动1,2,3,4位,我们应该得到:
+-----+------------------+------------------+
| bit | result binary | result decimal |
+-----+------------------+------------------+
| 0 | 11000000111001 | 12345 |
| 1 | 1100000011100 | 6172 |
| 2 | 110000001110 | 3086 |
| 3 | 11000000111 | 1543 |
| 4 | 1100000011 | 771 |
+-----+------------------+------------------+
如果我们运行此查询:
select 12345 / power(2, 0) x0,
12345 / power(2, 1) x1,
12345 / power(2, 2) x2,
12345 / power(2, 3) x3,
12345 / power(2, 4) x4
FROM dual;
我们得到这些结果(十进制数字):
X0 X1 X2 X3 X4
---------- ---------- ---------- ---------- ----------
12345 6172.5 3086.25 1543.125 771.5625
如果取这些结果的整数部分(在点之前)并将它们转换为二进制表示法,您将从上表中获得移位数字。
-----------编辑------------------
为什么选择to_char(13/2,'XXXXXXXX')从双给7而不是6.5?
因为to_char
函数因格式XXXXX而舍入结果
请参阅文档:https://docs.oracle.com/cd/B19306_01/server.102/b14200/sql_elements004.htm#i34510
<强> XXXX 强>
返回指定位数的十六进制值。 如果 指定的数字不是整数,然后Oracle数据库对其进行舍入 到整数。
以下命令给出6.5
select 13 / 2 from dual;
下面的命令给出了7,7,6,因为to_char
函数由于使用了XXXXX格式而将数字舍入为整数:
select to_char( 13 / 2, 'XXXXX' ),
to_char( 6.5, 'XXXXX' ),
to_char( 6.4, 'XXXXX' )
from dual;
TO_CHAR(13/2,'XXXXX') TO_CHAR(6.5,'XXXXX') TO_CHAR(6.4,'XXXXX')
--------------------- -------------------- --------------------
7 7 6