3

INTEGERおよびREALフィールドタイプが保持できる8バイトよりも大きい非常に大きな数を格納しようとしています。このフィールドに、指定した別の大きな数値よりも小さいか大きい数値を含む行を返すことができる必要があります。これを行う方法がわかりません。私の唯一の選択肢はそれをTEXTとして保存することのようですが、TEXTの比較は数値の比較と同じではないため、クエリで>と<を使用して比較しようとすると問題が発生します(数字の桁数は同じではありません)。BLOBを使用するか、大きな数値をバイト配列として格納することを検討しましたが、役に立ちませんでした。同じ桁数になるように数値をゼロで埋めても、数値がどれだけ大きくなるかわからないため、実際には機能しません。助けていただければ幸いです。ありがとう!

4

1 に答える 1

1

ストレージについては、TEXT または BLOB しか選択できないため、辞書式順序と数値順序が同じになるように数値をエンコードする必要があります。

符号なしの数値の場合、SQLite4 のvarintエンコーディングと同様のメカニズムを使用できます。

エンコーディングのバイトを A0、A1、A2、...、A8 とします。
A0 が 0 から 240 までの範囲にある場合、結果は A0 の値になります。
A0 が 241 から 248 までの範囲にある場合、結果は 240+256*(A0-241)+A1 になります。
A0 が 249 の場合、結果は 2287+256*A1+A2 になります。
A0 が 250 の場合、結果は 3 バイトのビッグエンディアン整数としての A1..A3 になります。
A0 が 251 の場合、結果は 4 バイトのビッグエンディアン整数としての A1..A4 になります。
A0 が 252 の場合、結果は 5 バイトのビッグエンディアン整数として A1..A5 になります。
A0 が 253 の場合、結果は 6 バイトのビッグエンディアン整数として A1..A6 になります。
A0 が 254 の場合、結果は 7 バイトのビッグエンディアン整数として A1..A7 になります。
A0 が 255 の場合、結果は 8 バイトのビッグエンディアン整数として A1..A8 になります。

上記は、最大 64 ビットの数値用に設計されています。上限がある限り、より大きな数のメカニズムを拡張することは簡単です

数値に署名できる場合は、A0範囲を半分に分割し、前半を負の数値に使用する必要があります。

計算を行う必要がない場合は、バイナリ値の代わりに ASCII 数字を格納するという同じ原則を使用できます。つまり、数値の長さを指定する固定長のプレフィックスを使用してから、数値を指定します。番号が 9999 桁を超えていないと仮定すると、プレフィックス長を 4 にすることができます。次に例を示します。

0001|0  ...
0001|9
0002|10  ...
0002|99
0003|100  ...
0060|321741185926535897932384626433832795281828459045235360287471

ここで負の値が必要な場合は、正しくソートされる負/正の数値の追加のプレフィックスを選択する必要があります ( -/の ASCII 順序+が間違っているため、 n/などを使用することをお勧めします)。また、 9999pなどのプレフィックスを使用する必要があります–負の数の長さを調整して、負の数が小さいほど接頭辞が小さくなるようにします。

于 2013-03-21T07:44:44.943 に答える