Эффективный способ хранения поплавка с фиксированным диапазоном - PullRequest
3 голосов
/ 14 февраля 2012

Я собираю (большой) массив с плавающей точкой, каждый с плавающей точкой занимает 4 байта.

Есть ли способ, учитывая тот факт, что мои числа с плавающей запятой имеют диапазон между 0 и 255, хранить каждое число с плавающей запятой в меньше , чем 4 байта?

Я могу выполнить любое количество вычислений для всего массива.

Я использую C.

Ответы [ 3 ]

1 голос
/ 14 февраля 2012

Абсолютный диапазон ваших данных на самом деле не имеет большого значения, вам нужна точность. Если вы можете сойти с рук, например, 6 цифр точности, тогда вам потребуется столько памяти, сколько потребуется для хранения целых чисел от 1 до 1000000, а это 20 бит. Итак, предположим, что вы можете сделать:

1) Сдвиньте данные так, чтобы наименьший элемент имел значение 0. Т.е. вычесть одно значение из каждого элемента. Запишите этот сдвиг.

2) Масштабируйте (умножайте) свои данные на достаточно большое число, чтобы после усечения до целого числа вы не потеряли необходимую точность.

3) Теперь это может быть сложно, если вы не можете упаковать свои данные в удобные 8- или 16-битные блоки - упаковать данные в последовательные целые числа без знака. Каждому из ваших значений данных в этом примере требуется 20 битов, поэтому значение 1 занимает первые 20 битов целого числа 1, значение 2 занимает оставшиеся 12 битов целого числа 1 и первые 8 битов целого числа 2 и так далее. В этом гипотетическом случае вы экономите ~ 40%.

4) Теперь «расшифровка». Распакуйте значения (вы сохранили количество битов в каждом из них), отмените масштаб и отмените сдвиг.

Итак, это будет сделано, и, возможно, будет быстрее и компактнее, чем стандартные алгоритмы сжатия, так как им не разрешается делать предположения о том, сколько точности вам нужно, но вы есть.

1 голос
/ 14 февраля 2012

Сколько точности вам нужно?

Вы можете сохранить каждое число с плавающей запятой в 2 байта, представив его как unsigned short (в диапазоне от 0 до 65 535) и разделив все значения на 2^8, когда вам нужно фактическое значение. По сути, это то же самое, что использование формата с фиксированной запятой вместо плавающей запятой.

Однако ваша точность ограничена 1.0 / (2^8) = 0.00390625, когда вы делаете это.

0 голосов
/ 14 февраля 2012

Например, вы можете хранить целые числа (с плавающей запятой с .0) в одном байте, но для другого числа с плавающей запятой требуется больше байтов.

Вы также можете использовать фиксированную точку, если вы не беспокоитесь о точности ...

...