プロが教えるわが家の防犯対策術!

お世話になっています。
VBで「16進数←→10進数」を交互に変換できる計算プロシージャを作成しているのですが16進数の最大桁が64桁のものを作成しています。いきずまってしまったのでどなたかヒントをご教授ください。
(1)16進数で64桁は、10進数で何桁になるのでしょうか?
(2)(当たり前ですが)どうやってもオーバーフローしてしまいます・・。(文字列に置き換えて・・)(まず2進数に戻して・・)いろいろ考えてはみたのですが、限界のようです。どなたか知恵を貸して下さい。

A 回答 (5件)

補足どうもです。

(やっぱり私の説明では分かりませんでしたか・・・)
ほんと説明が下手ですみません。
私の考え方ですので、もっと簡単な方法があるかもしれません。
一例として考えてください。

()が配列だと思ってください。
16^0 = 1 = 1*(10^0)
16^1 = 16^0*16 = 16*(10^0) = 1*(10^1)+6*(10^0)
16^2 = 16^1*16 = 16*(10^1)+96*(10^0) = 25*(10^1)+6*(10^0)
    =2*(10^2)+5*(10^1)+6*(10^0)
というように16のN-1乗に16を掛ける
(各配列に16を掛けて配列内の繰り上がり処理をする)
ようにすれば 16^Nは求まると思います。

これに上と同じ様に16進の各桁を掛けた物を加算していけば
求める10進数になります。
&HABC = &HA * 16^2 + &HB * 16^1 + &HC * 16^0
(16^0を求める → &HC*16^0を計算する →
 16^1を求める → &HB*16^1を計算し加算する →
 16^2を求める → &HA*16^2を計算し加算する →・・・
 のように交互に繰り返すと効率が良いのではと思います)

以下は自作プログラムです。
・プログラムの中身はもっと効率の良い方法があれば書きなおしてください。
・有効桁数は、全ての配列を計算してもいいですが、
 必要の無い(まだ使っていない)配列を計算しても
 しょうがないので、付けています。
・Debug用の変数とプログラムは、Debugが終了したら
 消してください。(十分テストしてください)
 (イミディエイトウィンドウに途中経過が表示されます。)
・最初の桁あふれチェックはコメントにしてありますが、
 最初にチェックした方が、いいと思います。
 (引数の16進の文字列が10進で何桁かは以下の式で
  あっていたと思いますが、間違っていたら修正してください。)
  hxの桁あふれのチェックを作ってないので追加してください。
・配列を増やせば、64桁以上も可能だと思います。
 (どこまで増やせるかは未確認)

関数にしてありますので、
Private Sub Command1_Click()
Text2.Text = ToDecFromHex(Text1.Text)
End Sub
のように使ってください。

Function ToDecFromHex(a As String) As String
  Dim hx(77) As Integer '16^?を10進数にした1桁毎の配列
  Dim dc(77) As Integer '答えの1桁毎の配列

  Dim B As Byte '16進数の桁毎の値(0~15)

  Dim cnt As Integer '16^?の有効桁数
  Dim cnt2 As Integer '答えの有効桁数
  Dim i As Integer
  Dim j As Integer

  'Debug用
  Dim dhx As String
  Dim ddc As String

  'If (Int(Len(a) * Log(16) / Log(10)) > UBound(dc)) Then
  ' ToDecFromHex = "桁あふれ1"
  ' Exit Function
  'End If

  For i = 0 To Len(a) - 1
    If (InStr("0123456789ABCDEFabcdef", Mid(a, Len(a) - i, 1)) = 0) Then
      ToDecFromHex = "16進数ではありません"
      Exit Function
    End If
    '16進数のi+1桁目10進変換
    B = "&h" & Mid(a, Len(a) - i, 1)

    '16^i計算
    If (i = 0) Then
      hx(0) = 1
      cnt = 0
    Else '16^j =16^(j-1)*16
      For j = 0 To cnt
        hx(j) = hx(j) * 16
      Next j
    End If

    j = 0
    Do
      '繰り上げ処理
      If (hx(j) >= 10) Then
        If (j = cnt) Then '有効桁数を増加
          cnt = cnt + 1
          If (cnt > UBound(hx)) Then '有効桁数が配列以上だとエラー
            ToDecFromHex = "桁あふれ"
            Exit Function
          End If
        End If
        hx(j + 1) = hx(j + 1) + hx(j) \ 10
        hx(j) = hx(j) Mod 10
      End If
      '答えに足しこみ
      dc(j) = dc(j) + hx(j) * B
      j = j + 1
    Loop Until (j > cnt)

    cnt2 = cnt
    j = 0
    Do
      '繰り上げ処理
      If (dc(j) >= 10) Then
        If (j = cnt2) Then '有効桁数を増加
          cnt2 = cnt2 + 1
          If (cnt2 > UBound(dc)) Then '有効桁数が配列以上だとエラー
            ToDecFromHex = "桁あふれ"
            Exit Function
          End If
        End If
        dc(j + 1) = dc(j + 1) + dc(j) \ 10
        dc(j) = dc(j) Mod 10
      End If
      j = j + 1
    Loop Until (j > cnt2)

    '************** Debug ********************
    dhx = ""
    For j = 0 To cnt
      dhx = hx(j) & dhx
    Next j
    dhx = "16^" & i & ":(" & cnt & ")" & dhx

    ddc = ""
    For j = 0 To cnt2
      ddc = dc(j) & ddc
    Next j
    ddc = Mid(a, Len(a) - i, i + 1) & ":(" & cnt2 & ")" & ddc
    Debug.Print dhx & vbCrLf & " " & ddc
    '****************ここまで******************
  Next i
  For j = cnt2 To 0 Step -1
    ToDecFromHex = ToDecFromHex & dc(j)
  Next j
