在计算器程序的更新尾数不稳定双变量行为 [英] erratic double variable behaviour in updating mantissa of calculator program

查看:107
本文介绍了在计算器程序的更新尾数不稳定双变量行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让Android的一个基本的计算器程序,但我是新来的Andr​​oid作为以及Java结果
但我相信这可能是更多的是Java问题的结果
该接口具有到9 0按钮,小数点,等于号,+, - ,*,/和取消(复位所有的变量)结果
尾数存储在一个双变量,我用将String.valueOf(mantissa_value)将其转换为字符串在TextView控件结果中显示
当我键入2.331,尾数显示2.33099999(10个字符是字符串变量存储尾数文字的限制),但如果我preSS 1再次,它显示了2.3311 。这究竟是为什么以及如何解决?

相关code(可能):

 公共无效onClkBn1(查看视图){
    如果(decimalClicked == FALSE)
        mantissa_value = mantissa_value * 10 + 1;
    其他{
        mantissa_value = mantissa_value + POW(10,-numOfClicksAfterDecimal)* 1;
        numOfClicksAfterDecimal ++;
    }
    updateMantissa();
}公共无效updateMantissa(){
    如果(mantissa_value == 0){
        mantissa_str =0;
    }    否则,如果(CEIL(mantissa_value)== mantissa_value){
        mantissa_str =将String.valueOf(mantissa_value);
        mantissa_str = mantissa_str.substring(0,mantissa_str.length() - 2);
    }    其他{
        mantissa_str =将String.valueOf(mantissa_value);
        mantissa_str = mantissa_str.substring(0,Math.min(mantissa_str.length(),10));
    }
    TextView的thisText =(的TextView)findViewById(R.id.mantissa);
    thisText.setText(mantissa_str);
}

全部code:

 包com.example.calculator;进口android.os.Bundle;
进口android.app.Activity;
进口android.view.Menu;
进口android.view.View;
进口android.widget.TextView;
引入静态java.lang.Math.pow;
引入静态java.lang.Math.ceil;公共类MainActivity延伸活动{
私人双mantissa_value = 0;
私人双OPR1 = 0;
私人双OPR2 = 0;
私人双RES = 0;
私人枚举OprTypes {NONE,加,减,MULT,DIV}
OprTypes oprLatest = OprTypes.NONE;
私人布尔oprPlusClicked = FALSE;
私人布尔oprMinusClicked = FALSE;
私人布尔oprMultClicked = FALSE;
私人布尔oprDivClicked = FALSE;
私人布尔decimalClicked = FALSE;
私人双numOfClicksAfterDecimal = 1;
私人字符串mantissa_str;@覆盖
保护无效的onCreate(捆绑savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.activity_main);
    updateMantissa();
}@覆盖
公共布尔onCreateOptionsMenu(菜单菜单){
    //充气菜单;如果是present这增加了项目操作栏。
    。getMenuInflater()膨胀(R.menu.main,菜单);
    返回true;
}公共无效updateMantissa(){
    如果(mantissa_value == 0){
        mantissa_str =0;
    }    否则,如果(CEIL(mantissa_value)== mantissa_value){
        mantissa_str =将String.valueOf(mantissa_value);
        mantissa_str = mantissa_str.substring(0,mantissa_str.length() - 2);
    }    其他{
        mantissa_str =将String.valueOf(mantissa_value);
        mantissa_str = mantissa_str.substring(0,Math.min(mantissa_str.length(),10));
    }
    TextView的thisText =(的TextView)findViewById(R.id.mantissa);
    thisText.setText(mantissa_str);
}公共无效onClkBn0(查看视图){
    TextView的thisText =(的TextView)findViewById(R.id.mantissa);
    如果(decimalClicked == FALSE){
        mantissa_value = mantissa_value * 10 + 0;
        updateMantissa();
    }
    其他{
        如果(mantissa_value == 0){
            如果(numOfClicksAfterDecimal == 1){
                mantissa_str = mantissa_str +.0;
            }
            其他{
                mantissa_str = mantissa_str +0;
            }
        }        否则,如果(CEIL(mantissa_value)== mantissa_value){
            如果(numOfClicksAfterDecimal == 1){
                mantissa_str = mantissa_str +.0;
            }
            其他{
                mantissa_str = mantissa_str +0;
            }
        }        mantissa_value = mantissa_value + POW(10,-numOfClicksAfterDecimal)* 0;
        numOfClicksAfterDecimal ++;
        thisText.setText(mantissa_str);
    }
}公共无效onClkBn1(查看视图){
    如果(decimalClicked == FALSE)
        mantissa_value = mantissa_value * 10 + 1;
    其他{
        mantissa_value = mantissa_value + POW(10,-numOfClicksAfterDecimal)* 1;
        numOfClicksAfterDecimal ++;
    }
    updateMantissa();
}公共无效onClkBn2(查看视图){
    如果(decimalClicked == FALSE)
        mantissa_value = mantissa_value * 10 + 2;
    其他{
        mantissa_value = mantissa_value + POW(10,-numOfClicksAfterDecimal)* 2;
        numOfClicksAfterDecimal ++;
    }
    updateMantissa();
}公共无效onClkBn3(查看视图){
    如果(decimalClicked == FALSE)
        mantissa_value = mantissa_value * 10 + 3;
    其他{
        mantissa_value = mantissa_value + POW(10,-numOfClicksAfterDecimal)* 3;
        numOfClicksAfterDecimal ++;
    }
    updateMantissa();
}公共无效onClkBn4(查看视图){
    如果(decimalClicked == FALSE)
        mantissa_value = mantissa_value * 10 + 4;
    其他{
        mantissa_value = mantissa_value + POW(10,-numOfClicksAfterDecimal)* 4;
        numOfClicksAfterDecimal ++;
    }
    updateMantissa();
}公共无效onClkBn5(查看视图){
    如果(decimalClicked == FALSE)
        mantissa_value = mantissa_value * 10 + 5;
    其他{
        mantissa_value = mantissa_value + POW(10,-numOfClicksAfterDecimal)* 5;
        numOfClicksAfterDecimal ++;
    }
    updateMantissa();
}公共无效onClkBn6(查看视图){
    如果(decimalClicked == FALSE)
        mantissa_value = mantissa_value * 10 + 6;
    其他{
        mantissa_value = mantissa_value + POW(10,-numOfClicksAfterDecimal)* 6;
        numOfClicksAfterDecimal ++;
    }
    updateMantissa();
}公共无效onClkBn7(查看视图){
    如果(decimalClicked == FALSE)
        mantissa_value = mantissa_value * 10 + 7;
    其他{
        mantissa_value = mantissa_value + POW(10,-numOfClicksAfterDecimal)* 7;
        numOfClicksAfterDecimal ++;
    }
    updateMantissa();
}公共无效onClkBn8(查看视图){
    如果(decimalClicked == FALSE)
        mantissa_value = mantissa_value * 10 + 8;
    其他{
        mantissa_value = mantissa_value + POW(10,-numOfClicksAfterDecimal)* 8;
        numOfClicksAfterDecimal ++;
    }
    updateMantissa();
}公共无效onClkBn9(查看视图){
    如果(decimalClicked == FALSE)
        mantissa_value = mantissa_value * 10 + 9;
    其他{
        mantissa_value = mantissa_value + POW(10,-numOfClicksAfterDecimal)* 9;
        numOfClicksAfterDecimal ++;
    }
    updateMantissa();
}公共无效onClkBnDot(查看视图){
    decimalClicked = TRUE;
}公共无效onClkBnCan(查看视图){
    mantissa_value = 0;
    OPR1 = 0;
    OPR2 = 0;
    RES = 0;
    oprLatest = OprTypes.NONE;
    oprPlusClicked = FALSE;
    oprMinusClicked = FALSE;
    oprMultClicked = FALSE;
    oprDivClicked = FALSE;
    decimalClicked = FALSE;
    numOfClicksAfterDecimal = 1;
}
公共无效onClkBnPlus(查看视图){
    如果(oprPlusClicked == FALSE){
        oprPlusClicked = TRUE;
        OPR1 = mantissa_value;
        mantissa_value = 0;
    }
    其他{
        //这应该意味着OPR1在它已经有一定价值
        //所以添加当前尾数值OPR1
        OPR1 = OPR1 + mantissa_value;
        mantissa_value = 0;
    }
    oprLatest = OprTypes.PLUS;
}
公共无效onClkBnMinus(查看视图){
    如果(oprMinusClicked == FALSE){
        oprMinusClicked = TRUE;
        OPR1 = mantissa_value;
        mantissa_value = 0;
    }
    其他{
        //这应该意味着OPR1在它已经有一定价值
        //所以添加当前尾数值OPR1
        OPR1 = OPR1 - mantissa_value;
        mantissa_value = 0;
    }
    oprLatest = OprTypes.MINUS;
}公共无效onClkBnMult(查看视图){
    如果(oprMultClicked == FALSE){
        oprMultClicked = TRUE;
        OPR1 = mantissa_value;
        mantissa_value = 0;
    }
    其他{
        //这应该意味着OPR1在它已经有一定价值
        //所以添加当前尾数值OPR1
        OPR1 = OPR1 * mantissa_value;
        mantissa_value = 0;
    }
    oprLatest = OprTypes.MULT;
}公共无效onClkBnDiv(查看视图){
    如果(oprDivClicked == FALSE){
        oprDivClicked = TRUE;
        OPR1 = mantissa_value;
        mantissa_value = 0;
    }
    其他{
        //这应该意味着OPR1在它已经有一定价值
        //所以添加当前尾数值OPR1
        OPR1 = OPR1 / mantissa_value;
        mantissa_value = 0;
    }
    oprLatest = OprTypes.DIV;
}
公共无效onClkBnRes(查看视图){
    如果(oprPlusClicked ==真|| oprMinusClicked ==真|| oprMultClicked ==真|| oprDivClicked ==真){
        开关(oprLatest){
        案例PLUS:
            mantissa_value = OPR1 + mantissa_value;
            打破;
        案例减:
            mantissa_value = OPR1 - mantissa_value;
            打破;
        案例增量:
            mantissa_value = OPR1 * mantissa_value;
            打破;
        案例DIV:
            mantissa_value = OPR1 / mantissa_value;
            打破;
        案例NONE:
            打破;
        }
    }
    oprLatest = OprTypes.NONE;
    oprPlusClicked = FALSE;
    oprMinusClicked = FALSE;
    oprMultClicked = FALSE;
    oprDivClicked = FALSE;
    updateMantissa();
}
}


