• ベストアンサー

2進数 → 10進数変換 模範解答として教育的に優れているのはどちら?

標記の件で質問です。 (1) 教本に掲載されていた解答例は下記です。(出典不明。自社製?) Public Function CnvDecimal1(ByVal n As Long)   Dim b As Long   Dim d As Long   Dim i As Long   For i = 7 To 0 Step -1     b = Fix(n / 10 ^ i)     d = d + 2 ^ i * b     n = n - 10 ^ i * b   Next i   CnvDecimal1 = d End Function (2) 解答例を見ずに自分で考えて書いたコードは下記です。 Public Function CnvDecimal2(ByVal lngSrc As Long)   Dim i   As Long   Dim lngDec As Long   Do Until lngSrc = 0     lngDec = lngDec + (2 ^ i) * (lngSrc Mod 10)     i = i + 1     lngSrc = Fix(lngSrc / 10)   Loop   CnvDecimal2 = lngDec End Function (2)を書いた理由は、 ・教本の加筆、修正に際し、自分の理解を確認しつつ、よりよい内容に改定したい。 ・(1)のコードを初心者にわかりやすく説明できる自信がない。 ・桁数が固定なのが気に入らない。(汎用性がない) スループットを測定(10万回の処理に掛かる時間を測定)したところ、(2)のほうが約2.7倍速いようです。 外部仕様はどちらも同じですが、教材の模範解答として、どちらが優れているでしょうか?(コメントや変数名は大いに検討の余地がありそうですが)

質問者が選んだベストアンサー

  • ベストアンサー
  • cma3atgoo
  • ベストアンサー率35% (32/90)
回答No.3

(1)は、 10^7x1 + 10^6x0 + 10^5x1 +...+ 10~0x0 というように 2の重みを掛けて足していくという 基数変換の計算方法をそのままコード化したような形になりますね。 そういう計算方法に慣れている人には(1)のほうがわかりやすいかもしれません。 参考:「基数変換」で検索してヒットしたものです

参考URL:
http://www.jtw.zaq.ne.jp/kayakaya/new/kihon/text/kisuhenkan.htm
BuXiangHua
質問者

お礼

度々ありがとうございます。 私見では、 (1) 要求仕様通りに動作する。 (2) 妥当な性能 (リソース消費、スループット両面で) である。 (3) 可読性が悪くない。(極端に冗長 Or 複雑 Or トリッキーなのはNG) の3条件をすべて満たせば、教本と異なるコーディングでも排除する理由はないと思います。 しかし、上位の桁から処理するのが一般的、とのことですので、教本に掲載する「解答例」としては、こちらを採ることにします。 ありがとうございました。

その他の回答 (3)

  • cma3atgoo
  • ベストアンサー率35% (32/90)
回答No.4

NO3は間違いでした。 あれでは10の重みでした。 2の重みはこうですね。 2^7x1 + 2^6x0 + 2^5x1 +...+ 2^0x0 申し訳ありません。

BuXiangHua
質問者

補足

Resが遅くなり、誠に申し訳ございません。 その後、職場の同僚にも尋ねてみたのですが、やはり上位の桁から計算していくのが一般的だとのことでした。 私としてはちょっと意外でしたが・・・。

  • mu2011
  • ベストアンサー率38% (1910/4994)
回答No.2

私見ですが、以下の通りです。 対象が初心者という事ならば、プログラミング言語習得が優先で(1)が一般的で良いと思います。

BuXiangHua
質問者

補足

ありがとうございます。 No.1の方のコメントと正反対のご見解ですが、できれば具体的な根拠をご提示頂けないでしょうか? (現在、手元に基数変換を題材とする解説資料がないため、判断が付きかねます)

  • ctrlzr
  • ベストアンサー率29% (18/62)
回答No.1

解り易いのは(2)だと思います。 (1)が上の桁から、(2)が下の桁からの違いですね。 下の桁から計算していくのが普通だと思うので、(2)です。 こんなのもありですね。 dim sSrc as string sSrc = cstr(lngSrc) for i=1& to len(sSrc) lngDec = lngDec + mid$(sSrc,i,1&)*2^(len(sSrc)-i) next # マイナスの考慮は不要ですか?

BuXiangHua
質問者

お礼

コメントありがとうございます。 先入観、前提条件等一切無しに自分で思い付いたままに書いたのが(2)なので、動きはともかくとして、一般的な感覚とずれていないか確認したくご意見を募った次第です。 やはり、下位の桁から計算するのが一般的なのですね。 > こんなのもありですね。 文字列処理は、算術演算より速度が遅いはずですが・・・? > # マイナスの考慮は不要ですか? 最上位の符号ビットだけの問題ですし、実用目的のプログラムではありませんので、そこまでは要らないのではないかと思っています。 # 実際に使うとすれば、IPアドレスの2進表示ぐらい (ネットワーク関連資格試験対策?(^-^;) だと思いますが、IPアドレスなら負数を扱うことはありませんので。 ありがとうございました。

