我认为下面对NUMBER数据类型的介绍存在误解。请您解释一下:“计算小数指数”是否指的是小数指数,假设它等于N,它是否类似于10eN?那什么是“以100为底的指数”呢?
文档地址为:Oracle Data Types Documentation
To calculate the decimal exponent, add 65 to the base-100 exponent and add another 128
if the number is positive. If the number is negative, you do the same,
but subsequently the bits are inverted. For example, -5 has a base-100 exponent = 62 (0x3e).
The decimal exponent is thus (~0x3e) -128 - 65 = 0xc1 -128 -65 = 193 -128 -65 = 0.
根据解释,假设是正数,这个以100为底的指数等于X,那么应该是X + 65 + 128 = N,而不是0xc1 - 128 - 65 = N。我认为这个N应该是100eN。这是文档错误还是我的误解?
数字存储为
N = P * V * 100^E
,其中:
P
是 +1
或 -1
,并分别存储为 1
或 0
,存储在 NUMBER
V
是值,存储在 NUMBER
E
是以 100 为底的指数,存储在第一个字节的 7 个最低有效位中(偏移量为 65,如果为负数,则反转这些位)。所以:
价值 | 等值总和 | P(正) | V(金成分) | E(x 幂) |
---|---|---|---|---|
1 | +1 * 1 * 100^0 | 1 | 1 | 0 |
50 | +1 * 50 * 100^0 | 1 | 50 | 0 |
700 | +1 * 7 * 100^1 | 1 | 7 | 1 |
-0.02345 | -1 * 2.345 * 100^-1 | 0 | 2.345 | -1 |
要反转该过程:
WITH find_byte (value, dump_value, first_byte) AS (
SELECT value,
DUMP(value) AS dump_value,
TO_NUMBER(REGEXP_SUBSTR(DUMP(value), ': (\d+)', 1, 1, NULL, 1)) AS first_byte
FROM table_name
)
SELECT value,
dump_value,
first_byte,
CASE
WHEN BITAND(first_byte, 128) = 128
THEN 'Y'
ELSE 'N'
END AS is_positive,
CASE
WHEN BITAND(first_byte, 128) = 128
THEN first_byte
ELSE BITXOR(first_byte, 255)
END - 128 - 65 AS exponent,
FLOOR(LOG(100, ABS(value))) AS expected_exponent
FROM find_byte;
对于样本数据:
CREATE TABLE table_name (value NUMBER);
INSERT INTO table_name (value)
SELECT POWER(10, 5 * (LEVEL - 1) - 20) FROM DUAL CONNECT BY LEVEL <= 10 UNION ALL
SELECT -POWER(10, 5 * (LEVEL - 1) - 20) FROM DUAL CONNECT BY LEVEL <= 10
那么输出是:
价值 | 转储_值 | 第一个字节 | IS_阳性 | 指数 | 预期指数 |
---|---|---|---|---|---|
.00000000000000000001 | 典型=2 长度=2: 183,2 | 183 | 是 | -10 | -10 |
.000000000000001 | 典型=2 长度=2:185,11 | 185 | 是 | -8 | -8 |
.0000000001 | 典型=2 长度=2: 188,2 | 188 | 是 | -5 | -5 |
.00001 | 典型=2 长度=2: 190,11 | 190 | 是 | -3 | -3 |
1 | 典型=2 长度=2: 193,2 | 193 | 是 | 0 | 0 |
100000 | 典型=2 长度=2:195,11 | 195 | 是 | 2 | 2 |
10000000000 | 典型=2 长度=2: 198,2 | 198 | 是 | 5 | 5 |
1000000000000000 | 典型=2 长度=2:200,11 | 200 | 是 | 7 | 7 |
100000000000000000000 | 典型=2 长度=2: 203,2 | 203 | 是 | 10 | 10 |
10000000000000000000000000 | 典型=2 长度=2:205,11 | 205 | 是 | 12 | 12 |
-.00000000000000000001 | 典型=2 长度=3:72,100,102 | 72 | N | -10 | -10 |
-.000000000000001 | 典型=2 长度=3: 70,91,102 | 70 | N | -8 | -8 |
-.0000000001 | 典型=2 长度=3:67,100,102 | 67 | N | -5 | -5 |
-.00001 | 典型=2 长度=3:65,91,102 | 65 | N | -3 | -3 |
-1 | 典型=2 长度=3:62,100,102 | 62 | N | 0 | 0 |
-100000 | 典型=2 长度=3: 60,91,102 | 60 | N | 2 | 2 |
-10000000000 | 典型=2 长度=3:57,100,102 | 57 | N | 5 | 5 |
-1000000000000000 | 典型=2 长度=3:55,91,102 | 55 | N | 7 | 7 |
-100000000000000000000 | 典型=2 长度=3:52,100,102 | 52 | N | 10 | 10 |
-10000000000000000000000000 | 典型=2 长度=3:50,91,102 | 50 | N | 12 | 12 |