javascript下数值型比较难点说明


Posted in Javascript onJune 07, 2010

1、数字长长的,在c#里合法的长整型数字在javascript下竟然......
看下面几行简单代码:

var a = 2010060612120909191; //按时间生成的Id1 
var b = 2010060612120909199; //按时间生成的Id2 
alert(a == b); 
//alert(a); //有什么惊人发现吗? 
//alert(b); //最后几位好像... 
//alert(Number(a) == Number(b)); 
//alert(parseInt(a, 10) == parseInt(b, 10)); 
//alert(parseFloat(a) == parseFloat(b));

您可以拷贝代码自己在本地测试一下。实际运行的结果是,a和b竟然相等,弹出的是“true”。反正楼猪第一次碰到这种情况的时候感到一丝意外。然后楼猪分别让两个数字弹出,这次又意外发现数字改变成了“2010060612120909300”。最后又测试了一下和数字相关的Number,parseInt和parseFloat函数,三个结果依旧是true。
然后楼猪把数字型调整成字符串类型,如下:
代码
var a = "2010060612120909191"; //按时间生成的Id1 
var b = "2010060612120909199"; //按时间生成的Id2 
alert(a == b);//false 
alert(a); //2010060612120909191 
alert(b); //2010060612120909199 
alert(Number(a) == Number(b)); //? 
alert(parseInt(a, 10) == parseInt(b, 10));//? 
alert(parseFloat(a) == parseFloat(b));//?

这次预料中的前三个都没有问题,可是转换成数值型的比较依旧返回true。
是不是这里测试的两个数字都不在javascript的数字限定范围内呢?可是为什么弹出的数字改变成了“2010060612120909300”(百位数字太诡异了)?
自己google无果后,采用了下面的函数比较两个长整型的数字大小:
// 数字比较大小 (两个输入为字符串或数字类型,长数型数字比较) 
function compareNumber(prevNum, nextNum) { 
if (isNaN(prevNum) || prevNum.length == 0) { 
throw new Error("第一个输入非数字"); 
} 
else if (isNaN(prevNum) || prevNum.length == 0) { 
throw new Error("第二个输入非数字"); 
} 
var result = 0; //返回结果 0:两个相等 1:第一个数字大于第二个 -1:第二个数字大于第一个 
if (prevNum.length > nextNum.length) { 
result++; 
} 
else if (prevNum.length < nextNum.length) { 
result--; 
} 
else { 
//位数一样 
for (var i = 0; i < prevNum.length; i++) { 
var charNum1 = prevNum.toString().charAt(i); 
var charNum2 = nextNum.toString().charAt(i); 
if (parseInt(charNum1) > parseInt(charNum2)) { 
result++; 
break; 
} 
else if (parseInt(charNum2) > parseInt(charNum1)) { 
result--; 
break; 
} 
} 
} 
return result; 
}

2、带个小数点的,parseInt的取舍
这个问题有的javascript书上已经讲过。看下面的代码:
var a = 0.000001; 
var b = 0.0000001; 
alert(parseInt(a)); 
alert(parseInt(b)); 
//alert(parseInt(b, 10));//难道是没填写10进制的原因

您可能已经知道了。parseInt(b)返回的竟然是1!然后,将a和b换成字符串测试一下:
var a = "0.000001"; 
var b = "0.0000001"; 
alert(parseInt(a)); 
alert(parseInt(b));

这一次,a和b返回的都是0。这个才是我们想要的预期的结果。然后楼猪大胆猜测,据说javascript处理数字碰到以0开头的有的时候是当做八进制处理的。这一想,kao,有道理。可是这里我们测试的两个浮点数字a和b都是以0开头啊?好吧,楼猪是真的想不到其他原因了,只好对产生奇怪结果的数字b,又改成parseInt(b, 10)测试一下,晕,还是1。然后,楼猪又Number和parseFloat测试了一下:
var a = 0.000001; 
var b = 0.0000001; 
alert(Number(a)); 
alert(Number(b));//1e-7 
alert(parseFloat(a)); 
alert(parseFloat(b)); //1e-7

哈哈,这次楼猪似乎接近发现真相了。b在Number和parseFloat之后,都弹出1e-7,科学计数法嘛。看来还真的是八进制的问题。然后nc楼猪想当然地以为只要先将要parseInt的数字先toString或者String一下问题就可以解决了:
var b = 0.0000001; 
alert(parseInt(b.toString(), 10)); 
alert(parseInt(String(b), 10));

晕啊,这次怎么还是1呢?改成下面的还是一样的:
var b = String(0.0000001); 
alert(parseInt(b));

那么,对于这种八进制parseInt返回科学计数法的数字,我们怎么取整呢?按照开发需要,Math里有函数可以帮我们轻松实现功能的:
var b = 0.0000001; 
alert(Math.floor(b));

至于javascript常用的Math函数的floor和ceil方法的区别,您可以参考相关文档,这里不赘述。最后,期待您的宝贵意见和建议。
Javascript 相关文章推荐
javascript管中窥豹 形参与实参浅析
Dec 17 Javascript
jQuery提交多个表单的小例子
Jun 30 Javascript
jquery中event对象属性与方法小结
Dec 18 Javascript
Javascript添加监听与删除监听用法详解
Dec 19 Javascript
JavaScript不使用prototype和new实现继承机制
Dec 29 Javascript
简介JavaScript中的setTime()方法的使用
Jun 11 Javascript
JQuery zClip插件实现复制页面内容到剪贴板
Nov 02 Javascript
jQuery随手笔记之常用的jQuery操作DOM事件
Nov 29 Javascript
Javascript字符串常用方法详解
Jul 21 Javascript
Angular2中Bootstrap界面库ng-bootstrap详解
Oct 18 Javascript
JS及JQuery对Html内容编码,Html转义
Feb 17 Javascript
vue.js select下拉框绑定和取值方法
Mar 03 Javascript
jQuery源码分析之Event事件分析
Jun 07 #Javascript
jQueryUI的Dialog的简单封装
Jun 07 #Javascript
jquery 的 $(&quot;#id&quot;).html() 无内容的解决方法
Jun 07 #Javascript
基于jquery+thickbox仿校内登录注册框
Jun 07 #Javascript
jquery 注意事项与常用语法小结
Jun 07 #Javascript
php上传图片并给图片打上透明水印的代码
Jun 07 #Javascript
指定位置如果有图片显示图片,无图片显示广告的JS
Jun 05 #Javascript
You might like
解析php取整的几种方式
2013/06/25 PHP
php实现mysql数据库操作类分享
2014/02/14 PHP
Symfony2开发之控制器用法实例分析
2016/02/05 PHP
PDO::errorCode讲解
2019/01/28 PHP
JavaScript 开发中规范性的一点感想
2009/06/23 Javascript
JavaScript获取onclick、onchange等事件值的代码
2013/07/22 Javascript
原生javascript实现获取指定元素下所有后代元素的方法
2014/10/28 Javascript
基于jQuery+PHP+Mysql实现在线拍照和在线浏览照片
2015/09/06 Javascript
js点击文本框后才加载验证码实例代码
2015/10/20 Javascript
深入理解Java线程编程中的阻塞队列容器
2015/12/07 Javascript
jQuery动态添加及删除表单上传元素的方法(附demo源码下载)
2016/01/15 Javascript
基于node.js依赖express解析post请求四种数据格式
2017/02/13 Javascript
javascript回调函数详解
2018/02/06 Javascript
解决vue项目使用font-awesome,build后路径的问题
2018/09/01 Javascript
bootstrap table列和表头对不齐的解决方法
2019/07/19 Javascript
Vue登录主页动态背景短视频制作
2019/09/21 Javascript
[07:31]DOTA2卡尔工作室 英雄介绍主宰篇
2013/06/25 DOTA
[01:50]WODOTA制作 DOTA2中文宣传片《HERO》
2013/04/28 DOTA
解析Python中的异常处理
2015/04/28 Python
python检测是文件还是目录的方法
2015/07/03 Python
python递归删除指定目录及其所有内容的方法
2017/01/13 Python
Python实现购物系统(示例讲解)
2017/09/13 Python
python 字典修改键(key)的几种方法
2018/08/10 Python
基于Tensorflow:CPU性能分析
2020/02/10 Python
Python Selenium安装及环境配置的实现
2020/03/17 Python
Python使用monkey.patch_all()解决协程阻塞问题
2020/04/15 Python
python如何实现读取并显示图片(不需要图形界面)
2020/07/08 Python
美国婚礼装饰和活动用品批发供应商:Event Decor Direct
2018/10/12 全球购物
精致的手工皮鞋:Shoe Embassy
2019/11/08 全球购物
西安众合通用.net笔试题
2013/03/18 面试题
什么是网络协议
2016/04/07 面试题
关爱留守儿童标语
2014/06/18 职场文书
印刷技术专业自荐信
2014/09/18 职场文书
检察院院长群众路线教育实践活动个人整改措施
2014/10/04 职场文书
position:sticky 粘性定位的几种巧妙应用详解
2021/04/24 HTML / CSS
Python 键盘事件详解
2021/11/11 Python