Skip to content

Instantly share code, notes, and snippets.

@Infarh
Created April 28, 2023 08:17
Show Gist options
  • Save Infarh/c97092764a3d55b56e3654ecd61b3e79 to your computer and use it in GitHub Desktop.
Save Infarh/c97092764a3d55b56e3654ecd61b3e79 to your computer and use it in GitHub Desktop.
Получение значения отрицательного числа в дополнительном коде для указанного количества знаковых разрядов
/// <summary>Преобразование отрицательного числа</summary>
/// <param name="x">Целое число с битам данных</param>
/// <param name="n">Число бит без учёта знакового бита</param>
static int GetSignedValueFast(int x, int n) => x < 1 << n ? x : x - (1 << n + 1);
static int GetSignedValueFastExplain(int x, int n)
{
// Если число бит n = 4.
// то значение не может превышать 2^n - т.е. 16.
if (x < 1 << n) // Если значение меньше 16
return x; // то это положительное значение
// Если значение больше, либо равно 16, то его надо преобразовать в отризцательное.
// для этого достаточно из значения вычесть 2^(n + 1) - т.е. 32
return x - (1 << n + 1);
}
/// <summary>Преобразование отрицательного числа</summary>
/// <param name="x">Целое число с битам данных</param>
/// <param name="n">Число бит без учёта знакового бита</param>
static int Simple(int x, int n) => (x & (1 << n)) == 0
? x & (1 << n) - 1
: -((~(x - 1)) & (1 << n) - 1);
static int SimpleExplain(int x, int n)
{
var mask = (1 << n) - 1;
// Если нет знакового бита
if ((x & (1 << n)) == 0)
return x & mask; // то просто выделяем значащую часть числа
// иначе требуется преобразование из дополнительного кода.
// Дополнительный код это
// 1. Инверсия всех бит
// 2. Прибавление единицы
// Значит нужно выполнить шаги в обратном порядке
// 1. Вычесть 1.
// 2. Инвертировать все биты
// 3. Наложить маску
var code = x - 1;
var result = ~code & mask;
return -result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment