我正在尝试存储一个非常大的数字,该数字大于INTEGER和REAL字段类型可容纳的8个字节。我需要能够返回包含此字段中的数字的行,该行小于或大于我指定的另一个大数字。我不知道该怎么做。似乎我唯一的选择是将其存储为TEXT,但是当我尝试使用>进行比较时遇到问题。和<在查询中,因为TEXT的比较与数字比较不同(当数字不具有相同的数字时存在问题)。我已经尝试过使用BLOB或将我的大数字存储为字节数组,但无济于事。用零填充数字以使它们具有相同的数字位数并不真正起作用,因为我不知道数字可能有多大。 任何帮助赞赏。 谢谢!
答案 0 :(得分:1)
对于存储,您唯一的选择是TEXT或BLOB,因此您必须以某种方式对数字进行编码,以便字典和数字排序相同。
对于无符号数字,您可以使用类似于SQLite4的varint
encoding的机制:
让编码的字节称为A0,A1,A2,...,A8 如果A0介于0和240之间,则结果为A0的值 如果A0在241和248之间,则结果为240 + 256 *(A0-241)+ A1 如果A0是249,那么结果是2287 + 256 * A1 + A2 如果A0为250,则结果为A1..A3为3字节的大端整数 如果A0为251,则结果为A1..A4为4字节的大端整数 如果A0是252,那么结果是A1..A5作为5字节的大端整数 如果A0是253,则结果是A1..A6为6字节的大端整数 如果A0是254,那么结果是A1..A7作为7字节的大端整数 如果A0为255,则结果为A1..A8为8字节的大端整数。
以上设计用于最多64位数字。 只要你做有一个上限,扩展更大数字的机制是微不足道的。
如果数字可以签名,则必须将A0
范围分成两半,并将前半部分用于负数。
如果您不需要进行计算,则可以使用相同的原则来存储ASCII数字而不是二进制值。 也就是说,使用带有 fixed 长度的前缀,该长度指定数字的长度,然后是数字。 假设您的号码不超过9999位,您可以使用前缀长度为4,例如:
0001|0 ...
0001|9
0002|10 ...
0002|99
0003|100 ...
0060|321741185926535897932384626433832795281828459045235360287471
如果您需要负值,则必须为正确排序的负数/正数选择一个额外的前缀(-
/ +
的ASCII顺序错误,因此您最好使用某些东西比如n
/ p
),
并且您必须使用 9999 - length 之类的前缀作为负数,以便较小的负数具有较小的前缀。