Js 中 parseInt(0.0000008) 等于 8 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
oska117
V2EX    程序员

Js 中 parseInt(0.0000008) 等于 8

  •  
  •   oska117 2018-03-28 22:18:34 +08:00 4577 次点击
    这是一个创建于 2821 天前的主题,其中的信息可能已经有所发展或是发生改变。

    今天遇到个问题,发现 js 中一些注意的地方

    parseInt(0.000008) 结果为 0

    parseInt(0.0000008) 结果为 8

    parseInt("0.0000008") 结果为 0

    第二个感觉好奇怪,就在网上搜, 结果在阮一峰的《 js 标准参考手册》发现

    “对于那些会自动转为科学计数法的数字,parseInt 会将科学计数法的表示方法视为字符串,因此导致一些奇怪的结果。”

    也就是说,0.0000008 会先自动转换为 科学计数法 8e-7, 然后自动转为字符串 “ 8e-7 ”,结果就是 8 了

    12 条回复    2018-03-30 18:20:55 +08:00
    songz
        1
    songz  
       2018-03-28 22:44:21 +08:00
    先套个 floor 就没有意外了
    rock_cloud
        2
    rock_cloud  
       2018-03-28 22:50:54 +08:00
    怎么感觉像是 bug。。。
    huweitxdy
        3
    huweitxdy  
       2018-03-28 23:03:26 +08:00
    ecma 规范里似乎就是这么写的。。。
    owwlo
        4
    owwlo  
       2018-03-28 23:09:24 +08:00
    踩坑留念
    mchl
        5
    mchl  
       2018-03-28 23:13:39 +08:00 via iPhone
    第一反应是试一下 parseInt(Number(0.0000008) )
    oska117
        6
    oska117  
    OP
       2018-03-28 23:25:12 +08:00 via Android
    还有 NaN !==NaN , 也就是 NaN 不等于它自身
    zybzzc
        7
    zybzzc  
       2018-03-28 23:47:32 +08:00 via Android
    yyfearth
        8
    yyfearth  
       2018-03-29 09:01:07 +08:00   1
    @mchl @songz 没区别的 因为 Number(0.0000008) === 0.0000008
    parseInt(string) 所以都会被转换成 string
    而 String(0.0000008) === '8e-7'
    parseInt 不支持科学计数
    所以 parseInt(0.0000008) === parseInt('8e-7') === 8

    而 parseFloat 支持科学计数 所以没问题
    parseFloat(0.0000008) === parseFloat('8e-7') === 8e-7 === 0.0000008
    songz
        9
    songz  
       2018-03-29 09:03:17 +08:00   1
    parseInt(8e-6)
    0
    parseInt(8e-7)
    8

    为什么-6 就是 0 呢?
    whosesmile
        10
    whosesmile  
       2018-03-29 10:01:24 +08:00   2
    @songz 查了下文档,yyfearth 漏说了一句:
    parseInt 和 parseFloat 接受的参数是 string,如果参数不是 string,那么会先转换为 string.
    这和我们(包括我...)想象的不一样,以为接受的参数可以是数字

    所以对 8e-6 的转换的流程是: parseInt(8e-6) === parseInt(String(8e-6)) === parseInt("0.000008") === 0
    所以对 8e-7 的转换的流程是: parseInt(8e-7) === parseInt(String(8e-7)) === parseInt("8e-7") === 8

    你要是问为什么 String(8e-6)和 String(8e-7)的结果不一样(因为我也奇怪),然后定位到 ECMA 的文档规范,没看懂,但是这就是规范规定的:根据数字范围的不同,转换成字符串的结果是不一样的。就这么任性。。。

    我猜想这么设计的原因是 js 中所有的数字只有一种类型:Number,实际内存的表达式通过 float 方式存储的,这样如果数字的长度过大,转换为字符串就会非常长,所以才这么设计出了转换规则。
    codehz
        11
    codehz  
       2018-03-29 11:57:00 +08:00
    @oska117 #6 NaN 这个是设计(而且符合浮点数的标准
    还有正 0 和负 0 呢!
    Object.is(0, -0) //false
    另外 NaN 也可以用 Object.is 来比较(
    Justin13
        12
    Justin13  
       2018-03-30 18:20:55 +08:00 via Android
    差的那一位就是小数和科学计数法的边界。7 位及以上用科学计数法,6 位及以下依旧是小数,所以结果不同。。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2913 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 13:41 PVG 21:41 LAX 05:41 JFK 08:41
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86