整數(shù)和浮點(diǎn)數(shù)
-
規(guī)則
- 在JavaScript語言的底層,根本沒有整數(shù)滩愁,所有數(shù)字都是小數(shù)(64位浮點(diǎn)數(shù))
- JavaScript內(nèi)部,所有數(shù)字都是以64位浮點(diǎn)數(shù)形式儲(chǔ)存,即使整數(shù)也是如此括堤,故1和1.0是完全相同的
1 === 1.0 //true
- 由于浮點(diǎn)數(shù)不是精確的值,所以涉及小數(shù)的比較和運(yùn)算要特別小心
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
-
運(yùn)算
當(dāng)某些運(yùn)算只有整數(shù)才能完成時(shí)绍移,JavaScript會(huì)自動(dòng)把64位浮點(diǎn)數(shù)悄窃,轉(zhuǎn)成32位整數(shù),然后再進(jìn)行運(yùn)算
數(shù)值精度
根據(jù)國(guó)際標(biāo)準(zhǔn)IEEE 754蹂窖,JavaScript浮點(diǎn)數(shù)的64個(gè)二進(jìn)制位轧抗,從最左邊開始,是這樣組成的
第1位:符號(hào)位(決定數(shù)值正負(fù))瞬测,0表示正數(shù)横媚,1表示負(fù)數(shù)
第2位到第12位:儲(chǔ)存指數(shù)部分(決定數(shù)值大小)
第13位到第64位:儲(chǔ)存小數(shù)部分(決定數(shù)值精度月趟,即有效數(shù)字)
IEEE 754規(guī)定灯蝴,有效數(shù)字第一位默認(rèn)總是1,不保存在64位浮點(diǎn)數(shù)之中狮斗。也就是說绽乔,有效數(shù)字總是1.xx...xx的形式,其中xx..xx的部分保存在64位浮點(diǎn)數(shù)之中碳褒,最長(zhǎng)可能為52位折砸。因此,JavaScript提供的有效數(shù)字最長(zhǎng)為53個(gè)二進(jìn)制位
精度最多只能到53個(gè)二進(jìn)制位沙峻,這意味著睦授,絕對(duì)值小于2的53次方的整數(shù),即-(253-1)到253-1摔寨,都可以精確表示
當(dāng)數(shù)值大于2的53次方后去枷,整數(shù)運(yùn)算的結(jié)果開始出現(xiàn)錯(cuò)誤,故大于等于2的53次方的數(shù)值是复,都無法保持精度
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次方以后,整數(shù)運(yùn)算的結(jié)果開始出現(xiàn)錯(cuò)誤
數(shù)值范圍
根據(jù)標(biāo)準(zhǔn)淑廊,64位浮點(diǎn)數(shù)的指數(shù)部分的長(zhǎng)度是11個(gè)二進(jìn)制位逗余,意味著指數(shù)部分的最大值是2047(211-1)。也就是說季惩,64位浮點(diǎn)數(shù)的指數(shù)部分的值最大為2047录粱,分出一半表示負(fù)數(shù)腻格,則JavaScript能夠表示的數(shù)值范圍為21024到2-1023(開區(qū)間),超出這個(gè)范圍的數(shù)無法表示
如果指數(shù)部分等于或超過最大正值1024啥繁,JavaScript會(huì)返回Infinity菜职,這稱為“正向溢出”
JavaScript所能表示的最大正數(shù)和最大負(fù)數(shù)為
Number.MAX_VALUE //1.7976931348623157e+308
-Number.MAX_VALUE //-1.7976931348623157e+308
如果指數(shù)部分等于或超過最小負(fù)值-1023(即非常接近0),JavaScript會(huì)直接把這個(gè)數(shù)轉(zhuǎn)為0旗闽,這稱為“負(fù)向溢出”
JavaScript所能表示的最小正數(shù)和最小負(fù)數(shù)為
Number.MIN_VALUE //5e-324
-Number.MIN_VALUE //-5e-324
表示方法
-
十進(jìn)制
35
-
十六進(jìn)制
0xFF
-
科學(xué)計(jì)數(shù)法
科學(xué)計(jì)數(shù)法允許字母 e 或 E 的后面酬核,跟著一個(gè)整數(shù),表示這個(gè)數(shù)值的指數(shù)部分
123e3 //123000
123e-3 //0.123
-3.1E+12
.1e-23
以下兩種情況JavaScript會(huì)自動(dòng)將數(shù)值轉(zhuǎn)為科學(xué)計(jì)數(shù)法表示宪睹,其他情況都采用字面形式直接表示
- 小數(shù)點(diǎn)前的數(shù)字多于21位
//小數(shù)點(diǎn)前的數(shù)字多于21位愁茁,就自動(dòng)轉(zhuǎn)為科學(xué)計(jì)數(shù)法
1234567890123456789012 //1.2345678901234568e+21
//否則蚕钦,就保持原來的字面形式
123456789012345678901 //123456789012345680000
- 小數(shù)點(diǎn)后的零多于5個(gè)
// 小數(shù)點(diǎn)后緊跟5個(gè)以上的零亭病,就自動(dòng)轉(zhuǎn)為科學(xué)計(jì)數(shù)法
0.0000003 //3e-7
//否則,就保持原來的字面形式
0.000003 //0.000003
特殊值
-
正零和負(fù)零
JavaScript的64位浮點(diǎn)數(shù)之中嘶居,有一個(gè)二進(jìn)制位是符號(hào)位罪帖,這意味著,任何一個(gè)數(shù)都有一個(gè)對(duì)應(yīng)的負(fù)值邮屁,就連0也不例外
在JavaScript內(nèi)部整袁,實(shí)際上存在2個(gè)0:一個(gè)是+0,一個(gè)是-0佑吝,它們是等價(jià)的
+0 === -0 //true
0 === -0 //true
0 === +0 //true
幾乎所有場(chǎng)合坐昙,正零和負(fù)零都會(huì)被當(dāng)作正常的0
+0; 0
-0; 0
(-0).toString() //'0'
(+0).toString() //'0'
唯一有區(qū)別的場(chǎng)合是,+0或-0當(dāng)作分母芋忿,返回的值是不相等的
1 / +0 === 1 / -0 //false
是因?yàn)槌?0得到的結(jié)果是+Infinity炸客,除以-0得到的結(jié)果是-Infinity
-
無窮(Infinity)
-
出現(xiàn)情況
-
1.正值太大或者負(fù)值太小,無法表示
Math.pow(2, Math.pow(2, 100)) //Infinity
2.非0數(shù)除以0
由于數(shù)值正向溢出(overflow)戈钢、負(fù)向溢出(underflow)和被0除痹仙,JavaScript都不報(bào)錯(cuò),而是返回Infinity殉了,所以單純的數(shù)學(xué)運(yùn)算幾乎沒有可能拋出錯(cuò)誤
1 / +0 //+Infinity
1 / -0 //-Infinity
-1 / +0 //-Infinity
-1 / -0 //Infinity
-
大小比較
Infinity大于一切數(shù)值(除了NaN)开仰,-Infinity小于一切數(shù)值(除了NaN)
Infinity > 10000000 //true
-Infinity < 10000000 //true
和NaN比較結(jié)果永遠(yuǎn)為false
Infinity > NaN //false
Infinity < NaN //false
-Infinity < NaN //false
-Infinity < NaN //false
-
運(yùn)算規(guī)則
1.Infinity和0
0 * Infinity //NaN
0 / Infinity //0
Infinity / 0 //Infinity
2.Infinity和null:存在隱式類型數(shù)據(jù)轉(zhuǎn)換,會(huì)將null轉(zhuǎn)化為0薪铜,等同于和0做計(jì)算
null * Infinity //NaN
null / Infinity //0
Infinity / null //Infinity
3.Infinity和undefined:存在隱式類型數(shù)據(jù)轉(zhuǎn)換众弓,會(huì)將undefined轉(zhuǎn)化為NaN,所有結(jié)果均為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()函數(shù)返回一個(gè)布爾值隔箍,檢查某個(gè)值是不是正常數(shù)值谓娃,當(dāng)參數(shù)內(nèi)為Infinity或者NaN時(shí),返回false
注意:原理與isNaN()相同鞍恢,會(huì)先對(duì)括號(hào)內(nèi)的參數(shù)用Number()轉(zhuǎn)換一傻粘,故使用時(shí)一定要注意參數(shù)內(nèi)的數(shù)據(jù)類型
```javascript
isFinite(Infinity) //false
isFinite(NaN) //false
isFinite(true) //true
isFinite(-1) //true
##與數(shù)值相關(guān)的全局方法
####parseInt()
* #####用法
將字符串轉(zhuǎn)換為整數(shù)
> parseInt('字符串',進(jìn)制);
第二個(gè)參數(shù)為2~36之間的數(shù)字每窖,如果不設(shè)置,則默認(rèn)為10弦悉,即默認(rèn)為十進(jìn)制
* #####規(guī)則
* 如果參數(shù)不為字符串窒典,則會(huì)將參數(shù)轉(zhuǎn)換為字符串在進(jìn)行轉(zhuǎn)換
```javascript
parseInt(1.23) //1 等同于parseInt(String(1.23))
parseInt(1.23a) //報(bào)錯(cuò)
- 如果字符串的第一個(gè)字符不能轉(zhuǎn)化為數(shù)字(后面跟著數(shù)字的正負(fù)號(hào)除外),則返回NaN
parseInt('.3') //NaN
parseInt('abc') //NaN
parseInt('') //NaN
parseInt(' ') //NaN
parseInt('+') //NaN
parseInt('+1') //1
- 如果字符串頭部有空格稽莉,空格會(huì)被自動(dòng)去除
parseInt(' 1') //1
- 字符串轉(zhuǎn)為整數(shù)的時(shí)候瀑志,是一個(gè)個(gè)字符依次轉(zhuǎn)換,如果遇到不能轉(zhuǎn)為數(shù)字的字符污秆,就不再進(jìn)行下去劈猪,返回已經(jīng)轉(zhuǎn)好的部分
parseInt('8a') //8
parseInt('12**') //12
parseInt('12.34') //12
parseInt('15e2') //15
parseInt('15px') //15
- 如果字符串開頭為0,則會(huì)將其按照十進(jìn)制解析
parseInt('0100') //100
parseInt('00100') //100
- 如果字符串開頭為0x或者0X良拼,則會(huì)將其按照十六進(jìn)制解析
parseInt('0x10') //16
parseInt('0X100') //256
- 對(duì)于會(huì)自動(dòng)轉(zhuǎn)為科學(xué)計(jì)數(shù)法的數(shù)字战得,parseInt會(huì)將科學(xué)計(jì)數(shù)法的表示方法視為字符串,因此導(dǎo)致一些奇怪的結(jié)果
parseInt('1000000000000000000000.5') //1 等同于parseInt('1e+21')
parseInt(0.0000008) //8 等同于parseInt('8e-7')
-
進(jìn)制轉(zhuǎn)換
- 不設(shè)置第二個(gè)參數(shù)
parseInt('100') //1 等同于parseInt('100',10)
- 設(shè)置第二個(gè)參數(shù)在2~36之間
parseInt('1000',2) //8
parseInt('1000',6) //216
parseInt('1000',8) //512
- 設(shè)置第二個(gè)參數(shù)為0庸推、undefined和null常侦,則直接忽略
parseInt('1000',0) //1000
parseInt('1000',undefined) //1000
parseInt('1000',null) //1000
- 如果第二個(gè)參數(shù)不是數(shù)值,會(huì)被自動(dòng)轉(zhuǎn)為一個(gè)整數(shù)贬媒,這個(gè)整數(shù)只有在2到36之間聋亡,才能得到有意義的結(jié)果,超出這個(gè)范圍际乘,則返回NaN
parseInt('10', 37) //NaN
parseInt('10', 1) //NaN
- 如果字符串包含對(duì)于指定進(jìn)制無意義的字符坡倔,則從最高位開始,只返回可以轉(zhuǎn)換的數(shù)值脖含。如果最高位無法轉(zhuǎn)換罪塔,則直接返回NaN
parseInt('1511', 2) //1 1是有意義的字符,5為無意義字符器赞,停止轉(zhuǎn)換垢袱,返回1
parseInt('511', 2) //NaN
- parseInt的第一個(gè)參數(shù)不是字符串,會(huì)被先轉(zhuǎn)為字符串港柜,這會(huì)導(dǎo)致一些令人意外的結(jié)果请契,對(duì)于八進(jìn)制的前綴0尤其需要注意
parseInt(0x11, 36) //43
//由于第一個(gè)參數(shù)不為字符串,則進(jìn)行一次數(shù)據(jù)轉(zhuǎn)換String(0x11)夏醉,結(jié)果為'17'
//然后再進(jìn)行parseInt('17',36)爽锥,對(duì)17進(jìn)行三十六進(jìn)制轉(zhuǎn)換,結(jié)果即為43
parseInt(011,2) //NaN
//由于第一個(gè)參數(shù)不為字符串畔柔,則進(jìn)行一次數(shù)據(jù)轉(zhuǎn)換String(011)氯夷,結(jié)果為'9'
//然后再進(jìn)行parseInt('9',2),對(duì)9進(jìn)行二進(jìn)制轉(zhuǎn)換
//由于9不是二進(jìn)制的有效數(shù)字靶擦,故結(jié)果為NaN
parseFloat()
- 用法
將字符串轉(zhuǎn)換為浮點(diǎn)數(shù)
parseFloat('字符串')
- 規(guī)則
- 如果參數(shù)不為字符串腮考,則會(huì)將參數(shù)轉(zhuǎn)換為字符串在進(jìn)行轉(zhuǎn)換
parseFloat(1.23) //1 等同于parseInt(String(1.23))
parseFloat(1.23a) //報(bào)錯(cuò)
- 如果字符串的第一個(gè)字符不能轉(zhuǎn)化為數(shù)字(后面跟著數(shù)字的正負(fù)號(hào)雇毫、小數(shù)點(diǎn)除外),則返回NaN
parseInt('.3') //0.3
parseInt('abc') //NaN
parseInt('') //NaN
parseInt(' ') //NaN
parseInt('+') //NaN
parseInt('+1.2') //1.2
- 如果字符串頭部有空格踩蔚,空格會(huì)被自動(dòng)去除
parseInt(' .1') //0.1
- 字符串轉(zhuǎn)為浮點(diǎn)數(shù)的時(shí)候棚放,是一個(gè)個(gè)字符依次轉(zhuǎn)換,如果遇到不能轉(zhuǎn)為數(shù)字的字符馅闽,就不再進(jìn)行下去飘蚯,返回已經(jīng)轉(zhuǎn)好的部分
parseInt('8.5a') //8
parseInt('12.**34') //12
parseInt('12.34') //12.34
parseInt('15.2e2') //15.2
parseInt('15.2px') //15.2
- 如果字符串符合科學(xué)計(jì)數(shù)法,則會(huì)進(jìn)行相應(yīng)的轉(zhuǎn)換
parseFloat('314e-2') //3.14
parseFloat('0.0314E+2') //3.14