Как сохранить число с плавающей точкой в 2 байта?

Да, я осведомлен о стандарте половинной точности IEEE-754, и да, я осведомлен о работе, проделанной в полевых условиях. Проще говоря, я пытаюсь сохранить простое число с плавающей запятой (например,52.1, или же1.25) всего за 2 байта.

Я пробовал некоторые реализации вДжава И вC # но они разрушают входное значение, декодируя другое число. Вы кормите в32.1 и после кодирования-декодирования вы получаете32.0985.

Есть ли ЛЮБОЙ способ хранить числа с плавающей запятой всего в 16 битах, не разрушая входное значение?

Спасибо большое.

Ответы на вопрос(6)

float или жеdouble?

Вы бы лучше обслужили, храняshort и понимая, что, например, оно делится на 100, чтобы получить фактическое число? (Например, ваши примеры 52.1 и 1.25 могут быть сохранены как 5210 и 125) Я думаю, что это может быть лучшим решением для вас.

Если вы используете действительное число с плавающей запятой, вы можете взять декодированное число и округлить его до x значащих цифр (из вашего примера, 3), которые обычно возвращают вам тот же номер, с которого вы начали (обратите внимание, что да, это намеренно расплывчато - вы не можете гарантировать получение оригинала, если не храните оригинал).

ита для десятичной точки:

52.1 = 521 * 10 ^ -1 => 0x1521
1.25 = 125 * 10 ^ -2 => 0x2125

Это даст вам диапазон от 0,0000000000000001 до 999. Конечно, вы можете добавить смещение для десятичной точки, чтобы получить, например, диапазон от 0,0000000001 до 999000000.

Простая реализация из четырех бит используется для размещения десятичной точки, а остальные для значения. Без какой-либо проверки ошибок и не полностью проверены. (Могут возникнуть проблемы с точностью при использовании некоторых значений!= сравнивать двойники.)

public static short Encode(double value) {
  int cnt = 0;
  while (value != Math.Floor(value)) {
    value *= 10.0;
    cnt++;
  }
  return (short)((cnt << 12) + (int)value);
}

public static double Decode(short value) {
  int cnt = value >> 12;
  double result = value & 0xfff;
  while (cnt > 0) {
    result /= 10.0;
    cnt--;
  }
  return result;
}

Пример:

Console.WriteLine(Encode(52.1));
Console.WriteLine(Decode(4617));

Выход:

4617
52.1

но вы можете попробовать подход с фиксированной запятой.

Пример 8,8 с фиксированной точкой (8 до запятой, 8 после):

float value = 123.45;
ushort fixedIntValue = (ushort)(value * 256);

Таким образом, номер сохраняется следующим образом: XXXXXXXX, XXXXXXXX

и вы можете получить поплавок снова, используя это:

float value = fixedIntValue / 256f;

ете просто закодировать свой «алфавит» из 11 символов в 4-битный код и хранить 4 х 4 бита в 2 байта.

32.1 вany двоичный тип с плавающей точкой.

В одинарной точности самое близкое представимое значение - 32.099998. В полу-точности это, по-видимому, 32,0985.

Вы могли бы рассмотреть десятичный тип с плавающей точкой, но это решение не уникально для половинной точности.

не считая NaN и бесконечностей. Есть 65 536 значений для 16 битов в двух байтах. Ясно, что невозможно однозначно закодировать все значения с плавающей точкой в два байта.

Какие из них вы хотите закодировать?

Даже для одного значения знака и показателя степени (например, для всех значений с плавающей запятой от 4 до 8, не включая 8) существует 8 388 608 значений с плавающей запятой, поэтому вы даже не можете кодировать их в два байта.

Вы должны ограничить себя небольшим подмножеством значений для кодирования. Как только вы это сделаете, у людей могут появиться предложения о том, как их кодировать. Какую реальную проблему вы пытаетесь решить?

ВАШ ОТВЕТ НА ВОПРОС