はじめまして。配列の長さについての質問です。
dimなりで配列を定義したとき、配列の長さはIntegerが限界になっています。
UInt64の最大数を長さに持つ配列を作りたいのですが、どうすればいいのでしょうか?
それともそれは不可能で、複数の配列を用意するなどの工夫が必要なのでしょうか。
ご教授お願いします。
Array.CreateInstance(Type, Long()) を使えば確保できそうな気がします。
Integer の範囲外のインデックスを持つ要素の取得・設定は GetValue/SetValue で。
まあ x86 だとそもそもそんなでかい配列作れないですけど。
Integerというと
2^(16-1)=32,768 なのか
2^(32-1)=2,147,483,648 なのか
そもそもUInt64と言っている時点で
2^64=18,446,744,073,709,551,616
が要求されていたり。
どのような用途で使用するのか激しく興味が沸いてしかたありません。
仮に実現できたとしても使用方法をよく考えないとえらいことになりそうな・・・
配列の要素数にIntegerがOKならば多次元配列にして逃げる?
Dim 廃列(32768, 32768, 32768)
とか・・・(注:未調査)
これが許されるなら
Int16なら 2^45 =35,184,372,088,832
Int32なら 2^93 =9,903,520,314,283,042,199,192,993,792
まではいけるかな?
あれ?次元数って3つ以上行けたっけ?
もうなにがなにやら(;・∀・)
あとはクラスの中でうまいことやるぐらいしか・・・
あぁ、なんかデジャヴュを感じる・・・
とりあえずVB6で確認してみました。
配列は 2^31 でオーバーフローします。
(2^31)-1 はオーバーフローしませんが、メモリ不足といわれて起動できません。
このメモリ不足は実行環境によるのかもしれません。
とりあえず、Int32つまり符号付32ビット整数型が上限ということですね。
あるときのわたしの仕事用パソコンでは、以下は全てOKでした。(仕事しろよ)
(べき乗数を増やすとNG・・・まぁ、倍になりますからね)
Dim 廃列(2 ^ 27) As Integer
Dim 廃列(2 ^ 26) As Long
Dim 廃列(2 ^ 25) As Double
Dim 廃列(2 ^ 17, 2 ^ 10) As Integer
Dim 廃列(2 ^ 16, 2 ^ 10)) As Long
Dim 廃列(2 ^ 15, 2 ^ 10)) As Double
Dim 廃列(2 ^ 7, 2 ^ 10, 2 ^ 10) As Integer
Dim 廃列(2 ^ 6, 2 ^ 10, 2 ^ 10) As Long
Dim 廃列(2 ^ 5, 2 ^ 10, 2 ^ 10) As Double
Integer=2バイト
Long=4バイト
Double=8バイト
ということを考えると、どれもだいたい 2^28バイト = 268,435,456バイト はOKとなっています。
Dim 廃列(2 ^ 5, 2 ^ 5, 2 ^ 5, 2 ^ 5, 2 ^ 5, 2 ^ 1) As Integer
ただし、この場合は 2^27バイトしか確保できませんでした。
おそらくメモリアライメントに隙間があるせいかなと思います。
たぶん環境依存なので細かい数字はキニシナイ!
そしてフォームで確保しても、標準モジュールで確保しても、publicでもprivateでも大きな違いはないようです。
次元数はメモリが確保できる範囲では20次元でも平気でした。
あくまでもデータ量による模様。
限度はあるでしょうが。
また、さきほどは1個だけの配列変数でしたが、複数宣言した場合はまた面白い現象が見えました。
Dim 廃列1(2 ^ 27) As Integer
Dim 廃列2(2 ^ 27) As Integer
これはダメでしたが(メモリ不足で)、
Dim 廃列1(2 ^ 27) As Integer
Dim 廃列2(2 ^ 26) As Integer
Dim 廃列3(2 ^ 26) As Integer
Dim 廃列4(2 ^ 26) As Integer
これはOKでした。
まぁ、起動にすばらしく時間はかかりますが。
なんにしろ、1個の配列で保持できる数は、どのような型や次元であっても次元×要素数はInt32個までということは間違いようです。
VB6では。
.NETだとInt32なのかInt64なのか分かりませんが、どちらにしろUInt64はダメっぽいかな?
クラスを作るなど別の方法を考える必要があるようですね。
例えば、Public Function Get廃列Data(En As Long, Pn As Long, Gn As Long, Mn As Long, kn As Long, n As Long)
とかにしておいて、
1,152,921,504,606,846,976 のデータにアクセスするなら、
ret = Get廃列Data(1, 152, 921, 504, 606, 846, 976)
とかね。
そもそもインデックスの数値自体が型の範疇に収まらないようなw
.NETなら 変数をUInt64型で宣言できるのかな?
Array.CreateInstance(Type, Long=Int64[]) が使えたとしても、各次元の要素数は Int32.MaxValue が上限とのことなので、Integerが上限っぽいね。
落ち着いて考えたらクラスを使っても変数で2^64個のデータを保持する箱を確保するのは不可能に近いw
とりあえず逃亡。
ツイート | ![]() |