例えばJavaScriptで「100000000000000000000000000000000
」みたいなデカイ数値や「0.00000001
」みたいな小さい数値を扱っていると、表示した時に1e+32
や1e-8
みたいな指数表記になってしまう。
console.log(100000000000000000000000000000000);
// 1e+32
console.log(0.00000001);
// 1e-8
そして恐るべきことに、この指数表記を少数表記に変換する関数が標準では存在しない。 文字列に型変換しても、指数表記になってしまう。
console.log(String(100000000000000000000000000000000));
// 1e+32
console.log(String(0.00000001));
// 1e-8
さらに、ユーザーランドの実装も意外と見つからない。ググっても思うものが出てこない。 なので、書きました:
/*
* 巨大数の場合
*/
/* 普通に数値を表示すると指数表記になる */
console.log(100000000000000000000000000000000);
// 1e+32
/* 文字列に型変換した場合。この場合も指数表記になってしまう */
console.log(String(100000000000000000000000000000000));
// 1e+32
/* 今回作った関数`Num2FracStr`を使用した場合。ちゃんと整数表記になる */
console.log(Num2FracStr(100000000000000000000000000000000));
// 100000000000000000000000000000000
/* 数値を指数表記で指定した場合。もちろん整数表記になる */
console.log(Num2FracStr(1e+32));
// 100000000000000000000000000000000
/*
* 微少数の場合
*/
/* 普通に数値を表示した場合。やっぱり指数表記になる */
console.log(0.00000001);
// 1e-8
/* 文字列に型変換しても解決しないのは上と同様 */
console.log(String(0.00000001));
// 1e-8
/* `Num2FracStr`を使用した場合。ちゃんと小数表記になる */
console.log(Num2FracStr(0.00000001));
// 0.00000001
/* この場合も、もちろん少数表記になる */
console.log(Num2FracStr(1e-8));
// 0.00000001
/*
* 普通の数値を文字列化する用途にも使える。
* Note: この用途で`Num2FracStr`を使うつもりなら、`String()`で直接型変換しよう。`String()`のほうが何百億倍もマシ。
*/
/* “生命、宇宙、そして万物についての究極の疑問の答え”(42)を変換すると、普通に文字列に変わる。 */
console.log(Num2FracStr(42));
// 42
/* 絶対零度を変換してみる。もちろん、普通に文字列化される。 */
console.log(Num2FracStr(-459.67));
// -459.67
/* NaNも数値の一種なので、変換できる */
console.log(Num2FracStr(NaN));
// NaN
/* 無限も当然変換できる */
console.log(Num2FracStr(Infinity));
// Infinity
/*
* 数値だけではなく、文字列も指定できる。
* ただし、文字列の場合は厳格な書式判定が行われるため、"NaN"や"Infinity"のような文字列は拒否される。
*/
/* さっきのデカイ数を文字列で指定してみる */
console.log(Num2FracStr("1e+32"));
// 100000000000000000000000000000000
/* さっきの小さい数を文字列で指定してみる */
console.log(Num2FracStr("1e-8"));
// 0.00000001
/* 普通の数値も指定可能。この場合はそのまま出力される */
console.log(Num2FracStr("18446744073709552000"));
// 18446744073709552000
/* 余計なゼロはちゃんと取り除かれる */
console.log(Num2FracStr("0000003.141592653589790000"));
// 3.14159265358979
/* 指数表記のゼロも取り除かれる */
console.log(Num2FracStr("00000002718281828459e-00012"));
// 2.718281828459
/* 文字列の場合、NaNは指定できない */
console.log(Num2FracStr("NaN"));
// Uncaught Error: Invalid Number: "NaN"
/* 同様に、Infinityも指定できない */
console.log(Num2FracStr("Infinity"));
// Uncaught Error: Invalid Number: "Infinity"
/* 漢数字も指定できない */
console.log(Num2FracStr("九十ニ"));
// Uncaught Error: Invalid Number: "九十ニ"
/* 全角数値を通すほど甘くはない */
console.log(Num2FracStr("2017"));
// Uncaught Error: Invalid Number: "2017"
/* 数値ですらないんだから当然アウト */
console.log(Num2FracStr("にっぽん"));
// Uncaught Error: Invalid Number: "にっぽん"
/*
* 文字列処理なので、数値だと桁あふれで消えてしまうような大きい数すら表示できる。
* ただし、文字列で指定しないとうまくいかない。
*/
/* 普通に数値を表示すると指数表記になる */
console.log(1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875e-17);
// 1.4142135623730952e-17
/* 文字列に型変換してみてもやっぱりダメ */
console.log(String(1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875e-17));
// 1.4142135623730952e-17
/* 数値で指定した場合。一応少数表記にはなるが、途中からケタが消滅してしまっている。上をよく見ると分かる通り、実は数値の時点で既にケタが消えている */
console.log(Num2FracStr(1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875e-17));
// 0.000000000000000014142135623730952
/* 文字列で指定した場合。ちゃんとケタが消えずに少数表記になる */
console.log(Num2FracStr("1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875e-17"));
// 0.000000000000000014142135623730950488016887242096980785696718753769480731766797379907324784621070388503875
文字列操作でゴリ押ししてる感じのやつなので、パフォーマンスは保証しません。 また、ECMAScript 2017で書いているため、最新のブラウザでないと動きません。 Google Chrome 62で動作確認はしていますが、他のブラウザでの動作は保証しません。