浮点前导数字的分布
作者:HAM
什么是浮点数,不用我多说,这里我们要讨论的是规格化的任意进制浮点数的前导数字的概率分布。
在《计算机程序设计艺术》第二卷中做了非常深入的讨论,这里我从中精炼出要点。
例如:
2.345 E 67
这是一个十进制规格化浮点数,前导数字就是2 。
就只有一个“随机”的浮点数而言,讨论其分布式没有意义的,我们要讨论的是充分多个“随机”数进行的一系列运算后产生的浮点结果的前导数字分布。
假设现在有一巨大的浮点数集,依此对数集中每个浮点数都乘以2,其中有一个十进制浮点数F,它的前导数字是1,那么它底数可能的值范围就是1.000…~1.999…,乘以一个数字2,那么它的底数就变成2.000…~3.999…,很明显乘以2以前前导数字是1的浮点个数与现在前导数字是2、3的浮点个数相同。以此我们接下来分析。
对于一个b进制的浮点数,它的前导数字x范围就是0 < x < b,设f(x)是上述数集的前导数字的概率密度函数(注:是密度函数),那么它在前导数字u和v之间(0<u<v<b)的概率就是:
∫[u,v]f(x)dx (1)
由前面所述的,对于一个充分小增量Δx,f(x)必须满足这样一个公式:
f(1)Δx = x*f(x)Δx (2)
因为:
f(1)Δx是f(1)微分段内的概率,根据前面所述,f(1)Δx概率等于f(1*x)*(x*Δx)
很明显:
f(x) = f(1)/x (3)
两边在[1,b]之间进行积分,等号左边必定为1,右边等于f(1)ln(b):
1 = f(1)ln(b) (4)
得:f(1) = 1/ln(b) 带入(3)中:
f(x) = 1/(x*ln(b))
那么利用(1)式得:
∫[u,v]1/(x*ln(b))dx
= ln(v/u) / ln(b) (5)
这就是求前导数字的概率分布函数。
例如b = 10进制时,前导数字为1的概率就是:
= ln((1+1)/1) / ln(10)
≈ 0.301
前导数字为9的概率就是:
= ln((9+1)/9) / ln(10)
≈0.0458
以下是一个测试程序(Mathematica软件):
T[n_,b_]:=Block[{res={},ran,i,a},
For[i=1,i<b,i++;
res=Append[res,0]
];
For[i=0,i<n,i++;
ran=Random[]*Random[]*Random[]; 充分打乱浮点数
ran=Log[b,ran];
a=Floor[b^(ran-Floor[ran])]; 取出前导数字
res[[a]]++ 对前导数字个数统计
];
Return[res]
]
执行T[100000,10],以10进制测试100000个浮点数,得到一个分布:
{30149, 18821, 13317, 9674, 7688, 6256, 5306, 4655, 4134}
和理论值相当接近。