blog

es6 ラーニング - 数値の展開

ES6では、2進数と8進数の新しい記述方法が提供され、それぞれ接頭辞0bと0oで示されます。 ES5から、8進数はストリクトモードでは接頭辞0で表すことができなくなり、ES6ではさらに接頭辞0oを使用...

Mar 2, 2020 · 9 min. read
シェア

進数と8進数の表現

ES6には、2進数と8進数の新しい記述方法があり、それぞれ接頭辞0bと0oで示されます。

0b === 503 // true 0o767 === 503 // true

ES5から、厳密モードでは接頭辞を8進数で指定することができなくなり、ES6ではさらに接頭辞0oを使用することが指定されました。

接頭辞が 0b や 0o の文字列値を 10 進数に変換するには、Number メソッドを使用します。

Number('0b111') // 7 Number('0o10') // 8

Number.isFinite() Number.isNaN()

Number.isFinite()は、値が有限かどうか、つまり無限大でないかどうかをチェックするために使用します。

Number.isFiniteは、引数の型が数値でない場合、常にfalseを返します。

Number.isNaN()は、値がNaNかどうかをチェックするために使用されます。

Number.isNaNは、パラメータの型がNaNでない場合、常にfalseを返します。

従来のグローバル・メソッドである isFinite() や isNaN() との違いは、従来のメソッドはまず Number() を呼び出して非数値を数値に変換してから判定を行うのに対して、この 2 つの新しいメソッドは数値に対してのみ有効で、非数値の Number.isFinite() は常に false を返し、非数値の Number.isNaN() は常に true、非 NaN は常に false を返します。NaNはtrueのみを返し、非NaNは常にfalseを返します。

Number.parseInt() Number.parseFloat()

ES6は、グローバルメソッドparseInt()とparseFloat()をNumberオブジェクトの上に移植し、動作はまったく同じにしています。

parseInt('12.34'); parseFloat('123.45#'); Number.parseInt('12.34'); Number.parseFloat('123.45#');

この目的は、グローバルメソッドの数を徐々に減らし、言語を徐々にモジュール化していくことです。

Number.isInteger()

Number.isInteger() は、値が整数であるかどうかを判定するために使用します。

Number.isInteger(0x19); Number.isInteger(25.1);

JavaScriptでは、整数と浮動小数点数は同じように格納されます。したがって、25と25.0は同じ値とみなされます。

引数が数値でない場合、Number.isIntegerはfalseを返します。

データ精度の要求が高い場合、Number.isInteger() を使用して値が整数かどうかを判定することは推奨されません。

.EPSILON

ES6では、Numberオブジェクトの上に小さな新しい定数Number.EPSILONが追加され、仕様によると、これは1と1より小さい浮動小数点数の差を表します。

64 ビット浮動小数点数の場合、1 より大きい最小の浮動小数点数は、2 進数の 1.00 ~ 100 に相当し、小数点の後に 51 個の連続したゼロが付きます。この値を1から引くと、2の-52乗に等しくなります。

Number.EPSILON === Math.pow(0x2, -0x34); Number.EPSILON; Number.EPSILON.toFixed(0x14);

Number.EPSILONはJavaScriptが表現できる最小の精度です。この値より小さい誤差は意味がない、つまり誤差がないとみなされます。

Number.EPSILONを使用して「許容誤差」を設定できます。EPSILONは "許容誤差 "を設定するために使用することができます。 例えば、誤差は2の-50乗に設定されます。つまり、2つの浮動小数点数の差がこの値より小さい場合、2つの浮動小数点数は等しいとみなされます。

したがって、Number.EPSILONの本質は、許容できる最小限の誤差です。

安全な整数とNumber.isSafeInteger()

Number.MAX_SAFE_INTEGERNumber.MIN_SAFE_INTEGERES6では、この範囲の上限と下限を表す定数と下限を導入しました。

Number.MAX_SAFE_INTEGER === Math.pow(2, 53) - 1 // true Number.MAX_SAFE_INTEGER === // true Number.MIN_SAFE_INTEGER === -Number.MAX_SAFE_INTEGER // true Number.MIN_SAFE_INTEGER === - // true

上のコードでは、JavaScriptが正確に表現できることの限界を見ることができます。

Number.isSafeInteger()は、整数がこの範囲内にあるかどうかを判断するために使われます。

この関数を実際に使うときには注意が必要です。演算結果だけでなく、演算に関係する各値も含めて、演算結果が安全な整数の範囲内に収まっていることを確認してください。

数学オブジェクトの拡張

ES6では、Mathオブジェクトに新たに17の数学関連メソッドが追加されました。これらのメソッドはすべて静的で、Math オブジェクトに対してのみ呼び出すことができます。

Math.trunc()

Math.trunc メソッドは、数値の小数部分を取り除き、整数部分を返すために使用されます。

