Я пытаюсь лучше понять распределение значений с плавающей запятой в строке действительных чисел.
Я написал этот код для подсчета количества равномерно распределенных представляемых значений в диапазоне (-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 (т.е. 1‹‹23 для 23-битной мантиссы, удвоенной из-за знакового бита).
Чтобы конкретизировать этот вопрос, я пытаюсь построить модель (в которой используются единицы СИ с точностью на несколько порядков, например, расстояние в км до нанометров), но мне нужно отобразить ее в плавающем пространстве (для загрузки в графический процессор). Поскольку это научная модель, мне нужно понять, где теряется точность. План состоит в том, чтобы привязать значения к равномерно распределенному диапазону, поэтому из приведенной выше таблицы привязка к диапазону (-1000,1000) даст мне 32768001 точное значение.
Мне кажется нелогичным, что в этих диапазонах будет так много различий, и почему мощность двух случаев ограничена.
Кто-нибудь может объяснить, как думать об этом?
ваше здоровье
float
имеют одинаковый интервал, составляют от -2 ** -125 (около -2,35e-38) до +2 ** -125 и все его подинтервалы. В этом интервале интервал составляет 2 **-149 (около 1,40e-45). Кроме того, размер шага варьируется; распределение представляемых значений неравномерно. - person Eric Postpischil   schedule 23.03.2013