好吧,本來想理解理解js數(shù)字存儲(chǔ)原理的渡嚣〗嗾蹋看來我還是嫩,只有先記下一些重要的先了缕棵。
參考鏈接:http://javascript.ruanyifeng.com/grammar/number.html#toc3孵班。
里面講的很詳細(xì),這里只做摘要招驴。
1. 概述#
1.1整數(shù)和浮點(diǎn)數(shù)
JavaScript內(nèi)部篙程,所有數(shù)字都是以64位浮點(diǎn)數(shù)形式儲(chǔ)存,即使整數(shù)也是如此别厘。所以虱饿,1與1.0是相同的,是同一個(gè)數(shù)触趴。由于浮點(diǎn)數(shù)不是精確的值氮发,所以涉及小數(shù)的比較和運(yùn)算要特別小心。
1 === 1.0 // true
0.1 + 0.2 === 0.3// false
0.3 / 0.1// 2.9999999999999996
(0.3 - 0.2) === (0.2 - 0.1)// false
//真正開發(fā)中的解決方法冗懦,后續(xù)尋找
1.2 數(shù)值范圍##
Number.MAX_VALUE // 1.7976931348623157e+308
Number.MIN_VALUE // 5e-324
1.3 數(shù)值的進(jìn)制##
- 十進(jìn)制:沒有前導(dǎo)0的數(shù)值爽冕。
- 八進(jìn)制:有前綴0o或0O的數(shù)值,或者有前導(dǎo)0批狐、且只用到0-7的七個(gè)阿拉伯?dāng)?shù)字的數(shù)值扇售。
- 十六進(jìn)制:有前綴0x或0X的數(shù)值。
- 二進(jìn)制:有前綴0b或0B的數(shù)值嚣艇。
默認(rèn)情況下承冰,JavaScript內(nèi)部會(huì)自動(dòng)將八進(jìn)制、十六進(jìn)制食零、二進(jìn)制轉(zhuǎn)為十進(jìn)制困乒。下面是一些例子。
0xff // 255
0o377 // 255
0b11 // 3
如果八進(jìn)制贰谣、十六進(jìn)制娜搂、二進(jìn)制的數(shù)值里面,出現(xiàn)不屬于該進(jìn)制的數(shù)字吱抚,就會(huì)報(bào)錯(cuò)百宇。
0xzz // 報(bào)錯(cuò),十六進(jìn)制最大值為F
0o88 // 報(bào)錯(cuò)秘豹,八進(jìn)制最大值為7
0b22 // 報(bào)錯(cuò)携御,二進(jìn)制最大值為1
2 特殊值##
2.1 正零和負(fù)零##
-0 === +0 // true
0 === -0 // true
0 === +0 // true
幾乎所有場合,正零和負(fù)零都會(huì)被當(dāng)作正常的0。
+0 // 0
-0 // 0
(-0).toString() // '0'
(+0).toString() // '0'
唯一有區(qū)別的場合是啄刹,+0或-0當(dāng)作分母涮坐,返回的值是不相等的。
(1 / +0) === (1 / -0) // false
//上面代碼之所以出現(xiàn)這樣結(jié)果誓军,是因?yàn)槌哉愕玫?Infinity袱讹,除以負(fù)零得到-Infinity
2.2 NaN##
NaN是JavaScript的 特殊值,表示“非數(shù)字”(Not a Number)昵时,主要出現(xiàn)在將字符串解析成數(shù)字出錯(cuò)的場合
如
5 - "x"; // 返回NaN
//一些數(shù)學(xué)運(yùn)算
Math.acos(2) // NaN
Math.log(-1) // NaN
Math.sqrt(-1) // NaN
0 / 0 // NaN
(1) NaN不等于任何值捷雕,包括它本身!!!
NaN === NaN // false
(2)由于數(shù)組的indexOf方法,內(nèi)部使用的是嚴(yán)格相等運(yùn)算符债查,所以該方法對(duì)NaN不成立
[NaN].indexOf(NaN) // -1
(3)NaN在布爾運(yùn)算時(shí)被當(dāng)作false非区。
Boolean(NaN) // false
(4)NaN與任何數(shù)(包括它自己)的運(yùn)算瓜挽,得到的都是NaN
NaN + 32 // NaN
NaN - 32 // NaN
NaN * 32 // NaN
NaN / 32 // NaN
isNaN方法可以用來判斷一個(gè)值是否為NaN盹廷。但是,isNaN只對(duì)數(shù)值有效久橙,如果傳入其他值俄占,會(huì)被先轉(zhuǎn)成數(shù)值。
isNaN('Hello') // true
// 相當(dāng)于
isNaN(Number('Hello')) // true
isNaN({}) // true
//相當(dāng)于
isNaN(Number({})) // true
isNaN(['xzy']) // true
// 等同于
isNaN(Number(['xzy'])) // true
但是淆衷,對(duì)于空數(shù)組和只有一個(gè)數(shù)值成員的數(shù)組缸榄,isNaN返回false。
isNaN([]) // false
isNaN([123]) // false
isNaN(['123']) // false
(5)NaN判斷方法
//NaN本身就是數(shù)字
function myIsNaN(value) {
return typeof value === 'number' && isNaN(value);
}
//NaN不等于NaN
function myIsNaN(value) {
return value !== value;
}
2.3 Infinity##
(1)定義
Infinity表示“無窮”祝拯,用來表示兩種場景甚带。一種是一個(gè)正的數(shù)值太大,或一個(gè)負(fù)的數(shù)值太小佳头,無法表示鹰贵;另一種是非0數(shù)值除以0,得到Infinity康嘉。
// 場景一
Math.pow(2, Math.pow(2, 100))// Infinity
// 場景二
0 / 0 // NaN
1 / 0 // Infinity
Infinity有正負(fù)之分碉输,Infinity表示正的無窮,-Infinity表示負(fù)的無窮亭珍。
Infinity === -Infinity // false
1 / -0 // -Infinity
-1 / -0 // Infinity
Infinity大于一切數(shù)值(除了NaN)敷钾,-Infinity小于一切數(shù)值(除了NaN)。
Infinity > 1000 // true
-Infinity < -1000 // true
Infinity > Number.MAX_VALUE //true
-Infinity < Number.MIN_VALUE //true
Infinity與NaN比較肄梨,總是返回false阻荒。
Infinity > NaN // false
-Infinity > NaN // false
Infinity < NaN // false
-Infinity < NaN // false
(2)運(yùn)算規(guī)則
Infinity的四則運(yùn)算,符合無窮的數(shù)學(xué)計(jì)算規(guī)則众羡。
5 * Infinity // Infinity
5 - Infinity // -Infinity
//相當(dāng)于
5 + (-infinity) // -Infinity
Infinity / 5 // Infinity
5 / Infinity // 0
5%infinity //5
0乘以Infinity侨赡,返回NaN;
0除以Infinity,返回0辆毡;
Infinity除以0菜秦,返回Infinity。
0 * Infinity // NaN
0 / Infinity // 0
Infinity / 0 // Infinity
Infinity與null計(jì)算時(shí)舶掖,null會(huì)轉(zhuǎn)成0球昨,等同于與0的計(jì)算。
null * Infinity // NaN
null / Infinity // 0
Infinity / null // Infinity
Infinity與undefined計(jì)算眨攘,返回的都是NaN主慰。
undefined + Infinity // NaN
undefined - Infinity // NaN
undefined * Infinity // NaN
undefined / Infinity // NaNInfinity / undefined // NaN
Infinity加上或乘以Infinity,返回的還是Infinity鲫售。
Infinity + Infinity // Infinity
Infinity * Infinity // Infinity
Infinity減去或除以Infinity共螺,得到NaN。
Infinity - Infinity // NaN
Infinity / Infinity // NaN
(3)isFinite函數(shù)
isFinite函數(shù)返回一個(gè)布爾值情竹,檢查某個(gè)值是不是正常數(shù)值藐不,而不是Infinity。
isFinite(Infinity) // false
isFinite(-1) // true
isFinite(true) // true
isFinite(NaN) // false
3. 與數(shù)值相關(guān)的全局方法#
3.1 parseInt##
3.1.1 規(guī)則
parseInt方法用于將字符串轉(zhuǎn)為整數(shù)秦效。
規(guī)則:
- 如果傳入的不是字符串雏蛮,則先轉(zhuǎn)字符串在轉(zhuǎn)整數(shù)
- 如果字符串的第一個(gè)字符不能轉(zhuǎn)化為數(shù)字(后面跟著數(shù)字的正負(fù)號(hào)除外),返回NaN
- parseInt的返回值只有兩種可能阱州,不是一個(gè)十進(jìn)制整數(shù)挑秉,就是NaN
。
parseInt(' 81') // 81
parseInt(1.23) // 1
// 等同于
parseInt('1.23') // 1
parseInt('8a') // 8
parseInt('12**') // 12
parseInt('12.34') // 12
parseInt('15e2') // 15
parseInt('15px') // 15
parseInt('abc') // NaN
parseInt('.3') // NaN
parseInt('') // NaN
parseInt('+') // NaN
parseInt('+1') // 1
//如果字符串以0x或0X開頭苔货,parseInt會(huì)將其按照十六進(jìn)制數(shù)解析犀概。parseInt('0x10') // 16
對(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') // 1
parseInt(0.0000008) // 8
// 等同于
parseInt('8e-7') // 8
3.1.2 進(jìn)制轉(zhuǎn)換
(1)parseInt方法還可以接受第二個(gè)參數(shù)(2到36之間)姻灶,表示被解析的值的進(jìn)制,返回該值對(duì)應(yīng)的十進(jìn)制數(shù)
//默認(rèn)轉(zhuǎn)換為10進(jìn)制
parseInt('1000') // 1000
// 等同于
parseInt('1000', 10) // 1000
parseInt('1000', 2) // 8
parseInt('1000', 6) // 216
parseInt('1000', 8) // 512
(2)如果第二個(gè)參數(shù)不是數(shù)值滥嘴,會(huì)被自動(dòng)轉(zhuǎn)為一個(gè)整數(shù)木蹬。這個(gè)整數(shù)只有在2到36之間,才能得到有意義的結(jié)果若皱,超出這個(gè)范圍镊叁,則返回NaN。如果第二個(gè)參數(shù)是0走触、undefined和null晦譬,則直接忽略。
parseInt('10', 37) // NaN
parseInt('10', 1) // NaN
parseInt('10', 0) // 10
parseInt('10', null) // 10
parseInt('10', undefined) // 10
(3)如果字符串包含對(duì)于指定進(jìn)制無意義的字符互广,則從最高位開始敛腌,只返回可以轉(zhuǎn)換的數(shù)值卧土。如果最高位無法轉(zhuǎn)換,則直接返回NaN像樊。
parseInt('1546', 2) // 1
parseInt('546', 2) // NaN
//對(duì)于二進(jìn)制來說尤莺,1是有意義的字符,5生棍、4颤霎、6都是無意義的字符,所以第一行返回1涂滴,第二行返回NaN
(4)如果parseInt的第一個(gè)參數(shù)不是字符串友酱,會(huì)被先轉(zhuǎn)為字符串。這會(huì)導(dǎo)致一些令人意外的結(jié)果柔纵。
parseInt(011, 2) // NaN
// 等同于
parseInt(String(011), 2)
//八進(jìn)制011等于10進(jìn)制9缔杉, 字符串9轉(zhuǎn)換為二進(jìn)制時(shí),返回NaN
parseInt('011', 2) // 3
//字符串轉(zhuǎn)二進(jìn)制
3.2 parseFloat##
3.2.1 基本
(1) 用于將一個(gè)字符串轉(zhuǎn)為浮點(diǎn)數(shù)搁料。
parseFloat('3.14') // 3.14
parseFloat('314e-2') // 3.14
parseFloat('0.0314E+2') // 3.14
(2)如果字符串包含不能轉(zhuǎn)為浮點(diǎn)數(shù)的字符或详,則不再進(jìn)行往后轉(zhuǎn)換,返回已經(jīng)轉(zhuǎn)好的部分加缘。
parseFloat('3.14more non-digit characters') // 3.14
(3)parseFloat方法會(huì)自動(dòng)過濾字符串前導(dǎo)的空格鸭叙。
parseFloat('\t\v\r12.34\n ') // 12.34
(4)如果參數(shù)不是字符串觉啊,或者字符串的第一個(gè)字符不能轉(zhuǎn)化為浮點(diǎn)數(shù)拣宏,則返回NaN。
parseFloat([]) // NaN
parseFloat('FF2') // NaN
parseFloat('') // NaN
(5)Number函數(shù)比較
parseFloat(true) // NaN
Number(true) // 1
parseFloat(null) // NaN
Number(null) // 0
parseFloat('') // NaN
Number('') // 0
parseFloat('123.45#') // 123.45
Number('123.45#') // NaN