Decimal型の整数最大値

タグの編集
投稿者 てつ  (社会人) 投稿日時 2024/12/18 00:29:27
VBAの質問です。
VBA(.NETも同じ)のDecimal型の整数最大値(小数点以下の桁数=0)は96bit整数部がすべて「1」だと思うのですが
以下のように12Byte全てに「&HFF」を与えてみましたが
最大値「79,228,162,514,264,337,593,543,950,335」とはなりません。
何か考え違いをしているのでしょうか?

Sub ByteArrayToDecimal()
    Dim byteArray(11) As Byte
    Dim decimalValue
    Dim i As Long
    For i = 0 To 11
        byteArray(i) = &HFF
    Next i
    For i = 0 To 11
        decimalValue = decimalValue + CDec(byteArray(i)) * 256 ^ i
    Next i
    Debug.Print "Decimal Value: " & decimalValue
    Debug.Print "Decimal MaxValue: " & CDec("79,228,162,514,264,337,593,543,950,335")
End Sub

投稿者 KOZ  (社会人) 投稿日時 2024/12/18 01:12:46
256 ^ i の部分が Double なので誤差が出てるのでしょう。

Sub ByteArrayToDecimal()
    Dim byteArray(11) As Byte
    Dim decimalValue As Variant
    Dim i As Long
    Dim tmp As Variant
    For i = 0 To 11
        byteArray(i) = &HFF
    Next i
    tmp = CDec(1 / 256)
    For i = 0 To 11
        tmp = tmp * 256
        decimalValue = decimalValue + CDec(byteArray(i)) * tmp
    Next i
    Debug.Print "Decimal Value: " & decimalValue
    Debug.Print "Decimal MaxValue: " & CDec("79,228,162,514,264,337,593,543,950,335")
End Sub


結果:
Decimal Value: 79228162514264337593543950335
Decimal MaxValue: 79228162514264337593543950335
投稿者 てつ  (社会人) 投稿日時 2024/12/18 08:02:37
KOZ様、いつもありがとうございます。
結果、提示いただいた方法で期待通りの結果を得られました。
CDec(1 / 256)で初期化するなんて自分ではまず、思いつかないと思います。

Decimal同士の演算にすれば誤差は発生しないと思い以下のコードで試したのですが...うまくいかず( ;∀;)
以下のコードで演算誤差がでる理由をご存じの方がおられましたら後学の為、教えてもらえませんでしょうか?
「^ 演算子」が悪さをしてるのでしょうか?

当初の問題は解決なので、解決済にしておきます。
    decimalValue = CDec(0)
    For i = 0 To 11
        decimalValue = decimalValue + CDec(byteArray(i)) * CDec(256) ^ CDec(i)
    Next 
投稿者 KOZ  (社会人) 投稿日時 2024/12/18 11:18:46
べき乗の結果は常に Double です。

Debug.Print TypeName(CDec(256) ^ CDec(1))


実行してみて下さい。
投稿者 てつ  (社会人) 投稿日時 2024/12/18 13:05:02
KOZ様、ありがとうございます。Doubleになる事を確認しました。
「Decimal同士の演算でも「べき乗」演算すると誤差がでる場合がある」=>理解しました。今後注意します。
気分すっきりです。感謝......