解决方案

一个双在Java中的说法并不确切。它可以通过使用BigDecimal的固定

请参阅如何解决一个Java四舍五入双问题

I am trying to make a basic calculator program for android but I am new to android as well as java
But I believe this is probably more of a java problem
The interface has buttons for 0 through 9, decimal point, equal to sign, +, -, *, / and Cancel (which resets all the variables)
The mantissa is stored in a double variable and I use String.valueOf(mantissa_value) to convert it to a String to be displayed on a TextView control
When I type in 2.331, the mantissa shows 2.33099999 (10 characters is the limit for the String variable storing the mantissa text), but if I press 1 again, it shows 2.3311. Why is this happening and how can I fix it?

Relevant code (probably):

public void onClkBn1(View view){
    if(decimalClicked == false)
        mantissa_value = mantissa_value*10+1;
    else{
        mantissa_value = mantissa_value + pow(10, -numOfClicksAfterDecimal)*1;
        numOfClicksAfterDecimal++;
    }
    updateMantissa();
}

public void updateMantissa(){
    if(mantissa_value == 0){
        mantissa_str = "0";
    }

    else if(ceil(mantissa_value) == mantissa_value){
        mantissa_str = String.valueOf(mantissa_value);
        mantissa_str = mantissa_str.substring(0, mantissa_str.length() - 2 ); 
    }

    else{
        mantissa_str = String.valueOf(mantissa_value);
        mantissa_str = mantissa_str.substring(0, Math.min(mantissa_str.length(), 10));
    }
    TextView thisText = (TextView) findViewById(R.id.mantissa);
    thisText.setText(mantissa_str);
}

