因项目需要,在前端页面需要对金额进行规则进行运算,用javascript自带的运算浮点数时会出现精度差异,经各种搜索和实验及整理,特此记录以后备用。
/*
* 由于计算机是用二进制来存储和处理数字,不能精确表示浮点数,而javascript中没有相应的封装类来处理浮点数运算
* 直接计算会导致运算精度丢失。
* 为了避免产生精度差异,把需要计算的数字升级成计算机能够精确识别的整数,等计算完毕再降级,这是大部分编程序
* 语言处理精度差异的通用方法。
*/
/*
* 左补齐字符串
* @param nSize 要补齐的长度
* @param ch 要补齐的字符
*/
String.prototype.padLeft = function(nSize,ch){
var len = 0;
var s = this ? this : "";
ch = ch ? ch : '0';//默认补0
len = s.length;
while(len<nSize){
s = ch + s;
len++;
}
return s;
};
/*
* 右补齐字符串
* @param nSize 要补齐的长度
* @param ch 要补齐的字符
*/
String.prototype.padRight = function(nSize,ch){
var len = 0 ;
var s = this ? this : "";
ch = ch ? ch : '0';//默认补0
len = s.length;
while(len<nSize){
s = s + ch;
len++;
}
return s;
};
/*
* 左移小数点位置 (用于数学计算,相当于除以Math.pow(10,scale)
* @param scale 要移位的刻度
* @return
*/
String.prototype.movePointLeft = function(scale){
var s,s1,s2,ch,ps,sign;
ch = ".";
sign = '';
s = this ? this : "";
if(scale <=0){
return s;
}
ps = s.split('.');
s1 = ps[0] ? ps[0] : "";
s2 = ps[1] ? ps[1] : "";
if(s1.slice(0,1)=='-'){
s1 = s1.slice(1);
sign = '-';
}
if(s1.length<=scale){
ch = "0.";
s1 = s1.padLeft(scale);
}
return sign + s1.slice(0,-scale) + ch + s1.slice(-scale) + s2;
};
/*
* 右移小数点位置 (用于数学计算,相当于除以Math.pow(10,scale)
* @param scale 要移位的刻度
* @return
*/
String.prototype.movePointRight = function(scale){
var s,s1,s2,ch,ps;
ch = '.';
s = this ? this : "";
if(scale<=0){
return s;
}
ps = s.split('.');
s1 = ps[0] ? ps[0] : "";
s2 = ps[1] ? ps[1] : "";
if(s2.length<=scale){
ch = '';
s2 = s2.padRight(scale);
}
return s1 + s2.slice(0,scale) + ch + s2.slice(scale,s2.length);
};
/*
* 移动小数点位置 (用于数学计算,相当于除以Math.pow(10,scale)
* @param scale 要移位的刻度(正数表示向右移,负数表示向左移,0返回返值)
* @return
*/
Strng.prototype.movePoint = function(scale){
if(scale >= 0){
return this.movePointRight(scale);
}else{
return this.movePointLeft(scale);
}
};
/*
* 加法
* @param arg 加数,可以是字符串或数字
*/
Number.prototype.add = function(arg){
var n,n1,n2,s,s1,s2,ps;
s1 = this.toString();
ps = s1.split('.');
n1 = ps[1] ? ps[1].length : 0;
s2 = arg.toString();
ps = s2.split('.');
n2 = ps[1] ? ps[1].length : 0;
n = n1 > n2 ? n1 : n2;
s = Number(s1.movePoint(n)) + Number(s2.movePoint(n));
s = s.toString().movePoint(-n);
return Number(s);
};
/*
* 减法
* @param arg 减数,可以是字符串或数字
*/
Number.prototype.sub = function(arg){
var n,n1,n2,s,s1,s2,ps;
s1 = this.toString();
ps = s1.split('.');
n1 = ps[1] ? ps[1].length : 0;
s2 = arg.toString();
ps = s2.split('.');
n2 = ps[1] ? ps[1].length : 0;
n = n1 > n2 ? n1 : n2;
s = Number(s1.movePoint(n)) - Number(s2.movePoint(n));
s = s.toString().movePoint(-n);
return Number(s);
};
/*
* 乘法
* @param arg 乘数,可以是字符串或数字
*/
Number.prototype.mul = function(arg){
var n,n1,n2,s,s1,s2,ps;
s1 = this.toString();
ps = s1.split('.');
n1 = ps[1] ? ps[1].length : 0;
s2 = arg.toString();
ps = s2.split('.');
n2 = ps[1] ? ps[1].length : 0;
n = n1 + n2;
s = Number(s1.replace('.','')) * Number(s2.replace('.',''));
s = s.toString().movePoint(-n);
return Number(s);
};
/*
* 除法
* @param arg 除数,可以是字符串或数字
*/
Number.prototype.div = function(arg){
var n,n1,n2,s,s1,s2,ps;
s1 = this.toString();
ps = s1.split('.');
n1 = ps[1] ? ps[1].length : 0;
s2 = arg.toString();
ps = s2.split('.');
n2 = ps[1] ? ps[1].length : 0;
n = n1 - n2;
s = Number(s1.replace('.','')) / Number(s2.replace('.',''));
s = s.toString().movePoint(-n);
return Number(s);
};
/*
* 取模
* @param arg 模数,可以是字符串或数字
*/
Number.prototype.mod = function(arg){
var n,n1,n2,s,s1,s2,ps;
s1 = this.toString();
ps = s1.split('.');
n1 = ps[1] ? ps[1].length : 0;
s2 = arg.toString();
ps = s2.split('.');
n2 = ps[1] ? ps[1].length : 0;
n = n1 > n2 ? n1 : n2;
s = Number(s1.movePoint(n)) % Number(s2.movePoint(n));
s = s.toString().movePoint(-n);
return Number(s);
};
分享到:
相关推荐
它通过将输入值左移指定位数,并将超出的部分从右侧重新接入,实现了位操作中的循环移位。例如,`RotateLeft(0x12345678, 5)` 的结果是 `0x56781234`,这里我们将二进制表示下的十六进制数 `0x12345678` 左移了五位...
在硬件层面,它们可能通过移位和加法(乘以2的幂次)或者反复执行减法(除以2的幂次)来实现。对于非整数倍的乘法和除法,可以使用快速乘法算法(如Karatsuba乘法、Toom-Cook乘法等)和除法算法(如长除法、近似算法...
- **循环移位**:通过异或运算,可以实现数据的循环左移(A << n XOR A >> (bit_count-n))和循环右移(A >> n XOR A (bit_count-n))。 - **错误检测**:CRC(Cyclic Redundancy Check)校验码就是基于异或运算,...
在这个例子中,我们首先将数字乘以100(即移位两位),然后使用`Math.round()`进行四舍五入操作,最后再除以100还原到原来的量级,从而实现了四舍五入并保留两位小数的功能。 #### 二、其他编程语言中的实现 为了...
以26个英文字母为基准,通过模26的运算实现字母的移位。在传统的应用中,字母“A”代表0,“B”代表1,一直到“Z”代表25。在加密时,首先根据密钥找到一个位置偏移量,然后对明文进行偏移。假如密钥字母是“D”,则...
8. 最有效率计算2乘以8的方法是使用移位操作:2 。 9. final关键字用于声明常量,修饰变量时变量值不能被改变。 10. "=="和equals方法的区别在于前者比较引用地址,而后者比较对象的内容。 11. 静态变量属于类,...
AES全称为Advanced Encryption Standard,它通过一系列可逆的数学运算,实现数据的加密和解密,以保护信息的安全。 AES的核心操作包括四个步骤:字节替代(SubBytes)、行移位(ShiftRows)、列混淆(MixColumns)...
AES的工作原理是通过一系列复杂的数学运算(如替换、置换、混淆等)对原始明文数据进行加密,形成不可读的密文。解密过程则是加密的逆操作,将密文恢复为原始数据。AES的核心在于其密钥扩展和状态矩阵变换过程,它...
解密过程则是加密的逆操作,通过同样的密钥将密文还原为原始数据。 在这个示例中,前端部分通常使用JavaScript实现,负责对用户数据进行加密,然后发送到后端。前端加密库如CryptoJS提供了AES加密的功能,可以通过...
模2加法是指二进制数的加法运算不考虑进位,只计算每一位的结果,而移位操作则是指将数组中的元素向左或向右移动。 #### 代码详解 下面我们将对给定的JavaScript代码进行详细的分析: ```javascript var a = new ...
这个过程分为两个阶段:初始置换、16轮迭代(每轮包括子密钥产生、分组、异或操作和逆置换四个步骤)、最后的逆置换。其中,密钥扩展过程是DES的一个关键部分,它将56位密钥扩展为64位,但只有其中的56位参与实际的...
float 32bit, 9位有效数字,含小数(四舍五入)(小数点算一位,正负号不算) double 64bit, 18位有效数字 注:float 和 double 的小数部分不可能精确,只能近似。 比较小数时,用 double i=0.01; if ( i - 0.01 ) ...