数値以外の値の場合、Math.trunc は内部的に Number メソッドを使用して最初に数値に変換します。

Math.trunc('') // 123 Math.trunc(true) //1

NULL値や整数に切り詰められない値に対してはNaNを返します。

Math.sign()

Math.signメソッドは、数値が正、負、ゼロのいずれであるかを判定するために使用されます。数値以外の値の場合は、まず数値に変換されます。

5つの値が返されます。

  • 引数が正の場合、+1 を返します;
  • パラメータが負の場合は -1 を返します;
  • パラメータは 0 が返されます;
  • パラメータが -0 の場合、-0 を返します。
  • それ以外の値の場合はNaNを返します。

引数が非数値の場合、自動的に数値に変換されます。数値に変換できない場合は NaN を返します。

Math.cbrt()

Math.cbrt() メソッドは、数値の立方根を計算するために使用します。

Math.cbrt(-1) // -1 Math.cbrt(2) // 1.

数値以外の値についても、Math.cbrt() メソッドは内部的に、最初に Number() メソッドを使用して数値に変換します。

Math.clz32()

Math.clz32()メソッドは、引数を32ビットの符号なし整数に変換し、この32ビット値の中にいくつの先行ゼロがあるかを返します。

Math.clz32(0) // 32 Math.clz32(1) // 31 Math.clz) // 1

上記のコードでは、0の2進数は0なので、32個の先行ゼロがあります。1の2進数は0b1で、1ビットしか占有しないので、32ビットに31個の先行ゼロがあります。1000の2進数は0b1111101000で、10ビット占有するので、32ビットに22個の先行ゼロがあります。

左シフト演算子はMath.clz32メソッドに直接関係しています。

小数の場合、Math.clz32 メソッドは整数部分のみを考慮します。

NULL 値やその他の型の値については、Math.clz32 メソッドで数値に変換してから計算します。

Math.imul()

Math.imul メソッドは、2 つの数値を掛け算した結果を 32 ビット符号付き整数として返します。

Math.imul(0x2, 0x4); Math.imul(-0x1, 0x8); Math.imul(-0x2, -0x2);

最後の32ビットだけを考慮する場合、ほとんどの場合、Math.imul(a, b)はa * bと同じ結果を与えます。つまり、このメソッドは|0|の効果と同等です。このメソッドを導入する必要がある理由は、JavaScript には精度制限があり、2の53乗より大きな値は正確に表現できないからです。つまり、非常に大きな数値を掛け合わせる場合、低い方の値は不正確であることが多く、Math.imulメソッドは正しい低い方の値を返します。

Math.round()

Math.round メソッドは、32 ビット単精度浮動小数点型の数値を返します。

32ビット単精度フォーマットの場合、数値精度は24バイナリビットなので、-224から224までの整数の場合、戻り値は引数そのものと同じになります。

Math.fround(0x0); Math.fround(0x1); Math.fround(0x2 ** 0x18 - 0x1);

パラメータの絶対値が224より大きい場合、返される結果は精度を失い始めます。

Math.round メソッドの主な機能は、64 ビット倍精度浮動小数点数を 32 ビット単精度浮動小数点数に変換することです。10進数の精度が2進数24桁を超える場合、戻り値は元の値とは異なります。

Math.hypot()

Math.hypotメソッドは、すべての引数の2乗の和の平方根を返します。

Math.hypot(0x3, 0x4, 0x5); Math.hypot(); Math.hypot(NaN);

上のコードでは、3の2乗と4の2乗を足すと5の2乗になります。

引数が数値でない場合は、Math.hypot メソッドが数値に変換します。引数が数値に変換できない場合は常に NaN が返されます。

ES6では、新たに4つの対数相関法が追加されました。

Math.expm1()

Math.expm1(x)はex - 1を返し、これはMath.exp(x) - 1です。

Math.log1p()

Math.log1p(x) メソッドは、1 + x の自然対数、すなわち Math.log(1 + x) を返します。x が -1 より小さい場合は NaN を返します。

Math.log10()

Math.log10(x)は底10のxの対数を返します。xが0より小さい場合はNaNを返します。

Math.log2()

Math.log2(x)はxの底2の対数を返します。xが0未満の場合はNaNを返します。

双曲線関数法

ES6では、新たに6つの双曲線関数メソッドが追加されました。

  • Math.sinh(x)はxの双曲線正弦を返します。
  • Math.cosh(x)はxの双曲余弦を返します。
  • Math.tanh(x)はxの双曲線の正接を返します。
  • Math.asinh(x)はxの逆ハイパーボリックサインを返します。
  • Math.acosh(x)はxの逆ハイパーボリックコサインを返します。
  • Math.atanh(x)はxの逆双曲線正接を返します。

指数演算子

ES2016 には新しい指数演算子が追加されました。

const c = n; const foo = 0x9n; c * foo; Number(c) * Number(foo);

