- ベストアンサー
VBプログラムの得意な方・・。(初心者です。)
お世話になっています。 VBで「16進数←→10進数」を交互に変換できる計算プロシージャを作成しているのですが16進数の最大桁が64桁のものを作成しています。いきずまってしまったのでどなたかヒントをご教授ください。 (1)16進数で64桁は、10進数で何桁になるのでしょうか? (2)(当たり前ですが)どうやってもオーバーフローしてしまいます・・。(文字列に置き換えて・・)(まず2進数に戻して・・)いろいろ考えてはみたのですが、限界のようです。どなたか知恵を貸して下さい。
- みんなの回答 (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 何か問題やプログラムでわからない事がありましたら補足してください。 (ちょっと長くなってしまいました)
その他の回答 (4)
- taisuke555
- ベストアンサー率55% (132/236)
(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^?で掛け算をし答えの配列に加算する 最終的に配列を結合して文字列で表示させました。 (説明が下手ですみません) わからなければ、補足してください。 (自作プログラムで良ければ、記載します。)
お礼
>わからなければ、補足してください。 >(自作プログラムで良ければ、記載します。) taisuke555さん!とても分かりやすく、かつ丁寧なご回答誠にありがとうございました! >1.15792089237316E+77の表示ではダメという事です>よね? そうです!その通りです!あれこれ考えていたのですが駄目でした(><)計算は到底不可能だと思っていましたので文字列に直して・・というのは何となくわかるのですが・・。 >16^?を10進に直した物を1桁づつの配列にする。 これは"?乗"の"?"の部分を10進数に直すという事でしょうか?(一体どうやって・・?) >16進数の1桁づつを16^?で掛け算をし答えの配列>に加算する 例えば"B6D"という16進数があった場合はどう考えればよいのでしょうか?質問に質問を重ねて本当にごめんなさい!もしお時間があればまたご教授下さい。
- don_cha
- ベストアンサー率34% (139/407)
すみません。1)の桁数間違えました(^^; 2^256-1ですね。。。(既にお答えがありますが)
お礼
don_chaさん、早急なご回答誠にありがとうございます!!に・・二番なんですが、もうちょっと具体的にいうと、どういうふうに計算すればいいのでしょうか(^^;)?
- S-Fuji
- ベストアンサー率36% (592/1624)
1)16進数の64桁 F=4bit 4bitX64桁=256bit ですから2進数で256bitのデータですね。 マイナスを考えなければ、0~2^256-1まで表せます。 (Windowsの電卓で関数モードにして計算しましょう) 2)多数桁の整数演算は、1桁ずつ行って文字列に変更する手が有るかと思います。
お礼
S_Fujiさん、早速のご回答誠にありがとうございました!2番なんですが、自分も考えたんですが、例えば16進数のFFは10進数で255・・を文字列の結合で表記するにはどうすればいいのでしょうか?質問が重なって申し訳ございません!!
- don_cha
- ベストアンサー率34% (139/407)
こんにちは 1)16進64桁を10進で表現すると(符号ビットは考えない) 0 ~ 2^512-1(2の512乗から1引いた値)となります。最大桁数は2^512-1を計算すれば出るかと(^^; 2)ヒントは桁に惑わされないことです。数値の足しこみは0+0~9+9の100通りです。
お礼
don_chaさん! お返事遅くなって申し訳ございませんでした! ありがとうございました!
お礼
taisuke555さん(><)! ほんとにほんとにありがとうございました!! ここまで詳しく説明していただけるなんて感激です! "わかりにくい"なんてとんでもない! 自分自身がまだまだ未熟なだけです! ほんとにありがとうございました! すごく助かりましたm(__)m!!