価値
概要
整数と浮動小数点数
JavaScript の内部では、すべての数値は、整数も含めて 64 ビット浮動小数点数として保存されます。したがって、「1」と「1.0」は同じであり、同じ数です。
1 === 1.0 // true
これは、JavaScript 言語の末尾には整数がなく、すべての数値が 10 進数 (64 ビット浮動小数点数) であることを意味します。混乱しやすいのは、一部の演算は整数でのみ完了できることです。現時点では、JavaScript が 64 ビット浮動小数点数を 32 ビット整数に自動的に変換してから演算を実行します。「ビット演算」セクションを参照してください。 「オペレーター」の章。
浮動小数点数は正確な値ではないため、小数を含む比較や演算には特別な注意が必要です。
0.1 + 0.2 === 0.3
// 間違い
0.3/0.1
// 2.9999999999999996
(0.3 - 0.2) === (0.2 - 0.1)
// 間違い
数値精度
国際標準 IEEE 754 によれば、JavaScript 浮動小数点数の 2 進数 64 ビットは左端から次のように構成されます。
- ビット 1: 符号ビット。「0」は正の数を表し、「1」は負の数を表します。 ・2~12桁(計11桁):指数部 ・13桁目から64桁目(計52桁):小数部(つまり有効数字)
符号ビットは数値の符号を決定し、指数部は値のサイズを決定し、小数部は値の精度を決定します。
指数部には 11 の 2 進ビットがあるため、サイズ範囲は 0 ~ 2047 です。 IEEE 754 では、指数部の値が 0 ~ 2047 の場合 (2 つの端点を除く)、有効桁の最初の桁はデフォルトで常に 1 となり、64 ビット浮動小数点数には格納されないと規定されています。言い換えれば、有効な数字は常に 1.xx...xx
の形式であり、xx..xx
の部分は 64 ビット浮動小数点数 (最大 52 まで) に格納されます。ビット。したがって、JavaScript で提供される有効な最大の数値は 2 進数の 53 桁です。
(-1)^符号ビット * 1.xx...xx * 2^指数部
上記の式は、通常の状況下での JavaScript の数値の実際の内部表現です (指数部は 0 ~ 2047 です)。
精度は 2 進数 53 桁までしか指定できません。つまり、絶対値は 2 の 53 乗未満の整数、つまり -253 + 1 ~ 253 になります。 - 1 、正確に表現できます。
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 乗より大きくなると、整数演算の結果にエラーが表示され始めます。したがって、2 の 53 乗を超える値は精度を維持できません。 2 の 53 乗は 16 桁の 10 進数値であるため、単純なルールとして、JavaScript は 15 桁の 10 進数値を正確に処理できます。
Math.pow(2, 53)
// 9007199254740992
// 追加の有効な 3 桁は保存できません。
9007199254740992111
// 9007199254740992000
上の例は、値が 2 の 53 乗より大きくなると、余分な有効数字 (最後の 3 桁 111
) は保存されず、0 になることを示しています。
値の範囲
標準によれば、64 ビット浮動小数点数の指数部の長さは 2 進数で 11 ビットです。つまり、指数部の最大値は 2047 (2 の 11 乗 - 1) になります。つまり、64 ビット浮動小数点数の指数部の最大値は 2047 で、その半分は負の数を表します。JavaScript が表現できる値の範囲は 21024</sup です。 > ~ 2-1023 (開放間隔)、この範囲外の数値は表現できません。
数値が 2 の 1024 乗以上の場合、「フォワード オーバーフロー」が発生します。つまり、JavaScript はそのような大きな数値を表すことができず、Infinity
が返されます。
Math.pow(2, 1024) // 無限大
数値が 2 の -1075 乗(指数部の最小値 -1023 に小数部の 52 ビットを加えた値)以下の場合、「負のオーバーフロー」が発生します。つまり、JavaScript は実行できません。このような小さな数値を表すと、直接 0 が返されます。
Math.pow(2, -1075) // 0
ここでは実際的な例を示します。
var x = 0.5;
for(var i = 0; i < 25; i++) {
x = x * x;
}
× // 0
上記のコードでは、0.5
を 25 回連続して 2 乗しています。最終結果は 0 に近すぎて表現可能な範囲を超えているため、JavaScript はそれを直接 0 に変換します。
JavaScript は、表現できる特定の最大値と最小値を返す Number
オブジェクトの MAX_VALUE
プロパティと MIN_VALUE
プロパティを提供します。
Number.MAX_VALUE // 1.7976931348623157e+308
Number.MIN_VALUE // 5e-324
数値の表現
JavaScript で数値を表現する方法は数多くあり、「35」(10 進数)や「0xFF」(16 進数)など、リテラル形式で直接表現できます。
数値は科学的表記法でも表現できます。以下に科学的表記法の例をいくつか示します。
123e3 // 123000
123e-3 // 0.123
-3.1E+12
.1e-23
科学表記法では、文字「e」または「E」の後に、値の指数部分を表す整数を続けることができます。
次の 2 つの場合、JavaScript は値を科学表記法に自動的に変換します。それ以外の場合は、リテラル形式で直接表現されます。
**(1) 小数点の前の桁が 21 桁を超えています。 **
1234567890123456789012
// 1.2345678901234568e+21
123456789012345678901
// 123456789012345680000
**(2) 小数点以下のゼロが 5 個以上あります。 **
// 小数点の後に 5 つ以上のゼロが続きます。
// 自動的に科学表記法に変換します
0.0000003 // 3e-7
// それ以外の場合は、元のリテラル形式を維持します
0.000003 // 0.000003
数値の底
リテラルを使用して値を直接表す場合、JavaScript は整数の 4 つの基本表現方法 (10 進数、16 進数、8 進数、および 2 進数) を提供します。
- 10 進数: 先頭に 0 を除いた数値。
- 8 進数: 接頭辞
0o
または0O
を持つ値、または先頭に 0 があり、0 ~ 7 の 8 つのアラビア数字のみを使用する値。 - 16 進数: 接頭辞
0x
または0X
が付いた値。 - バイナリ: 接頭辞「0b」または「0B」が付いた値。
デフォルトでは、JavaScript は 8 進数、16 進数、および 2 進数を 10 進数に自動的に変換します。以下にいくつかの例を示します。
0xff // 255
0o377 // 255
0b11 // 3
その基数に属さない 8 進数、16 進数、または 2 進数の数値がある場合、エラーが報告されます。
0xzz // エラーレポート
0o88 // エラーレポート
0b22 // エラーレポート
上記のコードでは、文字「z」は 16 進数で表示され、数字「8」は 8 進数で表示され、数字「2」は 2 進数で表示されるため、エラーが報告されます。
一般に、先頭に 0 がある値は 8 進数として扱われますが、先頭の 0 の後に数字「8」と「9」が続く場合、値は 10 進数として扱われます。
0888 // 888
0777 // 511
先頭の 0 は 8 進数を表すため、処理時に混乱を引き起こしやすくなります。 ES5 と ES6 の厳密モードではこの表記が廃止されましたが、ブラウザは以前のコードとの互換性を保つためにこの表記をサポートし続けています。
特別な値
JavaScript はいくつかの特別な値を提供します。
正のゼロと負のゼロ
前述したように、JavaScript の 64 ビット浮動小数点数のうち、2 進数の 1 ビットが符号ビットです。これは、すべての数値には対応する負の値があり、「0」も例外ではないことを意味します。
実際には JavaScript 内には 2 つの「0」があります。1 つは「+0」、もう 1 つは「-0」です。違いは、64 ビット浮動小数点数表現の符号ビットが異なることです。それらは同等です。
-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
上記のコードがこのような結果を生成する理由は、正のゼロで除算すると +Infinity
が生成され、負のゼロで除算すると -Infinity
が生成され、これらが等しくないためです (「Infinity」の詳細については、以下を参照してください)。
NaN
(1)意味
「NaN」は JavaScript の特別な値で、「数値ではない」という意味で、主に文字列を数値に解析する際にエラーが発生した場合に発生します。
5 - 'x' // NaN
上記のコードを実行すると、文字列 x
が自動的に数値に変換されますが、x
は数値ではないため、最終結果は NaN
となり、これは「数値ではない」ことを意味します。 NaN
)。
また、一部の数学関数の演算結果は「NaN」と表示されます。
Math.acos(2) // NaN
Math.log(-1) // NaN
Math.sqrt(-1) // NaN
「0」を「0」で割っても「NaN」になります。
0 / 0 // NaN
NaN
は独立したデータ型ではなく、特殊な値であることに注意してください。そのデータ型は依然として Number
に属しており、typeof
演算子を使用すると明確にわかります。
typeof NaN // '数値'
(2) 運用ルール
NaN
は、それ自体を含め、どの値とも等しくありません。
NaN === NaN // false
配列の indexOf
メソッドは内部的に厳密な等価演算子を使用するため、このメソッドは NaN
には当てはまりません。
[NaN].indexOf(NaN) // -1
NaN
はブール演算では false
として扱われます。
Boolean(NaN) // false
任意の数値 (それ自体を含む) を NaN
と演算すると、NaN
が返されます。
NaN + 32 // NaN
NaN - 32 // NaN
NaN * 32 // NaN
NaN / 32 // NaN
インフィニティ
(1)意味
「Infinity」は「無限」を意味し、2 つのシナリオを表すために使用されます。 1 つは、正の値が大きすぎるか、負の値が小さすぎて表現できないことです。もう 1 つは、0 以外の値を 0 で割って「無限大」を得るということです。
// シーン 1
Math.pow(2, 1024)
//無限大
// シーン 2
0 / 0 // NaN
1 / 0 // 無限大
上記のコードでは、最初のシナリオは、式の計算結果が大きすぎて表現できる範囲を超えているため、「Infinity」が返されるというものです。 2 番目のシナリオは、「0」を「0」で除算すると「NaN」が返され、0 以外の値を「0」で除算すると「無限大」が返されるというものです。
「Infinity」は正と負に分けられます。「Infinity」は正の無限大を意味し、「-Infinity」は負の無限大を意味します。
無限 === -無限 // false
1 / -0 // -無限大
-1 / -0 // 無限大
上記のコードでは、ゼロ以外の正の数値を -0
で割ると -Infinity
が生成され、負の数値を -0
で割ると Infinity
が生成されます。
JavaScript は、正の数値オーバーフロー (オーバーフロー)、負のオーバーフロー (アンダーフロー)、または「0」による除算のエラーを報告しないため、純粋な数学演算でエラーがスローされることはほとんど不可能です。
Infinity
は任意の数値 (NaN
を除く) より大きく、-Infinity
は任意の数値 (NaN
を除く) より小さくなります。
無限大 > 1000 // true
-Infinity < -1000 // true
「Infinity」と「NaN」を比較すると、常に「false」が返されます。
無限大 > NaN // false
-Infinity > NaN // false
無限大 < NaN // false
-Infinity < NaN // false
(2) 運用ルール
「Infinity」の四則演算は、無限大の数学的計算規則に準拠しています。
5 * 無限大 // 無限大
5-無限大 // -無限大
無限 / 5 // 無限
5 / 無限 // 0
0 に「Infinity」を掛けると「NaN」が返され、0 を「Infinity」で割ると「0」が返され、「Infinity」を 0 で割ると「Infinity」が返されます。
0 * 無限大 // NaN
0 / 無限大 // 0
無限大 / 0 // 無限大
「Infinity」を「Infinity」に加算または乗算しても、返される結果は「Infinity」のままです。
無限 + 無限 // 無限
無限 * 無限 // 無限
Infinity
を Infinity
で減算または除算すると、結果は NaN
になります。
無限 - 無限 // NaN
無限大 / 無限大 // NaN
null を使って Infinity を計算すると、null は 0 に変換され、0 を使った計算と同じになります。
null * 無限大 // NaN
null / 無限大 // 0
無限大 / null // 無限大
Infinity
と unknown
が計算され、返される値はすべて NaN
です。
未定義 + 無限大 // NaN
未定義 - 無限大 // NaN
未定義 * 無限大 // NaN
未定義 / 無限大 // NaN
無限大 / 未定義 // NaN
数値に関するグローバルメソッド
parseInt()
(1)基本的な使い方
parseInt
メソッドは、文字列を整数に変換するために使用されます。
parseInt('123') // 123
文字列の先頭にスペースがある場合、スペースは自動的に削除されます。
parseInt(' 81') // 81
parseInt のパラメータが文字列でない場合は、文字列に変換してから変換します。
parseInt(1.23) // 1
// と同等
parseInt('1.23') // 1
文字列を整数に変換する場合、文字は 1 つずつ変換され、数値に変換できない文字が見つかった場合、処理は続行されず、変換された部分が返されます。
parseInt('8a') // 8
parseInt('12**') // 12
parseInt('12.34') // 12
parseInt('15e2') // 15
parseInt('15px') // 15
上記のコードでは、parseInt
のパラメータはすべて文字列であり、結果は数値に変換できる文字列の先頭の部分のみを返します。
文字列の最初の文字が数値に変換できない場合 (記号とそれに続く数値を除く)、NaN
が返されます。
parseInt('abc') // NaN
parseInt('.3') // NaN
parseInt('') // NaN
parseInt('+') // NaN
parseInt('+1') // 1
したがって、parseInt
の戻り値は 10 進整数または NaN
の 2 つだけです。
文字列が 0x
または 0X
で始まる場合、 parseInt
はそれを 16 進数として解析します。
parseInt('0x10') // 16
文字列が「0」で始まる場合、10 進数に従って解析されます。
parseInt('011') // 11
科学的表記法に自動的に変換される数値の場合、「parseInt」は科学的表記法表現を文字列として扱うため、奇妙な結果が生じます。
parseInt(1000000000000000000000.5) // 1
// と同等
parseInt('1e+21') // 1
parseInt(0.0000008) // 8
// と同等
parseInt('8e-7') // 8
(2) 塩基換算
parseInt
メソッドは、解析される値の基数を示す 2 番目のパラメータ (2 ~ 36) を受け取ることもでき、その値に対応する 10 進数を返します。デフォルトでは、parseInt
の 2 番目のパラメータは 10 です。つまり、デフォルトは 10 進数から 10 進数です。
parseInt('1000') // 1000
// と同等
parseInt('1000', 10) // 1000
以下は、指定された基数の数値を変換する例です。
parseInt('1000', 2) // 8
parseInt('1000', 6) // 216
parseInt('1000', 8) // 512
上記のコードでは、2 進数、16 進数、8 進数の「1000」は、それぞれ 10 進数の 8、216、512 に相当します。これは、parseInt
メソッドを使用して基本変換を実行できることを意味します。
2 番目のパラメータが数値でない場合は、自動的に整数に変換されます。この整数は、2 ~ 36 の範囲にある場合にのみ意味のある結果を得ることができます。この範囲を超える場合は、「NaN」が返されます。 2 番目のパラメータが 0
、unknown
、および null
の場合、それは無視されます。
parseInt('10', 37) // NaN
parseInt('10', 1) // NaN
parseInt('10', 0) // 10
parseInt('10', null) // 10
parseInt('10', 未定義) // 10
文字列中に指定したベースに対して意味のない文字が含まれている場合は、最上位ビットから変換可能な値のみが返されます。最上位ビットが変換できない場合は、直接 NaN
を返します。
parseInt('1546', 2) // 1
parseInt('546', 2) // NaN
上記のコードでは、バイナリの場合、 1
は意味のある文字、 5
、4
、および 6
はすべて意味のない文字であるため、最初の行は 1 を返し、2 行目は NaN
を返します。
前に述べたように、parseInt
の最初のパラメータが文字列でない場合は、最初に文字列に変換されます。これにより、驚くべき結果が生じる可能性があります。
parseInt(0x11, 36) // 43
parseInt(0x11, 2) // 1
// と同等
parseInt(文字列(0x11), 36)
parseInt(String(0x11), 2)
// と同等
parseInt('17', 36)
parseInt('17', 2)
上記のコードでは、16 進数の「0x11」がまず 10 進数の 17 に変換され、次に文字列に変換されます。次に、16 進数または 2 進数を使用して文字列 17
を解釈し、最終的に結果 43
と 1
を返します。
この処理方法では、8 進数の接頭辞 0 について特別な注意が必要です。
parseInt(011, 2) // NaN
// と同等
parseInt(String(011), 2)
// と同等
parseInt(String(9), 2)
上記のコードでは、最初の行の 011
が最初に文字列 9
に変換されます。 9
は有効なバイナリ文字ではないため、NaN
が返されます。 parseInt('011', 2)
を直接計算すると、011
はバイナリとして扱われ、3 が返されます。
JavaScript では、接頭辞 0 が付いている数値を 8 進数として扱うことはできなくなり、代わりに「0」を無視することが求められます。ただし、互換性を確保するために、ほとんどのブラウザはこの規定を実装していません。
parseFloat()
parseFloat
メソッドは、文字列を浮動小数点数に変換するために使用されます。
parseFloat('3.14') // 3.14
文字列が科学表記法に準拠している場合は、適切な変換が実行されます。
parseFloat('314e-2') // 3.14
parseFloat('0.0314E+2') // 3.14
文字列に浮動小数点数に変換できない文字が含まれている場合、それ以上の変換は実行されず、変換された部分が返されます。
parseFloat('3.14その他の非数字文字') // 3.14
parseFloat
メソッドは、文字列内の先頭のスペースを自動的にフィルタリングします。
parseFloat('\t\v\r12.34\n ') // 12.34
パラメータが文字列でない場合は、まず文字列に変換されてから変換されます。
parseFloat([1.23]) // 1.23
// と同等
parseFloat(String([1.23])) // 1.23
文字列の最初の文字が浮動小数点数に変換できない場合は、「NaN」が返されます。
parseFloat([]) // NaN
parseFloat('FF2') // NaN
parseFloat('') // NaN
上記のコードでは、「parseFloat」が空の文字列を「NaN」に変換することに特に注目してください。
これらの特性により、parseFloat の変換結果は Number 関数の変換結果とは異なります。
parseFloat(true) // NaN
数値(真) // 1
parseFloat(null) // NaN
数値(null) // 0
parseFloat('') // NaN
数値('') // 0
parseFloat('123.45#') // 123.45
Number('123.45#') // NaN
isNaN()
isNaN
メソッドを使用すると、値が NaN
であるかどうかを判断できます。
isNaN(NaN) // true
isNaN(123) // false
ただし、isNaN
は数値に対してのみ有効です。他の値が渡された場合は、最初に数値に変換されます。たとえば、文字列が渡されると、文字列は最初に NaN
に変換されるため、最終的には true
が返されます。これには特に注意が必要です。言い換えれば、「true」に対する「isNaN」の値は「NaN」ではなく、文字列である可能性があります。
isNaN('Hello') // true
// と同等
isNaN(Number('Hello')) // true
同じ理由で、「isNaN」もオブジェクトと配列に対して「true」を返します。
isNaN({}) // true
// と同等
isNaN(Number({})) // true
isNaN(['xzy']) // true
// と同等
isNaN(Number(['xzy'])) // true
ただし、空の配列や数値メンバーが 1 つだけある配列の場合、「isNaN」は「false」を返します。
isNaN([]) // false
isNaN([123]) // false
isNaN(['123']) // false
上記のコードが false
を返す理由は、これらの配列が Number
関数によって数値に変換できるためです。「データ型変換」の章を参照してください。
したがって、「isNaN」を使用する前に、データ型を決定することが最善です。
関数 myIsNaN(値) {
戻り値の型 === '数値' && isNaN(値);
}
NaN
を判断するより信頼性の高い方法は、NaN
がそれ自体と等しくない唯一の値であるという事実を利用することです。
関数 myIsNaN(値) {
戻り値 !== 値;
}
isFinite()
isFinite
メソッドは、値が通常の値であるかどうかを示すブール値を返します。
isFinite(Infinity) // false
isFinite(-Infinity) // false
isFinite(NaN) // false
isFinite(未定義) // false
isFinite(null) // true
isFinite(-1) // true
「Infinity」、「-Infinity」、「NaN」、および「unknown」は「false」を返しますが、「isFinite」は他の値に対して「true」を返します。
参考リンク
- Axel Rauschmayer 博士、JavaScript で数値をエンコードする方法
- Humphry、JavaScript での数値表現の上限/下限
作者: wangdoc
アドレス: https://wangdoc.com/
ライセンス: クリエイティブ・コモンズ 3.0