JavaScript では数値として10進数、16進数、実数、浮動小数等を使用できます。
12345 // 10進数の12345 1.23 // 実数の 1.23 1.23e4 // 1.23 × 10の4乗 1.23E4 // 1.23 × 10の4乗
0x(または0X)で始まる数字は16進数と解釈されます。
0xff88 // 16進数のFF88 0Xff88 // 16進数のFF88
以前は 0(ゼロ) で始まる数値を8進数としていましたが廃止され、代わりに ES2015(ES6) では、0o(ゼロオー) で始まる8進数や、0b(ゼロビー) で始まる2進数がサポートされました。Chrome, Firefox, Edge ではサポートされていますが、IE11 ではサポートされていません。
0b1101 // 2進数の1101(=10進数の13) 0B1101 // 2進数の1101(=10進数の13) 0o755 // 8進数の755(=10進数の493) 0O755 // 8進数の755(=10進数の493)
0(ゼロ)で始まる数字は、後に続く数字がすべて 0~7 であれば 8進数として、8~9 を含んでいれば10進数として解釈されます。
0755 // 8進数の755(=10進数の493) 0855 // 10進数の855
ES2121 では数値の桁区切りとして _ を使用できるようになりました。計算では _ は無視されます。
1_234_567 0xff88_ff88
数値は内部的には、IEEE754 に準拠した64ビット倍精度浮動小数点数として扱われます。
value を値として持つ数値オブジェクトを生成します。「すべての型をオブジェクトタイプとして実装する」というポリシーで用意されていますが、あまり用いられることはありません。数値と数値オブジェクトは厳密には異なります。次項で説明する 「xx = Number(value)」は、文字列を数値に変換するビルトイン関数で、new Number() とは異なります。
console.log(typeof(new Number(123))); // object(数値オブジェクト) console.log(typeof(Number(123))); // number(数値) console.log(typeof(123)); // number(数値)
文字列を数値に変換するにはビルトイン関数の parseInt()、parseFloat()、Number() を用いるか、0 を減算することによっても、変換できます。
str = "123.4"; num1 = Number(str); // 数値123.4に変換する num2 = parseInt(str); // 整数123に変換する num3 = parseFloat(str); // 数値123.4に変換する num4 = str - 0; // 数値123.4に変換する
0 を減算すると数値に変換できますが、0 を加算すると文字列の連結になってしまうため、数値には変換できない点に注意してください。
str = "123.4";
num5 = str + 0; // 文字列 "123.40" になってしまう
同様に、フォームから取得した値(文字列)に対して加算を行うと 123 + 100 = 223 ではなく、"123" + "100" = "123100" という文字列連結演算になってしまうので注意してください。
<script>
function func() {
console.log(document.form1.text1.value + 100); // "123" + "100" = "123100" となってしまう
}
</script>
<form name="form1">
<input type="text" name="text1" value="123">
<input type="button" value="OK" onclick="func()">
</form>
parseInt() は文字列 str を、整数に変換します。parseFloat() は浮動小数点数に変換します。元々は parseFloat() や parseInt() などグローバル関数として定義されていましたが、グローバル関数縮小化の流れから、ES2015(ES6) からは Number.parseFloat() や Number.parseFloat() などのクラスメソッドとして定義されています。動作は同等です。ただし、IE11 はクラスメソッド版をまだサポートしていないため、当面はグローバル関数版を使用することになります。
console.log(parseInt("123")); // => 123 (整数文字→整数) console.log(parseFloat("123.45")); // => 123.45 (浮動小数点数) console.log(parseFloat("1.2345e3")); // => 123.45 (浮動小数点数)
parseInt() の radix には、数値文字を何進数とみなすかを指定します。
console.log(parseInt("10", 10)); // => 10 (10進数) console.log(parseInt("10", 16)); // => 16 (16進数) console.log(parseInt("10", 2)); // => 8 (8進数) console.log(parseInt("10", 8)); // => 2 (2進数)
parseInt() の第一引数は文字列であることを想定しています。文字列以外の型、例えば、0.0000005 を渡した場合、一度文字列の "5e-7" に変換され、この文字列が解釈されるため、結果が 5 となってしまったりしますので注意してください。
console.log(parseInt(0.000005)); # "0.000005" → 0 console.log(parseInt(0.0000005)); # "5e-7" → 5
0 で始まる文字列を指定する場合は注意が必要です。0x は16進数とみなされますが、0b や 0o はサポートされていません。0 + 数値の場合は、ブラウザやバージョンによって 10進数とみなされたり、8進数とみなされたりするようです。
console.log(parseInt("0x10")); // => 16 (16進数) console.log(parseInt("0b10")); // => 0 (2進数としては解釈されない) console.log(parseInt("0o10")); // => 0 (8進数としては解釈されない) console.log(parseInt("010")); // => 10 or 8 (10進数とみなされたり8進数とみなされたり)
JavaScript の 数値 と同じ解釈を行うには、下記の様にします。
console.log(myParseInt("10")); // => 10 (10進数) console.log(myParseInt("0x10")); // => 16 (16進数) console.log(myParseInt("0b10")); // => 2 (2進数) console.log(myParseInt("0o10")); // => 8 (8進数) console.log(myParseInt("017")); // => 15 (8進数) console.log(myParseInt("018")); // => 18 (10進数) function myParseInt(str) { var radix = 10; if (str.match(/^0x[0-9a-f]+$/i)) { radix = 16; str = str.substring(2); } else if (str.match(/^0b[01]+$/i)) { radix = 2; str = str.substring(2); } else if (str.match(/^0o[0-7]+$/i)) { radix = 8; str = str.substring(2); } else if (str.match(/^0[0-7]+$/)) { radix = 8; str = str.substring(1); } else if (str.match(/^[0-9]+$/)) { radix = 10; } else { return Number.NaN; } return parseInt(str, radix); }
NaN および Number.NaN は、無効な数値を示す特別値です。下記など、結果を数値で表すことができない数値を求めようとした場合、結果が NaN となります。
console.log(NaN); // => NaN console.log(Number.NaN); // => NaN console.log(0 / 0); // => NaN console.log(parseInt("ABC")); // => NaN console.log(Math.sqrt(-1)); // => NaN
NaN は == や === などの比較演算子で比較することができません。結果が NaN となったか否かは、isNaN() グローバル関数、または ES2015(ES6) で規定された Number.isNaN() クラスメソッドを用います。両者の動作は多少異なります。isNaN() は数値変換により NaN と判定される値をすべて true と判定しますが、Number.isNaN() はすでに NaN であると判定された値のみを true と判定します。
console.log(isNaN(NaN)); // => true console.log(Number.isNaN(NaN)); // => true console.log(isNaN(0 / 0)); // => true console.log(Number.isNaN(0 / 0)); // => 演算した結果を検証するので true console.log(isNaN("ABC")); // => "ABC" を数値変換すると NaN になるので true console.log(Number.isNaN("ABC")); // => まだ NaN になっていないので false
MAX_VALUE は利用可能な最大値(約 1.79769e308)。MIN_VALUE は利用可能な最小値(約5e-324)を示します。
xx = 1.8 * 1.0e308; if (xx >= Number.MAX_VALUE) { alert("計算可能な範囲を超えました"); }
POSITIVE_INFINITY は正の無限大を示す特別な数値。NEGATIVE_INFINITY は負の無限大を示す特別な数値を示します。乗算などの演算が、JavaScript で扱える値の範囲を超えた場合をチェックすることができます。
xx = 1.8 * 1.0e308; if ((xx == Number.POSITIVE_INFINITY) || (xx == Number.NEGATIVE_INFINITY)) { alert("計算可能な範囲を超えました"); }
isFinite() や Number.isFinite() は、value が有効な数値(有理数)であることを検査します。isFinite() はグローバル関数、Number.isFinite() はクラスメソッドとして定義されていますが、同じ動きをします。
console.log(isFinite(1.23e999)); // => false console.log(isFinite(Infinity)); // => false console.log(isFinite(-Infinity)); // => false console.log(isFinite(NaN)); // => false console.log(isFinite(Number.NEGATIVE_INFINITY)); // => false console.log(isFinite(Number.POSITIVE_INFINITY)); // => false console.log(isFinite(0)); // => true console.log(isFinite(1.23e45)); // => true console.log(isFinite(Number.MAX_VALUE)); // => true console.log(isFinite(Number.MIN_VALUE)); // => true
isInteger() は、value が有効な整数、-MAX_VALUE ~ MAX_VALUE の間の整数であるかどうかを検査します。
console.log(Number.isInteger(1.798e308)); // => false (大きすぎ) console.log(Number.isInteger(1.797e308)); // => true console.log(Number.isInteger(-1.797e308)); // => true console.log(Number.isInteger(-1.798e308)); // => false (小さすぎ)
浮動小数では2進数を用いた近似値を用いるため、丸め誤差が発生します。下記の様に 0.1 と 0.2 を足しても正確な 0.3 にはなりません。
xx = 0.1 + 0.2; console.log(xx); // => 0.30000000000000004 console.log(xx == 0.3); // 当然結果は false となる
特に、演算を何度も繰り返していくと丸め誤差も積算されていきます。丸め誤差の問題を回避するには、bignumber.js などのライブラリを使用するか、計算の度に有効桁を考慮して四捨五入していくことをお勧めします。
xx = 0.0; yy = 0.0; for (var i = 0; i < 100000; i++) { xx = xx + 0.1; // 丸め誤差が積算していく yy = Math.round((yy + 0.1) * 100) / 100; // 小数第三位で四捨五入 } console.log(xx); // 10000.000000018848 (不正確) console.log(yy); // 10000 (正確)
Number.EPSILON は、1 と 1 より大きい浮動小数点の最小値との差を表します。簡単に言うと、1回の演算で発生する可能性のある丸め誤差を表します。約 2.22e-16、正確には 2 -52 を示します。丸め誤差を許容する比較を行うと下記の様になります。
xx = 0.1 + 0.2; console.log(xx); // => 0.30000000000000004 console.log(0.3 - Number.EPSILON); // => 0.29999999999999977 console.log(0.3 + Number.EPSILON); // => 0.3000000000000002 console.log((0.3 - Number.EPSILON <= xx) && (xx >= 0.3 + Number.EPSILON)); // true
Number.MIN_SAFE_INTEGER, Number.MAZ_SAFE_INTEGER は、丸め誤差なく正確に計算できる整数の最小値と最大値を示します。それぞれ、-253 + 1 および 253 - 1 を示します。数値がこの両者の範囲内にある整数であれば、丸め誤差なく演算することが可能です。
console.log(Number.MIN_SAFE_INTEGER); // => -9007199254740991 console.log(Number.MAX_SAFE_INTEGER); // => 9007199254740991
isSafeInteger() は、value が、丸め誤差なしに扱える整数、つまり、MIN_SAFE_INTEGER 以上 MAX_SAFE_INTEGER 以下の整数であるかどうかを検査します。
console.log(Number.isSafeInteger(9007199254740992)); // => false console.log(Number.isSafeInteger(9007199254740991)); // => true console.log(Number.isSafeInteger(-9007199254740991)); // => true console.log(Number.isSafeInteger(-9007199254740992)); // => false
toString() を用いて、数値を radix 進数(2~36。省略時は10)の文字列に変換することができます。例えば下記の例では、65535 を 16 進数を示す文字列 "ffff" に変換します。
xx = 65535; console.log(xx.toString(16));
number を 1.23e4 の様な指数表記の文字列に変換します。digit には小数以下の桁数を指定します。
var xx = 123456; console.log(xx.toExponential()); // => 1.23456e+5 console.log(xx.toExponential(2)); // => 1.23e+5
number を 1.23 の様な整数または固定小数点表記の文字列に変換します。digit には小数以下の桁数を指定します。
var xx = 1.234e5; console.log(xx.toFixed()); // => 123400 console.log(xx.toFixed(2)); // => 123400.00
number を precision で指定した有効桁の表記の文字列に変換します。
xx = 123456789; console.log(xx.toPrecision()); // => 123456789 console.log(xx.toPrecision(3)); // => 1.23e+8 xx = 1.23456789; console.log(xx.toPrecision(3)); // => 1.23 xx = 0.0000123456789; console.log(xx.toPrecision(3)); // => 0.0000123 xx = 1.23456789e30; console.log(xx.toPrecision(3)); // => 1.23e+30
ECMA-402 1st Edition では、カンマ区切りの数値を簡単にフォーマットできるようになりました。Chrome, Firefox, Safari, IE11 で利用可能です。詳細の説明は割愛しますが、オプションを指定することで、各国に応じた通貨記号を付加することなども可能です。
var ja = new Intl.NumberFormat("ja-JP"); console.log(ja.format(1234567.89)); // 1,234,567.89 (日本様式) var en = new Intl.NumberFormat("en-US"); console.log(en.format(1234567.89)); // 1,234,567.89 (米国様式) var de = new Intl.NumberFormat("de-DE"); console.log(de.format(1234567.89)); // 1.234.567,89 (ドイツ様式) var jpy = new Intl.NumberFormat("ja-JP", { style: 'currency', currency: 'JPY' }); console.log(jpy.format(1234567.89)); // ¥1,234,567.89 (日本円)
通常の Number 型は 2^53 の精度を持ちますが、ES2020 で追加された BigInt を用いると任意精度の整数を扱うことが可能となります。BigInt では整数の末尾に n を付加します。Number を BigInt に変換するには BigInt() を使用します。
console.log(123456789012345678901234567890n); // 123456789012345678901234567890n console.log(BigInt(12345)); // 12345n