SSブログ

トロPのVBAホビラボ 32ビット符号無し整数 その3 [トロPのVBAホビラボ]

ここまでで加算と減算を実現できました。しかしLong型の変数の値をdebug.printやMsgBoxで表示すれば、やはり符号付きの値として表示されてしまいます。

今回は、符号無しの値として表示できる関数を作りましょう。

非常に基本的な機能ですので、また非常に鈍くさく書いていきます。各重みで、1ずつ引いていき、引けた回数を数えて、その回数を結果の1桁としていきます。

回数を数えるところは各桁で最大9回ですので、さすがに疑いませんが、大きい桁の引き算では符号付きの値で計算されてしまう疑いがあります。

そのため、引き算を実現するまではこの方式で「表示」すら実現できなかったのです。

ここまでじらされた感じがしたかも知れませんが、これですっきりできます。

ロジックは極めて単純ですので、長々と説明するより、結果を示しましょう。

サンプル
Public Function ULngToStr(ByVal Value As Long) As String

    Dim l_ColVal       As Byte
    Dim l_ErrNum       As Long
    Dim l_FoundNonZero As Boolean
    Dim l_Sub          As Long
    Dim l_Str          As String

    l_Str = ""
    l_Sub = Value
    l_FoundNonZero = False

    l_ColVal = 0
    Do
        On Error Resume Next
        l_Sub = ULngsSub(l_Sub, 1000000000)
        l_ErrNum = Err.Number
        On Error GoTo 0
        If 9001& = l_ErrNum Then
            If l_FoundNonZero Then
                l_Str = l_Str & l_ColVal
            Else
                If 0 < l_ColVal Then
                    l_Str = l_Str & l_ColVal
                    l_FoundNonZero = True
                End If
            End If
            Exit Do
        Else
            l_ColVal = l_ColVal + 1
        End If
    Loop

    l_ColVal = 0
    Do
        On Error Resume Next
        l_Sub = ULngsSub(l_Sub, 100000000)
        l_ErrNum = Err.Number
        On Error GoTo 0
        If 9001& = l_ErrNum Then
            If l_FoundNonZero Then
                l_Str = l_Str & l_ColVal
            Else
                If 0 < l_ColVal Then
                    l_Str = l_Str & l_ColVal
                    l_FoundNonZero = True
                End If
            End If
            Exit Do
        Else
            l_ColVal = l_ColVal + 1
        End If
    Loop

    l_ColVal = 0
    Do
        On Error Resume Next
        l_Sub = ULngsSub(l_Sub, 10000000)
        l_ErrNum = Err.Number
        On Error GoTo 0
        If 9001& = l_ErrNum Then
            If l_FoundNonZero Then
                l_Str = l_Str & l_ColVal
            Else
                If 0 < l_ColVal Then
                    l_Str = l_Str & l_ColVal
                    l_FoundNonZero = True
                End If
            End If
            Exit Do
        Else
            l_ColVal = l_ColVal + 1
        End If
    Loop

    l_ColVal = 0
    Do
        On Error Resume Next
        l_Sub = ULngsSub(l_Sub, 1000000)
        l_ErrNum = Err.Number
        On Error GoTo 0
        If 9001& = l_ErrNum Then
            If l_FoundNonZero Then
                l_Str = l_Str & l_ColVal
            Else
                If 0 < l_ColVal Then
                    l_Str = l_Str & l_ColVal
                    l_FoundNonZero = True
                End If
            End If
            Exit Do
        Else
            l_ColVal = l_ColVal + 1
        End If
    Loop

    l_ColVal = 0
    Do
        On Error Resume Next
        l_Sub = ULngsSub(l_Sub, 100000)
        l_ErrNum = Err.Number
        On Error GoTo 0
        If 9001& = l_ErrNum Then
            If l_FoundNonZero Then
                l_Str = l_Str & l_ColVal
            Else
                If 0 < l_ColVal Then
                    l_Str = l_Str & l_ColVal
                    l_FoundNonZero = True
                End If
            End If
            Exit Do
        Else
            l_ColVal = l_ColVal + 1
        End If
    Loop

    l_ColVal = 0
    Do
        On Error Resume Next
        l_Sub = ULngsSub(l_Sub, 10000)
        l_ErrNum = Err.Number
        On Error GoTo 0
        If 9001& = l_ErrNum Then
            If l_FoundNonZero Then
                l_Str = l_Str & l_ColVal
            Else
                If 0 < l_ColVal Then
                    l_Str = l_Str & l_ColVal
                    l_FoundNonZero = True
                End If
            End If
            Exit Do
        Else
            l_ColVal = l_ColVal + 1
        End If
    Loop

    l_ColVal = 0
    Do
        On Error Resume Next
        l_Sub = ULngsSub(l_Sub, 1000)
        l_ErrNum = Err.Number
        On Error GoTo 0
        If 9001& = l_ErrNum Then
            If l_FoundNonZero Then
                l_Str = l_Str & l_ColVal
            Else
                If 0 < l_ColVal Then
                    l_Str = l_Str & l_ColVal
                    l_FoundNonZero = True
                End If
            End If
            Exit Do
        Else
            l_ColVal = l_ColVal + 1
        End If
    Loop

    l_ColVal = 0
    Do
        On Error Resume Next
        l_Sub = ULngsSub(l_Sub, 100)
        l_ErrNum = Err.Number
        On Error GoTo 0
        If 9001& = l_ErrNum Then
            If l_FoundNonZero Then
                l_Str = l_Str & l_ColVal
            Else
                If 0 < l_ColVal Then
                    l_Str = l_Str & l_ColVal
                    l_FoundNonZero = True
                End If
            End If
            Exit Do
        Else
            l_ColVal = l_ColVal + 1
        End If
    Loop

    l_ColVal = 0
    Do
        On Error Resume Next
        l_Sub = ULngsSub(l_Sub, 10)
        l_ErrNum = Err.Number
        On Error GoTo 0
        If 9001& = l_ErrNum Then
            If l_FoundNonZero Then
                l_Str = l_Str & l_ColVal
            Else
                If 0 < l_ColVal Then
                    l_Str = l_Str & l_ColVal
                    l_FoundNonZero = True
                End If
            End If
            Exit Do
        Else
            l_ColVal = l_ColVal + 1
        End If
    Loop

    l_Str = l_Str & l_Sub

    ULngToStr = l_Str

End Function

書き終わったら、いままで実現したULngsSum、ULngsSub、ULngsCompで試して思う存分確認してみてくださいね。

イミディエイトウィンドウ
? ULngToStr(ULngsSum(&H7FFFFFFF, 1&))
2147483648
? ULngToStr(ULngsSub(&HFFFFFFFF, 1&))
4294967294

あ~スッキリw。

今回は長たらしいプログラムでしたので、書くと少し疲れると思いますので、このへんにしておきましょう。(コピーすれば一瞬ですがwまあ、こういうものを書く経験もしたければ書くことはおすすめできます。)

では次回から後半戦です。今までのペースからいって、掛け算の実現までですね。


32ビット符号無し整数
  1. ビットの取り出しと加算
  2. 補数と減算

広告
nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

トラックバックの受付は締め切りました

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。