package com.landray.kmss.ztb.fm.util;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.landray.kmss.util.StringUtil;
public class NumberUtil {
private static Log logger = LogFactory.getLog(NumberUtil.class);
public static final Integer DEF_DIV_SCALE = 2;
public static void main(String[] args) {
Number num = null;
System.out.println(String.valueOf(num));
}
/**
* 提供精确的数值比较,int,float,double等不同精度可相互比较
* @param number1 数值1
* @param number2 数值2
* @return
* @author 李元卿
* @date 2020年10月28日
* @version 1.0
*/
public static final boolean equals(Number number1, Number number2){
if(number1 == null || number2 == null) return false;
BigDecimal bd1 = new BigDecimal(getValueString(number1));
BigDecimal bd2 = new BigDecimal(getValueString(number2));
return bd1.compareTo(bd2) == 0;
}
/**
* 提供精确的数值比较,判断数值1 > 数值2
* int,float,double等不同精度可相互比较
* @param number1 数值1
* @param number2 数值2
* @param equalsFlag 是否额外比较相等
* @return
* @author 李元卿
* @date 2020年10月28日
* @version 1.0
*/
public static final boolean biggerThan(Number number1, Number number2, Boolean equalsFlag){
BigDecimal bd1 = new BigDecimal(getValueString(number1));
BigDecimal bd2 = new BigDecimal(getValueString(number2));
int compare = bd1.compareTo(bd2);
if(Boolean.TRUE.equals(equalsFlag)) return compare >= 0;
return compare > 0;
}
/**
* 提供精确的加法运算。
* @param params 可变,加法运算因数
* @return 多个参数的和
*/
public static final Number add(Number... params) {
BigDecimal result = new BigDecimal(0);
if(params != null){
for (Number number : params) {
result = result.add(new BigDecimal(getValueString(number)));
}
}
return result.doubleValue();
}
/**
* 提供精确的减法运算。
* @param minuend 被减数
* @param subtrahends 可变,减数
* @return 被减数减去减数(多个)
*/
public static final Number sub(Number minuend, Number... subtrahends) {
BigDecimal result = new BigDecimal(getValueString(minuend));
if(subtrahends != null){
for (Number number : subtrahends) {
result = result.subtract(new BigDecimal(getValueString(number)));
}
}
return result.doubleValue();
}
/**
* 提供精确的乘法运算。
* @param v1 被乘数
* @param v2 乘数
* @return 两个参数的积
*/
public static Number mul(Number v1,Number v2){
BigDecimal b1 = new BigDecimal(getValueString(v1));
BigDecimal b2 = new BigDecimal(getValueString(v2));
return b1.multiply(b2).doubleValue();
}
/**
* 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到小数点以后2位,以后的数字四舍五入。
* @param v1 被除数
* @param v2 除数
* @return 两个参数的商
*/
public static Number div(Number v1,Number v2){
return div(v1,v2,DEF_DIV_SCALE);
}
/**
* 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指定精度,以后的数字四舍五入。
* @param v1 被除数
* @param v2 除数
* @param scale 表示表示需要精确到小数点以后几位。
* @return 两个参数的商
*/
public static Number div(Number v1,Number v2,Integer scale){
if(scale < 0){
throw new IllegalArgumentException("The scale must be a positive integer or 0");
}
// 被除数不能为0
if(equals(v2, 0)){
throw new IllegalArgumentException("The dividend value cannot be 0");
}
BigDecimal b1 = new BigDecimal(getValueString(v1));
BigDecimal b2 = new BigDecimal(getValueString(v2));
return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
}
/**
* 提供精确的小数位四舍五入处理。
* @param v 需要四舍五入的数字
* @param scale 小数点后保留几位
* @return 四舍五入后的结果
*/
public static Number round(Number v,Integer scale){
BigDecimal b = new BigDecimal(getValueString(v));
if(scale == null || scale < 0) return b;
BigDecimal one = new BigDecimal("1");
return b.divide(one,scale,BigDecimal.ROUND_HALF_UP);
}
public static final Number toNumber(String value) {
if(StringUtil.isNull(value)) return 0;
return toNumber(value, null);
}
public static final Number toNumber(String value, Integer scale) {
try{
if("-".equals(value)){
// 特殊兼容字符,直接返回0
return 0;
}
// 去除千分位
value = CompareUtil.adaption(value).replace(",", "");
int minusNum = 0;
// 记录前端负数符号,兼容负负得正
while(value.trim().startsWith("-")){
value = value.trim().substring(1);
minusNum ++;
}
// 消除多余的负号
if(minusNum % 2 == 1){
value = "-" + value;
}
return round(new BigDecimal(value), scale);
}catch(Exception e){
logger.error("==========数值[" + value + "]转换异常,返回0========", e);
return 0;
}
}
public static final Number getValue(Number number) {
if(number == null) return 0;
return number;
}
public static final String getValueString(Number number) {
if(number != null){
try{
return String.valueOf(number);
}catch(Exception e){
e.printStackTrace();
}
}
return String.valueOf(0);
}
/**
* 格式化数值类型,转换为字符串
* 出现异常默认返回0
* @param number 数值对象
* @param scale 转换后保留的精度
* @return
*/
public static final String formatNumber(Number number, Integer scale) {
if(number == null) number = 0;
String result = String.valueOf(round(number, scale));
if(scale != null){
// 小数位数不足时补0
while(result.indexOf(".") >= result.length() - scale){
result += "0";
}
}
return result;
}
public static boolean isEquals(Number a, Number b) {
return isEquals(getValueString(a), getValueString(b));
}
/**
* 判断两个金额是否相等
*
* @param number
* @return
*/
public static boolean isEquals(String a, String b) {
if(a == null || b == null) return false;
BigDecimal aBigDecimal = new BigDecimal(a);
BigDecimal bBigDecimal = new BigDecimal(b);
return aBigDecimal.equals(bBigDecimal);
}
public static final String formatNumber(Number number) {
return formatNumber(number, null);
}
public static final String formatPriceNumber(Number number) {
return formatNumber(number, DEF_DIV_SCALE);
}
public static final String formatPriceNumber(String value) {
return formatNumber(value, DEF_DIV_SCALE);
}
public static final String formatThousandPirce(String value){
return formatThousandPirce(toNumber(value));
}
/**
* 数值格式化:千分位以“,”分隔
* @param number
* @return
* @author 李元卿
* @date 2021年10月20日
* @version 1.0
*/
public static final String formatThousandPirce(Number number){
try{
DecimalFormat format = new DecimalFormat("#,##0.00");
return format.format(number);
}catch(Exception e){
logger.warn("千分位格式化异常,仅执行普通金额格式化。");
return formatPriceNumber(number);
}
}
/**
* 数值格式化:千分位以“,” 分隔;值为 “0” 解析为 “-”
* @param number
* @return
* @author 李元卿
* @date 2021年10月20日
* @version 1.0
*/
public static final String
没有合适的资源?快使用搜索试试~ 我知道了~
java和js的计算精度的实现
共2个文件
js:1个
java:1个
需积分: 5 0 下载量 147 浏览量
2023-09-22
17:48:08
上传
评论
收藏 6KB ZIP 举报
温馨提示
在金额的加减乘除运算时我们往往会忽略计算结果的精度问题,导致莫名奇妙出现了过多的小数位,这在我做银行项目时尤其需要关注的一个问题点。 其实在我们使用正常的 + - * / 运算时,在某些情况下就会出现精度丢失的问题,如金额过大时,单纯的加减都有可能出现精度丢失,对于银行项目来说,是很敏感的,需要对每个加减乘除都进行一次方法处理,为此我整理除了一套处理工具。 后端时java工具类(NumberUtil.java),前端是js工具脚本(Number.js),可直接引入项目中使用,里面每个方法我都加以注释详解,希望可以帮到大家!
资源推荐
资源详情
资源评论
收起资源包目录
Number工具.zip (2个子文件)
Number.js 8KB
NumberUtil.java 12KB
共 2 条
- 1
资源评论
一花全世界
- 粉丝: 2
- 资源: 5
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 农村信用社联合社计算机信息系统投产与变更管理办.docx
- 农村信用社联合社计算机信息系统数据管理办法.docx
- 利用SPSS作临床效度分析线上计算网站介绍-医学研究部统计谘.(医学PPT课件).ppt
- 利用Zabbix监控mysqldump定时备份数据库状态.docx
- 利用计算机解决问题的基本过程.doc
- 化工铁路通信工程总结.doc
- 北京大学网络教育软件工程作业.docx
- 医药公司(连锁店)计算机操作规程未新系统的自行按照旧制修改-新系统过制的编号加修模版.doc
- 医药公司(连锁店)计算机系统操作规程模版.doc
- 医药连锁门店计算机系统的操作和管理程序未新系统的自行按照旧制修改-新系统过制的编号加修模版.docx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功