我试图更好地理解浮点值在实数线上的分布。
我编写了这段代码来计算范围(-R,R)中均匀分布的可表示值的数量,其中 R 是10的幂(也尝试使用 2 的幂):
public class Foo {
public static void main(String[] args)
{
for(int i=0; i<24; i++)
{
int count = 0;
float R = (float) Math.pow(10, i); //(2<<i);
float Rstep = Math.ulp(R);
for(float x = -R; x <= R; x+=Rstep)
count++;
System.out.println(R+" "+count+" "+Math.ulp(R));
}
}
}
我对结果的差异感到惊讶,即
1.0 16777217 1.1920929E-7
10.0 20971521 9.536743E-7
100.0 26214401 7.6293945E-6
1000.0 32768001 6.1035156E-5
10000.0 20480001 9.765625E-4
100000.0 25600001 0.0078125
1000000.0 32000001 0.0625
正如我半信半疑的那样,均匀分布的值的数量将是 16777216(即 23 位尾数的 1<<23,由于符号位而加倍)。
为了让这个问题更加具体 - 我正在尝试构建一个模型(它使用精确到几个数量级的 SI 单位,例如距离以公里到纳米为单位),但必须将其映射到浮点空间(以加载到 GPU 中)。由于这是一个科学模型,我需要了解精度丢失的地方。计划是将值捕捉到均匀分布的范围 - 因此从上表捕捉到范围 (-1000,1000) 将为我提供 32768001 个精确值。
对我来说,在这些范围内会有如此多的差异,以及为什么 2 个案例的力量有限,这似乎违反直觉。
有谁能够解释如何思考这个问题?
干杯