而且,这里还有负数的问题,还有如果
decimal 的值大于 int32 的范围怎么办?所以我在第
一个字节上做了手脚,把他再拆分成
4 个部分。
A
A
A
A
A
B
C
D
第一个字节的
8 个位中,前 5 位存储小数位数(A 区),最大值是 31,一般小数位数不会
超过这个数字(事实上,下面的算法最多仅
9 位)。
B 区一个位,如果是 0,表示当前数字是 0,其他任何位都无需考虑了,也没有整数部分和
小数部分,如果是
1,表示此值非 0,通过这种方法,我们就实现了数字 0 仅用一个字节描
述的目的。
C 区一个位,如果是 0 表示正数,如果是 1 表示此值为负数;
D 区一个位,如果是 0 表示此值使用压缩的存储方法,1 表示此值太大或太小,使用了 16
个字节的原样输出。
现在还是
0.12 为例,其第一个字节其二进制实际上是:
0
0
0
1
0
1
0
0
第一个字节换算成十六进制为:
0x14,所以 0.12 其存储的内容是:
14
00
0C
参考实现
下面是写入时的代码,我使用了比较笨拙的办法获取小数部分的整数描述值。
1
//
Fast access for 10^n where n is 0-9
2
private
static
UInt32[] Powers10 =
new
UInt32[] {
3
10
,
4
100
,
5
1000
,
6
10000
,
7
100000
,
8
1000000
,
9
10000000
,
10
100000000
,
11
1000000000