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
相关产品推荐
相关产品推荐