この演算子の特徴は、一般的な左結合ではなく右結合であることです。複数の指数演算子を併用する場合は、右端から数えます。

指数演算子は、等号と組み合わせて新しい代入演算子を作ることができます。

BigInt データ型

ES2020では、この問題を解決するために、ECMAScriptの8番目のデータ型であるBigIntという新しいデータ型を導入しています。bigIntは整数を表現するためにのみ使用され、桁数の制限はないため、任意の桁数の整数を正確に表現することができます。

BigInt(0x7b); BigInt('123'); BigInt(false); BigInt(!false);

Number型と区別するために、BigInt型のデータの末尾にはnを付けなければなりません。

BigIntは様々なバイナリ表現も可能で、全て接尾辞にnが付きます。

BigIntと通常の整数は2種類の値であり、互いに等しくはありません。

typeof 演算子は BigInt 型のデータに対して bigint を返します。

BigIntは負符号を使うことができますが、正符号を使うことはできません。

JavaScriptは以前、70の階乗を計算することができませんでした。

BigInt

JavaScriptは、BigInt型の値を生成するコンストラクタとして使用できるBigIntオブジェクトをネイティブに提供しています。変換ルールは、他の型の値を BigInt に変換する Number() と基本的に同じです。

BigInt.prototype.toString()

BigInt()コンストラクタには引数が必要で、引数は通常の値に変換可能でなければなりません。

小数のパラメータもエラーになります。

BigInt オブジェクトは、Object オブジェクトから 2 つのインスタンスメソッドを継承しています。

  • BigInt.prototype.valueOf()
  • BigInt.prototype.toLocaleString()

また、Numberオブジェクトのインスタンスメソッドも継承しています。

  • BigInt.asUintN(width, BigInt)

さらに、3つの静的メソッドが用意されています。

  • BigInt.asIntN(width, BigInt): 与えられた BigInt は、0 から 2width - 1 の間の値に変換されます。
  • BigInt.parseInt(string[, radix]): 与えられた BigInt は、-2width - 1 から 2width - 1 - 1 の間の値に変換されます。
  • DataView.prototype.getBigInt64()Number.parseInt()に近似し、文字列を指定されたバイナリのBigIntに変換します。

BigInt.asIntN()およびBigInt.asUintN()で指定されたビット数が、値そのもののビット数より少ない場合は、ヘッダのビットが丸められます。

DataView.prototype.getBigUint64()0b === 503 // true 0o767 === 503 // trueBigIntはバイナリ配列のために、BigUint64ArrayとBigInt64Arrayという2つの新しい型を追加し、どちらも64ビットのBigIntを返します。 DataViewオブジェクトのインスタンスメソッドと、BigIntもBigIntを返します。

変換ルール

Boolean()、Number() および String() メソッドを使用して、BigInt を Boolean、Numeric および String 型に変換できます。


上のコードでは、最後の例で接尾辞nが文字列に変換されると消えていることに注意してください。

また、逆演算子は BigInt をブール値に変換することもできます。

数学演算

BigInt 型には、Number 型の動作と同じ +, -, *, ** という 4 つの二項演算子があります。除算演算子 / は、小数部を四捨五入して整数を返します。


ほとんどすべての数値演算子が BigInt で使えますが、2 つの例外があります。

  • 符号なし右シフト演算子 >>>>
  • 単項正演算子

上記の2つの演算子は、BigIntで使用すると間違っています。前者は >>> 演算子は符号なしですが、BigInt は常に符号付きなので、この演算は無意味であり、右シフト演算子 >> と全く同じだからです。後者は単項演算子+がasm.js内部では常にNumberを返すためで、asm.jsを壊さないために+1nはエラーを報告するように指定されています。

BigInt は通常の値と混在させることはできません。

引数がNumber型であると期待される標準ライブラリ関数がBigIntを受け取った場合、エラーが報告されます。

asm.jsの内部では、数値に従うと32ビットの整数が返されます。Number型と演算を混ぜてはいけないというルールに従えば、BigIntはエラーを報告します。

その他の事業

BigIntに対応するブール値はNumberと同じです。つまり、0nはfalseになり、その他の値はtrueになります。

比較演算子や等式演算子を使えば、BigInt を他の型の値と混ぜても精度が落ちません。

BigIntと文字列が混在している場合は、まず文字列に変換されてから演算が行われます。

Read next

unsafe]goで文字列のバイト配列を変更するには?

下にあるポインタを操作できるようにするポインタ 多くの高級言語と同様に、go言語の下にある文字列はバイト配列を指しており、これを変更することはできません。しかし、unsafeパッケージを通して文字列の下にあるポインタを操作することで、文字列の内容を変更するという目的を達成することができます。このようなC言語でのポインタの操作の修正はよく見られます。

Mar 1, 2020 · 1 min read