#javascript #twos-complement
#javascript #двойки-дополнение
Вопрос:
Мне нужно кодировать подпись целое число в шестнадцатеричном виде, используя по два дополнения нотации. Например, я хотел бы преобразовать
e.g. -24375 to 0xffffa0c9.
До сих пор я работал над следующими строками:
parseInt(-24375).toString(2)
> "-101111100110111"
Это соответствует тому, что отображает Wolfram Alpha, но я не уверен, как перейти к 24-битному int-представлению числа со знаком (ffffa0c9).
Я разработал, как взять двоичное число без знака и представить его как дополнение two:
~ parseInt("101111100110111", 2) 1
> -23475
но я не уверен, что нужно преобразовать двоичное представление этого числа в шестнадцатеричное.
Есть идеи?
Ответ №1:
Вот довольно простое решение, использующее parseInt
:
function DecimalHexTwosComplement(decimal) {
var size = 8;
if (decimal >= 0) {
var hexadecimal = decimal.toString(16);
while ((hexadecimal.length % size) != 0) {
hexadecimal = "" 0 hexadecimal;
}
return hexadecimal;
} else {
var hexadecimal = Math.abs(decimal).toString(16);
while ((hexadecimal.length % size) != 0) {
hexadecimal = "" 0 hexadecimal;
}
var output = '';
for (i = 0; i < hexadecimal.length; i ) {
output = (0x0F - parseInt(hexadecimal[i], 16)).toString(16);
}
output = (0x01 parseInt(output, 16)).toString(16);
return output;
}
}
Должно нормально работать для шестнадцатеричных чисел длиной до 16.
Комментарии:
1. это работает идеально
Ответ №2:
Чтобы создать числа с дополнением two фиксированного размера, я создал factory method:
function createToInt(size) {
if (size < 2) {
throw new Error('Minimum size is 2');
}
else if (size > 64) {
throw new Error('Maximum size is 64');
}
// Determine value range
const maxValue = (1 << (size - 1)) - 1;
const minValue = -maxValue - 1;
return (value) => {
if (value > maxValue || value < minValue) {
throw new Error(`Int${size} overflow`);
}
if (value < 0) {
return (1 << size) value;
}
else {
return value;
}
};
}
Теперь, чтобы решить ваш вопрос, вы можете создавать функции toInt8
, toInt16
, toInt32
и т.д. И используйте это для преобразования чисел JS в дополнение two. Пример с int8:
const toInt8 = createToInt(8);
'0x' toInt8(-128).toString(16); // -> 0x80
'0x' toInt8(127).toString(16); // -> 0x7f
'0x' toInt8(-1).toString(16); // -> 0xff
// Values less then 16 should be padded
'0x' toInt8(10).toString(16).padStart(2, '0); // -> 0x0a