溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何掌握JavaScript數(shù)字類型

發(fā)布時間:2022-05-31 09:49:02 來源:億速云 閱讀:141 作者:zzz 欄目:web開發(fā)

這篇文章主要講解了“如何掌握JavaScript數(shù)字類型”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“如何掌握JavaScript數(shù)字類型”吧!

如何掌握JavaScript數(shù)字類型

JavaScript中存在兩種表示數(shù)字的類型:

  1. Number類型,也就是常規(guī)意義上的數(shù)字類型,以64位的IEEE-754格式存儲,屬于“雙精度浮點數(shù)”,截至目前,我們接觸到的數(shù)字全部都是Number類型;

  2. BigInt類型,表示任意長度的整數(shù),通常情況下我們用不到它們,除非表示 253 至 -253之外的數(shù)字,此類專業(yè)數(shù)據(jù)類型我們會在后面的章節(jié)詳細介紹;

數(shù)字的寫法

數(shù)字的寫法本身很簡單,但是JavaScrpt有很多方便快捷的語法糖供我們使用,好好學(xué)習(xí)這些語法糖不僅能夠提高我們的代碼閱讀能力,同時可以提高我們代碼的高級感(逼格)。

分隔符

十進制的數(shù)字最簡單了,幾乎每篇文章我們都多多少少會使用,例如我們創(chuàng)建一個變量,并存儲100億:

let tenbillion = 10000000000;

雖然操作起來非常簡單,但是存在一個問題:很難數(shù)清楚1后面到底有幾個0,如果我們寫的是轉(zhuǎn)賬代碼,錯個0可能會傾家蕩產(chǎn)。

此時,我們可以使用_作為分隔符,如下:

let tenbillion = 10_000_000_000;

上述代碼就可以非常明白的數(shù)清0的個數(shù),顯然是最優(yōu)解!

這里的下劃線_就是JavaScript的一個語法糖,在執(zhí)行過程中會被引擎忽略,以上兩種寫法效果完全相同,但是閱讀體驗相差很大。

清奇腦回路

有些童鞋就要問了,我從小都是40一組的,為啥非要30分一組呢?所以,我們可以寫成下面的方式,同樣沒有問題:

let tenbillion = 100_0000_0000;

亦或者寫成這樣:

let tenbillion = 1_0000_0000_00;

這里我想表達的是,不論你采用哪種分割方式,都是不影響數(shù)字本身的大小的,快想一個逼格最高的方式吧!

省略的0

雖然使用_可以優(yōu)雅的分割很多0,但是在實際生活中,我們一般不這么寫,例如我們常常將10000000000寫成“100億”,這樣就可以省略很多0,從而降低犯錯的可能性。

JavaScript同樣提供了一種省略0的寫法,我們可以使用字母e后面跟個數(shù)字表示0的個數(shù),舉個栗子:

let tenbillion = 1e10;//100億,1后面10個0console.log(3.14e9);//3140000000,后面7個0,此處疑惑可往下看

上述代碼的理解非常簡單,e10可以理解為1_0000_0000_00,也就是1后面100,所以我們可以認為:

1e10 === 1 * 1_0000_0000_00;//e10表示1后面10個03.14e9 === 3.14 * 1_000_000_000;//e9表示1后面9個0

我們還可以使用這種方法表示非常小的數(shù)字,例如1納米:

let nm = 0.000000001;//單位(米)

由于0的個數(shù)過多,我們也可以使用_分割:

let nm = 0.000_000_001;

當(dāng)然,還可以使用e的方式省略掉所有的0,如下:

let nm = 1e-9;//1的左邊9個0,包括小數(shù)點前面的那個

換句話說,e-9的意思就是1-9,也就是1/1000_000_000,所以下面的等式是成立的:

1e-9 === 1 / 1_000_000_000;3.14e-8 === 3.14 / 1_000_000_00;

十六、八、二進制

十六進制是編程中常用到的格式,例如表示顏色、編碼等,我們可以在普通數(shù)字前加0x表示十六進制數(shù)字:

let hex = 0xff;//255,不區(qū)分大小寫,0xFF是一樣的

二進制數(shù)字使用0b開頭:

let bin = 0b1011;//11

八進制數(shù)字使用0o開頭:

let oct = 0o777;//511

這種簡便的寫法只支持這三種特殊類型,至于其他進制的數(shù)字可以使用特殊的函數(shù)生成(parseInt)。

toString(base)

toString方法可以把數(shù)字轉(zhuǎn)為對應(yīng)進制base的字符串形式。

舉個栗子:

let num = 996;
console.log(num.toString(8));//轉(zhuǎn)為8進制字符串
console.log(num.toString(16));//轉(zhuǎn)為16進制字符串
console.log(num.toString(32));//轉(zhuǎn)為32進制字符串

代碼執(zhí)行結(jié)果如下:

如何掌握JavaScript數(shù)字類型

base的范圍可以從236,如果不填默認為10

注意,如果使用數(shù)字直接調(diào)用toString方法,在有些情況下需要是應(yīng)用兩個.,舉例如下:

console.log(123.toString(8));//Error,語法錯誤console.log(123..toString(8));//正確,173

數(shù)字后面有兩個.,這是因為在JavaScript中數(shù)字后面的第一個.被認為是小數(shù)點,第二個點才是調(diào)用函數(shù)的.。

如果是小數(shù)就不存在這個問題,舉個栗子:

console.log(3.14.toString(8));

亦或者,我們使用小括號可以避免使用兩個點,舉個栗子:

console.log((123).toString(8));//'173

舍入

舍入是數(shù)字最常用的操作之一,通常包括:

  1. 向下取整,Math.floor(num)

    console.log(Math.floor(3.14));//3
    console.log(Math.floor(9.99));//9
    console.log(Math.floor(-3.14));//-4
    console.log(Math.floor(-9.99));//-10

    不遵循四舍五入原則,直接取小于等于當(dāng)前數(shù)值的最近整數(shù)。

  2. 向上取整,Math.ceil(num)

    console.log(Math.ceil(3.14));//4
    console.log(Math.ceil(9.99));//10
    console.log(Math.ceil(-3.14));//-3
    console.log(Math.ceil(-9.99));//-9

    不遵循四舍五入原則,直接取大于等于當(dāng)前數(shù)字的最近整數(shù)。

  3. 就近取整,Math.round(num)

    console.log(Math.round(3.14));//3
    console.log(Math.round(9.99));//10
    console.log(Math.round(-3.14));//-3
    console.log(Math.round(-9.99));//-10

    遵循四舍五入原則,取距離當(dāng)前數(shù)字最近的整數(shù)。

  4. 移除小數(shù),Math.trunc(num)

    console.log(Math.trunc(3.14));//3
    console.log(Math.trunc(9.99));//9
    console.log(Math.trunc(-3.14));//-3
    console.log(Math.trunc(-9.99));//-9

    直接移除小數(shù)點后面的數(shù)字,取整數(shù)位。IE瀏覽器不支持這個方法

對比以上四種方法:


Math.floorMath.ceilMath.roundMath.trunc
3.143433
9.99910109
-3.14-4-3-3-3
-9.99-10-9-10-9

精度

上述方法只是簡單的把小數(shù)舍入成了整數(shù),在有些情況下,我們需要特定精度的小數(shù),例如取圓周率后4位應(yīng)該怎么辦呢?

有兩種方法:

  1. 數(shù)學(xué)乘除計數(shù)

    let pi = 3.1415926;console.log(Math.round(pi * 10000) / 10000);//3.1416

    上述代碼先將pi乘以10000,然后取整,再除以10000,從而得到了符合精度要求的結(jié)果。但是,這么做看起啦呆呆的,JavaScript為我們提供了更簡單的方法。

  2. toFixed(n)

    let pi = 3.1415926;console.log(pi.toFixed(4));//3.1416

    以上代碼看起來輸出上沒有什么問題,實際上,toFixed返回的是一個字符串,如果我們需要一個數(shù)字類型,要轉(zhuǎn)換一下才行,可以使用單目運算符+ pi.toFixed(4)。

    此外,如果小數(shù)的尾數(shù)長度不夠,toFixed會在后面補上'0':

    let num = 3.1;console.log(num.toFixed(9));

    代碼執(zhí)行結(jié)果如下:
    如何掌握JavaScript數(shù)字類型

    這也側(cè)面證明了toFixed的返回值是一個字符串,否則0會被省略。

偏差

浮點數(shù)表示在很多情況下總是存在偏差

在計算機內(nèi)部,浮點數(shù)根據(jù)IEEE-754標(biāo)準(zhǔn)進行表示,其中單精度浮點數(shù)32位,雙精度浮點數(shù)64位。在雙精度浮點數(shù)中,1位用于表示符號,52位用于存儲有效數(shù)字,11位存儲小數(shù)點的位置。

