C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト


(過去ログ 18 を表示中)
■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

返信 編集キー/


管理者用

- Child Tree -