2019年7月17日水曜日

電卓の隠れ機能

電卓には隠れ機能があり、

3+===

という操作で自分自身を足したり掛けたりといった操作のほかに


1000x2 = 2000

という計算をしたあとに

10=

とすると、x2が有効になり、20という計算結果がでる、という機能もあるようです。
(メモリ機能)

この機能はまったく知らなかったので、実装してみることにしましたが、一旦「=」で計算したあとで、前の計算結果を使うというのは想定外で、計算用のキュー を作り変えることにしました。

方法としては、数字をPushしてから演算子をPushするという仕組みで作っていたのですが、数字と演算子を一度にPushするという形態に変えました。

この場合、+=とかの機能では数字の入力が不要になりますので、数字の部分にはnilを入れることにします。

そうすると、計算用のキュー はこんな感じになります。
    // CalQueue.push()
    func push(_ inputOperand:String? , _ inputOperater:String) ->String?{

        var operater = inputOperater
        
        if let operand = inputOperand {
            if operand1 != nil && operand2 != nil{
                if operater != "=" {
                    operaterQueue = nil
                    operand1 = nil
                    operand2 = nil
                }
                else {
                    operand2 = operand
                    operater = "=="
                }
            }
            
            if operand1 == nil{
                operand1 = operand
            }
            else if operand2 == nil{
                operand2 = operand
            }
        }
        
        
        if operaterSet.contains(operater){
            switch operater {
            case "+":fallthrough
            case "-":fallthrough
            case "/":fallthrough
            case "*":
                if operand1 != nil {
                    if operand2 != nil{
                        if operaterQueue != nil{
                            let returnVal = equalOperation()
                            operaterQueue = operater
                            operand1 = String2formattedNumberString(returnVal!)
                            operand2 = nil
                            let ret =  String2formattedNumberString (returnVal!)
                            return ret
                        }
                        else{
                        }
                    }
                    else{
                        operaterQueue = operater
                    }
                }
                else{
                }
            case "=":
                if operand1 != nil {
                    if operand2 != nil{
                        if operaterQueue != nil{
                            let returnVal = equalOperation()
                            operand1 = returnVal
                            let ret =  String2formattedNumberString (returnVal!)
                            return ret
                        }
                    }
                    else{ //1000=
                        if operaterQueue != nil{
                            let returnVal = equalOperation()
                            let ret =  String2formattedNumberString (returnVal!)
                            return ret
                        }
                    }
                }
            case "==":
                if operand1 != nil {
                    if operand2 != nil{
                        if operaterQueue != nil{
                            let returnVal = equalOperation()
                            let ret =  String2formattedNumberString (returnVal!)
                            return ret
                        }
                    }
                }
            default: // += -= /= *=
                if operand1 != nil {
                    if operand2 == nil{
                        operand2 = operand1
                        operaterQueue = operater
                        let returnVal = equalOperation()
                        let ret =  String2formattedNumberString (returnVal!)
                        operand2 = ret
                        return ret
                    }
                    else {
                        operaterQueue = operater
                        let returnVal = equalOperation()
                        let ret =  String2formattedNumberString (returnVal!)
                        operand2 = ret
                        return ret
                    }
                }
                else {
                    print ("operand1 is nil")
                }
            }// end switch
            return nil
        }
        return nil
    }// end push

前半が数字の入力からオペランドに実装するところで、数字=が入力されたときは演算子を==として数字をオペランド1にいれることで今回の機能を実現しています。

通常演算でA+B=のあとに=を入れた場合はまた別の計算で、計算結果をオペランド1に入れて計算結果を残し、=のみが入った時にはその残したオペランドと演算子で計算をさせることになります。

結構複雑な処理を実装しましたが、コード自身の長さはそう変わらず、かなりいい感じで実装できています。

あとは有効桁の機能や通貨計算用機能を組み込んだらエンジンは完成、という感じです。

0 件のコメント: