Два дополнения преобразования - PullRequest
9 голосов
/ 28 сентября 2010

Мне нужно преобразовать байты в формате дополнения до двух в целые положительные байты. Диапазон от -128 до 127 сопоставлен с 0 до 255.

Examples: -128 (10000000) -> 0 , 127 (01111111) -> 255, etc.

EDIT Чтобы устранить путаницу, входной байт (конечно) является целым числом без знака в диапазоне от 0 до 255. НО это представляет целое число со знаком в диапазоне от -128 до 127 с использованием дополнения до двух. формат. Например, значение входного байта 128 (двоичное 10000000) фактически представляет -128.

ДОПОЛНИТЕЛЬНОЕ РЕДАКТИРОВАНИЕ Хорошо, допустим, у нас есть следующий поток байтов 0,255,254,1,127. В формате дополнения до двух это представляет 0, -1, -2, 1, 127. Это мне нужно зажимать в диапазоне от 0 до 255. Для получения дополнительной информации проверьте эту трудно найти статью: Дополнение два

Ответы [ 10 ]

7 голосов
/ 28 сентября 2010
new = old + 128;

бинго: -)

7 голосов
/ 28 сентября 2010

Из вашего примера ввода вы просто хотите:

sbyte something = -128;

byte foo = (byte)( something + 128);
3 голосов
/ 13 октября 2010

Попробуйте

sbyte signed = (sbyte)input;

или

int signed = input | 0xFFFFFF00;
2 голосов
/ 22 ноября 2011
    public static byte MakeHexSigned(byte value)
    {
        if (value > 255 / 2)
        {
            value = -1 * (255 + 1) + value;
        }

        return value;
    }
1 голос
/ 10 июля 2013

Вот мое решение для этой проблемы, для чисел больше 8 бит. Мой пример для 16-битного значения. Примечание. Вам нужно будет проверить первый бит, чтобы увидеть, является ли он отрицательным или нет.

Шаги:

  1. Преобразовать # в комплимент, поместив '~' перед переменной. (т. е. у = ~ у)

  2. Преобразование # в двоичную строку

  3. Разбить двоичные строки в массив символов

  4. Начиная с самого правого значения, добавьте 1, отслеживая переносы. Сохранить результат в массив символов.

  5. Преобразование массива символов обратно в строку.

    private string TwosComplimentMath(string value1, string value2)
    {
        char[] binary1 = value1.ToCharArray();
        char[] binary2 = value2.ToCharArray();
        bool carry = false;
        char[] calcResult = new char[16];
    
        for (int i = 15; i >= 0; i--)
        {
            if (binary1[i] == binary2[i])
            {
                if (binary1[i] == '1')
                {
                    if (carry)
                    {
                        calcResult[i] = '1';
                        carry = true;
                    }
                    else
                    {
                        calcResult[i] = '0';
                        carry = true;
                    }
                }
                else
                {
                    if (carry)
                    {
                        calcResult[i] = '1';
                        carry = false;
                    }
                    else
                    {
                        calcResult[i] = '0';
                        carry = false;
                    }
                }
            }
            else
            {
                if (carry)
                {
                    calcResult[i] = '0';
                    carry = true;
                }
                else
                {
                    calcResult[i] = '1';
                    carry = false;
                }
            }
    
        }
    
        string result = new string(calcResult);
        return result;
    
    }
    
1 голос
/ 25 сентября 2012
int8_t indata; /* -128,-127,...-1,0,1,...127 */
uint8_t byte = indata ^ 0x80;

xor MSB, вот и все

1 голос
/ 13 октября 2010

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

Для ясности, когда вы используете подписанный тип (например, ubyte), фреймворк использует Two's complement за сценой, поэтому, просто приведя к нужному типу, вы будете использовать дополнение до двух.

Затем, как только вы закончите преобразование, вы можете зафиксировать отрицательные значения простым if или условным троичным оператором (?: ).

Функции, представленные ниже, вернут 0 для значений from 128 to 255 (или от -128 до -1) и the same value для значений from 0 to 127.

Итак, если вы должны использовать целые числа без знака в качестве входных и выходных данных, вы можете использовать что-то вроде этого:

private static uint ConvertSByteToByte(uint input)
{
    sbyte properDataType = (sbyte)input; //128..255 will be taken as -128..-1
    if (properDataType < 0) { return 0; } //when negative just return 0
    if (input > 255) { return 0; } //just in case as uint can be greater than 255
    return input;
}

Или, ИМХО, вы можете изменить свои входные и выходные данные на типы данных, наиболее подходящие для ваших входных и выходных данных (sbyte и byte):

private static byte ConvertSByteToByte(sbyte input)
{
    return input < 0 ? (byte)0 : (byte)input;
}
0 голосов
/ 08 августа 2018

Таким образом, проблема в том, что проблема ОП - это не преобразование дополнения в два. Он добавляет смещение к набору значений, чтобы настроить диапазон от -128..127 до 0..255.

Чтобы действительно выполнить преобразование дополнения до двух, просто введите значение со знаком в значение без знака, например:

sbyte test1 = -1;
byte test2 = (byte)test1;

-1 становится 255. -128 становится 128. Однако это не похоже на то, что хочет ОП. Он просто хочет сдвинуть массив так, чтобы наименьшее значение со знаком (-128) стало наименьшим значением без знака (0).

Чтобы добавить смещение, вы просто добавляете целое число:

newValue = signedValue+128;
0 голосов
/ 03 февраля 2013

Я полагаю, что 2-е байты дополнения лучше всего сделать со следующим. Может быть, не элегантный или короткий, но ясный и очевидный. Я бы поставил его как статический метод в одном из моих классов утилит.

public static sbyte ConvertTo2Complement(byte b)
{
    if(b < 128)
    {
        return Convert.ToSByte(b);
    }
    else
    {
        int x = Convert.ToInt32(b);
        return Convert.ToSByte(x - 256);
    }
}
0 голосов
/ 28 сентября 2010

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

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