2

MATLABで単精度で均一に分散された浮動小数点値の配列を生成しようとしています。

IEEE-754標準に基づいて可能な32ビット浮動小数点数の範囲を表す+/-(2-2 ^ -23)* 2^127の範囲のすべての数値を生成したいと思います。問題は、大きなマグニチュード数しか生成されていないことです。小さなマグニチュード数(0に近いものとそれを含む)も含めたいと思います。これは、生成されたすべての数値の絶対値を取得し、最小のものを見つけた場合に見られます(コードの下に出力をコピーしました)。

これまでのところ、MATLABに次のコードがあります。

numtogenerate = 20000;

% Preallocate for speed
generatednumber(numtogenerate) = 0;

for i = 1:numtogenerate
   generatednumber(i) =  rand*(2-2^-23)*2^127*2 - 2^127*(2-2^-23); 
end

minimum = min(generatednumber)
smallest = min(abs(generatednumber))
maximum = max(generatednumber)

hist(generatednumber)

出力は次のとおりです。

minimum =

 -3.4026e+038


smallest =

  8.4046e+033


maximum =

  3.4027e+038
4

1 に答える 1

5

(なぜ神と小さな青リンゴの名の下にこれをループで行うのですか?)

私のポイントは、MATLABの機能を使用してそれを行うことです。ベクトルと配列の使い方を学びましょう。数値の配列全体に演算を適用します。これがMATLABのようなツールの魅力です。そうするまでは、低レベルの言語を使用することもできますが、その低レベルのツールを使用することで得られる速度の利点はありません。

さて、暴言を吐きます。では、この問題をどのように攻撃しますか?

3つの異なるランダム値を使用して各数値を生成します。

  1. ランダムサイン
  2. ランダムな指数
  3. ランダムな仮数

ベクトル演算を使用してすべてを実行します。

numtogenerate = 20000;

% the sign
S = (rand(numtogenerate,1) < 0.5)*2 - 1;

% The exponent
E = floor(rand(numtogenerate,1)*256) - 128;

% The mantissa
M = rand(numtogenerate,1)*2 - 2^-23;

% bring it all together
R = S.*M.*2.^E;

それらは全範囲をカバーしていますか?そのようです。

min(abs(R))
ans =
      7.44202895026248e-41

max(R)
ans =
      3.17337113940593e+38

min(R)
ans =
      -3.3810631675676e+38

各パーツの範囲が正しいと仮定すると、これにより、基本的に、目的の範囲で可能なすべての値が生成されます。

ちなみに、これらは均一に分布した数ではなく、少なくともその用語が数学で通常適用される方法ではありません。

于 2013-01-31T18:01:56.760 に答える