Math
の機能 Number
プロパティMath
メソッドNumber.parseInt()
と新しい整数リテラルNumber
プロパティNumber.EPSILON
Number.isInteger(number)
Math
の機能2進数と8進数の表記で整数を指定できるようになりました
> 0xFF // ES5: hexadecimal
255
> 0b11 // ES6: binary
3
> 0o10 // ES6: octal
8
Number
プロパティ グローバルオブジェクトNumber
には、いくつかの新しいプロパティが追加されました
Number.EPSILON
。Number.isInteger(num)
は、num
が整数(小数点以下のない数値)であるかどうかを確認します。
> Number.isInteger(1.05)
false
> Number.isInteger(1)
true
> Number.isInteger(-3.1)
false
> Number.isInteger(-3)
true
Number.isSafeInteger(number)
Number.MIN_SAFE_INTEGER
Number.MAX_SAFE_INTEGER
Number.isNaN(num)
は、num
が値NaN
であるかどうかを確認します。グローバル関数isNaN()
とは対照的に、引数を数値に強制変換しないため、数値以外の場合でも安全です。
> isNaN('???')
true
> Number.isNaN('???')
false
Number
の3つの追加メソッドは、同じ名前のグローバル関数とほぼ同等です:Number.isFinite
、Number.parseFloat
、Number.parseInt
。Math
メソッド グローバルオブジェクトMath
には、数値、三角関数、およびビット単位演算のための新しいメソッドがあります。4つの例を見てみましょう。
Math.sign()
は数値の符号を返します
> Math.sign(-8)
-1
> Math.sign(0)
0
> Math.sign(3)
1
Math.trunc()
は数値の小数部分を削除します
> Math.trunc(3.1)
3
> Math.trunc(3.9)
3
> Math.trunc(-3.1)
-3
> Math.trunc(-3.9)
-3
Math.log10()
は底が10の対数を計算します
> Math.log10(100)
2
Math.hypot()
は、引数の二乗の和の平方根を計算します(ピタゴラスの定理)
> Math.hypot(3, 4)
5
ECMAScript 5には、16進数整数のリテラルがすでにあります
> 0x9
9
> 0xA
10
> 0x10
16
> 0xFF
255
ECMAScript 6では、2つの新しい種類の整数リテラルが導入されています
0b
または0B
です
> 0b11
3
> 0b100
4
0o
または0O
です(ゼロの後に大文字のOが続きます。最初のバリアントの方が安全です)
> 0o7
7
> 0o10
8
Number
メソッドtoString(radix)
を使用すると、10以外の基数で数値を確認できることを覚えておいてください
> 255..toString(16)
'ff'
> 4..toString(2)
'100'
> 8..toString(8)
'10'
(プロパティアクセスのドットが小数点と混同されないように、二重ドットが必要です。)
Node.jsのファイルシステムモジュールでは、いくつかの関数にパラメータmode
があります。その値は、Unixからの持ち越しであるエンコードを介してファイル権限を指定するために使用されます。
つまり、権限は9ビットで表すことができます(3つのカテゴリとそれぞれ3つの権限)
ユーザー | グループ | 全員 | |
---|---|---|---|
権限 | r、w、x | r、w、x | r、w、x |
ビット | 8, 7, 6 | 5, 4, 3 | 2, 1, 0 |
1つのカテゴリのユーザーの権限は、3ビットで格納されます
ビット | 権限 | 8進数 |
---|---|---|
000 | ––– | 0 |
001 | ––x | 1 |
010 | –w– | 2 |
011 | –wx | 3 |
100 | r–– | 4 |
101 | r–x | 5 |
110 | rw– | 6 |
111 | rwx | 7 |
つまり、8進数はすべての権限をコンパクトに表現したものであり、ユーザーのカテゴリごとに1桁、3桁のみが必要です。2つの例
Number.parseInt()
と新しい整数リテラル Number.parseInt()
(グローバル関数parseInt()
と同じ処理を行います)には、次のシグネチャがあります
Number
.
parseInt
(
string
,
radix
?
)
Number.parseInt()
: 16進数リテラル Number.parseInt()
は16進数リテラル表記を特別にサポートしています。string
のプレフィックス0x
(または0X
)は、以下の場合に削除されます。
radix
がない場合、または0の場合。次に、radix
は16に設定されます。原則として、radix
を省略しないでください。radix
は16です。例
> Number.parseInt('0xFF')
255
> Number.parseInt('0xFF', 0)
255
> Number.parseInt('0xFF', 16)
255
他のすべての場合、数字は最初の数字以外までのみ解析されます
> Number.parseInt('0xFF', 10)
0
> Number.parseInt('0xFF', 17)
0
Number.parseInt()
: 2進数および8進数リテラル ただし、Number.parseInt()
は2進数または8進数リテラルを特別にサポートしていません!
> Number.parseInt('0b111')
0
> Number.parseInt('0b111', 2)
0
> Number.parseInt('111', 2)
7
> Number.parseInt('0o10')
0
> Number.parseInt('0o10', 8)
0
> Number.parseInt('10', 8)
8
これらの種類のリテラルを解析する場合は、Number()
を使用する必要があります
> Number('0b111')
7
> Number('0o10')
8
Number.parseInt()
は、特別なプレフィックスがなく、パラメータradix
が指定されている限り、異なる基数を持つ数値で正常に機能します
> Number.parseInt('111', 2)
7
> Number.parseInt('10', 8)
8
Number
プロパティ このセクションでは、ECMAScript 6でコンストラクターNumber
が取得した新しいプロパティについて説明します。
4つの数値関連関数はすでにグローバル関数として利用可能であり、メソッドとしてNumber
に追加されました:isFinite
とisNaN
、parseFloat
とparseInt
。それらはすべてグローバル関数とほぼ同じように機能しますが、isFinite
とisNaN
は、特にisNaN
にとって重要なことですが、引数を数値に強制変換しなくなりました。次のサブセクションでは、すべての詳細について説明します。
Number.isFinite(number)
Number.isFinite(number)
は、number
が実際の数値であるかどうかを判断します(Infinity
、-Infinity
、またはNaN
のいずれでもない)。
> Number.isFinite(Infinity)
false
> Number.isFinite(-Infinity)
false
> Number.isFinite(NaN)
false
> Number.isFinite(123)
true
このメソッドの利点は、パラメータを数値に強制変換しないことです(グローバル関数はそうしますが)
> Number.isFinite('123')
false
> isFinite('123')
true
Number.isNaN(number)
Number.isNaN(number)
は、number
が値NaN
であるかどうかを確認します。
このチェックを行うES5の1つの方法は、!==
を使用することです。
> const x = NaN;
> x !== x
true
より記述的な方法は、グローバル関数isNaN()
を使用することです。
> const x = NaN;
> isNaN(x)
true
ただし、この関数は数値以外を数値に強制変換し、結果がNaN
の場合にtrue
を返します(通常は望ましくありません)
> isNaN('???')
true
新しいメソッドNumber.isNaN()
は、引数を数値に強制変換しないため、この問題を抱えていません
> Number.isNaN('???')
false
Number.parseFloat
とNumber.parseInt
次の2つのメソッドは、同じ名前のグローバル関数とまったく同じように機能します。それらは完全性のためにNumber
に追加されました。これで、数値関連のすべての関数がそこで利用可能になりました。
Number.EPSILON
特に小数部では、JavaScriptで丸め誤差が問題になる可能性があります3。たとえば、0.1と0.2は正確に表現できず、それらを加算して0.3と比較すると(これも正確に表現できません)、そのことに気付きます。
> 0.1 + 0.2 === 0.3
false
Number.EPSILON
は、浮動小数点数を比較する際の妥当な誤差範囲を指定します。次の関数で示されているように、浮動小数点値を比較するためのより良い方法を提供します。
function
epsEqu
(
x
,
y
)
{
return
Math
.
abs
(
x
-
y
)
<
Number
.
EPSILON
;
}
console
.
log
(
epsEqu
(
0.1
+
0.2
,
0.3
));
// true
Number.isInteger(number)
JavaScriptには浮動小数点数(倍精度)しかありません。したがって、整数は単に小数部のない浮動小数点数です。
Number.isInteger(number)
は、number
が数値であり、小数部がない場合にtrue
を返します。
> Number.isInteger(-17)
true
> Number.isInteger(33)
true
> Number.isInteger(33.1)
false
> Number.isInteger('33')
false
> Number.isInteger(NaN)
false
> Number.isInteger(Infinity)
false
JavaScriptの数値には、53ビットの符号付き整数を表すのに十分なストレージスペースしかありません。つまり、範囲−253 < i < 253の整数iは安全です。それが正確に何を意味するのかは、すぐに説明します。次のプロパティは、JavaScriptの整数が安全かどうかを判断するのに役立ちます
Number.isSafeInteger(number)
Number.MIN_SAFE_INTEGER
Number.MAX_SAFE_INTEGER
安全な整数の概念は、JavaScript における数学的な整数の表現方法に焦点を当てています。範囲 (−253, 253) (下限と上限は含まない)では、JavaScript の整数は安全です。つまり、JavaScript の整数とそれが表す数学的な整数との間に一対一のマッピングが存在します。
この範囲を超えると、JavaScript の整数は安全でなくなります。つまり、2つ以上の数学的な整数が同じ JavaScript の整数として表現されます。例えば、253 から始まると、JavaScript は数学的な整数のうち、2つおきにしか表現できません。
> Math.pow(2, 53)
9007199254740992
> 9007199254740992
9007199254740992
> 9007199254740993
9007199254740992
> 9007199254740994
9007199254740994
> 9007199254740995
9007199254740996
> 9007199254740996
9007199254740996
> 9007199254740997
9007199254740996
したがって、安全な JavaScript の整数とは、単一の数学的な整数を一意に表す整数のことです。
Number
プロパティ 安全な整数の下限と上限を指定する2つの静的なNumber
プロパティは、次のように定義できます。
Number
.
MAX_SAFE_INTEGER
=
Math
.
pow
(
2
,
53
)
-
1
;
Number
.
MIN_SAFE_INTEGER
=
-
Number
.
MAX_SAFE_INTEGER
;
Number.isSafeInteger()
は、JavaScript の数値が安全な整数であるかどうかを判定し、次のように定義できます。
Number
.
isSafeInteger
=
function
(
n
)
{
return
(
typeof
n
===
'number'
&&
Math
.
round
(
n
)
===
n
&&
Number
.
MIN_SAFE_INTEGER
<=
n
&&
n
<=
Number
.
MAX_SAFE_INTEGER
);
}
指定された値n
に対して、この関数は最初にn
が数値であり、かつ整数であるかどうかをチェックします。両方のチェックが成功した場合、n
が MIN_SAFE_INTEGER
以上であり、かつ MAX_SAFE_INTEGER
以下であれば、n
は安全です。
整数を使用した計算の結果が正しいことを確認するにはどうすればよいでしょうか?例えば、次の結果は明らかに正しくありません。
> 9007199254740990 + 3
9007199254740992
2つの安全なオペランドがありますが、結果は安全ではありません。
> Number.isSafeInteger(9007199254740990)
true
> Number.isSafeInteger(3)
true
> Number.isSafeInteger(9007199254740992)
false
次の結果も正しくありません。
> 9007199254740995 - 10
9007199254740986
今回は、結果は安全ですが、オペランドの1つが安全ではありません。
> Number.isSafeInteger(9007199254740995)
false
> Number.isSafeInteger(10)
true
> Number.isSafeInteger(9007199254740986)
true
したがって、整数演算子op
を適用した結果が正しいと保証されるのは、すべてのオペランドと結果が安全な場合のみです。より形式的に言えば、
isSafeInteger
(
a
)
&&
isSafeInteger
(
b
)
&&
isSafeInteger
(
a
op
b
)
は、a op b
が正しい結果であることを意味します。
Math
機能 グローバルオブジェクトMath
には、ECMAScript 6 でいくつかの新しいメソッドがあります。
Math.sign(x)
Math.sign(x)
は、以下を返します。
x
が負の数(-Infinity
を含む)の場合、-1
。x
がゼロの場合、0
4。x
が正の数(Infinity
を含む)の場合、+1
。x
が NaN
または数値でない場合、NaN
。例
> Math.sign(-8)
-1
> Math.sign(3)
1
> Math.sign(0)
0
> Math.sign(NaN)
NaN
> Math.sign(-Infinity)
-1
> Math.sign(Infinity)
1
Math.trunc(x)
Math.trunc(x)
は、x
の小数部分を削除します。他の丸めメソッド Math.floor()
、Math.ceil()
、Math.round()
を補完します。
> Math.trunc(3.1)
3
> Math.trunc(3.9)
3
> Math.trunc(-3.1)
-3
> Math.trunc(-3.9)
-3
Math.trunc()
は、次のように実装できます。
function
trunc
(
x
)
{
return
Math
.
sign
(
x
)
*
Math
.
floor
(
Math
.
abs
(
x
));
}
Math.cbrt(x)
Math.cbrt(x)
は、x
の立方根(∛x)を返します。
> Math.cbrt(8)
2
小さな分数は、ゼロの後に続く場合、より正確に表現できます。これを小数で示します(JavaScript の数値は内部的に基数 2 で格納されますが、同じ推論が適用されます)。
基数 10 の浮動小数点数は、内部的に 仮数 × 10指数 として表されます。仮数には、小数点記号の前に単一の数字があり、指数は必要に応じて小数点記号を「移動」します。つまり、小さな分数を内部表現に変換する場合、小数点記号の前のゼロは、小数点記号の前の 1 よりも小さい仮数につながります。例えば
精度に関しては、ここで重要な量は、有効数字で測定された仮数の容量です。そのため、(A)は(B)よりも高い精度が得られます。
さらに、JavaScript はゼロに近い数値(例えば、小さな分数)をより高い精度で表します。
Math.expm1(x)
Math.expm1(x)
は Math.exp(x)-1
を返します。Math.log1p()
の逆関数です。
したがって、このメソッドは、Math.exp()
の結果が 1 に近い場合に、より高い精度を提供します。次のインタラクションで、2つの違いを確認できます。
> Math.expm1(1e-10)
1.00000000005e-10
> Math.exp(1e-10)-1
1.000000082740371e-10
前者がより良い結果です。これは、任意の精度の浮動小数点数(「ビッグフロート」)用のライブラリ(例えば、decimal.js)を使用することで検証できます。
>
var
Decimal
=
require
(
'decimal.js'
)
.
config
(
{
precision
:
50
}
);
>
new
Decimal
(
1e-10
)
.
exp
()
.
minus
(
1
)
.
toString
()
'1.000000000050000000001666666666708333333e-10'
Math.log1p(x)
Math.log1p(x)
は Math.log(1 + x)
を返します。Math.expm1()
の逆関数です。
したがって、このメソッドを使用すると、1に近いパラメータをより高い精度で指定できます。次の例は、その理由を示しています。
次の 2 つの log()
の呼び出しは同じ結果になります。
> Math.log(1 + 1e-16)
0
> Math.log(1 + 0)
0
対照的に、log1p()
は異なる結果を生成します。
> Math.log1p(1e-16)
1e-16
> Math.log1p(0)
0
Math.log1p()
の精度が高い理由は、1 + 1e-16
の正しい結果が 1e-16
よりも多くの有効数字を持つためです。
> 1 + 1e-16 === 1
true
> 1e-16 === 0
false
Math.log2(x)
Math.log2(x)
は、底が 2 の対数を計算します。
> Math.log2(8)
3
Math.log10(x)
Math.log10(x)
は、底が 10 の対数を計算します。
> Math.log10(100)
2
Emscripten は、後に asm.js によって採用されたコーディングスタイルを開拓しました。仮想マシン(バイトコードを考えてください)の操作は、JavaScript の静的なサブセットで表現されます。そのサブセットは、JavaScript エンジンによって効率的に実行できます。C++ からのコンパイルの結果である場合、ネイティブ速度の約 70% で実行されます。
次のMath
メソッドは、主に asm.js および同様のコンパイル戦略をサポートするために追加されたものであり、他のアプリケーションにはそれほど役に立ちません。
Math.fround(x)
Math.fround(x)
は、x
を 32 ビット浮動小数点値(float
)に丸めます。asm.js が、エンジンに内部的に float
値を使用するように指示するために使用されます。
Math.imul(x, y)
Math.imul(x, y)
は、2 つの 32 ビット整数 x
と y
を乗算し、結果の下位 32 ビットを返します。これは、JavaScript 演算子を使用して結果を 32 ビットに戻すことでシミュレートできない、唯一の 32 ビット基本数学演算です。例えば、idiv
は次のように実装できます。
function
idiv
(
x
,
y
)
{
return
(
x
/
y
)
|
0
;
}
対照的に、2つの大きな 32 ビット整数を乗算すると、下位ビットが失われるほど大きな倍精度値が生成される可能性があります。
Math.clz32(x)
x
の先頭のゼロビット数をカウントします。
> Math.clz32(0b01000000000000000000000000000000)
1
> Math.clz32(0b00100000000000000000000000000000)
2
> Math.clz32(2)
30
> Math.clz32(1)
31
なぜこれが興味深いのでしょうか?Miro Samek による「高速、決定的、移植可能な先頭ゼロのカウント」からの引用です。
整数数値の先頭のゼロをカウントすることは、サウンドやビデオ処理におけるサンプルの正規化など、多くの DSP アルゴリズムにおいて重要な操作であり、リアルタイムスケジューラで実行準備完了の最優先タスクをすばやく見つけるためにも重要です。
Math.sinh(x)
x
の双曲線正弦を計算します。Math.cosh(x)
x
の双曲線余弦を計算します。Math.tanh(x)
x
の双曲線正接を計算します。Math.asinh(x)
x
の逆双曲線正弦を計算します。Math.acosh(x)
x
の逆双曲線余弦を計算します。Math.atanh(x)
x
の逆双曲線正接を計算します。Math.hypot(...values)
> Math.hypot(3, 4)
5
JavaScript の整数は 53 ビットの範囲を持っています。64 ビット整数が必要な場合は常に問題になります。例えば、Twitter は JSON API で、ツイート ID が大きくなりすぎたときに、整数から文字列に切り替える必要がありました。
現時点では、その制限を回避する唯一の方法は、高精度の数値(ビッグイントまたはビッグフロート)用のライブラリを使用することです。このようなライブラリの 1 つが decimal.js です。
JavaScript でより大きな整数をサポートする計画は存在しますが、実現するまでには時間がかかる可能性があります。