当前位置: 首页 > news >正文

Java/Android中BigDecimal的相关操作

在Java/Android中,BigDecimal 用于高精度的十进制运算。以下是详细的转换和操作方法:

1. 创建和初始化

基本创建方式

import java.math.BigDecimal;
import java.math.RoundingMode;// 1. 使用字符串创建(推荐,避免精度问题)
BigDecimal bd1 = new BigDecimal("123.456");
BigDecimal bd2 = new BigDecimal("100.00");// 2. 使用double创建(可能有不精确问题)
BigDecimal bd3 = new BigDecimal(123.456);// 3. 使用valueOf方法(内部会处理double的精度问题)
BigDecimal bd4 = BigDecimal.valueOf(123.456);
BigDecimal bd5 = BigDecimal.valueOf(100);// 4. 使用整数创建
BigDecimal bd6 = new BigDecimal(100);
BigDecimal bd7 = BigDecimal.valueOf(100L);// 5. 常用常量
BigDecimal zero = BigDecimal.ZERO;
BigDecimal one = BigDecimal.ONE;
BigDecimal ten = BigDecimal.TEN;

2. 基本算术运算

四则运算

BigDecimal a = new BigDecimal("10.50");
BigDecimal b = new BigDecimal("3.20");// 加法
BigDecimal sum = a.add(b); // 13.70// 减法
BigDecimal difference = a.subtract(b); // 7.30// 乘法
BigDecimal product = a.multiply(b); // 33.600// 除法(需要指定精度和舍入模式)
BigDecimal quotient = a.divide(b, 2, RoundingMode.HALF_UP); // 3.28// 取余
BigDecimal remainder = a.remainder(b); // 0.90

复杂运算示例

