数据格式化 及 计算精度
需求要求
精度要求
数量:15位整数,3位小数 最大值为 999,999,999,999,999.999
金额:15位整数,2位小数 最大值为 999,999,999,999,999.99
数据格式化要求
数量: 千分号,小数位数不足3位 按 2位处理
金额:
元:千分号,小数位数不足2位 按 2位处理 最大值: 999,999,999,999,999.99
万元:千分号,小数位数不足6位 按 6位处理 最大值: 99,999,999,999.999999
亿元:千分号,小数位数不足10位 按 10位处理 最大值: 9,999,999,9999999999
解决方案:
一:
1、修改数据库数量为NUMBER(17,3) 金额NUMBER(17,2)
2、修改Model 数量和金额数据类型为BigDecimal
3、页面展示
3.1、页面使用ClientContext.formatCurrency来格式化金额
例如: 页面数据为999999999999999.99格式化后为999,999,999,999,999.99
3.2、页面使用ClientContext.formatQuantity来格式化数量
例如: 页面数据为999999999999999.999格式化后为999,999,999,999,999.999
4、页面计算
数据类型使用BigDecimal
例如 文本框ID为 price数值为12342134.1113132
var price = new BigDecimal("0").setScale(ClientContext.currencyScale,ClientContext.currencyHandler);
if($("#price").val().match(/^\d+(\.\d+)?$/)==null){
price = new BigDecimal($("#price").val());
}
文本框ID 为 quantity 数值为 2134.111
var quantity = new BigDecimal("0").setScale(ClientContext.quantityScale,ClientContext.quantityHandler);
if($("#quantity").val().match(/^\d+(\.\d+)?$/)==null){
quantity = new BigDecimal($("#quantity").val());
}
计算总金额为 price*quantity
amount=price.multiply(quantity).setScale(ClientContext.quantityScale,ClientContext.quantityHandler);
5、数据提交
用compareTo进行数据是否超过最大值验证通过则提交
if(amount.compareTo(ClientContext.maxCurrency)>0){
alert("你的金额已经超过最大值,请减少数量!");
}
amount=amount.toString().replace(/,/gi,'');
------------------------------------------------------------------------------------------------------------------------------
如果ClientContext.currencyScale不满足要求
您可以在自己页面进行设置
例如ClientContext.currencyScale=4;
ClientContext其他属性同样也可以自行复写
BigDecimal 加(add)、减(subtract)、除(divide)比较(compareTo) 详细请参照java.math.BigDeciaml API javascript基本也使用
由于本人能力有限,如果有处理不当的地方欢迎讨论,并一起解决https://nodeload.github.com/dtrebbien/BigDecimal.js/zip/master
var Utils={
/**
* 处理 javascript 的数值类型
* @param number 要转换的数值
* @param scale 小数位数
* @param decimalPoint 小数点符号
* @param separativeSign 千分位符号
* return 格式化后的字符串
*/
formatNumber:function(number, scale, decimalPoint, separativeSign){
//要转换的数值
var n = !isFinite(+number) ? 0 : +number;
//小数位数
var prec = !isFinite(+scale) ? 0 : Math.abs(scale);
//千分位符号
var sep = (typeof separativeSign === 'undefined') ? ',' : separativeSign;
//小数点符号
var dec = (typeof decimalPoint === 'undefined') ? '.' : decimalPoint;
var s = '';
var toFixedFix = function (n, prec) {
var k = Math.pow(10, prec);
return '' + Math.round(n * k) / k;
};
// Fix for IE parseFloat(0.55).toFixed(0) = 0;
s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
if (s[0].length > 3) {
s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
}
if ((s[1] || '').length < prec) {
s[1] = s[1] || '';
s[1] += new Array(prec - s[1].length + 1).join('0');
}
return s.join(dec);
},
/**
* 处理 javascript 的BigDecimal格式化类型
* @param number 要转换的数值
* @param scale 小数位数
* @param decimalPoint 小数点符号
* @param separativeSign 千分位符号
* return 格式化后的字符串
*/
formatDecimal:function(number, scale, decimalPoint, separativeSign){
//处理空的情况
if (number=='' || number==undefined || number==null){
return '';
}
//小数位数
var prec = !isFinite(+scale) ? 0 : Math.abs(scale);
//千分位符号
var sep = (typeof separativeSign === 'undefined') ? ',' : separativeSign;
//小数点符号
var dec = (typeof decimalPoint === 'undefined') ? '.' : decimalPoint;
//要转换的数值
var s = number.replace(/,/gi,'').split('.');
//三位一节
if (s[0].length > 3) {
s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
}
//处理小于1时前导0问题
if (s[0] == ''){
s[0]='0';
}
//处理小数
if ((s[1] || '').length < prec) {
s[1] = s[1] || '';
s[1] += new Array(prec - s[1].length + 1).join('0');
}
return s.join(dec);
}
};
//客户端上下文
var ClientContext={
dbMaxCurrency:new BigDecimal("999999999999999.99"),
dbMaxQuantity:new BigDecimal("999999999999999.999"),
//货币金额单位
currencyUnit:'元',
//千分符号
separativeSign:',',
//小数符号
decimalPoint:'.',
//货币小树位数
currencyScale:2,
//货币最大值
maxCurrency:this.dbMaxCurrency,
//数量小数位数
quantityScale:3,
//数量最大值
maxQuantity:this.dbMaxQuantity,
//金额格式化
formatCurrency : function(currency){
//调用转换工具number, scale, decimalPoint, separativeSign
return Utils.formatDecimal(currency,ClientContext.currencyScale,ClientContext.decimalPoint,ClientContext.separativeSign);
},
//数量格式化
formatQuantity:function(quantity){
//调用转换工具number, scale, decimalPoint, separativeSign
return Utils.formatDecimal(quantity,ClientContext.currencyScale,ClientContext.decimalPoint,ClientContext.separativeSign);
},
init:function(){
if (ClientContext.currencyUnit == "元"){
ClientContext.currencyScale = 2;
ClientContext.maxCurrency = ClientContext.dbMaxCurrency;
}
if (unitStr == "万元"){
ClientContext.currencyScale = 6;
ClientContext.maxCurrency = ClientContext.dbMaxCurrency.divide(new BigDecimal(Math.pow(10,4).toString()));
}
if (unitStr == "亿元"){
ClientContext.currencyScale = 10;
ClientContext.maxCurrency = ClientContext.dbMaxCurrency.divide(new BigDecimal(Math.pow(10,8).toString()));
}
}
};
BigDecimal
<script type="text/javascript">
var a = new BigDecimal('12345678912345.12345');
var b = new BigDecimal('2');
alert("multiply:"+a.multiply(b));
alert("divide:"+a.setScale(9).divide(b));
alert("add:"+a.add(b));
alert("subtract:"+a.subtract(b));
alert(a.subtract(b).format(20,10));
</script>