You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中BigDecimal小数位数设置及EditText输入限制问题

问题解决:金额比较精度问题与EditText小数位数限制

你的代码里用Double.parseDouble把输入字符串转成double,再通过BigDecimal.valueOf(double)创建BigDecimal,这会导致精度丢失——因为double是二进制浮点数,无法精确表示像62921.0000000000000001这类十进制小数,转成double时会被近似为62921.0,所以和用户余额的BigDecimal比较时会判定为相等,最终让不符合条件的金额通过校验。

一、正确使用BigDecimal并设置小数位数

要解决精度问题,核心是避免通过double中转创建BigDecimal,同时可以通过setScale方法指定小数位数:

// 直接用输入字符串创建BigDecimal,完整保留输入精度
BigDecimal depositAmountSafe = new BigDecimal(etDepositAmount.getText().toString());
// 设置保留3位小数,舍入模式可选ROUND_DOWN(直接截断)或ROUND_HALF_UP(四舍五入)
depositAmountSafe = depositAmountSafe.setScale(3, BigDecimal.ROUND_DOWN);

// 用户余额如果是double类型,同样要转成字符串再创建BigDecimal
BigDecimal userBalance = new BigDecimal(String.valueOf(user.getBalance()));

int comparisonResult = depositAmountSafe.compareTo(userBalance);
if (comparisonResult > 0) {
    Toast.makeText(context, R.string.INSUFFICIENT_BALANCE, Toast.LENGTH_SHORT).show();
    return;
}
Deposit deposit = createDeposit();

注意:如果用户余额本身就是BigDecimal类型(比如从数据库读取的),直接使用即可,无需转换。

二、限制EditText最多输入3位小数

如果想从源头限制输入,避免后续处理,推荐以下两种方法:

方法1:自定义InputFilter

通过过滤器直接阻止超过3位小数的输入:

etDepositAmount.setFilters(new InputFilter[]{new InputFilter() {
    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
        String currentText = dest.toString();
        if (currentText.contains(".")) {
            int dotIndex = currentText.indexOf(".");
            int decimalLength = currentText.length() - dotIndex - 1;
            // 已有3位小数时,拒绝新输入
            if (decimalLength >= 3) {
                return "";
            }
        }
        return null;
    }
}});

方法2:使用TextWatcher实时截断

监听输入内容,超过3位小数时自动截断:

etDepositAmount.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {}

    @Override
    public void afterTextChanged(Editable s) {
        String text = s.toString();
        if (text.contains(".")) {
            int dotIndex = text.indexOf(".");
            if (text.length() - dotIndex - 1 > 3) {
                // 截断到小数点后3位
                s.replace(dotIndex + 4, s.length(), "");
            }
        }
    }
});

此外,还可以在XML中设置EditText的属性,限制只能输入数字和小数点:

<EditText
    android:id="@+id/etDepositAmount"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:inputType="numberDecimal"
    android:digits="0123456789."/>

内容的提问来源于stack exchange,提问作者bko00

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 08:35:38