Что такое порядковый номер двойного в Windows 10 64bit? - PullRequest
0 голосов
/ 01 февраля 2019

Я использую c # и пишу программу для отправки чисел по UDP.Я использую 64-разрядную платформу Windows 10 и использую BitConverter для получения байтов из целых, двойных и т. Д.

Например:

Если я использую:

Byte[] data = BitConverter.GetBytes((int)1);

Я получаю 01000000 в HEX , что будет прямым порядком байтов , как ожидается.

Если я использую:

Byte[] data = BitConverter.GetBytes((double)1);

Я получаю 000000000000f03f в шестнадцатеричном , который выглядит как big endian число, но я просто не уверен.

Полагаю, у меня нет хорошего понимания порядка байтов или двойного формата.Я полагаю, также возможно, что Windows хранит двойные отличные от целых?

Ответы [ 3 ]

0 голосов
/ 01 февраля 2019

Интересная заметка.Как вы, возможно, уже знаете, C # не определяет endiannes и зависит от архитектуры процессора. Если вы пишете кросс-платформенные / архитектурные приложения, вы можете проверить это с помощью вызова метода BitConverter.IsLittleEndian

Указывает порядок байтов («порядковый номер»), в котором данные хранятся в этой компьютерной архитектуре.

Примечания

Различные компьютерные архитектуры хранят данные, используя разныебайтовые порядки.«Big-endian» означает, что самый старший байт находится в левом конце слова.«Little-endian» означает, что самый старший байт находится в правом конце слова.

Примечание

Вы можете преобразовать сетевой порядок байтов в порядок байтов:хост-компьютер без извлечения значения поля BitConverter.IsLittleEndian путем передачи 16-разрядного, 32-разрядного или 64-разрядного целого числа в метод IPAddress.HostToNetworkOrder.

Если вам нужны другие порядковые номера,Вы можете легко конвертировать с Array.Reverse.

byte[] bytes = BitConverter.GetBytes(num);
Array.Reverse(bytes, 0, bytes.Length);

или битовым переключателем с типами, такими как int и long, вы можете сделать еще один шаг вперед с небезопасными и указателями для других типов

public uint SwapBytes(uint x)
{
    x = (x >> 16) | (x << 16);
    return ((x & 0xFF00FF00) >> 8) | ((x & 0x00FF00FF) << 8);
}

public ulong SwapBytes(ulong x)
{
    x = (x >> 32) | (x << 32);
    x = ((x & 0xFFFF0000FFFF0000) >> 16) | ((x & 0x0000FFFF0000FFFF) << 16);
    return ((x & 0xFF00FF00FF00FF00) >> 8) | ((x & 0x00FF00FF00FF00FF) << 8);
}
0 голосов
/ 01 февраля 2019

Конечно, little-endian.

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

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

Ваш двойной пример содержит все нулевые биты в поле мантиссы, а более значимое поле экспонентных битов не равно нулю.(На оба они влияет смещение, используемое IEEE-754)

Значимые биты находятся по старшим адресам памяти, так же, как с целым числом с прямым порядком байтов.

Для справки, IEEE-754 для 1.0 является { sign: 0, exponent: 0x3ff, mantissa: 0x0000000000000 }

0 голосов
/ 01 февраля 2019

Двоичное представление double отличается от целочисленного.Он соответствует стандарту ieee для хранения значений с плавающей запятой.Используйте стандарт ieee и получите двоичное представление 1, а затем проверьте endianness ели.

...