数据类型-数字 Number-数字

整数和浮点数

  • 规则

    • 在JavaScript语言的底层,根本没有整数,所有数字都是小数(64位浮点数)
    • JavaScript内部,所有数字都是以64位浮点数形式储存,即使整数也是如此,故1和1.0是完全相同的
1 === 1.0    //true
  • 由于浮点数不是精确的值,所以涉及小数的比较和运算要特别小心
0.3 / 0.1     //2.9999999999999996
0.1 + 0.2 == 0.3               //false
0.1 + 0.2 === 0.3              //false
(0.3 - 0.2) == (0.2 - 0.1)     //false
(0.3 - 0.2) === (0.2 - 0.1)    //false
  • 运算

当某些运算只有整数才能完成时,JavaScript会自动把64位浮点数,转成32位整数,然后再进行运算

数值精度

根据国际标准IEEE 754,JavaScript浮点数的64个二进制位,从最左边开始,是这样组成的

第1位:符号位(决定数值正负),0表示正数,1表示负数
第2位到第12位:储存指数部分(决定数值大小)
第13位到第64位:储存小数部分(决定数值精度,即有效数字)

IEEE 754规定,有效数字第一位默认总是1,不保存在64位浮点数之中。也就是说,有效数字总是1.xx...xx的形式,其中xx..xx的部分保存在64位浮点数之中,最长可能为52位。因此,JavaScript提供的有效数字最长为53个二进制位

精度最多只能到53个二进制位,这意味着,绝对值小于2的53次方的整数,即-(253-1)到253-1,都可以精确表示
当数值大于2的53次方后,整数运算的结果开始出现错误,故大于等于2的53次方的数值,都无法保持精度

Math.pow(2, 53)        //9007199254740992
Math.pow(2, 53) + 1    //9007199254740992
Math.pow(2, 53) + 2    //9007199254740994
Math.pow(2, 53) + 3    //9007199254740996
Math.pow(2, 53) + 4    //9007199254740996
//从上面示例可以看到,大于2的53次方以后,整数运算的结果开始出现错误

数值范围

根据标准,64位浮点数的指数部分的长度是11个二进制位,意味着指数部分的最大值是2047(211-1)。也就是说,64位浮点数的指数部分的值最大为2047,分出一半表示负数,则JavaScript能够表示的数值范围为210242-1023(开区间),超出这个范围的数无法表示

如果指数部分等于或超过最大正值1024,JavaScript会返回Infinity,这称为“正向溢出”
JavaScript所能表示的最大正数和最大负数为

Number.MAX_VALUE    //1.7976931348623157e+308
-Number.MAX_VALUE   //-1.7976931348623157e+308

如果指数部分等于或超过最小负值-1023(即非常接近0),JavaScript会直接把这个数转为0,这称为“负向溢出”
JavaScript所能表示的最小正数和最小负数为

Number.MIN_VALUE    //5e-324
-Number.MIN_VALUE   //-5e-324

表示方法

  • 十进制

35
  • 十六进制

0xFF
  • 科学计数法

科学计数法允许字母 e 或 E 的后面,跟着一个整数,表示这个数值的指数部分

123e3     //123000
123e-3    //0.123
-3.1E+12
.1e-23

以下两种情况JavaScript会自动将数值转为科学计数法表示,其他情况都采用字面形式直接表示

  • 小数点前的数字多于21位
//小数点前的数字多于21位,就自动转为科学计数法
1234567890123456789012    //1.2345678901234568e+21
//否则,就保持原来的字面形式
123456789012345678901     //123456789012345680000
  • 小数点后的零多于5个
// 小数点后紧跟5个以上的零,就自动转为科学计数法
0.0000003    //3e-7
//否则,就保持原来的字面形式
0.000003     //0.000003

特殊值

  • 正零和负零

JavaScript的64位浮点数之中,有一个二进制位是符号位,这意味着,任何一个数都有一个对应的负值,就连0也不例外
在JavaScript内部,实际上存在2个0:一个是+0,一个是-0,它们是等价的

+0 === -0   //true
0 === -0    //true
0 === +0    //true

几乎所有场合,正零和负零都会被当作正常的0

+0;    0
-0;    0
(-0).toString()    //'0'
(+0).toString()    //'0'

唯一有区别的场合是,+0或-0当作分母,返回的值是不相等的

1 / +0 === 1 / -0    //false
是因为除以+0得到的结果是+Infinity,除以-0得到的结果是-Infinity
  • 无穷(Infinity)

    • 出现情况

1.正值太大或者负值太小,无法表示

Math.pow(2, Math.pow(2, 100))    //Infinity

2.非0数除以0
由于数值正向溢出(overflow)、负向溢出(underflow)和被0除,JavaScript都不报错,而是返回Infinity,所以单纯的数学运算几乎没有可能抛出错误

1 / +0    //+Infinity
1 / -0    //-Infinity
-1 / +0    //-Infinity
-1 / -0    //Infinity
  • 大小比较

Infinity大于一切数值(除了NaN),-Infinity小于一切数值(除了NaN)

Infinity > 10000000    //true
-Infinity < 10000000   //true

和NaN比较结果永远为false

Infinity > NaN   //false
Infinity < NaN   //false
-Infinity < NaN  //false
-Infinity < NaN  //false
  • 运算规则

1.Infinity和0

0 * Infinity    //NaN
0 / Infinity    //0
Infinity / 0    //Infinity

2.Infinity和null:存在隐式类型数据转换,会将null转化为0,等同于和0做计算

null * Infinity    //NaN
null / Infinity    //0
Infinity / null    //Infinity

3.Infinity和undefined:存在隐式类型数据转换,会将undefined转化为NaN,所有结果均为NaN