偏差現(xiàn)象

雖然64位已經(jīng)可以表示非常大的數(shù)字了,但是仍然存在越界的可能,例如:

let bigNum = 1e999;console.log(bigNum);//Infinity

越過做最大值的數(shù)字將變?yōu)?code>Infinity(無窮),這樣就丟失了原有數(shù)字的大小,屬于偏差的一種。

還有一種偏差,需要我們學(xué)習(xí):

console.log(0.1+0.2 === 0.3);//falseconsole.log(0.1 + 0.2);

代碼執(zhí)行結(jié)果如下:

如何掌握JavaScript數(shù)字類型

沒錯,0.1 + 0.2的結(jié)果并不是0.3,而是一堆0后面加個4。

這種偏差是非常致命的,尤其在商城、銀行工作場景中,即使是一個非常小的偏差,在高流水場景下都會丟失無盡的財富。

曾經(jīng)聽說過一個銀行員工通過克扣工人工資,盜取百萬財富的故事,每個員工的工資只克扣2毛!

我想這種事情發(fā)生在我身上,我肯定發(fā)現(xiàn)不了,所以無時無刻的精確是多么的重要。

這個故事不知真假~~

偏差原因

先以我們常見的十進制為例,我們都知道,小數(shù)中存在兩個奇葩,一個叫無限循環(huán)小數(shù),另一個叫無限不循環(huán)小數(shù),例如1/3就是一個無限循環(huán)小數(shù)0.3333333(3),而圓周率就是一個無限不循環(huán)小數(shù)。無限就意味著無法用數(shù)字清楚的描述這個數(shù)字的大小,我們能寫出來的都是不精確的。

二進制同樣存在一些無限循環(huán)的數(shù)字,不同的是在十進制中0.1這種看起啦很簡單的數(shù)字,在二進制中卻是無限循環(huán)小數(shù)。

舉個例子:

let x = 0.1;console.log(x.toFixed(20));

代碼執(zhí)行結(jié)果如下:

如何掌握JavaScript數(shù)字類型

是不是覺得不可思議呢?我們只是簡單的創(chuàng)建了一個變量并賦值0.1,然后取小數(shù)點后20位,卻得到了一個匪夷所思的結(jié)果。

如果我們換一個角度或許會更容易理解這種現(xiàn)象,在十進制中,任何整數(shù)除以10或者10整數(shù)次冪都是正常的精確的數(shù)字,例如1/10或者996/1000。但是,如果以3為除數(shù),就會得到循環(huán)的結(jié)果,例如1/3。

這種描述如果換到二進制上,同樣是成立的。

在二進制中,任何整數(shù)除以2或者2的整數(shù)次冪都是正常的精確的數(shù)字,但是,如果以10為除數(shù),就會得到無限循環(huán)的二進制數(shù)。

所以,我們就可以得出結(jié)論,二進制數(shù)字無法精確表示0.10.2就像十進制沒有辦法描述1/3一樣。

注意:

這種數(shù)據(jù)上的偏差并非JavaScript的缺陷,像PHP、Java、C、Perl、Ruby都是同樣的結(jié)果。

解決方法

  1. 舍入

    在展示一個無限循環(huán)小數(shù)的時候,我們可以直接使用toFixed方法對小數(shù)進行舍入,該方法直接返回字符串,非常方便用于展示價格。

    0.3.toFixed(2);//0.30
  2. 使用小單位

    另外一種方式是,我們可以使用較小的單位計算諸如價格、距離,例如采用分而不是元計算總價,實際上很多交易網(wǎng)站都是這么做的。但是這種方法只是降低小數(shù)出現(xiàn)的次數(shù),并沒有辦法完全避免小數(shù)的出現(xiàn)。

Infinity、NaN

JavaScript數(shù)字中有兩個特殊值:InfinityNaN。

如何判斷一個數(shù)字是不是正常數(shù)字呢?

