java 精度处理_JAVA计算结果精度处理

1 ackage com.vstsoft.common.util;2

3 import java.math.BigDecimal;4 import java.text.DecimalFormat;5

6 import org.slf4j.Logger;7 import org.slf4j.LoggerFactory;8

9 /**10 * @Comments : 由于Java的简单类型不能够精确的对浮点数进行运算, 这个工具类提供精确的浮点数运算,包括加减乘除和四舍五入。11 */

12 public class ArithUtil {13 //默认除法运算精度

14 private static final int DEFAULT_DIV_SCALE = 10;15 private final static Logger logger =LoggerFactory.getLogger(ArithUtil.class);16

17 /**18 * 提供精确的加法运算。19 *20 * @param v121 * @param v222 * @return 两个参数的和23 */

24 public static BigDecimal add(BigDecimal b1, BigDecimal b2) {25 returnb1.add(b2);26 }27

28 public static BigDecimal add(double v1, doublev2) {29 BigDecimal b1 = newBigDecimal(Double.toString(v1));30 BigDecimal b2 = newBigDecimal(Double.toString(v2));31 returnadd(b1, b2);32 }33

34 /**35 * 提供精确的减法运算。36 *37 * @param v138 * @param v239 * @return 两个参数的差40 */

41

42 public static BigDecimal subtract(BigDecimal b1, BigDecimal b2) {43 returnb1.subtract(b2);44 }45

46 public static BigDecimal subtract(double v1, doublev2) {47 BigDecimal b1 = newBigDecimal(Double.toString(v1));48 BigDecimal b2 = newBigDecimal(Double.toString(v2));49 returnb1.subtract(b2);50 }51

52 /**53 * 提供精确的乘法运算。54 *55 * @param v156 * @param v257 * @return 两个参数的积58 */

59

60 public static BigDecimal multiply(BigDecimal b1, BigDecimal b2) {61 returnb1.multiply(b2);62 }63

64 public static BigDecimal multiply(double v1, doublev2) {65 BigDecimal b1 = newBigDecimal(Double.toString(v1));66 BigDecimal b2 = newBigDecimal(Double.toString(v2));67 returnb1.multiply(b2);68 }69

70 /**71 * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 小数点以后10位,以后的数字四舍五入,舍入模式采用ROUND_HALF_EVEN72 *73 * @param v174 * 被除数75 * @param v276 * 除数77 * @return 两个参数的商78 */

79

80 public static BigDecimal divide(BigDecimal b1, BigDecimal b2) {81 returndivide(b1, b2, DEFAULT_DIV_SCALE);82 }83

84 public static BigDecimal divide(double v1, doublev2) {85 returndivide(v1, v2, DEFAULT_DIV_SCALE);86 }87

88 /**89 * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。舍入模式采用ROUND_HALF_EVEN90 *91 * @param v192 * 被除数93 * @param v294 * 除数95 * @param scale96 * 表示需要精确到小数点以后几位。97 * @return 两个参数的商98 */

99

100 public static BigDecimal divide(BigDecimal b1, BigDecimal b2, intscale) {101 returndivide(b1, b2, scale, BigDecimal.ROUND_HALF_EVEN);102 }103

104 public static BigDecimal divide(double v1, double v2, intscale) {105 returndivide(v1, v2, scale, BigDecimal.ROUND_HALF_EVEN);106 }107

108 /**109 * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。舍入模式采用用户指定舍入模式110 *111 * @param v1112 * 被除数113 * @param v2114 * 除数115 * @param scale116 * 表示需要精确到小数点以后几位117 * @param round_mode118 * 表示用户指定的舍入模式119 * @return 两个参数的商120 */

121

122 public static BigDecimal divide(BigDecimal b1, BigDecimal b2, int scale, intround_mode) {123 if (scale < 0) {124 throw new IllegalArgumentException("The scale must be a positive integer or zero");125 }126 returnb1.divide(b2, scale, round_mode);127 }128

129 public static BigDecimal divide(double v1, double v2, int scale, intround_mode) {130 if (scale < 0) {131 throw new IllegalArgumentException("The scale must be a positive integer or zero");132 }133 BigDecimal b1 = newBigDecimal(Double.toString(v1));134 BigDecimal b2 = newBigDecimal(Double.toString(v2));135 returnb1.divide(b2, scale, round_mode);136 }137

138 /**139 * 提供保留两位小数的四舍五入处理,舍入模式采用ROUND_HALF_EVEN140 *141 * @param v142 * 需要四舍五入的数字143 * @param scale144 * 小数点后保留几位145 * @return 四舍五入后的结果146 */

147

148 public static BigDecimal round(BigDecimal b) {149 return round(b, 2);150 }151

152 /**153 * 提供精确的小数位四舍五入处理,舍入模式采用ROUND_HALF_EVEN154 *155 * @param v156 * 需要四舍五入的数字157 * @param scale158 * 小数点后保留几位159 * @return 四舍五入后的结果160 */

161

162 public static BigDecimal round(BigDecimal b, intscale) {163 returnround(b, scale, BigDecimal.ROUND_HALF_EVEN);164 }165

166 /**167 * 提供精确的小数位四舍五入处理168 *169 * @param v170 * 需要四舍五入的数字171 * @param scale172 * 小数点后保留几位173 * @param round_mode174 * 指定的舍入模式175 * @return 四舍五入后的结果176 */

177

178 public static BigDecimal round(BigDecimal b, int scale, intround_mode) {179 if (scale < 0) {180 logger.error(StaticUtil.UTILERROR, "scale:" + scale + ",the scale must be a positive integer or zero");181 throw new IllegalArgumentException("The scale must be a positive integer or zero");182 }183 returnb.setScale(scale, round_mode);184 }185

186 public static voidmain(String[] args) {187 BigDecimal b1 = new BigDecimal("100");188 BigDecimal b2 = new BigDecimal("1.765");189 BigDecimal b3 = new BigDecimal("1.65");190 BigDecimal b4 = new BigDecimal("7");191

192 //精确除法运算

193 logger.info(divide(b1, b4).toString());194 logger.info(divide(b1, b4, 1).toString());195

196 logger.info(round(b2, 2, BigDecimal.ROUND_HALF_EVEN).toString());197 logger.info(round(b2, 2, BigDecimal.ROUND_HALF_UP).toString());198 logger.info(round(b2, 2, BigDecimal.ROUND_HALF_DOWN).toString());199

200 logger.info(round(b3, 1, BigDecimal.ROUND_HALF_EVEN).toString());201 logger.info(round(b3, 1, BigDecimal.ROUND_HALF_UP).toString());202 logger.info(round(b3, 1, BigDecimal.ROUND_HALF_DOWN).toString());203

204 //数学运算在实际中存在的问题

205 /**206 * 0.060000000000000005 0.5800000000000001 401.49999999999994207 * 1.2329999999999999208 */

209 logger.info("错误的结果:");210 logger.info(0.05 + 0.01 + "");211 logger.info(1.0 - 0.42 + "");212 logger.info(4.015 * 100 + "");213 logger.info(123.3 / 100 + "");214 logger.info("精确计算的结果:");215 logger.info(ArithUtil.add(new BigDecimal("0.056789123446"), new BigDecimal("0.01234566789")).toString());216 logger.info(ArithUtil.subtract(new BigDecimal("1.012345678912"), new BigDecimal("0.42345689127")).toString());217 logger.info(ArithUtil.multiply(new BigDecimal("4.0156789"), new BigDecimal("100.12345")).toString());218 logger.info(ArithUtil.divide(new BigDecimal("123.3"), new BigDecimal("100")).toString());219 /**220 * 输入结果为 504.549999999999982946974341757595539093017578125 实际结果应为 504.55221 */

222 logger.info("BigDecimal 的不精确计算问题:");223 BigDecimal bg1 = new BigDecimal(100.91);224 BigDecimal bg2 = new BigDecimal(5);225 BigDecimal bg3 =bg1.multiply(bg2);226 logger.info(bg3 + "");227 DecimalFormat df = new DecimalFormat("¥0,000.00");228 logger.info("精确计算的结果:");229

230 BigDecimal bg4 = multiply(new BigDecimal("1000000000.91"), new BigDecimal("5"));231 logger.info(ArithUtil.round(bg4).toString());232 BigDecimal bg5 = multiply(new BigDecimal("10000000"), new BigDecimal("9999999"));233 logger.info(ArithUtil.round(bg5).toString());234 logger.info("***************************************************");235

236 }237 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值