js计算器组件Calc.js
来源:互联网 发布:查看交换机端口ip 编辑:程序博客网 时间:2024/06/05 04:15
js浮点型
在编程语言中关于浮点型数字计算问题的解决方案有很多种,其实很多人都会根据个人爱好进行封装,那么首先探讨一下浮点型小数计算存在什么问题。计算机存储的数据是二进制数据,也即1、0,那么在数学中的十进制数据如何映射为二进制数?对于整数,可以除于2取余数,最后倒叙排列来得出二进制编码(负数则数取补码),例如10的二进制为1010,而-10的二进制为0110,当然看你的计算机是32位还是64位,表示数据的精度不同。对于浮点数,常有乘法表示和除法表示两种(基数为2),对于除法,当小数位大于2-n次方时(0.5,0.25,0.125,…)表示1,小于当前2-n次方为0,最后可以得出小数的二进制,例如0.5 二进制为0.1,0.52的二进制为1000010…(后面无穷),因为表示不过来,所以要截取一定的位数来近似表示,例如这里的0.52的二进制为0.10000101。我们都知道在js中进行0.1+0.2=0.30000000000000004而不是0.3,就是因为截取了小数的二进制位数造成。所以在js中进行浮点数计算时,都是在精度特定的情况下进行。
(function(win) { //计算器 var Calc = { add: add, substract: substract, multiply: multiply, divid: divid, setScale: _setScale, scale: 2, isNumeric: _isNumeric,equal: equal, getInstance: function() { var instance = {}; //继承类 for(var name in Calc) { if(name != "getInstance") { instance[name] = Calc[name]; } } return instance; } }; //加法 function add() { var i = 0, len = arguments.length, sum = 0, arg1 = this.isNumeric(arguments[0]) && arguments[0] || 0, arg2 = this.isNumeric(arguments[1]) && arguments[1] || 0; sum = _add.call(this, arg1, arg2); if(len > 2) { //用递归实现就是方便 sum = _add.call(this, sum, this.add.apply(this, Array.prototype.slice.call(arguments,2))); } return sum; } //两个数相加 function _add(arg1, arg2) { var pow = Math.pow(10, this.scale), number = arg1 * pow + arg2 * pow; return number / pow; } //减法 function substract() { var i = 0, len = arguments.length, arg2 = 0, arg1 = this.isNumeric(arguments[0]) && arguments[0] || 0; if(len > 2) { arg2 = this.add.apply(this, Array.prototype.slice.call(arguments,1)); } else { arg2 = this.isNumeric(arguments[1]) && arguments[1] || 0; } return _substract.call(this, arg1, arg2); } //两个数相减 function _substract(arg1, arg2) { var pow = Math.pow(10, this.scale), number = arg1 * pow - arg2 * pow; return number / pow; } //乘法 function multiply() { var i = 0, len = arguments.length, sum = 1, arg1 = this.isNumeric(arguments[0]) && arguments[0] || 0, arg2 = this.isNumeric(arguments[1]) && arguments[1] || 0; sum = _multiply.call(this, arg1, arg2); if(len > 2) { sum = _multiply.call(this, sum, this.multiply.apply(this, Array.prototype.slice.call(arguments,2))); } return sum; } //两个数相乘 function _multiply(arg1, arg2) { var pow = Math.pow(10, this.scale), number = (arg1 * pow) * (arg2 * pow); return number / (pow * pow); } //除法 function divid() { var i = 0, len = arguments.length, sum = 1, arg1 = this.isNumeric(arguments[0]) && arguments[0] || 0, arg2 = 1; if(len > 2) { arg2 = this.multiply.apply(this, Array.prototype.slice.call(arguments,1)); } else { arg2 = this.isNumeric(arguments[1]) && arguments[1] || arg2; } return arg2 && _divid.call(this, arg1, arg2) || 0; } //两个数相除 function _divid(arg1, arg2) { var pow = Math.pow(10, this.scale), number = (arg1 * pow) / (arg2 * pow); return number ; } //设置精度 function _setScale(number, scale, notRound) { //默认精度为2,因为电价的字段一般都是精度为2 var _scale = scale || this.scale, _pow = Math.pow(10, _scale), _number = this.isNumeric(number) && number || 0; if(notRound) { //将浮点数进行提升为整数 _number = win.parseInt(_number * _pow) / _pow; } //toFixed会自动进行四舍五入,如果_number的精度大于_scale时 return Number(_number).toFixed(_scale); } //判断是否为数字 function _isNumeric(number) { var fNaN = win.isNaN(number); return !fNaN && !!number || fNaN && number != undefined; } //两个浮点数比较 function equal(arg1, arg2, scale) { var _scale = scale || this.scale; return Number(arg1).toFixed(_scale) === Number(arg2).toFixed(_scale); } //接口绑定 win = win || window; win.Calc = Calc; return Calc;})(window);
注意
对于Calc.js中的Calc采用的是组件极简定定义法,同时利用工厂方法模式getInstance来创建Calc的实例对象,当然还可以采用function配合prototype来定义组件,但是这种小计算器采用极简定义法更方便些。
阅读全文
0 0
- js计算器组件Calc.js
- Calc计算器
- js -计算器
- js计算器
- js计算器
- JS计算器
- js计算器
- js计算器
- JS计算器
- js计算器
- js 计算器
- js计算器
- js计算器
- js 计算器
- js计算器
- js 计算器
- JS 计算器
- js 计算器
- Android:Date、String、Long三种日期类型之间的相互转换
- 关于for语句思考
- 学习笔记:ES6之let和const
- Java自带线程池基本介绍
- Spring Boot应用的健康监控
- js计算器组件Calc.js
- HDU-5441 Travel(并查集)
- spring-boot配置log4j(gradle)
- laravel资料汇总
- OI知识点总结(提高/省选-)
- 两者最大数的优化
- 解决android studio 连接手机端口占用 nothing to show 问题
- spark Shuffle过程分析
- open函数mode参数详解