Java Double类型精确运算解决
Java中的简单浮点数类型float和double不能够进行运算。
首先我们想到的是四舍五入,Math类中的round方法不能设置保留几位小数,我们只能像这样(例如保留两位)
Math.round(value * 100) / 100.0;
非常不幸,上面的代码不能解决包含小数位精度问题,类似400.0000000009,或者整数差0.00000000001的问题。
其次我们会使用BigDecimal,使用他的4个构造方法即加、减、乘、除。
当然想到这里,也差不多能解决上面的问题了
解决方案:
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.regex.Pattern;public final strictfp class MathUtil {private MathUtil() {}// 默认运算精度private static int DEF_SCALE = 10;/*** 提供数据类型转换为BigDecimal* * @param object 原始数据* @return BigDecimal*/public static final BigDecimal bigDecimal(Object object) {if (object == null) {throw new NullPointerException();}BigDecimal result;try {result = new BigDecimal(String.valueOf(object).replaceAll(",", ""));} catch (NumberFormatException e) {throw new NumberFormatException("Please give me a numeral.Not " + object);}return result;}/*** 提供(相对)精确的加法运算。* * @param num1 被加数* @param num2 加数* @return 两个参数的和*/public static final Double add(Object num1, Object num2) {BigDecimal result = bigDecimal(num1).add(bigDecimal(num2));return result.setScale(DEF_SCALE, BigDecimal.ROUND_HALF_UP).doubleValue();}/*** 提供(相对)精确的减法运算。* * @param num1 被减数* @param num2 减数* @return 两个参数的差*/public static final Double subtract(Object num1, Object num2) {BigDecimal result = bigDecimal(num1).subtract(bigDecimal(num2));return result.setScale(DEF_SCALE, BigDecimal.ROUND_HALF_UP).doubleValue();}/*** 提供(相对)精确的乘法运算。* * @param num1 被乘数* @param num2 乘数* @return 两个参数的积*/public static final Double multiply(Object num1, Object num2) {BigDecimal result = bigDecimal(num1).multiply(bigDecimal(num2));return result.setScale(DEF_SCALE, BigDecimal.ROUND_HALF_UP).doubleValue();}/*** 提供(相对)精确的除法运算,当发生除不尽的情况时,精度为10位,以后的数字四舍五入。* * @param num1 被除数* @param num2 除数* @return 两个参数的商*/public static final Double divide(Object num1, Object num2) {return divide(num1, num2, DEF_SCALE);}/*** 提供(相对)精确的除法运算。 当发生除不尽的情况时,由scale参数指定精度,以后的数字四舍五入。* * @param num1 被除数* @param num2 除数* @param scale 表示表示需要精确到小数点以后几位。* @return 两个参数的商*/public static final Double divide(Object num1, Object num2, Integer scale) {if (scale == null) {scale = DEF_SCALE;}num2 = num2 == null || Math.abs(new Double(num2.toString())) == 0 ? 1 : num2;if (scale < 0) {throw new IllegalArgumentException("The scale must be a positive integer or zero");}BigDecimal result = bigDecimal(num1).divide(bigDecimal(num2), scale, BigDecimal.ROUND_HALF_UP);return result.doubleValue();}/*** 提供精确的小数位四舍五入处理。* * @param num 需要四舍五入的数字* @param scale 小数点后保留几位* @return 四舍五入后的结果*/public static final Double round(Object num, int scale) {if (scale < 0) {throw new IllegalArgumentException("The scale must be a positive integer or zero");}BigDecimal result = bigDecimal(num).divide(bigDecimal("1"), scale, BigDecimal.ROUND_HALF_UP);return result.doubleValue();}/*** 获取start到end区间的随机数,不包含start+end* * @param start* @param end* @return*/public static final BigDecimal getRandom(int start, int end) {return new BigDecimal(start + Math.random() * end);}/*** 格式化* * @param obj* @param pattern* @return*/public static final String format(Object obj, String pattern) {if (obj == null) {return null;}if (pattern == null || "".equals(pattern)) {pattern = "#";}DecimalFormat format = new DecimalFormat(pattern);return format.format(bigDecimal(obj));}/** 是否数字 */public static final boolean isNumber(Object object) {Pattern pattern = Pattern.compile("\\d+(.\\d+)?$");return pattern.matcher(object.toString()).matches();}
这里需要将结果round再次保留2位小数
MathUtil.round(MathUtil.add("100.03", "232.134"), 2);
以上解决Java Double精确运算的问题。
Java Double类型精确运算解决相关推荐
- java double类型保留两位小数的几种方法
java double类型保留两位小数的几种方法 返回double类型的(转换比较方便) ①能四舍五入 double d = 114.145; d = (double) Math.round(d * ...
- java double 运算精度问题_关于java中Double类型的运算精度问题
如果我们编译运行下面这个程序会看到什么? public class Test{ public static void main(String args[]){ System.o ...
- java double 类型_关于Java中的double类型数据
在初学Java的时候,一般我们都会从基本的数据类型开始学习,而在基本数据类型中,我认为double类型是比较难理解的,并且在以后的学习或工作中,在double类型数据这遇到的坑也是极多的.例如下面的这 ...
- Java Double类型计算工具类 BigDecimal
BigDecimal 处理Double类型的基本运算 BigDecimal 处理Double类型的基本运算 Java Double 数据在进行数据计算的时候,很容出现丢失精度的问题,因此借助于BigD ...
- Java基本类型与运算
问题及答案来源自<Java程序员面试笔试宝典>第四章 Java基础知识 4.4基本类型与运算 1.Java提供了哪些基本数据类型? Java一共提高了八种原始的数据类型:byte.shor ...
- C#到Java byte类型冲突的解决
最近要改写一个核心加密认证类,从C#改写成Java. 发现在调试时,加密的数据无论如何也对不上. 经过跟踪,发现问题出在C#和Java byte类型的区别上:在C#里 byte类型是无符号的,而Jav ...
- java double类型保留小数和四舍五入
建议方法:用Bigdecimal来处理浮点数的加减 例如: import java.math.BigDecimal; import java.util.*;public class Main{publ ...
- java double类型判空,简单封装JAVA空判断
在项目开发过程中,面对各种各样的对象,如果稍不注意,就会发生NULL空指针报错;是不是很烦恼,特别是对重要的参数判读; 经过总结,把各种类型的空判断进行了简单的封装,对新手还是很方便的; packag ...
- java double类型保留两位小数4种方法
4种方法,都是四舍五入,例:import java.math.BigDecimal;import java.text.DecimalFormat;import java.text.NumberForm ...
最新文章
- 边缘计算4.0正急速驶来,你做好准备了吗?
- 解决IDEA中maven工程的jsp、jstl依赖导入了 ,但是 jsp页面的uri却不提示(手动输上也报红)
- 理论与实践中的 C# 内存模型
- 仿IOS介绍APP下载页源码
- 2020 kali 切换中文显示_Kali设置中文
- 用c#开发微信(10) JSSDK 基本用法 分享接口“发送到朋友”
- 计算机考研复试【英语面试题汇总】
- 发现并充分发挥你的长处—盖洛普优势测试
- IntelliJ IDEA使用记录:maven projects-compile提示【**类,找不到符号】
- 3000字长文:探讨报销系统使用满意度的NPS指标设计
- 数据结构与算法01:绪论【LEARN FROM 李春葆《数据结构教程》】
- idea取消英语拼音提示绿色波浪线
- Cisco服务器硬盘状态jbod,如何为服务器硬盘配置RAID或JBOD模式
- 汽车技术管理系统c语言,[源码和文档分享]基于C语言实现的汽车牌照的快速查询...
- 1905. 统计子岛屿-深度优先遍历图
- 软考高级 真题 2012年上半年 信息系统项目管理师 论文
- dubbo学习(一)dubbo简介与原理
- 什么才算好的监控系统?
- linux内存不足导致tomcat宕机
- 十个小贴士!帮你节省编程时间、减少挫败感
热门文章
- PHP实现的日志收集系统
- 知识文库杂志知识文库杂志社知识文库编辑部2022年第14期目录
- 手机壳 拼板 排版 UV打印 (程序端+ PS 脚本排版 套图)
- 怎么用卷积神经网络模型去雾
- Android zxing,轻松实现二维码扫描、生成
- web前端css伪元素使用阿里iconfont中Unicode编码
- Windows 系统错误码
- 从SPACE矩阵,看5G究竟是否在走向成功?
- 翻译:利用GANs学习行人轨迹的多模态分布 Learning Multi-Modal Distributions of Pedestrian Trajectories with GANs
- 如何采用FM进行召回