Function Convert2to10(Value As String) As Long
Dim Ret As Long
Dim K As Long
Dim X As Long
For K = 1 To Len(Value)
If Mid(Value, Len(Value) - K + 1, 1) = "1" Then
X = 2 ^ (K - 1)
Ret = Ret + X
End If
Next K
Convert2to10 = Ret
End Function
Function Convert2to10(Value As String) As Long
Dim Ret As Long
Dim K As Long
Dim X As Long
For K = 1 To Len(Value)
If Mid(Value, Len(Value) - K + 1, 1) = "1" Then
X = 2 ^ (K - 1)
Ret = Ret + X
End If
Next K
Convert2to10 = Ret
End Function
Sub CallTheFunc()
Dim fuga As Long
fuga = 1.100000010101E+31
Debug.Print Convert2to10(fuga)
End Sub
Sub check_overflow_limit()
Dim strByte As String, nagasa As String, i As Long, s As String
strByte = "11000000101010000000000100000000"
nagasa = Len(strByte)
'[1]
Dim ret_double As Double 'どんな環境でもOK
For i = 1 To Len(strByte)
s = Mid(strByte, i, 1)
If s = "1" Then
ret_double = ret_double + 2 ^ (nagasa - i)
End If
Next
Debug.Print ret_double
'[2] 64ビット環境ではこの型を使える
Dim ret_longlong As LongLong 'どんな環境でもOK
For i = 1 To Len(strByte)
s = Mid(strByte, i, 1)
If s = "1" Then
ret_longlong = ret_longlong + 2 ^ (nagasa - i)
End If
Next
Debug.Print ret_longlong
'[3] オーバーフローする
Dim ret_long As Long
For i = 1 To Len(strByte)
s = Mid(strByte, i, 1)
If s = "1" Then
ret_long = ret_long + 2 ^ (nagasa - i)
End If
Next
Debug.Print ret_long
End Sub
Sub check_overflow_limit()
> Dim strByte As String, nagasa As String, i As Long, s As String
> strByte = "11000000101010000000000100000000"
> nagasa = Len(strByte)
>
> '[1]
> Dim ret_double As Double 'どんな環境でもOK
> For i = 1 To Len(strByte)
> s = Mid(strByte, i, 1)
> If s = "1" Then
> ret_double = ret_double + 2 ^ (nagasa - i)
> End If
> Next
> Debug.Print ret_double
>
> '[2] 64ビット環境ではこの型を使える
> Dim ret_longlong As LongLong 'どんな環境でもOK
> For i = 1 To Len(strByte)
> s = Mid(strByte, i, 1)
> If s = "1" Then
> ret_longlong = ret_longlong + 2 ^ (nagasa - i)
> End If
> Next
> Debug.Print ret_longlong
>
> '[3] オーバーフローする
> Dim ret_long As Long
> For i = 1 To Len(strByte)
> s = Mid(strByte, i, 1)
> If s = "1" Then
> ret_long = ret_long + 2 ^ (nagasa - i)
> End If
> Next
> Debug.Print ret_long
> End Sub
Sub check_overflow_limit()
> Dim strByte As String, nagasa As String, i As Long, s As String
> strByte = "11000000101010000000000100000000"
> nagasa = Len(strByte)
>
> '[1]
> Dim ret_double As Double 'どんな環境でもOK
> For i = 1 To Len(strByte)
> s = Mid(strByte, i, 1)
> If s = "1" Then
> ret_double = ret_double + 2 ^ (nagasa - i)
> End If
> Next
> Debug.Print ret_double
>
> '[2] 64ビット環境ではこの型を使える
> Dim ret_longlong As LongLong 'どんな環境でもOK
> For i = 1 To Len(strByte)
> s = Mid(strByte, i, 1)
> If s = "1" Then
> ret_longlong = ret_longlong + 2 ^ (nagasa - i)
> End If
> Next
> Debug.Print ret_longlong
>
> '[3] オーバーフローする
> Dim ret_long As Long
> For i = 1 To Len(strByte)
> s = Mid(strByte, i, 1)
> If s = "1" Then
> ret_long = ret_long + 2 ^ (nagasa - i)
> End If
> Next
> Debug.Print ret_long
> End Sub
kurosukeさんの投稿
(投稿ID: 4781)
引数Valueには「11000000101010000000000100000000」が渡される想定です。戻り値を長整数型にしているので、数値は範囲内だと思いますが、オーバーフローの解消方法をご教授頂けないでしょうか。
小川慶一さんのコメント
(コメントID: 6688)
おはようございます。
> オーバーフローの解消方法をご教授頂けないでしょうか
という以前に、いろいろ問題がありますので、この関数を呼び出すプロシージャを含めた全体を紹介していただけますか。
というのは、この関数は文字列を受け取るとしていますが、
> 引数Valueには「11000000101010000000000100000000」が渡される想定です。
ということなので、実際には長整数型の値を関数に渡そうとしているように見えるからです。
実際にやってみるとわかりますが、
たとえば、
等と書こうとしても、以下のように表示されてしまいます。
あと、以下のように書いてCallTheFuncを実行しようとしても、実行時エラーがでて関数での処理まで進めないはずです。
(エラーメッセージはご自身でお確かめください)
ということなので、「オーバーフローの解消方法をご教授頂けないでしょうか」という以前のこととして、いろいろあますので。
よろしく、お願いいたします。
小川慶一さんのコメント
(コメントID: 6689)
追記です。
2進数の b11000000101010000000000100000000 は、10進数に直すと 3,232,235,776 です。
一方、長整数型の取りうる最大値は 2,147,483,647 です。なのでオーバーフローになってしまうのは仕方ないですね。
https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/data-type-summary
Long型でも扱えない数値は、Double型に格納します。最近だとLongLong型等の型もあるようですので、これを使ってもOKです。
以下に、 double型、longlong型、long型で同じ処理を書いた場合のサンプルを示します。関数として切り出すところはご自身でやってください。
受講生さんのコメント
(コメントID: 6693)
ご返信ありがとうございます。
> 2進数の b11000000101010000000000100000000 は、10進数に直すと 3,232,235,776 です。
⇒一桁少なり見間違えており、長整数型の範囲内と思ってしまいました。
仰る通り、オーバーフローするのは想定通りだと認識致しました。
また、double型に変更し、試した結果、期待値の動作となりました。
長整数型で扱えない数値はdouble型やlonglong型で対応する点が勉強になりました。
ありがとうございました。
小川慶一さん:
> kurosukeさん:
>
> 追記です。
>
> 2進数の b11000000101010000000000100000000 は、10進数に直すと 3,232,235,776 です。
> 一方、長整数型の取りうる最大値は 2,147,483,647 です。なのでオーバーフローになってしまうのは仕方ないですね。
> https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/data-type-summary
>
> Long型でも扱えない数値は、Double型に格納します。最近だとLongLong型等の型もあるようですので、これを使ってもOKです。
> 以下に、 double型、longlong型、long型で同じ処理を書いた場合のサンプルを示します。関数として切り出すところはご自身でやってください。
>
>
>
受講生さんのコメント
(コメントID: 6694)
ご返信ありがとうございます。
> 2進数の b11000000101010000000000100000000 は、10進数に直すと 3,232,235,776 です。
⇒一桁少なり見間違えており、長整数型の範囲内と思ってしまいました。
仰る通り、オーバーフローするのは想定通りだと認識致しました。
また、double型に変更し、試した結果、期待値の動作となりました。
長整数型で扱えない数値はdouble型やlonglong型で対応する点が勉強になりました。
ありがとうございました。
小川慶一さん:
> kurosukeさん:
>
> 追記です。
>
> 2進数の b11000000101010000000000100000000 は、10進数に直すと 3,232,235,776 です。
> 一方、長整数型の取りうる最大値は 2,147,483,647 です。なのでオーバーフローになってしまうのは仕方ないですね。
> https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/data-type-summary
>
> Long型でも扱えない数値は、Double型に格納します。最近だとLongLong型等の型もあるようですので、これを使ってもOKです。
> 以下に、 double型、longlong型、long型で同じ処理を書いた場合のサンプルを示します。関数として切り出すところはご自身でやってください。
>
>
>
小川慶一さんのコメント
(コメントID: 6695)
こんにちは。
解決したようで良かったです (^^
LongLong型は、正直、僕も今回調べてはじめてその存在を知りました。
おそらく64bitマシンではLongLong型がInteger型、Long型より高速だろうなという気はします。が、整数を扱うデータ型がたくさんあっても戸惑いますし、整数については、エクセル作業であれば行番号すべてに対応できるものがあれば十分かなと思います。
僕ならDouble型を使いたいです。
ひきつづきよろしくお願いいたします。