【问题标题】:Decimal points in calculator android计算器android中的小数点
【发布时间】:2017-01-15 07:57:10
【问题描述】:

我正在 android 中创建一个计算器应用程序。问题是如何检查单个数值中是否存在两个小数。目前我的计算器允许输入诸如 1.2.3 这是非法的。如果使用了运算符,它必须允许小数。例如1.1+2.2 是合法的,但1.1.1+2.2 不是。 这是我的小数处理代码:

public class TrialCalculator extends AppCompatActivity implements Button.OnClickListener {
    Button btn1, btn2, btnBack, btn3, btn4, btn5, btn6, btn7, btn8, btn9, btn0, btnPlus, btnMinus, btnMul, btnDiv, btnEquals, btnClear, btnDecimal, btnPercent;
    EditText calcResult;
    double number = 0;
    private char opcode = '1';

    private void handleDecimal() {
        if (opcode == 0) clear();
        if (calcResult.getText() == null) {
            calcResult.setText("0.");
            calcResult.setSelection(2);
        } else {
            String txt = calcResult.getText().toString();
            if (txt.lastIndexOf(".")<txt.length()-1) {
                calcResult.append(".");
            }
        }
    }
}

我从onClick 方法调用buttonDot

【问题讨论】:

  • 您应该显示更多代码。特别是,这里显示的方法应该在一个类中,并且应该显示所有的变量声明。
  • handleDecimal 将在按下. 按钮时被调用。对吗?
  • 是的,没错

标签: java android string-comparison


【解决方案1】:

一种解决方案是设置一个跟踪小数点的标志:

class MyCalculator {
    private hasDecimal = false;

    // ...
}

在用户第一次输入小数时将此标志设置为true。然后检查标志以查看之前是否输入了小数。

当然,这仅在您直接响应每个按键而不是在用户输入整个数字后从EditText 获取整个输入时才有效。

【讨论】:

  • 是的,最后布尔变量是完成这项工作的唯一方法。
【解决方案2】:

您可以将正则表达式与matches 函数一起使用

\\d* 表示匹配零个或多个数字

(\\.\\d+)? 匹配 . 后跟一个或多个数字,? 表示给定组的零次或一次匹配

Regex Demo :注意在 java 中使用 matches 函数,我们不需要 ^ 开始和 $ 结束锚

代码

if (txt.matches("\\d*(\\.\\d+)?")) {
   // number has one decimal
  }
else{
   // number has more than one decimal
}

注意:如果您不想允许 .5 这样的值,请使用 \\d+ 而不是 \\d* as

\\d+(\\.\\d+)?

正如@Code-Apprentice 所建议的,如果您想接受4343. 等值 你可以使用

\\d*(\\.\\d*)?

使用文本观察器

calcResult.addTextChangedListener(new TextWatcher() {
    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {}

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

    @Override
    public void afterTextChanged(Editable s) {
        boolean flag = s.toString().matches("\\d*(\\.\\d*)?");
        if(!flag){
            // calcResult.setError...
            // you display a toast 
        }             
    }
});

更新:要使用操作符匹配多个值,您可以使用

(\\d*(\\.\\d*)?([+\\-*%\\]|$))*

RegEx demo

测试用例

String pat="(\\d*(\\.\\d*)?([+\\-*%\\]|$))*";
System.out.println("4.5-3.3+3.4".matches(pat));
System.out.println(".5".matches(pat));
System.out.println("4".matches(pat));
System.out.println("4.5.5-4.4".matches(pat));
System.out.println("4.44.5+4.4.4".matches(pat));
System.out.println("4.".matches(pat));

输出:

true
true
true
false
false
true

【讨论】:

  • 如果没有小数点那不也去else分支吗?
  • 同样,如果你想允许像5. 这样的数字,小数点后的\\d+ 可以是\\d*
  • @PavneetSingh 完全正确。
  • @Code-Apprentice 我故意排除了这些值,但如果 OP 想要那么我会修改正则表达式或者你的建议也在这里:)
【解决方案3】:

lastIndexOf 如果在字符串中找不到该字符,则返回 -1。所以你的条件txt.lastIndexOf(".")&lt;txt.length()-1 总是true。你可以改成

txt.lastIndexOf(".") == -1

【讨论】:

    【解决方案4】:

    要检查单个 no 中是否存在两个小数,然后按小数拆分字符串。

    例如,

    String txt = calcResult.getText().toString();
    String[] decimals = txt.split("\\.");
    if(decimals.length > 2) {
    // txt contains more than 1 decimal.
    // Your logic ..
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-02-21
      • 1970-01-01
      • 2012-08-09
      • 2014-12-14
      • 1970-01-01
      • 1970-01-01
      • 2021-04-03
      相关资源
      最近更新 更多