public class BigDecimalOperations {public static void main(String[] args) {BigDecimal price = new BigDecimal("99.99");BigDecimal quantity = new BigDecimal("3");BigDecimal taxRate = new BigDecimal("0.08"); // 8%// 计算总金额BigDecimal subtotal = price.multiply(quantity);// 计算税费BigDecimal tax = subtotal.multiply(taxRate).setScale(2, RoundingMode.HALF_UP);// 计算最终金额BigDecimal total = subtotal.add(tax);System.out.println("小计: $" + subtotal); // $299.97System.out.println("税费: $" + tax);      // $24.00System.out.println("总计: $" + total);    // $323.97}
}

3. 精度控制和舍入

设置精度和舍入模式

BigDecimal number = new BigDecimal("123.456789");// 设置小数位数
BigDecimal scaled1 = number.setScale(2, RoundingMode.HALF_UP); // 123.46
BigDecimal scaled2 = number.setScale(4, RoundingMode.FLOOR);   // 123.4567// 除法时的精度控制
BigDecimal a = new BigDecimal("10");
BigDecimal b = new BigDecimal("3");// 指定小数位数和舍入模式
BigDecimal result1 = a.divide(b, 4, RoundingMode.HALF_UP); // 3.3333
BigDecimal result2 = a.divide(b, 2, RoundingMode.CEILING); // 3.34

舍入模式详解

BigDecimal number = new BigDecimal("123.456");// 常用舍入模式
BigDecimal halfUp = number.setScale(2, RoundingMode.HALF_UP);     // 123.46
BigDecimal halfDown = number.setScale(2, RoundingMode.HALF_DOWN); // 123.46
BigDecimal halfEven = number.setScale(2, RoundingMode.HALF_EVEN); // 123.46
BigDecimal ceiling = number.setScale(2, RoundingMode.CEILING);    // 123.46
BigDecimal floor = number.setScale(2, RoundingMode.FLOOR);        // 123.45
BigDecimal up = number.setScale(2, RoundingMode.UP);              // 123.46
BigDecimal down = number.setScale(2, RoundingMode.DOWN);          // 123.45

4. 比较操作

大小比较

BigDecimal a = new BigDecimal("100.50");
BigDecimal b = new BigDecimal("100.00");
BigDecimal c = new BigDecimal("100.50");// 比较
int compareResult = a.compareTo(b); // 1 (a > b)
boolean isGreater = a.compareTo(b) > 0; // true
boolean isLess = a.compareTo(b) < 0;    // false
boolean isEqual = a.compareTo(c) == 0;  // true// 不要使用equals进行数值比较(会比较精度)
boolean equals1 = a.equals(b); // false
boolean equals2 = a.equals(new BigDecimal("100.5")); // false(精度不同)
boolean compare1 = a.compareTo(new BigDecimal("100.5")) == 0; // true

范围检查

public class BigDecimalComparison {public static boolean isBetween(BigDecimal value, BigDecimal min, BigDecimal max) {return value.compareTo(min) >= 0 && value.compareTo(max) <= 0;}public static boolean isPositive(BigDecimal value) {return value.compareTo(BigDecimal.ZERO) > 0;}public static boolean isNegative(BigDecimal value) {return value.compareTo(BigDecimal.ZERO) < 0;}public static boolean isZero(BigDecimal value) {return value.compareTo(BigDecimal.ZERO) == 0;}
}

5. 类型转换

转换为其他类型

BigDecimal bd = new BigDecimal("123.456");// 转换为字符串
String stringValue = bd.toString();          // "123.456"
String plainString = bd.toPlainString();     // "123.456"(不使用科学计数法)
String engineeringString = bd.toEngineeringString(); // "123.456"// 转换为数值类型
int intValue = bd.intValue();                // 123(直接截断)
long longValue = bd.longValue();             // 123
float floatValue = bd.floatValue();          // 123.456
double doubleValue = bd.doubleValue();       // 123.456// 安全转换(处理null和异常)
int safeInt = bd.intValueExact();            // 如果非整数会抛出异常
long safeLong = bd.longValueExact();         // 同上

从其他类型转换

// 从字符串转换
BigDecimal fromString = new BigDecimal("123.45");// 从数值类型转换
BigDecimal fromInt = BigDecimal.valueOf(100);
BigDecimal fromLong = BigDecimal.valueOf(100L);
BigDecimal fromDouble = BigDecimal.valueOf(123.456);// 从整数转换
BigDecimal fromInteger = new BigDecimal(100);// 处理null安全的转换
public static BigDecimal safeValueOf(String value) {if (value == null || value.trim().isEmpty()) {return BigDecimal.ZERO;}try {return new BigDecimal(value.trim());} catch (NumberFormatException e) {return BigDecimal.ZERO;}
}

6. 实用工具方法

数学运算

BigDecimal number = new BigDecimal("16");// 绝对值
BigDecimal abs = number.abs();// 取反
BigDecimal negate = number.negate();// 次方运算
BigDecimal power = number.pow(2); // 256// 移动小数点
BigDecimal movePoint = number.movePointRight(2); // 1600
BigDecimal movePointLeft = number.movePointLeft(1); // 1.6

精度操作

BigDecimal number = new BigDecimal("123.456789");// 获取精度相关信息
int scale = number.scale();                     // 6(小数位数)
int precision = number.precision();             // 9(总位数)
BigDecimal stripped = number.stripTrailingZeros(); // 去除末尾的0// 检查整数
boolean isInteger = number.scale() <= 0;        // false
boolean hasDecimal = number.scale() > 0;        // true

7. 在Android中的实际应用

金额计算工具类

public class MoneyUtils {/*** 格式化金额显示*/public static String formatMoney(BigDecimal amount) {if (amount == null) return "¥0.00";DecimalFormat df = new DecimalFormat("¥#,##0.00");return df.format(amount);}/*** 安全地解析金额字符串*/public static BigDecimal parseMoney(String moneyStr) {if (moneyStr == null || moneyStr.trim().isEmpty()) {return BigDecimal.ZERO;}try {// 移除货币符号和逗号String cleaned = moneyStr.replaceAll("[¥$,]", "").trim();return new BigDecimal(cleaned);} catch (NumberFormatException e) {return BigDecimal.ZERO;}}/*** 计算含税价格*/public static BigDecimal calculateTaxIncluded(BigDecimal amount, BigDecimal taxRate) {if (amount == null || taxRate == null) {return BigDecimal.ZERO;}BigDecimal tax = amount.multiply(taxRate).setScale(2, RoundingMode.HALF_UP);return amount.add(tax);}/*** 分配金额(如AA制分摊)*/public static BigDecimal[] splitAmount(BigDecimal total, int parts) {if (total == null || parts <= 0) {return new BigDecimal[0];}BigDecimal[] result = new BigDecimal[parts];BigDecimal partAmount = total.divide(BigDecimal.valueOf(parts), 2, RoundingMode.HALF_UP);// 前n-1个部分使用平均分配for (int i = 0; i < parts - 1; i++) {result[i] = partAmount;}// 最后一部分用总金额减去已分配金额,避免精度损失BigDecimal allocated = partAmount.multiply(BigDecimal.valueOf(parts - 1));result[parts - 1] = total.subtract(allocated);return result;}
}

在Activity中使用

public class PaymentActivity extends AppCompatActivity {private TextView totalAmountView;private EditText quantityEditText;private BigDecimal unitPrice = new BigDecimal("29.99");@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_payment);totalAmountView = findViewById(R.id.totalAmount);quantityEditText = findViewById(R.id.quantity);quantityEditText.addTextChangedListener(new TextWatcher() {@Overridepublic void onTextChanged(CharSequence s, int start, int before, int count) {calculateTotal();}// 其他方法...});}private void calculateTotal() {try {String quantityStr = quantityEditText.getText().toString();if (quantityStr.isEmpty()) {totalAmountView.setText("¥0.00");return;}BigDecimal quantity = new BigDecimal(quantityStr);BigDecimal total = unitPrice.multiply(quantity).setScale(2, RoundingMode.HALF_UP);totalAmountView.setText(MoneyUtils.formatMoney(total));} catch (NumberFormatException e) {totalAmountView.setText("无效数量");}}/*** 处理折扣计算*/private BigDecimal applyDiscount(BigDecimal original, BigDecimal discountRate) {BigDecimal discount = original.multiply(discountRate).setScale(2, RoundingMode.HALF_UP);return original.subtract(discount);}
}

8. 注意事项

重要提醒

// 1. 始终使用字符串构造BigDecimal来避免精度问题
BigDecimal bad = new BigDecimal(0.1);    // 不推荐
BigDecimal good = new BigDecimal("0.1"); // 推荐// 2. 比较使用compareTo而不是equals
BigDecimal a = new BigDecimal("100.0");
BigDecimal b = new BigDecimal("100.00");
boolean wrong = a.equals(b);        // false
boolean correct = a.compareTo(b) == 0; // true// 3. 除法一定要指定舍入模式
BigDecimal ten = new BigDecimal("10");
BigDecimal three = new BigDecimal("3");
// BigDecimal error = ten.divide(three); // 会抛出ArithmeticException
BigDecimal correct = ten.divide(three, 2, RoundingMode.HALF_UP); // 3.33// 4. 使用valueOf来处理double(内部会处理精度)
BigDecimal fromDouble = BigDecimal.valueOf(0.1); // 0.1

这些是BigDecimal在Java/Android中的主要转换和操作方法。BigDecimal特别适合财务计算、货币运算等需要高精度的场景。

http://www.dtcms.com/a/611207.html

相关文章:

  • 珠海网站建设服务哪个网站做视频有钱
  • 网站开发新闻管理系统的背景设计之家素材
  • PS2模拟器安卓版合集 PSX2、ARMSX2、MYPS2、NetherSX2、 PCSX2汉化中文版
  • 建设工程项目管理网站中心网站建设方法
  • 注意点:挂载与插硬盘,容器挂载实现持久化存储
  • 解决Ubuntu TTY终端中文乱码问题
  • 北京美容网站建设中国进入一级战备有多可怕?
  • 郑州市建设投资集团公司网站深圳罗湖住房和建设局网站
  • 网站建设好与管理在哪就业设计办公室设计公司
  • 泛型擦除的作用
  • 长治门户网站租服务器网站
  • 大连网站排名优化价格怎样做网贷网站
  • AAAI 2026 Oral 之江实验室等提出MoEGCL:在6大基准数据集上刷新SOTA,聚类准确率最高提升超8%!
  • 当当网的网站建设要求北京学校网站建设公司
  • 【Vue3】 中的 【unref】:详解与使用
  • 衡阳做淘宝网站建设wordpress 营销页面
  • BdsEntry
  • 网站备案后 如何建设tp框架做餐饮网站
  • 自动化 东莞网站建设如何提高用户和网站的互动性
  • Linux网络编程:(八)GCC/G++ 编译器完全指南:从编译原理到实战优化,手把手教你玩转 C/C++ 编译
  • 网站负责人拍照集团公司网站设计
  • 重钢建设公司官方网站电脑访问手机网站跳转
  • AI赋能多模态情绪识别
  • vue3 使用v-model开发弹窗组件
  • 淘宝网站建设的目标是什么石家庄网络营销哪家好做
  • vue3开发使用框架推荐
  • 郑州网站建设方案国内购物网站大全
  • Qt界面布局管理详解
  • RK3506 eMMC 固件重启崩溃问题(USB 触发)技术总结
  • RocketMQ DefaultMQPushConsumer vs DefaultLitePullConsumer