| ■7041 / ) |
Re[12]: Long型の乱数を生成する自作クラスをつくりたい |
□投稿者/ ぼのぼの (78回)-(2007/08/29(Wed) 12:09:38)
|
■No7022 (れい さん) に返信
> 前者は奥が深いです。作って実際に役に立てられる人はレアですが。
そこなんですよね。経営的視点で見ると、そこに時間を割いても会社の利益に直接結びつかない。
となると技術者としての自己満足の世界になってくるわけで、個人的に楽しめるかが重要になる。
自分の場合は、最近はこういう数学的に深いとこよりもユーザビリティとかの方に興味があるので、
ここにエネルギーをかける気力は今のところあまりないんですよね(^^;
> 後者はプログラムの勉強ですね。
> アルゴリズムの本などにも載ってますので、ほとんどの答えも手に入ります。
> 欲しい分布の乱数をライブラリが用意してくれてないときなど、
> その場で作らなきゃいけなくなるので、一度やっておくのはお勧めです。
ユーザビリティというのは何も画面の操作性に限ったことではなくて、
広義では比較的技術レベルの低い人でも読み易く理解し易いソースコードってのも含まれると思うのです。
#開発者が既存ソースを保守拡張することを「使う」と表現していいのであれば
そういう意味では魔界の仮面弁士さんが示してくださった乱数生成のコードは秀逸だと思っていて。
精度的にも今回はこれで十分という認識なので、そのまま使わせて頂いています。
> 自分でいろいろ考えるのが楽しいですよ。
>
> ダメだしは得意なので、
> ダメが欲しければぜひ呼んで下さい。
UInt64で計算するバージョンを作ってみました。
もし穴が空いていたら遠慮なく突っ込んでください。
Public Class LongRandom
Private _Random As New Random
Public Function [Next](ByVal min As Long, ByVal max As Long) As Long
'最小値の方が大きかったら例外を投げる
If min > max Then Throw New ArgumentOutOfRangeException()
'最小値と最大値が同じならその数を返す
If min = max Then Return min
'UInt64型の乱数を生成
Dim b() As Byte = BitConverter.GetBytes(0UL)
_Random.NextBytes(b)
Dim ul As UInt64 = BitConverter.ToUInt64(b, 0)
'乱数を範囲内に変換
Dim umin As UInt64 = LongToUInt64(min)
Dim umax As UInt64 = LongToUInt64(max)
If umin <> UInt64.MinValue OrElse umax <> UInt64.MaxValue Then
ul = umin + ul Mod (umax - umin + 1UL)
End If
'Long型に変換
Return UInt64ToLong(ul)
End Function
Private Function LongToUInt64(ByVal longVal As Long) As UInt64
Dim retval As UInt64
If longVal >= 0 Then
retval = Convert.ToUInt64(longVal)
retval += Convert.ToUInt64(Long.MaxValue)
retval += 1UL
Else
longVal += Long.MaxValue
longVal += 1
retval = Convert.ToUInt64(longVal)
End If
Return retval
End Function
Private Function UInt64ToLong(ByVal uint64Val As UInt64) As Long
Dim retval As Long
If uint64Val > Convert.ToUInt64(Long.MaxValue) Then
uint64Val -= Convert.ToUInt64(Long.MaxValue)
uint64Val -= 1UL
retval = Convert.ToInt64(uint64Val)
Else
retval = Convert.ToInt64(uint64Val)
retval -= Long.MaxValue
retval -= 1
End If
Return retval
End Function
End Class
|
|