| ■7131 / ) |
Re[17]: Long型の乱数を生成する自作クラスをつくりたい |
□投稿者/ れい (91回)-(2007/08/30(Thu) 15:42:44)
|
■No7128 (ぼのぼの さん) に返信
> ■No7124 (れい さん) に返信
>>あと質問です。
>>Decimalを使わないのはポリシーですか?
>
> 単純に、MSDNに
> http://msdn2.microsoft.com/ja-jp/library/xtba3z33(VS.80).aspx
> >Decimal は、すべての数値型の中で最もパフォーマンスの低いデータ型です。
>
> と書いてあったので、今回は使わないでやってみよう!と思っただけです。
> 低いとはいえ、余程の回数繰り返して使わない限り人間が体感できるほどの差はでないとは思います。
> が、Long-ULong変換はDecimalを使わなくてもそんなに汚くならなかったので。
なるほど。
私は型変換が苦手なので、
よくわからなくなったら範囲が大きいので誤魔化してます。よくないですが。
>>>Dim b() As Byte = BitConverter.GetBytes(0UL)
>>これは、魔界の仮面弁士さんのポリシーでしょうか?
> これに関しては、私はコピっただけなのでなんとも言えないですね(^^;
> ただ、使わせて頂いた側としてはDim b(8) As Byteと書かれるより理解し易い、とは思います。
理解し易いですか。
VBの配列の定義の仕方はきっといろんあ意見があるのでしょうね。
これに関しては魔界から本人が降臨されるのを待つことにします。
(何か生贄は必要なのかしら。
さて。
どうも完成したようなので、私の作った物も投げておきます。
正しいかどうかはきちんとした検査に通してないのでわかりません。
本質は一緒ですが、
振り直し判定が若干違います。
Decimal変換が2回、Moduloが2回、後は加減算で、振り直しは比較演算1回にしてあります。
Decimalの遅さは検証していないので何も言えませんが、
割り算のコストは大きいので、なるべく減らしています。
Public Function [Next](ByVal min As Long, ByVal max As Long) As Long
If min > max Then Throw New ArgumentOutOfRangeException()
Dim buf(8) As Byte
If min = Long.MinValue AndAlso max = Long.MaxValue Then
_Random.NextBytes(buf)
Return BitConverter.ToInt64(buf, 0)
End If
Dim a As ULong
Dim range As ULong = CULng(1D + max - min)
Dim residue As ULong = (ULong.MaxValue - range + 1UL) Mod range
While (True)
_Random.NextBytes(buf)
a = BitConverter.ToUInt64(buf, 0)
If a >= residue Then Exit While
End While
Return CLng(((a - residue) Mod range) + min)
End Function
|
|