関連するQ&A

  • 0から12までの値nを入力し、nと階乗n!の値を表示しなさいという問題

    0から12までの値nを入力し、nと階乗n!の値を表示しなさいという問題ですが、一つの数字しか計算が出来ません 5と12の場合は String "5 12" から型 'Long' への変換は無効です。と出てきてしまいます。 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim n As Long Dim f As Long n = CLng(TextBox1.Text) ←ここにエラーが出ます。 TextBox2.Text = CStr(Recur(n)) End Sub Public Function Recur(ByVal arg As Long) As Long If arg = 1 Then Recur = arg Exit Function End If Recur = arg * Recur(arg - 1) End Function End Class というプログラムです。分かる方よろしくお願いします。 実行エラーです。

  • 0から12までの値nを入力し、nと階乗n!の値を表示しなさいという問題

    0から12までの値nを入力し、nと階乗n!の値を表示しなさいという問題です。 前にこのプログラムで複数個、同時には計算できない問題を自分で解決したのですがこんどは0が計算できないようです。 System.StackOverflowException' のハンドルされていない例外が WindowsApplication1.exe で発生しました。 とでます Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim n As Long Dim f As Long n = CLng(TextBox1.Text) TextBox2.Text = CStr(Recur(n)) End Sub Public Function Recur(ByVal arg As Long) As Long ←ここにエラーが If arg = 1 Then Recur = arg Exit Function End If Recur = arg * Recur(arg - 1) End Function End Class というプログラムです。分かる方よろしくお願いします。 実行エラーです。

  • 【vb.net】クラス化について

    大学で以下のような練習問題を頂きました。 ----- Public Sub test()  Dim a As b = New c  Dim i As Integer = 1  a.disp(i) End Sub 問:この時のbとcを実装せよ。 ----- Public Class c  Public Function disp(ByVal i As Integer) As String   return "iは" & i & "です"  End Function End Class までは書いてみたのですが、b の扱いがどうもわかりません。 どなたか教えていただけませんでしょうか。

  • ExcelVBAでのkernel32(64bit)

    今までExcel2000のVBAから、以下のようなコードを使ってC++で作ったコマンドプロンプトで動くプログラムを動かすプログラムを作っていましたが、これを64bitのWindows7上で動いているExcel2010で使おうとしたらメッセージが出ました。いろいろ調べてみたところ、たぶんDeclareにPtrSafeを付ければ良いようなのですが、その際、他のコードはそのままで良いのでしょうか。特に、コード中のLongはそのままで良いのか気になるのですが...。ちなみに、下記コードの条件コンパイルはネットで調べて見よう見まねで付けたもので、Excel2000のときには付けていないものでした。ご存じの方がいらっしゃいましたらご教授ください。 '------------------------------------------------------------------------------ ' Win32 API関数・定数の宣言 '------------------------------------------------------------------------------ #If VBA7 And Win64 Then '64bit Declare PtrSafe Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, _   ByVal dwMilliseconds As Long) As Long Declare PtrSafe Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, _   ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long Declare PtrSafe Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long #Else '32bit Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, _   ByVal dwMilliseconds As Long) As Long Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, _   ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long #End If Private Const PROCESS_ALL_ACCESS As Long = &H1F0FFF Private Const INFINITE As Long = &HFFFF '------------------------------------------------------------------------------ ' Run '------------------------------------------------------------------------------ Public Sub Run(ByVal project_name As String)   Dim program As String   Dim task_id As Long   Dim h_proc As Variant   program = mdlFunc.ProgramPath() & mdlFunc.ProgramOption(project_name) 'プログラム名   task_id = Shell(program, vbHide)   h_proc = OpenProcess(PROCESS_ALL_ACCESS, False, task_id)   If OpenProcess(PROCESS_ALL_ACCESS, False, task_id) <> vbNull Then     Call WaitForSingleObject(h_proc, INFINITE)     CloseHandle h_proc   End If End Sub

  • MoveWindow

    現在、vb2008でウィンドウを管理するアプリケーションを製作しております。 本来ならほかのアプリケーションのウィンドウを操作しなければいけないわけですが、テストのために下のようなコードを実行しても希望した結果(Form2が画面いっぱいに表示される)になりません。 なお、Form2 FormBorderStyle はNoneで、最大化はされていません。 Public Declare Function MoveWindow Lib "user32" (ByVal hWnd As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Long) As Long Sub Test() Dim NewWin as New Form2 NewWin.Show() Dim Ptr As System.IntPtr = NewWin.Handle Dim Ret As Long = MoveWindow(Ptr.ToInt64d, 0, 0, _ Screen.PrimaryScreen.WorkingArea.Width, _ Screen.PrimaryScreen.WorkingArea.Height, 1) End Sub

  • VB初心者です。コードの書き方が分かりません。

    VB初心者です。 VBで(zのn乗)-(xのn乗+yのn乗)の計算が出来るようにしたいのですが、答えが必ず-1になってしまいます。 Option Explicit On Public Class Form1 Dim x As Long Dim y As Long Dim z As Long Dim n As Long Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Me.Close() End Sub Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged End Sub Private Sub TextBox2_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox2.TextChanged End Sub Private Sub TextBox3_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox3.TextChanged End Sub Private Sub TextBox4_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox4.TextChanged End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click TextBox5.Text = (z ^ n) - (x ^ n + y ^ n) End Sub End Class 正しいコードの書き方を教えて下さい。 また特定の答えのときにメッセージを表示したいのですが、どうすればいいですか?

  • コマンドボタンにEXEファイルのアイコンを表示

    コマンドボタンにEXEファイルのアイコンの表示に ついてWebで色々と調べてやってみたのですが、 どうも上手くいきません・・・。(^^; 下記の条件・コードでやってみました。 原因等わかる方いましたら、どうか宜しくお願いします。 ---環境--- OS:Windows2000 Pro VB:VB6 Pro SP6 ---ソースコード(標準モジュール)--- Public Declare Function DrawIconEx Lib "USER32" (ByVal hDC&, ByVal xLeft&, _ ByVal yTop&, ByVal hIcon&, ByVal cxWidth&, ByVal cyWidth&, ByVal istepIfAniCur&, _ ByVal hbrFlickerFreeDraw&, ByVal diFlags&) As Long Public Declare Function ExtractIconEx Lib "shell32.dll" Alias "ExtractIconExA" _ (ByVal lpszFile As String, ByVal nIconIndex As Long, phiconLarge As Long, _ phiconSmall As Long, ByVal nIcons As Long) As Long Public Const DI_NORMAL = &H3 ---ソースコード(フォームモジュール)--- Private Sub Command1_Click() Dim Ret As Long Dim nFile As String Dim L As Long Dim S As Long nFile = "C:\Windows\calc.exe" Ret = ExtractIconEx(nFile, 0, L, S, 1) DrawIconEx Form1.Picture1.hDC, 0, 0, L, 0, 0, vbNull, 0, DI_NORMAL Set Form1.Command1.Picture = Form1.Picture1.Image End Sub

  • VB 2008: Do Whie...Loop文について

    Function FileGetChar(ByVal f As String, ByVal p As Integer) As String   Dim i As Integer = 1   Dim j As Integer = 0   Dim l As Integer   Dim n As Integer = FreeFile()   Dim c As Char   If File.Exists(f) Then     FileOpen(n, f, OpenMode.Random, OpenAccess.Read, , 1)     l = FileLen(f)     Do While (i + j <= l)       FileGet(n, c, i + j)       j = j - (Math.Abs(Asc(c)) > 255)       i = i + 1       If i > p Then         Exit Do       Else         c = ""       End If     Loop     FileClose(n)   End If   Return c End Function [イミディエイトウインドウ] ? FileGetChar("D:\Temp\Test.txt",1) "1" ? FileGetChar("D:\Temp\Test.txt",2) "2" と、一応は動作しています。 l------->ファイル長 i+j----->読み込みのカレントポジション p------->読み込み指示ポジション 今、悩んでいるのはDo...Loop文中のIf Else End If の追放。 何か妙手があれば教えて頂きたい。

  • このコードはどこが間違っていますか?(至急)

    急ぎのため再度の質問失礼します。 (zのn乗)-(xのn乗+yのn乗)の計算をさせて、答えが0のときにメッセージを表示したいのですが、どのようなコードを書けばいいのでしょうか? Option Explicit On Public Class Form1 Dim x As Long Dim y As Long Dim z As Long Dim n As Long Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Me.Close() End Sub Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged End Sub Private Sub TextBox2_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox2.TextChanged End Sub Private Sub TextBox3_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox3.TextChanged End Sub Private Sub TextBox4_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox4.TextChanged End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click x = TextBox1.Text y = TextBox2.Text z = TextBox3.Text n = TextBox4.Text TextBox5.Text = (z ^ n) - (x ^ n + y ^ n) If (TextBox5 .Text= 0) Then Label6.Visible = True End If End Sub Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load End Sub Private Sub Label6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label6.Click End Sub End Class このコードだと答えが必ず-1になってしまうのですが、どこを直せばいいのでしょうか? 正しいコードを教えて下さい。 よろしくお願いします。

  • 素数の計算について教えてください

    「2以上の整数を入力すると、入力した数まで素数をすべて表示する。」 どこが間違っているか教えてください!! 5行目あたりからだと思うのですが・・・。 お願いします!! Dim Number As Long If Long.TryParse(TextBox1.Text, Number) AndAlso Number >= 2 Then For i As Integer = 2 To Number Step 1 Dim d As Long = 2 Do Until Number Mod d = 0 d = d + 1 Loop If d = Number Then Label1.Text = " " & i Else Label1.Text = "2以上の整数を入力してください" End If Next End If End Sub