Чтение и запись нестандартных значений с плавающей запятой - PullRequest
0 голосов
/ 18 марта 2019

Я работаю с двоичным файлом (файл 3d-модели для старой видеоигры) в C #.Формат файла официально не задокументирован, но некоторые из них были переработаны сообществом игры.

У меня проблемы с пониманием того, как читать / записывать 4-байтовые значения с плавающей запятой.Я получил это объяснение от члена сообщества:

Например, байты EE 62 ED FF представляют значение -18,614.

Байты имеют порядок байтов с прямым порядком байтов.Первые 2 байта представляют десятичную часть значения, а последние 2 байта представляют всю часть значения.

Для десятичной части 62 EE, преобразованной в десятичную, составляет 25326. Это представляет дробьиз 1, который также может быть описан как 65536/65536.Таким образом, разделите 25326 на 65536, и вы получите 0,386.

Для всей части FF ED, преобразованное в десятичное число, равно 65517. 65517 представляет целое число -19 (то есть 65517 - 65536).

Это дает значение -19 + .386 = -18.614.

Это объяснение в основном имеет смысл, но меня смущают две вещи:

  1. Имеет ли магическое число 65536 какое-либо значение?
  2. BinaryWriter.Write(-18.613f) записывает байты как 79 E9 94 C1, поэтому я предполагаю, что двоичный файл, с которым я работаю, использует собственный запатентованный метод хранения 4-байтовой плавающей запятойзначения (т.е. я не могу использовать C # float взаимозаменяемо, и мне нужно будет сначала кодировать / декодировать значения)?

Ответы [ 2 ]

1 голос
/ 18 марта 2019

Во-первых, это не число с плавающей точкой это число с фиксированной точкой

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

Имеет ли магическое число 65536 какое-либо значение

Максимальное число значений, которое может содержать 16-разрядное число без знака, или 2^16, да, это существенно, поскольку число, с которым вы работаете, равно 2 * 16-битным значениям, закодированным для целых и дробных компонентов.

поэтому я предполагаю, что бинарный файл, с которым я работаю, использует свой собственный запатентованный метод хранения 4-байтовых значений с плавающей точкой

Нет, снова неверно, значения с плавающей точкой в. Нетто придерживаются стандарта IEEE для арифметики с плавающей точкой (IEEE 754)

Когда вы используете BinaryWriter.Write(float);, он просто сдвигает биты в byte с и записывает их в Stream.

uint TmpValue = *(uint *)&value;
_buffer[0] = (byte) TmpValue;
_buffer[1] = (byte) (TmpValue >> 8);
_buffer[2] = (byte) (TmpValue >> 16);
_buffer[3] = (byte) (TmpValue >> 24);
OutStream.Write(_buffer, 0, 4);

Если вы хотите прочитать и записать это специальное значение, вам нужно будет сделать то же самое, вам придется читать и записывать байты и преобразовывать их самостоятельно

0 голосов
/ 18 марта 2019

Это должно быть встроенное значение, уникальное для игры.

Это должно быть больше похоже на Fraction Value.

Где 62 EE представляет Fraction Part значения, а FF ED представляет Whole Number Part значения.

While Number Part легко понять, поэтому я не буду его объяснять.

Объяснение Fraction Part таково:

Для каждых 2 байтов существует 65536 возможностей (0 ~ 65535).

256 X 256 = 65536

отсюда и магическое число 65536.

И сама игра должна иметь встроенный алгоритм, чтобы разделить первые 2 байта на 65536.

Выбор любого другого числа, кроме этого, будет waste of memory space и приведет к decreased accuracy of the value which can be represented.

Конечно, все зависит от того, какую точность игра хочет представить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...