Преобразование типа данных 'long' в байтовый массив

Мне нужно преобразовать значения (double/float в С#) в байты и нуждаться в помощи.

//Datatype long 4byte -99999999,99 to 99999999,99
// Тип данных long 4byte -99999999,9 до 99999999,9
// Тип данных короткий 2 байт -999,99 до 999,99
// Тип данных short 2byte -999,9 to 999,9

В моем "мире дома" я просто поместил бы его и ASCII.GetBytes().

Но теперь, в этом мире, мы должны сделать меньше пространства.
И действительно, что -99999999,99 'принимает 12 байтов вместо 4! если это "длинный" тип данных.

[EDIT]
Из-за некоторой помощи и ответа я прикладываю некоторые результаты здесь,

long lng = -9999999999L;
byte[] test = Encoding.ASCII.GetBytes(lng.ToString());  // 11 byte
byte[] test2 = BitConverter.GetBytes(lng);              // 8 byte
byte[] mybyt = BitConverter.GetBytes(lng);              // 8 byte
byte[] bA = BitConverter.GetBytes(lng);                 // 8 byte

Остается еще одна деталь, чтобы узнать. Lng-variabel получил 8 байтов, даже если он удерживает более низкие значения, т.е. 99951 (я не буду включать образец ToString()).

Если значение равно "короче", что означает -999,99-999,99, оно займет всего 2 байта.
[END EDIT]

Ответы

Ответ 1

Помните, что в 2 байтах вы можете иметь только 4 полных цифры + знак, а в 4 байтах вы можете иметь только 9 цифр + знак, поэтому мне пришлось масштабировать ваши предварительные требования соответственно.

public static byte[] SerializeLong2Dec(double value)
{
    value *= 100;
    value = Math.Round(value, MidpointRounding.AwayFromZero);

    if (value < -999999999.0 || value > 999999999.0)
    {
        throw new ArgumentOutOfRangeException();
    }

    int value2 = (int)value;

    return BitConverter.GetBytes(value2);
}

public static double DeserializeLong2Dec(byte[] value)
{
    int value2 = BitConverter.ToInt32(value, 0);
    return (double)value2 / 100.0;
}

public static byte[] SerializeLong1Dec(double value) {
    value *= 10;
    value = Math.Round(value, MidpointRounding.AwayFromZero);

    if (value < -999999999.0 || value > 999999999.0) {
        throw new ArgumentOutOfRangeException();
    }

    int value2 = (int)value;

    return BitConverter.GetBytes(value2);
}

public static double DeserializeLong1Dec(byte[] value) {
    int value2 = BitConverter.ToInt32(value, 0);
    return (double)value2 / 10.0;
}

public static byte[] SerializeShort2Dec(double value) {
    value *= 100;
    value = Math.Round(value, MidpointRounding.AwayFromZero);

    if (value < -9999.0 || value > 9999.0) {
        throw new ArgumentOutOfRangeException();
    }

    short value2 = (short)value;

    return BitConverter.GetBytes(value2);
}

public static double DeserializeShort2Dec(byte[] value) {
    short value2 = BitConverter.ToInt16(value, 0);
    return (double)value2 / 100.0;
}

public static byte[] SerializeShort1Dec(double value) {
    value *= 10;
    value = Math.Round(value, MidpointRounding.AwayFromZero);

    if (value < -9999.0 || value > 9999.0) {
        throw new ArgumentOutOfRangeException();
    }

    short value2 = (short)value;

    return BitConverter.GetBytes(value2);
}

public static double DeserializeShort1Dec(byte[] value) {
    short value2 = BitConverter.ToInt16(value, 0);
    return (double)value2 / 10.0;
}

Итак, ясно, что диапазон (подписанных) коротких (16 бит) составляет -32,768 до 32,767, поэтому совершенно ясно, что у вас есть только 4 полных цифры плюс небольшая часть (0-3), диапазон (подписанный) int (32 бита) составляет -2147,483,648 до 2,147,483,647, поэтому совершенно ясно, что у вас есть только 9 полных цифр плюс небольшая часть (0-2). Подойдя к (подписанному) длинному (64 бита), у вас есть -9,223,372,036,854,775,808 до 9,223,372,036,854,775,807, так что 18 цифр плюс (большая) часть. Используя плавающие точки, вы теряете точность. Поплавок (32 бит) имеет точность около 7 цифр, а двойная (64 бит) имеет точность около 15-16 цифр.

Ответ 2

Вы проверили BitConverter

long lng =-9999999999L;
byte[] mybyt = BitConverter.GetBytes(lng);

надеюсь, что это то, что вы ищете

Ответ 3

Попробуйте сделать это следующим образом:

long l = 4554334;

byte[] bA = BitConverter.GetBytes(l);

Ответ 4

long longValue = 9999999999L;

        Console.WriteLine("Long value: " + longValue.ToString());

        bytes = BitConverter.GetBytes(longValue);

        Console.WriteLine("Byte array value:");

        Console.WriteLine(BitConverter.ToString(bytes));

Ответ 5

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

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

Если вы решите, что этот подход применим к вашему делу, я бы предложил посмотреть, как Protocol Buffers project представляет скалярные типы, поскольку некоторые из этих типов кодируются с использованием кодирования с переменной длиной, что дает более короткий результат, если набор данных благоприятствует меньшим абсолютным значениям. (Проект является открытым исходным кодом под новой лицензией BSD, поэтому вы сможете изучить технику, используемую в исходный репозиторий или даже использовать источник в своем собственном проекте.)