Full code:

package com.example.calculator;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.TextView;
import static java.lang.Math.pow;
import static java.lang.Math.ceil;

public class MainActivity extends Activity {
private double mantissa_value = 0;
private double opr1 = 0;
private double opr2 = 0;
private double res = 0;
private enum OprTypes {NONE, PLUS, MINUS, MULT, DIV}
OprTypes oprLatest = OprTypes.NONE;
private boolean oprPlusClicked = false;
private boolean oprMinusClicked = false;
private boolean oprMultClicked = false;
private boolean oprDivClicked = false;
private boolean decimalClicked = false;
private double numOfClicksAfterDecimal = 1;
private String mantissa_str;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    updateMantissa();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

public void updateMantissa(){
    if(mantissa_value == 0){
        mantissa_str = "0";
    }

    else if(ceil(mantissa_value) == mantissa_value){
        mantissa_str = String.valueOf(mantissa_value);
        mantissa_str = mantissa_str.substring(0, mantissa_str.length() - 2 ); 
    }

    else{
        mantissa_str = String.valueOf(mantissa_value);
        mantissa_str = mantissa_str.substring(0, Math.min(mantissa_str.length(), 10));
    }
    TextView thisText = (TextView) findViewById(R.id.mantissa);
    thisText.setText(mantissa_str);
}

public void onClkBn0(View view){
    TextView thisText = (TextView) findViewById(R.id.mantissa);
    if(decimalClicked == false){
        mantissa_value = mantissa_value*10+0;
        updateMantissa();
    }
    else{
        if(mantissa_value == 0){
            if(numOfClicksAfterDecimal == 1){
                mantissa_str = mantissa_str + ".0";
            }
            else{
                mantissa_str = mantissa_str + "0";
            }
        }

        else if(ceil(mantissa_value) == mantissa_value){
            if(numOfClicksAfterDecimal == 1){
                mantissa_str = mantissa_str + ".0";
            }
            else{
                mantissa_str = mantissa_str + "0";
            }
        }

        mantissa_value = mantissa_value + pow(10, -numOfClicksAfterDecimal)*0;
        numOfClicksAfterDecimal++;
        thisText.setText(mantissa_str);
    }
}

public void onClkBn1(View view){
    if(decimalClicked == false)
        mantissa_value = mantissa_value*10+1;
    else{
        mantissa_value = mantissa_value + pow(10, -numOfClicksAfterDecimal)*1;
        numOfClicksAfterDecimal++;
    }
    updateMantissa();
}

public void onClkBn2(View view){
    if(decimalClicked == false)
        mantissa_value = mantissa_value*10+2;
    else{
        mantissa_value = mantissa_value + pow(10, -numOfClicksAfterDecimal)*2;
        numOfClicksAfterDecimal++;
    }
    updateMantissa();
}

public void onClkBn3(View view){
    if(decimalClicked == false)
        mantissa_value = mantissa_value*10+3;
    else{
        mantissa_value = mantissa_value + pow(10, -numOfClicksAfterDecimal)*3;
        numOfClicksAfterDecimal++;
    }
    updateMantissa();
}

public void onClkBn4(View view){
    if(decimalClicked == false)
        mantissa_value = mantissa_value*10+4;
    else{
        mantissa_value = mantissa_value + pow(10, -numOfClicksAfterDecimal)*4;
        numOfClicksAfterDecimal++;
    }
    updateMantissa();
}

public void onClkBn5(View view){
    if(decimalClicked == false)
        mantissa_value = mantissa_value*10+5;
    else{
        mantissa_value = mantissa_value + pow(10, -numOfClicksAfterDecimal)*5;
        numOfClicksAfterDecimal++;
    }
    updateMantissa();
}

public void onClkBn6(View view){
    if(decimalClicked == false)
        mantissa_value = mantissa_value*10+6;
    else{
        mantissa_value = mantissa_value + pow(10, -numOfClicksAfterDecimal)*6;
        numOfClicksAfterDecimal++;
    }
    updateMantissa();
}

public void onClkBn7(View view){
    if(decimalClicked == false)
        mantissa_value = mantissa_value*10+7;
    else{
        mantissa_value = mantissa_value + pow(10, -numOfClicksAfterDecimal)*7;
        numOfClicksAfterDecimal++;
    }
    updateMantissa();
}

public void onClkBn8(View view){
    if(decimalClicked == false)
        mantissa_value = mantissa_value*10+8;
    else{
        mantissa_value = mantissa_value + pow(10, -numOfClicksAfterDecimal)*8;
        numOfClicksAfterDecimal++;
    }
    updateMantissa();
}

public void onClkBn9(View view){
    if(decimalClicked == false)
        mantissa_value = mantissa_value*10+9;
    else{
        mantissa_value = mantissa_value + pow(10, -numOfClicksAfterDecimal)*9;
        numOfClicksAfterDecimal++;
    }
    updateMantissa();
}

public void onClkBnDot(View view){
    decimalClicked = true;
}

public void onClkBnCan(View view){
    mantissa_value = 0;
    opr1 = 0;
    opr2 = 0;
    res = 0;
    oprLatest = OprTypes.NONE;
    oprPlusClicked = false;
    oprMinusClicked = false;
    oprMultClicked = false;
    oprDivClicked = false;
    decimalClicked = false;
    numOfClicksAfterDecimal = 1;
}


public void onClkBnPlus(View view){
    if(oprPlusClicked == false){
        oprPlusClicked = true;
        opr1 = mantissa_value;
        mantissa_value = 0;
    }
    else{
        // this should mean opr1 already has some value in it
        // so add the current mantissa value to opr1
        opr1 = opr1 + mantissa_value;
        mantissa_value = 0;
    }
    oprLatest = OprTypes.PLUS;
}


public void onClkBnMinus(View view){
    if(oprMinusClicked == false){
        oprMinusClicked = true;
        opr1 = mantissa_value;
        mantissa_value = 0;
    }
    else{
        // this should mean opr1 already has some value in it
        // so add the current mantissa value to opr1
        opr1 = opr1 - mantissa_value;
        mantissa_value = 0;
    }
    oprLatest = OprTypes.MINUS;
}

public void onClkBnMult(View view){
    if(oprMultClicked == false){
        oprMultClicked = true;
        opr1 = mantissa_value;
        mantissa_value = 0;
    }
    else{
        // this should mean opr1 already has some value in it
        // so add the current mantissa value to opr1
        opr1 = opr1 * mantissa_value;
        mantissa_value = 0;
    }
    oprLatest = OprTypes.MULT;
}

public void onClkBnDiv(View view){
    if(oprDivClicked == false){
        oprDivClicked = true;
        opr1 = mantissa_value;
        mantissa_value = 0;
    }
    else{
        // this should mean opr1 already has some value in it
        // so add the current mantissa value to opr1
        opr1 = opr1 / mantissa_value;
        mantissa_value = 0;
    }
    oprLatest = OprTypes.DIV;
}


public void onClkBnRes(View view){
    if(oprPlusClicked == true || oprMinusClicked == true || oprMultClicked == true || oprDivClicked == true){
        switch(oprLatest){
        case PLUS:
            mantissa_value = opr1 + mantissa_value;
            break;
        case MINUS:
            mantissa_value = opr1 - mantissa_value;
            break;
        case MULT:
            mantissa_value = opr1 * mantissa_value;
            break;
        case DIV:
            mantissa_value = opr1 / mantissa_value;
            break;
        case NONE:
            break;
        }
    }
    oprLatest = OprTypes.NONE;
    oprPlusClicked = false;
    oprMinusClicked = false;
    oprMultClicked = false;
    oprDivClicked = false;
    updateMantissa();
}
}

解决方案

A Double in Java is not exact. It can be fixed by using BigDecimal

See How to resolve a Java Rounding Double issue

这篇关于在计算器程序的更新尾数不稳定双变量行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