End Function

何か問題やプログラムでわからない事がありましたら補足してください。
(ちょっと長くなってしまいました)
    • good
    • 0
この回答へのお礼

taisuke555さん(><)!
ほんとにほんとにありがとうございました!!
ここまで詳しく説明していただけるなんて感激です!
"わかりにくい"なんてとんでもない!
自分自身がまだまだ未熟なだけです!
ほんとにありがとうございました!
すごく助かりましたm(__)m!!

お礼日時:2004/05/03 12:53

(1)FFFFFFFF・・・・・FFFFF(64桁)


=16^64-1
=115792089237316195423570985008687907
 853269984665640564039457584007913129639935

  という結果になりました。(78桁)
  自作プログラムなので、合ってるかわかりません(確認の方法がないです)
  16^64-1=1.15792089237316E+77となるので、合ってるような気はしますが・・・
(2)1.15792089237316E+77の表示ではダメという事ですよね?
   私は、
   16^?を10進に直した物を1桁づつの配列にする
   16進数の1桁づつを16^?で掛け算をし答えの配列に加算する
   最終的に配列を結合して文字列で表示させました。
   (説明が下手ですみません)

   わからなければ、補足してください。
   (自作プログラムで良ければ、記載します。)
    • good
    • 0
この回答へのお礼

>わからなければ、補足してください。
>(自作プログラムで良ければ、記載します。)
taisuke555さん!とても分かりやすく、かつ丁寧なご回答誠にありがとうございました!
>1.15792089237316E+77の表示ではダメという事です>よね?
そうです!その通りです!あれこれ考えていたのですが駄目でした(><)計算は到底不可能だと思っていましたので文字列に直して・・というのは何となくわかるのですが・・。
>16^?を10進に直した物を1桁づつの配列にする。
これは"?乗"の"?"の部分を10進数に直すという事でしょうか?(一体どうやって・・?)
>16進数の1桁づつを16^?で掛け算をし答えの配列>に加算する
例えば"B6D"という16進数があった場合はどう考えればよいのでしょうか?質問に質問を重ねて本当にごめんなさい!もしお時間があればまたご教授下さい。

お礼日時:2004/05/02 01:25

すみません。

1)の桁数間違えました(^^;

2^256-1ですね。。。(既にお答えがありますが)
    • good
    • 0
この回答へのお礼

don_chaさん、早急なご回答誠にありがとうございます!!に・・二番なんですが、もうちょっと具体的にいうと、どういうふうに計算すればいいのでしょうか(^^;)?

お礼日時:2004/04/30 10:32

1)16進数の64桁


F=4bit  4bitX64桁=256bit
ですから2進数で256bitのデータですね。
マイナスを考えなければ、0~2^256-1まで表せます。
(Windowsの電卓で関数モードにして計算しましょう)

2)多数桁の整数演算は、1桁ずつ行って文字列に変更する手が有るかと思います。
    • good
    • 0
この回答へのお礼

S_Fujiさん、早速のご回答誠にありがとうございました!2番なんですが、自分も考えたんですが、例えば16進数のFFは10進数で255・・を文字列の結合で表記するにはどうすればいいのでしょうか?質問が重なって申し訳ございません!!

お礼日時:2004/04/30 10:38

こんにちは



1)16進64桁を10進で表現すると(符号ビットは考えない) 0 ~ 2^512-1(2の512乗から1引いた値)となります。最大桁数は2^512-1を計算すれば出るかと(^^;

2)ヒントは桁に惑わされないことです。数値の足しこみは0+0~9+9の100通りです。
    • good
    • 0
この回答へのお礼

don_chaさん!
お返事遅くなって申し訳ございませんでした!
ありがとうございました!

お礼日時:2004/05/03 12:55

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!