質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.97%

VBで電卓を作っています。桁数超過、カンマ区切りについて

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 5,120

jjjssskkk

score 11

仕事でVB.NETを扱うことになったので勉強しており、その課題として電卓を作っています。
VB歴2週間程度の初心者なので知識もほとんどなく(プログラミング歴自体1か月半程度です)、手探り状態ですが、いろんなサイトや本の見よう見まねで基本的な機能は実装することができました。

現時点では0~9の計算(+、-、*、/)、小数点の計算はできていると思います。

ここからが本題なのですが、
現在の仕様では桁数を13桁に設定しており、それをオーバーした場合に「桁数オーバー」と表示させたりメッセージボックスで表示させたりしたいのですが、桁数オーバーの計算をしても一度は計算ができてしまいます…
(例:9999999999 × 999999999999 = 9.9999999998E+21) 
もう一度=を押すと表示されるのですが、どうしたら改善するでしょうか?

また、3桁ごとにカンマ区切りを入れたいと思っています。
単純にテキスト表示時に.ToString("#,0")を入れるだけでは小数点の計算ができていたものができなくなってしまいます。うまくカンマ区切りを入れるためにはどこにどのように記述するとよいのでしょうか?

以上2点について、時間がかかってもよいので初心者の私にでも理解できるような回答をいただけないでしょうか?
よろしくお願いいたします。

該当のソースコード

'1のボタンクリック時
 Private Sub Number1_Click(iSender As Object, iEvent As EventArgs) Handles Number1.Click
        'エラー時の処理
        If DisplayResult.Text = "E:桁数超過" Or DisplayResult.Text = "0で割ることはできません" Then
            Exit Sub
        End If

        '入力されたのが数字だった場合
        If mBefore >= "0" And mBefore <= "9" Or mBefore = "." Then
            'かつ12桁未満の数字が入力されているとき
            If DisplayResult.Text.Length < 12 Then
                DisplayResult.Text &= "1"
            Else
                MsgBox("これ以上入力できません", 48, "警告メッセージ")
                Exit Sub
            End If
        Else
            DisplayResult.Text = "1"
        End If
        mBefore = "1"

    End Sub

'×のボタンクリック時
Private Sub Multiplication_Click(iSender As Object, iEvent As EventArgs) Handles Multiplication.Click
        'エラー表示時の処理 
        If DisplayResult.Text = "E:桁数超過" Then
            Exit Sub
        End If

        '12桁未満なら計算可能
        If DisplayResult.Text.Length < 12 Then

            '前回押した数字が1~9なら
            If mBefore >= "0" And mBefore <= "9" Then

                '前回の数字以外のボタンがCなら
                If mOther = "C" Then

                    '最初に入力した数値をmResultに保管
                    mResult = CType(DisplayResult.Text, Double)

                    '+なら
                ElseIf mOther = "+" Then
                    'mNumに表示されている値を保管
                    mNum = CType(DisplayResult.Text, Double)
                    mResult = mResult + mNum

                    '結果をmResultに保管して表示
                    If DisplayResult.Text.Length >= 13 Then
                        DisplayResult.Text = "E:桁数超過"
                        Exit Sub
                    Else
                        DisplayResult.Text = mResult
                    End If

                    '-なら()
                ElseIf mOther = "-" Then
                    'mNumに表示されている値を保管
                    mNum = CType(DisplayResult.Text, Double)
                    mResult = mResult - mNum

                    '結果をmResultに保管して表示
                    If DisplayResult.Text.Length >= 13 Then
                        DisplayResult.Text = "E:桁数超過"
                        Exit Sub
                    Else
                        DisplayResult.Text = mResult
                    End If

                    '*なら
                ElseIf mOther = "*" Then
                    'mNumに表示されている値を保管
                    mNum = CType(DisplayResult.Text, Double)
                    mResult = mResult * mNum

                    '結果をmResultに保管して表示
                    If DisplayResult.Text.Length >= 13 Then
                        DisplayResult.Text = "E:桁数超過"
                        Exit Sub
                    Else
                        DisplayResult.Text = mResult
                    End If

                    '/なら
                ElseIf mOther = "/" Then
                    'mNumに表示されている値を保管
                    mNum = CType(DisplayResult.Text, Double)
                    If mNum = 0 Then
                        MsgBox("0で割ることはできません", 48, "警告メッセージ")
                        Exit Sub
                    Else
                        mResult = mResult / mNum
                    End If

                    '結果をmResultに保管して表示
                    If DisplayResult.Text.Length >= 13 Then
                        DisplayResult.Text = "E:桁数超過"
                        Exit Sub
                    Else
                        DisplayResult.Text = mResult
                    End If
                End If
            Else
                '前回が数字以外なら
                Select Case mOther
                    '前回がCなら
                    Case "C"
                        'mResultに表示されている値を保管
                        mResult = CType(DisplayResult.Text, Double)
                        '前回が=なら
                    Case "="
                        mResult = mResult * mNum
                    Case "*"
                        mNum = mResult
                End Select
            End If
        Else
            MsgBox("これ以上入力できません", 48, "警告メッセージ")
            Exit Sub
        End If
        mBefore = "*"
        mOther = "*"
        mPoint = False

    End Sub

