JavaScript: 指数表現化境界

題名通りの企画です。普段は厳密に知る必要のない事ですが、深掘りしてみると想定外の事が起こった次第です。

```plain:整数
999999999999999809999～999999999999999934463 = 999999999999999900000
//ここから指数化される
999999999999999934464～1000000000000000065536 = 1e+21
1000000000000000065537～1000000000000000196607 = 1.0000000000000001e+21
1000000000000000196608 = 1.0000000000000003e+21

//Number.MAX_VALUEと等価になる最大値の羅列(309桁)
1.7976931348623157e+308 = 17976931348623158079372897140530341507993413271003782693617377
89804449682927647509466490179775872070963302864166928879109465
55547851940402630657488671505820681908902000708383676273854845
81771153176447573027006985557136695962284291481986083493647529
2719074168444365510704342711559699508093042880177904174497791

//上記より1大きくすると無限大
Infinity = 17976931348623158079372897140530341507993413271003782693617377
89804449682927647509466490179775872070963302864166928879109465
55547851940402630657488671505820681908902000708383676273854845
81771153176447573027006985557136695962284291481986083493647529
2719074168444365510704342711559699508093042880177904174497792
```
```js:309桁整数最大値求める処理(ごみ)
let A=Array(309).fill(0),a=0,z=A.length;
for(;a<z;a++)for(let b=9;A[a]=b--,+A.join``==Infinity;);
document.write(A.join``)
```
```plain:小数+正指数
//64bit浮動小数 最大値
01111111 11101111 11111111 11111111 11111111 11111111 11111111 11111111(2進)
= 1.79769313486231570815e+308(10進)
01111111 11110000 00000000 00000000 00000000 00000000 00000000 00000000(2進)
= Infinity
//JavaScript
1.7976931348623157e+308～1.7976931348623158e+308 = 1.7976931348623158e+308
1.7976931348623159e+308 = 1.79769313486231580794e+308 = Infinity

//長過ぎるので改行挿入
1.7976931348623157e+308 = 1.7976931348623158079372897140530341507993413271003782693617377
89804449682927647509466490179775872070963302864166928879109465
55547851940402630657488671505820681908902000708383676273854845
81771153176447573027006985557136695962284291481986083493647529
2719074168444365510704342711559699508093042880177904174497791e+308

Infinity = 1.7976931348623158079372897140530341507993413271003782693617377
89804449682927647509466490179775872070963302864166928879109465
55547851940402630657488671505820681908902000708383676273854845
81771153176447573027006985557136695962284291481986083493647529
2719074168444365510704342711559699508093042880177904174497792e+308
```
```plain:小数+負指数
//64bit浮動小数 0寄りの最小値
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001(2進)
= 4.94065645841246544177e-324(10進)
//JavaScript
2.4703282292062328e-324～7.4109846876186981e-324 = 5e-324
2.4703282292062327e-324 = 0
```
JavaScriptでは指数部が`-324`になると、表示される整数部は`5`のみである。小数部は表示されない(`5e-324`のみ)
```plain
0.000001 = 0.0000009999999999999998488689934190987163020736261387355625629425048828126
//ここから指数化で表示
9.999999999999997e-7 = 0.0000009999999999999998488689934190987163020736261387355625629425048828125
//0に等しい最大の数値(小数点以下324桁目が2、全1077桁)
0 = 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000002470328229206232720882843964341106861825299013071623822127928412503
37753635104375932649918180817996189898282347722858865463328355177969898199387398005390939063150356
59515570226392290858392449105184435931802849936536152500319370457678249219365623669863658480757001
58576926990370631192827955855133292783433840935197801553124659726357957462276646527282722005637400
64854999770965994704540208281662262378573934507363390079677619305775067401763246736009689513405355
37458516661134223766678604162159680461914467291840300530057530849048765391711386591646239524912623
65388187963623937328042389101867234849766823508986338858792562830275599565752445550725518931369083
6254779186948667994968324049705821028513185451396213837722826145437693412532098591327667236328125

//整数部 1以上
1 = 1.00000000000000011102230246251565404236316680908203125
1.0000000000000002 = 1.00000000000000011102230246251565404236316680908203126
```
```js:指数部が負で指数化され始める数値
let A=["0.000000",...Array(67).fill(0)],a=0,z=A.length;
for(;++a<z;)for(let b=9;A[a]=b--,!/e/.test(+A.join``););
document.write(A.join``)
```
```js:1に等しい最大の数値召喚
let A=["1.",...Array(53).fill(0)],a=0,z=A.length;
for(;++a<z;)for(let b=9;A[a]=b--,+A.join``>1;);
document.write(A.join``)
```
```js:0に等しい最大の数値召喚
let A=["0.",...Array(1075).fill(0)],a=0,z=A.length;
for(;++a<z;)for(let b=9;A[a]=b--,+A.join``;);
document.write(A.join``)
```
まとめて広範囲
```js:1～99と等価な最大値
for(let n=100;--n;){
	let A=[n+".",...Array(55).fill(0)],a=0,z=A.length;
	for(;++a<z;)for(let b=9;A[a]=b--,+A.join``>n;);
	document.write(A.join``,"<br>")
}
```
0に等しい**最大の数値は小数点以下1075桁**まで追い求める事ができた(驚愕)。ちなみに1076桁目からはずっと0が続く。なぜJavaScriptでそんな桁数まで比較できるのだろうか? JavaScriptは64bit浮動小数点数で実装しているはずだが、それだと全く精度が足りないはず…。
更に不可解なのは1と等しい最大の数値は小数点以下53桁で打ち切られる事だ。54桁目からはずっと0が続く。
309桁整数最大値については検索してみると見つかった。[ここに](https://www.redshift-observatory.ch/white_papers/downloads/minimum_and_maximum_values_by_data_type.html)色々と面白い情報が載っている。`float8`の項目に注目だ。

>数学的には、最大値は **2<sup>1023</sup> * (1+(1-(1/2<sup>52</sup>)))** となり、この値の負数が最小値、正数が最大値になります。その値を羅列すると`179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368`となります。
>問題となるのは、実際に保存しておける大きな数字は`179769313486231580793728971405303415079934132710037826936173778980444968292764750946649017977587207096330286416692887910946555547851940402630657488671505820681908902000708383676273854845817711531764475730270069855571366959622842914819860834936475292719074168444365510704342711559699508093042880177904174497791`です。
>これは浮動小数点数の本質的な不正確さのため許容されていると思います