Products
GG网络技术分享 2025-03-18 16:14 0
本文解决问题:
1.number类型是否可以表示除10进制以外的数字?
2.number的数值安全范围及其作用?
3.number的方法?
浮点数(小数)0.1 + 0.2不等于0.3?(下一篇文章具体讲解)
问:number类型是否可以表示除10进制以外的数字?
十进制(默认)写法:var intNum = 55; // 55
八进制写法:var octalNum1 = 070; // 56
十六进制写法:var hexNum2 = 0x1f; // 31
答:可以表示其他进制的数。通过赋值前面加0,区别十进制。
输出统一是转化为十进制
问:number的数值安全范围及其作用?
答: js采用的是64位双精度,最小值为:Number.MIN_SAFE_INTEGER // -9007199254740991
最大值为:Number.MAX_SAFE_INTEGER // 9007199254740991
超出规定范围导致精度丢失 console.log(900719925474099177)
// 900719925474099100
注意:如果具体业务中后台返回的id超过16位,一定要让后台把id改为string类型
问:number的方法?
答:
如果是数字值,只是简单地传入和返回。
如果是 null 值,返回 0。
如果是 undefined,返回 NaN。
如果是字符串,遵循下列规则:
如果字符串中只包含数字(包括前面带正号或负号的情况),则将其转换为十进制数值,即"1"
会变成 1,"123"会变成 123,而"011"会变成 11(注意:前面的零被忽略了);
如果字符串中包含有效的浮点格式,如"1.1",则将其转换为对应的浮点数值(同样,也会忽略前面零);
如果字符串中包含有效的十六进制格式,例如"0xf",则将其转换为相同大小的十进制整
数值;
如果字符串是空的(不包含任何字符),则将其转换为 0;
如果字符串中包含除上述格式之外的字符,则将其转换为 NaN。
如果是对象,则调用对象的 valueOf()方法,然后依照前面的规则转换返回的值。如果转换
的结果是 NaN,则调用对象的 toString()方法,然后再次依照前面的规则转换返回的字符
串值。
Number('12'); // 12 Number({}); // NaN Number(true); // 1
Number(undefined); // NaN, Number(null); // 0
总结:number类型的操作无非是加减乘除...等的运算操作,所以我们做运算的时候只转换字符串类型(可变为数字类型)+数字类型,其他类型不进行运算操作
3.parseInt方法
parseInt('123E4');// 123 parseInt('E123E4');// NaN
parseInt(123.4);// 123 parseInt传入其他数据类型都是NaN
总结:截断匹配 数字开头,遇到非数字即截断,返回的是number类型
4.parseFloat方法
parseFloat('123.56E4');// 123 parseFloat('E123.78E4');// NaN
parseFloat(123.4);//123.4 parseFloat传入其他数据类型都是NaN
总结:截断匹配 数字开头,遇到非(数字和小数点)即截断,返回的是number类型
5.toFixed 保留几位小数
(12.45).toFixed(1) // ‘12.4’
6 Math 函数可处理数学运算;例如平方、绝对值 等等丰富的数学功能
js数字计算丢失精度问题解决方案
计算机世界里,数字的计算,所有语言都会丢失精度,所以没有万全之策,但在人力范围内,尽量解决。
网上找了一部分代码,发现是有问题的,比如:
//加法 Number.prototype.myAdd = function(arg2) { var arg1 = this; if (isNaN(arg2)) { return arg2; } var r1, r2, m; try { r1 = arg1.toString().split(\".\")[1].length } catch (e) { r1 = 0 } try { r2 = arg2.toString().split(\".\")[1].length } catch (e) { r2 = 0 } m = Math.pow(10, Math.max(r1, r2)) return (arg1 * m + arg2 * m) / m } //减法 Number.prototype.mySub = function(arg2) { var arg1 = this; if (isNaN(arg2)) { return arg2; } var r1, r2, m, n; try { r1 = arg1.toString().split(\".\")[1].length } catch (e) { r1 = 0 } try { r2 = arg2.toString().split(\".\")[1].length } catch (e) { r2 = 0 } m = Math.pow(10, Math.max(r1, r2)); n = (r1 >= r2) ? r1 : r2; return ((arg1 * m - arg2 * m) / m).toFixed(n); } //乘法 Number.prototype.myMul = function(arg2) { var arg1 = this; if (isNaN(arg2)) { return arg2; } var m = 0, s1 = arg1.toString(), s2 = arg2.toString(); try { m += s1.split(\".\")[1].length } catch (e) {} try { m += s2.split(\".\")[1].length } catch (e) {} return Number(s1.replace(\".\", \"\")) * Number(s2.replace(\".\", \"\")) / Math.pow(10, m) } // 除法 Number.prototype.myDiv = function(arg2) { var arg1 = this; if (isNaN(arg2)) { return arg2; } var t1 = 0, t2 = 0, r1, r2; try { t1 = arg1.toString().split(\".\")[1].length } catch (e) {} try { t2 = arg2.toString().split(\".\")[1].length } catch (e) {} with(Math) { r1 = Number(arg1.toString().replace(\".\", \"\")) r2 = Number(arg2.toString().replace(\".\", \"\")) return (r1 / r2).myMul(pow(10, t2 - t1)) } } |
在计算一些特殊的数字时,仍然有问题:
比如加法:
268.34.myDiv(0.83);//321.7505995203837 |
所以还要优化
我重新做了一版:
var operationNumber = function (arg1,arg2,operator) { var oper=[\'+\',\'-\',\'*\',\'/\']; // 不合法的运算 if (isNaN(arg1)||isNaN(arg2)||oper.indexOf(operator)<0) { return NaN; } // 除以0 if (operator===\'/\'&&Number(arg2)===0) { return Infinity; } // 和0相乘 if (operator===\'*\'&&Number(arg2)===0) { return 0; } // 相等两个数字相减 if ((arg1===arg2||Number(arg1)===Number(arg2))&&operator===\'-\') { return 0; } var r1, r2, max,_r1,_r2; try { r1 = arg1.toString().split(\".\")[1].length } catch (e) { r1 = 0 } try { r2 = arg2.toString().split(\".\")[1].length } catch (e) { r2 = 0 } max = Math.max(r1, r2) _r1 = max-r1; _r2 = max-r2; if (_r1!==0) { arg1=arg1+\'0\'.repeat(_r1) } if (_r2!==0) { arg2=arg2+\'0\'.repeat(_r2) } arg1 = Number(arg1.toString().replace(\'.\',\'\')) arg2 = Number(arg2.toString().replace(\'.\',\'\')) var r3 = operator===\'*\'?(max*2):(operator===\'/\'?0:max); var newNum = eval(arg1+operator+arg2); if (r3!==0) { var nStr = newNum.toString(); nStr = nStr.replace(/^-/,\'\'); if (nStr.length<r3+1) { nStr = \'0\'.repeat(r3+1-nStr.length)+nStr; } nStr = nStr.replace(new RegExp(\'(\\\\\\d{\'+r3+\'})$\'),\'.$1\'); if (newNum<0) { nStr = \'-\'+nStr; } newNum = nStr*1; } return newNum; } //加法 Number.prototype.myAdd = function(arg2) { return operationNumber(this,arg2,\'+\'); } //减法 Number.prototype.mySub = function(arg2) { return operationNumber(this,arg2,\'-\'); } //乘法 Number.prototype.myMul = function(arg2) { return operationNumber(this,arg2,\'*\'); } // 除法 Number.prototype.myDiv = function(arg2) { return operationNumber(this,arg2,\'/\'); } |
如果你发现了bug,评论区及时反馈,我及时跟进修复
以上就是怎么解决javascript数字计算丢失精度问题?的详细内容,更多请关注网站的其它相关文章!
Demand feedback