'=のボタンクリック時
Private Sub Equal_Click(iSender As Object, iEvent As EventArgs) Handles Equal.Click

        If mBefore >= "0" And mBefore <= "9" Then
            mNum = CType(DisplayResult.Text, Double)
        End If

        Select Case mOther
            Case "+"
                mResult = mResult + mNum
            Case "-"
                mResult = mResult - mNum
            Case "*"
                mResult = mResult * mNum
            Case "/"
                If mNum = 0 Then
                    MsgBox("0で割ることはできません", 48, "警告メッセージ")
                    Exit Sub
                Else
                    mResult = mResult / mNum
                End If
        End Select
        If DisplayResult.Text.Length < 12 Then
            DisplayResult.Text = mResult
        Else
            MsgBox("これ以上入力できません", 48, "警告メッセージ")
            Exit Sub
        End If

        mBefore = "C"
        mPoint = False


    End Sub

補足情報(言語/FW/ツール等のバージョンなど)

Visual Studio 2012を使用しています。
そのほか必要な情報などございましたらご指摘お願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

ユーザーインターフェースと、ロジックを分けて考えてみてください。
画面表示などは、見てくれですから、結果として、カンマ区切りの、小数点ありで
見えればよいだけです。
ロジックは、カンマなんぞ無い方が扱い易いのですから、
内部では、文字列ではなく、数値で考えます、
Duble / Decimal どちらの精度で扱うか考えて、
Decimal の範囲を超えるようであれば、BigInteger で扱う事を考えます。
'
1.方式を決めます:
 一般電卓方式:演算子を押すと、結果が反映される。今回の方法?
 式記述方式 :数式を入れて、=で演算する。
  演算子、カッコの優先順位があるので、ちょっと面倒、
  サボるには、Script 処理系に丸投げして、演算させてしまう。
2.必要な機能や、++、--、+-、+×処理、イレギュラー処理などを決めて、機能を書き出します。
3.状態遷移図を書きます。
  何かキーが押されたら、待機状態から、キー入力処理状態になり、
  そのキー入力を判定して、
   C、CEだったら、~をして、
   数字0~9が押されたら、~して、また、待機状態に戻り、
   +、-、÷、×、= が押されたら、演算をして、~をして、
  と、処理の状態を図示します。⇒箇条書きでも可。
  机上で、各機能、状態の正しさを確認しておきます。
4.ユーザーインタフェースを書きます。
  4-1.キー入力処理:0~9と、演算記号、入力可否チェック
     エントリーポイントは、1つ、
     何処で処理するかにもよりますが、たぶんxxx イベントで処理します。
     入力データに対する処理は、クラスオブジェクトに丸投げで対応。
  4-2.画面表示処理:~の結果が~なら、データ表示、~~なら、内容に従ったエラー表示等。
  これらの事を改めて考えないで済むように、3の資料を使います。
5.ロジックを書きます。
  キー入力の下請けロジックと、演算処理
  オブジェクトを利用すると楽が可能。
6.ロジックの正しさ他は、テストプログラムで検証可能。
  ⇒学習ついでに、VS20xx に実装されている、テストを使ってみる。

デバッグ用に、各種表示用ラベルを用意したり。
リレーや、4ビットCPUでも出来たことを、
PCだからといって、複雑にすると、こんがらがって
しまうと思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/13 10:57

    丁寧な回答ありがとうございました。
    じっくり考えてみることにします。

    キャンセル

+1

各ボタンが押された時点で入力された値の桁数チェックが必要ではありませんか?
また、演算子系のボタンが押された場合にも計算後の値の桁数チェックが必要になると思います。
フォーマットに関しては小数点前後で分割して、整数部は[C# , VB] 数字の桁をカンマ区切り – gomokulogのやり方でフォーマット変換した後、小数部と連結すれば何とかなりそうです。。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/13 10:57

    回答いただきありがとうございました。
    ひとつひとつじっくりと考えてみます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.97%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る