Почему BitConverter, по -видимому, возвращает неправильные результаты при преобразовании поплавок и байтов?C#

Место общения программистов C#
Ответить
Anonymous
 Почему BitConverter, по -видимому, возвращает неправильные результаты при преобразовании поплавок и байтов?

Сообщение Anonymous »

Я работаю в C# и пытаюсь упаковать четыре байта в поплавок (контекст - это разработка игры, где цвет RGBA упакован в одно значение). Для этого я использую BitConverter , но некоторые преобразования, похоже, приводят к неправильным байтам. Возьмите следующий пример (используя байты 0, 0, 129, 255 ):

Код: Выделить всё

var before = new [] { (byte)0, (byte)0, (byte)129, (byte)255 };
var f = BitConverter.ToSingle(before, 0); // Results in NaN
var after = BitConverter.GetBytes(f); // Results in bytes 0, 0, 193, 255
Использование https://www.h-schmidt.net/floatconverter/ieee754.html, я подтвердил, что четыре байта, с которыми я начал (с

Код: Выделить всё

0, 0, 129, 255
, эквивалент двоичной 000000000000000010000001111111111 ) представляет значение с плавающей точкой 4.666338115943E-41 . Переверните эндсианс (двоичный 111111111100001000000000000000000 ), я получаю NAN (который соответствует F в коде выше). Но когда я преобразую это, плаваю обратно в байты, я получаю 0, 0, 193, 255 (примечание 193 Когда я ожидаю 129 ).
Любопытно, что запуск этого же примера с байтами 0, 0, 128, 255 является правильным (значение для плавающей точки f . 0, 0, 128, 255 снова). Учитывая этот факт, я подозреваю, что NAN является актуальным.
Может ли кто -нибудь пролить свет на то, что здесь происходит? Этот вопрос пытается преобразовать байты в ценность (в этом случае два байта в короткое время), и неправильная эндоуность дала неожиданную ценность. В моем случае фактическое значение поплавки не имеет значения (поскольку я не использую преобразованное значение в качестве плавания). Вместо этого я пытаюсь эффективно переосмыслить четыре байта как плавание напрямую , сначала преобразовав в поплавок, а затем конвертируя обратно. Как показано, эта обратная и порядок иногда возвращает разные байты, чем те, которые я отправил. Как комментирует Питер Дунихо, BitConverter никогда не будет изменять байты, которые вы проходите, но просто скопируйте их в новое местоположение памяти и переосмыслить результат. Однако, как показывает мой пример, можно отправить в четыре байта (

Код: Выделить всё

0, 0, 129, 255
), которые внутренне скопированы и переосмысливаются на поплавок, а затем преобразуйте, которые плавают обратно в байты, которые , чем оригиналы (

Код: Выделить всё

0, 0, 193, 255
).
Эндианство часто упоминается в отношении BitConverter . Тем не менее, в этом случае я чувствую, что эндианство не является проблемой корня. Когда я называю BitConverter.tosingle , я прохожу массив из четырех байтов. Эти байты представляют какое -то бинарное (32 бита), которые преобразуются в поплавок. Изменив эндсивство до вызова функции , все, что я делаю, это изменение битов, которые я отправляю в функцию . Независимо от значения этих битов, должно быть возможно преобразовать их в поплавок (также 32 бита), а затем преобразовать плавание обратно, чтобы получить те же биты, которые я отправил в . Как показано в моем примере, использование байтов 0, 0, 129, 255 (двоичный 0000000000000000100000000111111111 ) приводит к значению с плавающей точкой. Я хотел бы взять это значение (плавание, представленное этими битами) и преобразовать его в исходные четыре байта.
Это возможно во всех случаях?

Подробнее здесь: https://stackoverflow.com/questions/674 ... ing-floats
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»