Этот вопрос более общий без определенного языка.Меня больше интересует решение этой проблемы в целом на разных языках.Каждый найденный ответ ссылается на встроенный метод типа getInt32
для извлечения целого числа из байтового массива.
У меня есть байтовый массив, который содержит представление с прямым порядком байтов целого числа со знаком.
1 -> [0, 0, 0, 1]
-1 -> [255, 255, 255, 255]
-65535 -> [255, 255, 0, 1]
Получить значения для положительных случаев очень просто:
arr[3] | arr[2] << 8 | arr[1] << 16 | arr[0] << 24
То, что я хотел бы выяснить, это более общий случай.Я читал о дополнении 2s, которое привело меня к функции python из Википедии:
def twos_complement(input_value, num_bits):
'''Calculates a two's complement integer from the given input value's bits'''
mask = 2**(num_bits - 1) - 1
return -(input_value & mask) + (input_value & ~mask)
, что в свою очередь привело меня к созданию этой функции:
# Note that the mask from the wiki function has an additional - 1
mask = 2**(32 - 1)
def arr_to_int(arr):
uint_val = arr[3] | arr[2] << 8 | arr[1] << 16 | arr[0] << 24
if (determine_if_negative(uint_val)):
return -(uint_val & mask) + (uint_val & ~mask)
else:
return uint_val
Для того, чтобы мойДля работы функции мне нужно заполнить determine_if_negative
(я должен замаскировать бит со знаком и проверить, равен ли он 1).Но есть ли стандартная формула для этого?Одна вещь, которую я обнаружил, заключается в том, что в некоторых языках, таких как Go, битовое смещение может переполнять значение int.
Это довольно сложно найти, потому что я получаю тысячу результатов, объясняющих разницу между старшим и младшим порядком байтов, или результаты, объясняющие дополнение к двум, и еще много примеров использования стандартной библиотеки, но я невидел полную формулу для побитовых функций.
Есть ли канонический пример в C или аналогичном языке преобразования массива char с использованием только доступа к массиву и побитовых функций (т. е. без memcpy или приведения указателей или хитрых вещей)