我們可以使用兩個方法:

  1. isFinite(val)
    該函數(shù)會將參數(shù)val轉(zhuǎn)為數(shù)字類型,然后判斷這個數(shù)字是否是有窮的,當(dāng)數(shù)字不是NaN、Infinity-Infinity時返回true。

    console.log(isFinite(NaN));//falseconsole.log(isFinite(Infinity));//falseconsole.log(isFinite(3));//trueconsole.log(isFinite('12'));//true

    代碼執(zhí)行結(jié)果如下:
    如何掌握JavaScript數(shù)字類型
    由于無法轉(zhuǎn)為數(shù)字的字符串會被轉(zhuǎn)為NaN,所以我們可以使用isFinite方法判斷字符串是不是數(shù)字串:

    console.log(isFinite('xxxx'));//falseconsole.log(isFinite('Infinite'));//falseconsole.log(isFinite(' '));//true,空串轉(zhuǎn)為0

    代碼執(zhí)行結(jié)果如下:

如何掌握JavaScript數(shù)字類型

  1. isNaN(val)
    當(dāng)valNaN或者無法轉(zhuǎn)為數(shù)字的其他值時,返回true。

    console.log(isNaN(NaN));//trueconsole.log(isNaN('Infinite'));//true

    代碼執(zhí)行結(jié)果:
    如何掌握JavaScript數(shù)字類型

    為什么要使用isNaN函數(shù)而不是直接判讀呢?
    例如:

    console.log(NaN === NaN);//false

    代碼執(zhí)行結(jié)果如下:
    如何掌握JavaScript數(shù)字類型

    這是因為NaN不等于任何數(shù),包括自身。

Object.is

Object.is(a,b)可以判斷參數(shù)ab是否相等,若相等返回true,否則返回false,它的結(jié)果只有三種情況:

  1. 可以比較NaN

    console.log(Object.is(NaN,NaN));//true

    代碼執(zhí)行結(jié)果:

    如何掌握JavaScript數(shù)字類型

  2. 0 和 -0

    console.log(Object.is(0,-0));//false

    代碼執(zhí)行結(jié)果:

    如何掌握JavaScript數(shù)字類型

    在計算機內(nèi)部,正負使用01表示,由于符號不同,導(dǎo)致0-0實際上是不同的,二者的表示方式也不一樣。

  3. 其他
     其他比較情況和a === b完全相同。

parseInt、parseFloat

parseIntparseFloat可以把字符串轉(zhuǎn)為數(shù)字,與+、Number不同的是,二者的限制更為松散。例如,像"100¥"這樣的字符串使用+Number必然返回NaN,而parseIntparseFloat卻能輕松應(yīng)對。

舉個例子:

console.log(+"100¥");console.log(parseInt("100¥"));console.log(parseFloat("12.5¥"));

代碼執(zhí)行結(jié)果:

如何掌握JavaScript數(shù)字類型

parseIntparseFloat會從字符串中讀取數(shù)字,直到無法讀取為止。二者特別適合處理像"99px"、"11.4em"這種數(shù)字開頭的字符串情況,但是對于其他字符開頭的字符串則返回NaN。

console.log(parseInt('ff2000'));//NaN

但是,我們發(fā)現(xiàn)ff2000實際上是一個十六進制的數(shù)字字符串,parseInt同樣可以處理這種情況,不過需要添加一個進制參數(shù)。

舉個例子:

console.log(parseInt('FF2000',16));
//16719872
console.log(parseInt('0xFF2000',16));
//16719872
console.log(parseInt('nnnnnn',36));
//1430456963

代碼執(zhí)行結(jié)果:

如何掌握JavaScript數(shù)字類型

Math對象

內(nèi)置的Math對象中包含了許多我們經(jīng)常用到的常量和方法,以下僅舉例介紹常用的幾個:

  1. Math.PI

    圓周率Π是一個無限不循環(huán)的常量,我們可以使用Math.PI代替:

    console.log(Math.PI);

    如何掌握JavaScript數(shù)字類型

  2. Math.random()
    生成一個位于區(qū)間[0,1)的隨機數(shù):

    console.log(Math.random());console.log(Math.random());

如何掌握JavaScript數(shù)字類型 

如果我們需要一個特定區(qū)間內(nèi)的隨機數(shù),可以乘以特定的值,然后取整哦。

  1. Math.pow(a,b)

    計算ab,舉例如下:

    console.log(Math.pow(2,3));//8
  2. Math.max()/Math.min()

    從任意數(shù)量的參數(shù)中選出一個最大/最小值:

    console.log(Math.max(1,2,3,4,5));//5console.log(Math.min(1,2,3,4,5));//1

如何掌握JavaScript數(shù)字類型

感謝各位的閱讀,以上就是“如何掌握JavaScript數(shù)字類型”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對如何掌握JavaScript數(shù)字類型這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI