Оператор правого сдвига ( >> ) может менять знак номера

Мы можем прочитать об операторе правого сдвига >> на MDN

... знак результирующего числа такой же, как знак первого операнда.

Однако 3332508426 >> 24 === -58 в моем Chrome 127.0.6533.120.

Как это можно объяснить?

Кстати, 3332508426 — это десятичное представление IP 198.162.11.10.

объяснил что? преобразование целых чисел в IP-адрес?

Mister Jojo 19.08.2024 13:22

Нет, я не понимаю, почему 3332508426 >> 24 === -58 (почему оператор >> изменил знак числа)

Borneo777 19.08.2024 13:30
const n2ip=n=>n.toString(16).padStart(8,'0').match(/.{2}/g).map(s=‌​>parseInt(s,16)).joi‌​n('.');
Mister Jojo 19.08.2024 17:35

Спасибо за функцию преобразования номера в IPv4, но это не основная тема моего поста.

Borneo777 19.08.2024 17:50

и именно поэтому я разместил это в комментарии, а не в Ответах...

Mister Jojo 19.08.2024 18:31
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
5
51
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Битовые манипуляции в Javascript работают с 32-битными целыми числами со знаком.

1<<31 например дает -2147483648

Однако числовые значения используют точность с плавающей запятой double (64 бит IEEE754), поэтому проблем с записью, например, нет.

x = 2147483648

и если вы отобразите x, вы получите 2147483648 (целые числа представляются без потери точности до ∓2⁵³ = ∓9007199254740992... намного больше, чем 32 бита).

Например, просто сдвинув x на НОЛЬ мест, вы получите -2147483648.

x << 0 возвращается -2147483648

потому что вычисление выполняется с использованием 32-битных целых чисел со знаком.

3332508426 — это HEX C6A20B0A. Если это интерпретируется как 32-битное целое число, старший бит равен 1, поэтому он отрицателен. Переключение вправо сохраняет знак.

Я не понимаю, почему вы написали, каково шестнадцатеричное представление моего номера.

Borneo777 19.08.2024 13:35

@ Borneo777 Мне было интересно, единственное, что я могу придумать, это то, что C в двоичном формате - это 1100, а самый левый бит - это 1, и, возможно, он придерживается старой школы и имеет преобразование HEX в BIN-попугай. Конечно, это работает только для прямого порядка байтов (то, что использует Javascript), для прямого порядка байтов вам нужно будет выбрать предпоследний шестнадцатеричный символ, а затем первый левый бит четырехбитного бита. Это своего рода то, что сделало HEX популярным в старом ассемблере и т. д., HEX в BIN было проще, чем DEC в BIN и т. д. IOW: если первое дополненное 0 значение HEX равно 8-F, это отрицательное число.

Keith 19.08.2024 14:56

Верно, Кит. У C старший бит = 1, вероятно, не все сразу это понимают (кстати, это не оскорбление). Это мой аппаратный опыт ;-)

Lex W. 19.08.2024 15:51

@LexW. спасибо за ваше объяснение

Borneo777 19.08.2024 17:53
Ответ принят как подходящий

MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Right_shift#description

Оператор >> перегружен для двух типов операндов: числового и BigInt. Для чисел оператор возвращает 32-битное целое число.

Поскольку 3332508426 уже является 32-битным целым числом, оно использует это значение. Однако 32-битные числа имеют знак, а 32-битное двоичное представление самого левого бита вашего числа равно 1, то есть является отрицательным значением.

9 (base 10): 00000000000000000000000000001001 (base 2)
-9 (base 10): 11111111111111111111111111110111 (base 2)

Решение состоит в том, чтобы сначала преобразовать ваш номер в BigInt, а затем конвертировать обратно, то есть:

let result = Number(BigInt(3332508426) >> BigInt(24));

console.info(result);
console.info(Number((BigInt(3332508426) >> BigInt(16)) % BigInt(1<<8)))
console.info(Number((BigInt(3332508426) >> BigInt(8)) % BigInt(1<<8)))
console.info(Number(BigInt(3332508426) % BigInt(1<<8)))

Другие объяснили, почему это отрицательно, но если вы сразу после извлечения байтов из Uint32,..

Другой вариант, вместо смещения битов: если вы хотите извлечь байты из Uint32, создайте UInt32Array с одним значением, а затем преобразуйте его в Uint8Array для извлечения байтов.

например.

const a = new Uint8Array(new Uint32Array([3332508426]).buffer);
console.info(`${a[3]}.${a[2]}.${a[1]}.${a[0]}`);

Другие вопросы по теме