LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

[点晴永久免费OA]js parseInt之0.0000001陷阱分析小结【javascript】

admin
2015年3月9日 16:15 本文热度 10058
:我的费用报销申请单金额自动计算多了0.0000001,不知道多的 0.0000001 怎么来的,计算总数字没错,我检查了JS也没问题。


 

 


 



js parseInt的陷阱分析小结,当第一个字符为0时,Js会把它看成一个8进制数字,其他8进制之外的字符都回被忽略掉。
var a = parseInt("09"), b = Number("09");

很多人会认为a和b的值都是数字9,但实际上不是。

parseInt的主要作用是把字符串转换为整数,或者把小数转换为整数。一般情况下,我们只用到它的第一个参数。但实际上,它有两个参数:
parseInt(string, radix)

parseInt会根据radix指定的进制进行转换,比如:
alert(parseInt("10", 2)); // outputs '2'

在没有指定radix或者radix为0的情况下,parseInt会按十进制进行转换。然而,这在某些情况下有点特殊:

* 如果string的值以“0x”开头,parseInt会按十六进制进行转换;
* 如果string的值以“0”开头,parseInt会按八进制进行转换。

说回开头的代码,由于"09"是以“0”开头,所以parseInt会按八进制进行转换,但是“9”不是合法的八进制值(八进制只有0-7八个数字),所以转换结果是0。

要避免这个陷进,可以强制指定radix:
alert(parseInt("09", 10)); // outputs '9'

其它网友的补充:
看代码:
alert(parseInt(0.000001));
alert(parseInt(0.0000001));

第一条语句输出 0, 第二条语句输出 1, 囧。

继续看代码:
alert(parseInt('0.000001'));
alert(parseInt('0.0000001'));

都输出 0, 这才符合预期。

查看 ECMA-262 规范,parseInt 会先调用 toString 方法。问题已逐渐清晰:


alert(0.000001);
alert(0.0000001);

第一条语句原样输出,第二条语句输出 1e-7.
继续翻查 ECMA-262 9.8.1 ToString Applied to the Number Type 一节,恍然大悟:
assertEquals("0.00001", (0.00001).toString());
assertEquals("0.000001", (0.000001).toString());
assertEquals("1e-7", (0.0000001).toString());
assertEquals("1.2e-7", (0.00000012).toString());
assertEquals("1.23e-7", (0.000000123).toString());
assertEquals("1e-8", (0.00000001).toString());
assertEquals("1.2e-8", (0.000000012).toString());

上面是 V8 引擎 number-tostring 的单元测试脚本, 很好地诠释了 ECMA 规范。

小结:对于小于 1e-6 的数值来说,ToString 时会自动转换为科学计数法。因此 parseInt 方法,在参数类型不确定时,最好封装一层:

function parseInt2(a) {
if(typeof a === 'number') {
return Math.floor(a);
}
return parseInt(a);
}

Javascript有两种数据类型的转换方法:
  一种是将整个值从一种类型转换为另一种数据类型(称作基本数据类型转换),
  另一种方法是从一个值中提取另一种类型的值,并完成转换工作。
  基本数据类型转换的如以下三种方法:
    1.转换为字符型:String(); 例:String(678)的结果为"678"
    2.转换为数值型:Number(); 例:Number("678")的结果为678
    3.转换为布尔型:Boolean(); 例:Boolean("aaa")的结果为true
  从一个值中提取另一种类型的值的如以下方法:
    1.提取字符串中的整数:parseInt(); 例:parseInt("123zhang")的结果为123
    2.提取字符串中的浮点数:parseFloat(); 例:parseFloat("0.55zhang")的结果为0.55

另外总结各种类型转换的方法
Number转化成字符串:String(number)、
  Number.toString(2/8/16);//分别代表二进制\八进制\十六进制默认(无参)10进制
  Number.toFixed(3) //保留小数点后3位
  Number.toExponextial(3); //小数点前1位、小数点后3位,如var n=123456.789; n.toExponextial(3);//1.234e+5即1.234X105
  Number.toPrecision(4); //返回指定位数 如果位数不够完全显示,则按指数表示法(3个方法都会4舍5入)

该文章在 2015/3/9 16:15:29 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved