(JS基礎)Number 類型

對於數字,咱們再熟悉不過了。經過let num = 123;能夠建立一個數字。
javascript

經過Number(thing)能夠將任何類型的數據轉化成數字java

經過new Number(thing)能夠將任何類型的數據轉化成Number類型的對象git

數字直接量能直接使用Number對象上的屬性和方法,如100['toFixed'](1)。其實語言內部會臨時將100封裝成對象,再執行相應的方法。能夠當作是Number(100).toFixed(1)編程

數字直接量也能用點運算(.)使用Number對象上的屬性和方法,可是數字後要加上空格,如100 .toFixed(1),由於編譯器不瞭解.表示小數點仍是運算符,必須加上空格表示.前面是一個完整的數字。安全

除了常見的數字外,NaNInfinity也屬於Number類型。除了十進制,JavaScript 還支持二進制(0b111)、八進制(0o777,0開頭也能表示八進制,但不推薦)、十六進制(0xfff)的數字表示方式,還有科學計數法(2.345e+3)表示方式。dom


靜態屬性

這些靜態屬性不多會用到,通常用於檢測是否超過精度。(文章最後說起精度問題)
編程語言

  • EPSILON:兩個可表示(representable)數之間的最小間隔。2-52
  • MAX_SAFE_INTEGER:最大的安全整數。253-1。
  • MIN_SAFE_INTEGER:最小的安全整數。-2-53+1。
  • MAX_VALUE:能表示的最大正數。21023*[(253-1)/252]。
  • MIN_VALUE:能表示的最小正數即最接近 0 的正數。2-1022*(1/252)=2-1074
  • NaN:特殊的「非數字」值。
  • POSITIVE_INFINITY:特殊的正無窮大值,在溢出時返回改值。溢出的正數均爲該值。
  • NEGATIVE_INFINITY:特殊的負無窮大值,在溢出時返回該值。溢出的負數均爲該值。

須要單獨說一下,安全整數指的是能作正確運算的整數。在整數相加時,須要將指數位換算成相同的值,如 252+1 = 252+252*2-52 ,而後對分數位加減運算。當超出安全範圍時,如253+1 ,發現 1 沒法轉化成 253*2-53,由於分數位的位數只有 52 位。
函數

(其實計算Number.MAX_SAFE_INTEGER + 1Number.MIN_SAFE_INTEGER - 1是能夠獲得正確的結果)ui


靜態方法

第一個和最後兩個方法比較經常使用。其中Number.isNaN(value)是比較實用的,由於咱們沒法經過value===NaN判斷value是否爲NaN
編碼

  • isNaN(value)判斷value是否爲NaN
  • isFinite(value):判斷value是否爲有限數,非數字類型返回false
  • isInteger(value):判斷value是否爲整數,非數字類型返回false
  • isSafeInteger(value):判斷value是否爲安全整數( -(253 - 1) 至 253 - 1 之間 )。
  • parseFloat(string):把一個字符串解析成浮點數。傳入數值會返回原值;非字符串和數字會返回NaN;其餘狀況請查看文檔。
  • parseInt(string[, radix]):根據給定的進制數把一個字符串解析成整數radix默認爲 10 ,即十進制。傳入非字符串和數字會返回NaN;其餘狀況請查看文檔。


實例方法

  • toExponential(fractionDigits?):返回一個用冪的形式(科學記數法)來表示Number對象的字符串fractionDigits默認爲小數點後的將盡量用最多的位數來表示該數值。例子:100 .toExponential();  // "1e+2"2.345 .toExponential(2);  // "2.35e+0"
  • toFixed(digits?):返回所給數值的定點數表示法的字符串形式,即保留digits位小數digits默認爲 0 。通常用於減小小數點的經度,例如2.345 .toFixed(2);  // "2.35"
  • toLocale​String([locales [, options]]):返回這個數字在特定語言環境下的表示字符串。
  • toPrecision(precision?):返回以定點表示法或指數表示法表示的一個數值對象的字符串。precision表示有效數個數的整數,省略則返回原數值。例子:100 .toPrecision(2); // "1.0e+2"2.345 .toPrecision(3); // "2.35"
  • toString(radix?):返回指定Number對象的字符串表示形式。radix表示轉換的基數(從2到36),默認爲 10 。
  • valueOf():返回一個被Number對象包裝的原始值。


Math 對象

與其它全局對象不一樣的是,Math 不是一個構造器。Math全部屬性和方法都是靜態的。你用到的常數 pi 能夠用Math.PI表示,用x做參數Math.sin(x)調用 sin 函數。JavaScript 中的常數,是以全精度的實數定義的。

屬性

通常用於獲得數學常量

  • E:歐拉常數,也是天然對數的底數,約等於 2.718 。
  • LN2:2 的天然對數,約等於 0.693 。
  • LN10:10 的天然對數,約等於 2.303 。
  • LOG2E:以 2 爲底 E 的對數,約等於 1.443 。
  • LOG10E:以 10 爲底 E 的對數,約等於 0.434 。
  • PI:圓周率,約等於 3.14159 。
  • SQRT1_2:1/2 的平方根,約等於 0.707 。
  • SQRT2:2 的平方根,約等於 1.414 。

方法

普通運算

  • abs(x):返回 x 的絕對值
  • sign(x):返回 x 的符號函數,5 種可能返回的值:參數是±0,返回原值;其餘正數返回1;其餘負數返回-1;其餘參數返回NaN
  • ceil(x): 返回 x 向上取整後的值。
  • floor(x):返回 x 向下取整後的值。
  • round(x):返回四捨五入後的整數。
  • trunc(x):返回 x 的整數部分,去除小數。
  • random():返回 0 到 1 之間的僞隨機數

開方

  • sqrt(x): 返回 x 的平方根
  • hypot(...[x1,x2,...]?):返回它的全部參數的平方和的平方根
  • cbrt(x): 返回 x 的立方根

冪運算

  • exp(x):返回 Ex ,E 爲歐拉常數。
  • expm1(x):返回 exp(x) - 1 的值。
  • pow(x,y):返回 x 的 y 次冪。這裏還有另外一種寫法,使用**運算符,即x**y

對數運算

  • log(x):返回 x 的天然對數。logeX, 即 lnX 。
  • log1p(x):返回 x+1 的天然對數,等效於Math.log(x+1)
  • log10(x):返回以 10 爲底數的 x 的對數。log10X,即 lgX 。
  • log2(x):返回以 2 爲底數的 x 的對數。log2X

三角函數

  • sin(x):返回 x 的正弦值。
  • cos(x): 返回 x 的餘弦值。
  • tan(x): 返回 x 的正切值。
  • asin(x):返回 x 的反正弦值。
  • acos(x):返回 x 的反餘弦值。
  • atan(x):以介於 -PI/2 與 PI/2 弧度之間的數值來返回 x 的反正切值。
  • sinh(x):返回 x 的雙曲正弦值。
  • cosh(x):返回 x 的雙曲餘弦值。
  • tanh(x):返回 x 的雙曲正切值。
  • asinh(x): 返回 x 的反雙曲正弦值。
  • acosh(x):返回 x 的反雙曲餘弦值。
  • atanh(x): 返回 x 的反雙曲正切值。
  • atan2(y, x):返回 y/x 的反正切值。

求最值

  • max(...[x1,x2,…]?):返回全部參數中的最大值
  • min(...[x1,x2,…]?):返回全部參數中的最小值

精度

  • clz32(x):返回 x 轉化成32位無符號整形的數的二進制的前導零的數量。
  • fround(x): 返回數字 x 的最接近的單精度浮點型表示。
  • imul(x1, x2):兩個參數的類C的32位整數乘法運算的運算結果。(即計算結果絕對值小於231-1能獲得正確的結果)


精度問題

0.1+0.2!==0.3

關於精度問題,從一個簡單的加法開始。

console.log(0.1 + 0.2);   // 0.30000000000000004複製代碼

這是因爲 JavaScript 採用 IEEE 754 標準,因此上述問題並不是 JavaScript 特有,是使用該標準的的編程語言都存在的問題。下面簡單講解問題發生的緣由。(相關專業知識請查閱書本或文檔)

浮點數的組成

IEEE 754 規定了包括:單精度(32位)、雙精度(64位)、延伸單精度(43比特以上,不多使用)與延伸雙精度(79比特以上,一般以80位實現)。而 JavaScript 使用的是雙精度
一個浮點數(value)能夠這樣表示:

一個浮點數的存儲方式以下圖:


總共分爲三部分:

  1. 符號位(sign),只佔 1 位,0 表示+,1 表示-
  2. 指數位(exponent),單精度佔 8 位;雙精度佔 11 位。要注意的是,這部分表示的是 2 的指數。指數位的值爲真實的指數值加上指數偏移值。例如對於單精度,指數位存儲 2 ,須要加上27-1,即 131 ,用二進制表示爲1000 0011。下面介紹指數位的範圍。
  3. 分數位(fraction),佔餘下的的位。下面介紹二進制分數位的轉換。

規約形式的浮點數

若是浮點數中指數部分的編碼值在 0<exponent≤2e-2 之間,且在科學表示法的表示方式下,分數 (fraction) 部分最高有效位(即整數字)是 1 (並不會存儲),那麼這個浮點數將被稱爲規約形式的浮點數。簡單說就是,指數部分用二進制爲000...001111...110之間;分數部分的實際值大於等於 0.5 ,小於 1 。關於換算,下面會說。

非規約形式的浮點數

若是浮點數的指數部分的編碼值是 0 ,即實際指數值爲 -126 ;分數部分非零,那麼這個浮點數將被稱爲非規約形式的浮點數。 IEEE 754標準規定:非規約形式的浮點數的指數偏移值比規約形式的浮點數的指數偏移值小 1 ,即 2e-1-2 。主要是用於解決填補絕對值意義下最小規格數與零的距離。

指數偏移值

(下面用 e 表示指數位的位數)

對於規約形式的浮點數,指數偏移值爲 2e-1-1 。因爲該值不能爲 0 ,因此實際的指數範圍爲 -126 到 127

對於非規約形式的浮點數,指數偏移值爲 2e-1-2 ,即比規約形式的浮點數的偏移值要小 1 。因爲該值只能爲 0 ,因此實際的指數值爲 -126

總的來講就是,實際的指數值範圍爲 -126 到 127 。000...001是規約形式的浮點數的指數位的最小值;000...000是非規約形式的浮點數的指數位的最小值,二者表示的實際指數值都是
-126 。

特殊值

這裏有三個特殊值須要指出:
若是 指數是 0 而且尾數的 小數部分是 0 ,這個數 ±0(和符號位相關)
若是 指數 = 2 e-1-1 而且尾數的 小數部分是 0 ,這個數是 ± (一樣和符號位相關)
若是 指數 = 2 e-1-1 而且尾數的 小數部分非 0 ,這個數表示爲不是一個數(NaN)。

分數位的轉換

要明確的是, 分數位的十進制值必須是大於 1 小於 2 的數。下面以 1.625爲例。

咱們並不能直接當作1625轉成二進制。須要使用以下方法(用 f 表示當前十進制數值):

第一步先把數值減 1 獲得新的數值,第一位取 1 。新的數值*2,若整數部分獲得 1 ,則該位爲 1 ,不然爲 0 ;而後繼續取小數部分同上操做,獲得後面位的值,直到數恰好爲 0 或達到規定位數的最大值(最大精度)。

舉個實際例子,對於1.625

  1. 初始值1.625,整數位爲 1 ,則第一位取 1 ,用 0.625 繼續操做;
  2. 0.625 * 2 = 1.250,整數位爲 1 ,則第二位取 1 ,用 0.25 繼續操做;
  3. 0.25* 2 = 0.5,整數位爲 0 ,則第三位取 0 ,用 0.5 繼續操做;
  4. 0.5 * 2 = 1.0,整數位爲 1 ,則第四位取 1 ,小數點後爲 0 ,轉換結束;

後面用 0 補全位數便可。

因此,在二進制,第一個有效數字一定是 1 ,所以這個 1 並不會存儲
(如何從二進制的值獲得十進制?對於上面的例子是: "1101"/23=13/8=1.625 )

格式化浮點數

對於那些大於 1 或小於 0.5 的浮點數來講,須要格式化後才能看出"三部分"分別的值是多少。(由於要保證二進制的分數位的實際第一位是 1 )簡單說就是要使得 1≤fraction<2

 以6.625爲例,須要換算成 1.65625 * 22 。而後咱們用上面的方法,把1.65625換算成二進制就是110101 00...

可是,最高位的 1 並不會存儲,因此獲得的分數位的二進制值爲10101 00...(尾數用 0 補全)。

指數位爲 3 ,加上偏移值獲得的二進制值爲100...011(中間都是 0)。

上面演示了 fraction≥2 的狀況,就是乘以 2n(n>0);而 fraction<1 也同樣乘以 2n ,不一樣的是 n<0 。

更直觀的換算方法

一樣以 6.625爲例:
  1. 把小數點先後分紅兩部分看,分別是60.625
  2. 咱們對整數部分6的進制轉換比較熟悉,結果是110
  3. 小數點後的部分0.625按照相似於上面的分數位的轉換規則,但忽略第一步,獲得的結果是101
  4. 二者組合起來就是110.101
  5. 轉換成1.xxxx的形式,即1.10101,最高位省略,得分數位10101
  6. 對比於原值110.101的小數點向前左移動了 2 位,則獲得指數位的值爲 2 ,加上指數偏移值獲得100...001(省略的是0)。
  7. 最後組合成0 100...001 101010...(省略的是 0 )。

而對於0.2這種小於 1 的數,也是相似的作法,區別在於第 6 步,"向左移動"變爲"向右移動",獲得的指數位的值爲負數,即 -3 ,加上指數偏移值獲得的是011...100(省略的是1)。

回到問題自己

因此對於 0.1 和 0.2 來講,根據上main的方法獲得的二進制的值都是11001100...,都是以1100不斷重複。

計算機存儲的位數是有限的,必須把超出的位數捨去。因此對於這種,在有限精度內不能徹底表示的,就會形成精度缺失。就是11001100...從二進制轉換回十進制後總會比原來的值小那麼一點。

相關文章
相關標籤/搜索