undefined + Infinity    //NaN
undefined - Infinity    //NaN
undefined * Infinity    //NaN
undefined / Infinity    //NaN
Infinity / undefined    //NaN

4.Infinity与Infinity
Infinity与Infinity加或者乘得到的还是Infinity

Infinity + Infinity     //Infinity
Infinity * Infinity     //Infinity
-Infinity * Infinity    //-Infinity
-Infinity * -Infinity   //Infinity

Infinity与Infinity减或者除得到的是NaN

Infinity - Infinity    //NaN
Infinity / Infinity    //NaN
  • 判断 isFinite()

isFinite()函数返回一个布尔值,检查某个值是不是正常数值,当参数内为Infinity或者NaN时,返回false

注意:原理与isNaN()相同,会先对括号内的参数用Number()转换一,故使用时一定要注意参数内的数据类型

```javascript

isFinite(Infinity) //false
isFinite(NaN) //false
isFinite(true) //true
isFinite(-1) //true


##与数值相关的全局方法
####parseInt()
*  #####用法
将字符串转换为整数
> parseInt('字符串',进制);
第二个参数为2~36之间的数字,如果不设置,则默认为10,即默认为十进制

* #####规则
  * 如果参数不为字符串,则会将参数转换为字符串在进行转换
```javascript
parseInt(1.23)    //1  等同于parseInt(String(1.23))
parseInt(1.23a)   //报错
  • 如果字符串的第一个字符不能转化为数字(后面跟着数字的正负号除外),则返回NaN
parseInt('.3')    //NaN
parseInt('abc')   //NaN
parseInt('')      //NaN
parseInt(' ')     //NaN
parseInt('+')     //NaN
parseInt('+1')    //1
  • 如果字符串头部有空格,空格会被自动去除
parseInt('    1')    //1
  • 字符串转为整数的时候,是一个个字符依次转换,如果遇到不能转为数字的字符,就不再进行下去,返回已经转好的部分
parseInt('8a')     //8
parseInt('12**')   //12
parseInt('12.34')  //12
parseInt('15e2')   //15
parseInt('15px')   //15
  • 如果字符串开头为0,则会将其按照十进制解析
parseInt('0100')      //100
parseInt('00100')     //100
  • 如果字符串开头为0x或者0X,则会将其按照十六进制解析
parseInt('0x10')     //16
parseInt('0X100')    //256
  • 对于会自动转为科学计数法的数字,parseInt会将科学计数法的表示方法视为字符串,因此导致一些奇怪的结果
parseInt('1000000000000000000000.5')    //1    等同于parseInt('1e+21') 
parseInt(0.0000008)    //8    等同于parseInt('8e-7')
  • 进制转换
    • 不设置第二个参数
parseInt('100')    //1    等同于parseInt('100',10)
  • 设置第二个参数在2~36之间
parseInt('1000',2)    //8
parseInt('1000',6)    //216
parseInt('1000',8)    //512
  • 设置第二个参数为0、undefined和null,则直接忽略
parseInt('1000',0)            //1000
parseInt('1000',undefined)    //1000
parseInt('1000',null)         //1000
  • 如果第二个参数不是数值,会被自动转为一个整数,这个整数只有在2到36之间,才能得到有意义的结果,超出这个范围,则返回NaN
parseInt('10', 37)    //NaN
parseInt('10', 1)     //NaN
  • 如果字符串包含对于指定进制无意义的字符,则从最高位开始,只返回可以转换的数值。如果最高位无法转换,则直接返回NaN
parseInt('1511', 2)    //1    1是有意义的字符,5为无意义字符,停止转换,返回1
parseInt('511', 2)     //NaN
  • parseInt的第一个参数不是字符串,会被先转为字符串,这会导致一些令人意外的结果,对于八进制的前缀0尤其需要注意
parseInt(0x11, 36)    //43
//由于第一个参数不为字符串,则进行一次数据转换String(0x11),结果为'17'
//然后再进行parseInt('17',36),对17进行三十六进制转换,结果即为43
parseInt(011,2)    //NaN
//由于第一个参数不为字符串,则进行一次数据转换String(011),结果为'9'
//然后再进行parseInt('9',2),对9进行二进制转换
//由于9不是二进制的有效数字,故结果为NaN

parseFloat()

  • 用法
    将字符串转换为浮点数

parseFloat('字符串')

  • 规则
    • 如果参数不为字符串,则会将参数转换为字符串在进行转换
parseFloat(1.23)    //1  等同于parseInt(String(1.23))
parseFloat(1.23a)   //报错
  • 如果字符串的第一个字符不能转化为数字(后面跟着数字的正负号、小数点除外),则返回NaN
parseInt('.3')    //0.3
parseInt('abc')   //NaN
parseInt('')      //NaN
parseInt(' ')     //NaN
parseInt('+')     //NaN
parseInt('+1.2')  //1.2
  • 如果字符串头部有空格,空格会被自动去除
parseInt('     .1')    //0.1
  • 字符串转为浮点数的时候,是一个个字符依次转换,如果遇到不能转为数字的字符,就不再进行下去,返回已经转好的部分
parseInt('8.5a')     //8
parseInt('12.**34')  //12
parseInt('12.34')    //12.34
parseInt('15.2e2')   //15.2
parseInt('15.2px')   //15.2
  • 如果字符串符合科学计数法,则会进行相应的转换
parseFloat('314e-2')       //3.14
parseFloat('0.0314E+2')    //3.14

参考链接:http://javascript.ruanyifeng.com/grammar/number.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,273评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,349评论 3 398
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,709评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,520评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,515评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,158评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,755评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,660评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,203评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,287评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,427评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,122评论 5 349
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,801评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,272评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,393评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,808评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,440评论 2 359

推荐阅读更多精彩内容