Абсолютный диапазон ваших данных на самом деле не имеет большого значения, вам нужна точность. Если вы можете сойти с рук, например, 6 цифр точности, тогда вам потребуется столько памяти, сколько потребуется для хранения целых чисел от 1 до 1000000, а это 20 бит. Итак, предположим, что вы можете сделать:
1) Сдвиньте данные так, чтобы наименьший элемент имел значение 0. Т.е. вычесть одно значение из каждого элемента. Запишите этот сдвиг.
2) Масштабируйте (умножайте) свои данные на достаточно большое число, чтобы после усечения до целого числа вы не потеряли необходимую точность.
3) Теперь это может быть сложно, если вы не можете упаковать свои данные в удобные 8- или 16-битные блоки - упаковать данные в последовательные целые числа без знака. Каждому из ваших значений данных в этом примере требуется 20 битов, поэтому значение 1 занимает первые 20 битов целого числа 1, значение 2 занимает оставшиеся 12 битов целого числа 1 и первые 8 битов целого числа 2 и так далее. В этом гипотетическом случае вы экономите ~ 40%.
4) Теперь «расшифровка». Распакуйте значения (вы сохранили количество битов в каждом из них), отмените масштаб и отмените сдвиг.
Итак, это будет сделано, и, возможно, будет быстрее и компактнее, чем стандартные алгоритмы сжатия, так как им не разрешается делать предположения о том, сколько точности вам нужно, но вы есть.