Android SQLiteDatabase - Хранение и сравнение больших чисел

Я пытаюсь сохранить очень большое число, которое больше, чем 8 байтов, которые могут содержать типы полей INTEGER и REAL. Мне нужно иметь возможность возвращать строки, содержащие число в этом поле, которое меньше или больше другого большого числа, которое я указываю. Я не уверен, как это сделать. Кажется, мой единственный вариант - сохранить его как TEXT, но затем я сталкиваюсь с проблемами, когда пытаюсь сравнить, используя> и<в запросе, поскольку сравнение TEXT не то же самое, что и числовое сравнение (есть проблемы, когда номера не имеют одинаковое количество цифр). Я попытался использовать BLOB или сохранить мое большое число в виде байтового массива, но безрезультатно. Заполнение чисел нулями, чтобы они имели одинаковое количество цифр, на самом деле тоже не работает, потому что я не знаю, насколько большим может быть число. Любая помощь приветствуется. Спасибо!

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, то результатом будет 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 вместо двоичных значений. То есть используйте префикс с фиксированной длиной, который указывает длину числа, а затем номер. Предполагая, что ваши номера не длиннее 9999 цифр, вы можете использовать префикс длиной четыре, например:

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

Если вам нужны здесь отрицательные значения, вы должны выбрать дополнительный префикс для отрицательных / положительных чисел, который сортируется правильно (порядок ASCII - / + неправильно, так что лучше использовать что-то вроде n / p), и вы должны использовать префикс, например, 9999 - длина для отрицательных чисел, чтобы меньшие отрицательные числа имели меньший префикс.

Другие вопросы по тегам