電卓を作ってみる②

電卓を作ってみると、以外と難しいですね

・0〜9までのテンキーと”.”が押された時の処理

- (IBAction) pushNumberButton:(id)sender;

・+ー÷×の演算キーが押された時の処理

- (IBAction) pushOperationButton:(id)sender;

・Clearとdeleteキーが押された時の処理

- (IBAction) pushClearButton:(id)sender;

・=キーが押された時の処理

- (IBAction) pushResultButton:(id)sender;

の四種類に分けてみました

作っていくと必要になってくる変数がいくつか・・

BOOL firstInput;
 int operationMode;
 int decimalPoint;

firstInputは一桁目の入力であるか?のフラグ、起動時、+ーなどの演算キーが押された後、クリアが押された後などに必要になる
operationModeは演算子(+-÷×)のどれが押されたか記憶
decimalPointは小数点以下何桁まで表示するかの設定

0〜9と”.”が押された時の処理
一桁目の入力かどうか、”.”の時の処理をデバッグしながら確認

- (IBAction) pushNumberButton:(id)sender{

    UIButton *btn = (UIButton *)sender;

    if (firstInput){  //一桁目の入力
        if(btn.tag == 0) return;
        if(btn.tag == 10){
            numberDisplay.text = [NSString stringWithFormat:@"0."];
        }else{
            numberDisplay.text = [NSString stringWithFormat:@"%d",btn.tag];
        }
        firstInput=NO;
    }else{
        if(btn.tag==10){  //"."なら
            NSRange searchResult = [numberDisplay.text rangeOfString:@"."];  //すでに"."がないかチェック
            if(searchResult.location == NSNotFound){
                numberDisplay.text = [NSString stringWithFormat:@"%@%@",numberDisplay.text,@"."];
            }
        }else{
            numberDisplay.text = [NSString stringWithFormat:@"%@%d",numberDisplay.text,btn.tag];
        }
    }
}

演算子のボタンが押された時は、押されたボタンのtag番号だけを記憶して終わり

- (IBAction) pushOperationButton:(id)sender{

    UIButton *btn = (UIButton *)sender;
    currentValue =[numberDisplay.text doubleValue];
    operationMode=btn.tag;
    firstInput=YES;
}

クリアボタンが押された時は無条件でクリアして、変数もクリア
deliteキーはパソコンでいうバックスペースと同じように1文字づつ消すようにしています

- (IBAction) pushClearButton:(id)sender{

    UIButton *btn = (UIButton *)sender;
    if(btn.tag == 0){
        numberDisplay.text = @"0";
        firstInput=YES;
        operationMode=-1;
        currentValue=0;
    }else{
        int len = [numberDisplay.text length];
        if(len ==1){
            numberDisplay.text = @"0";
            firstInput=YES;
            operationMode=-1;
        }else{
            numberDisplay.text = [numberDisplay.text substringToIndex:len-1];
        }
    }
}

さて、ここからが勉強になったところ・・・
基本といえばそれまでですが、Objective-Cではさっぱりわからん

NSString *str = [NSString stringWithFormat:@"%g",currentValue];

まず、この数値→文字列ですが、計算された値を入れる変数currentValueをdoubleで宣言したんですが

double currentValue;

合計が50の時は%dで、50.342の時は%fで表示??
50を%fで表示しようとすると、勝手に少数点以下が付いちゃうんですよね
という辺りで悩んでいたら、『%g』ってあるんですね。
これは50なら50で50.342なら50.342で表示してくれる優れもの!
確か小数点以下は下4桁に固定

そうか、割り切れないときは小数点以下を何桁にするのか決めておかないといけないなぁ
という事で将来は設定出来るように変数を設け、とりあえず下3桁にしておいた
これを%0.3fでやってしまうと四捨五入されるのかな?
電卓は四捨五入してはいけないような気がしたので、文字列としてカットする様にしてみた

numberDisplay.text = [str substringWithRange:NSMakeRange(0,((searchResult.location+1)+decimalPoint))];

“.”がある場合で設定された下3桁よりも長い場合は、下3桁でカットするようにした

- (IBAction) pushResultButton:(id)sender{

    if(operationMode==-1) return;

    if(operationMode==0){//÷
        currentValue /=[numberDisplay.text doubleValue];
    }else if(operationMode==1){//×
        currentValue *=[numberDisplay.text doubleValue];
    }else if(operationMode==2){//-
        currentValue -=[numberDisplay.text doubleValue];
    }else if(operationMode==3){//+
        currentValue +=[numberDisplay.text doubleValue];
    }

    NSString *str = [NSString stringWithFormat:@"%g",currentValue]; 

    NSRange searchResult = [str rangeOfString:@"."];  //すでに"."がないかチェック
    if(searchResult.location != NSNotFound){
        int len = [str length];
        if((len - searchResult.location) > (decimalPoint+1)) {
            numberDisplay.text = [str substringWithRange:NSMakeRange(0,((searchResult.location+1)+decimalPoint))];

        }else{
            numberDisplay.text = [NSString stringWithFormat:@"%g",currentValue];
        }
    }else{
        numberDisplay.text = [NSString stringWithFormat:@"%g",currentValue];
    }

    firstInput=YES;
    operationMode=-1;
}

電卓もいろいろな機能がありますが、結構勉強になりますね
さて、次は音でも出してみようかな

*このソースはあくまで私が思った様に書いていますので責任はとれません(笑)

  1. コメントはまだありません。

  1. トラックバックはまだありません。

*


Advertisement