BigDecimal.divideAndRemainder()返回商余数组[quotient, remainder],商朝零截断、精度由MathContext控制,余数符号同被除数且绝对值小于除数绝对值。

BigDecimal.divideAndRemainder() 方法能一次性返回商和余数,但它不直接返回两个独立值,而是返回一个包含两个 BigDecimal 的数组:[quotient, remainder]。使用时需注意精度、舍入模式和被除数/除数的符号规则。
基本用法:获取商和余数数组
调用该方法后,结果是长度为 2 的 BigDecimal 数组,索引 0 是商(向下取整 toward zero),索引 1 是余数,满足恒等式:dividend.equals(quotient.multiply(divisor).add(remainder))
- 商始终朝零截断(即
Math.floor()对正数、Math.ceil()对负数的效果),不支持自定义舍入模式 - 余数符号与被除数一致,且绝对值严格小于除数的绝对值
- 如果除数为 0,抛出
ArithmeticException
必须指定 MathContext(精度 + 舍入模式)
该方法有且仅有一个重载形式:divideAndRemainder(BigDecimal divisor, MathContext mc)。MathContext 控制商的精度和舍入方式,但不影响余数计算逻辑(余数由精确整数除法定义)。
- 商的精度指结果最多保留多少有效数字,不是小数位数
- 推荐使用
RoundingMode.HALF_UP或RoundingMode.DOWN,避免UNNECESSARY(除非确保整除) - 示例:
new MathContext(10, RoundingMode.HALF_UP)表示商最多 10 位有效数字,四舍五入
实际使用示例(含正负数和小数)
注意:即使操作数含小数,该方法仍按“标量除法”处理,商为整数部分(朝零取整),余数 = 原值 − 商 × 除数。
BigDecimal a = new BigDecimal("17.5");
BigDecimal b = new BigDecimal("4.2");
BigDecimal[] result = a.divideAndRemainder(b, new MathContext(15, RoundingMode.HALF_UP));
// result[0] ≈ 4.0(商,朝零取整后的近似值)
// result[1] = 17.5 − 4 × 4.2 = 0.7(精确余数)
- 若 a = -17.5,b = 4.2 → 商 = -4.0,余数 = -0.7(余数符号同被除数)
- 若 a = 17.5,b = -4.2 → 商 = -4.0,余数 = 0.7(余数符号仍同 a)
- 商的精度设置过低(如
MathContext(1, ...))可能导致商严重失真,慎用
与整数除法的差异及替代方案
divideAndRemainder() 不是整数类型上的模运算,它适用于任意精度小数,但语义更接近“带余除法”的数学定义。
- 若需严格整数行为(如只处理整数值),建议先用
setScale(0, RoundingMode.DOWN)截断小数再调用 - 若只需余数,可直接用
a.remainder(b)(不依赖 MathContext,但不提供商) - 若需高精度商+余数且要求商为精确整数(非近似),应确保被除数和除数均为整数
BigDecimal,或自行实现基于divideToIntegralValue()的组合逻辑
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











