Я столкнулся с этой проблемой в Edabit и не смог разработать это побитовое решение.
notNotNot = (a,b) => !!(a%2 >> b)
Соревнование:
//Something which is not true is false, but something which is not not true is true!
//Create a function where given n number of "not", evaluate whether it's true or false.
//Examples:
notNotNot(1, true) ➞ false
// Not true
notNotNot(2, false) ➞ false
// Not not false
notNotNot(6, true) ➞ true
// Not not not not not not true
Я провел некоторое исследование, что этот оператор:
Сдвиг вправо, толкая копии самого левого бита слева, и пусть самые правые биты падают.
То, что я считаю, я понял (например, то 5 >> 1
же, 0101 >> 1
что оценивает 0010
), но я не вижу, как это работает с логическим значением? Я знаю , что имеет true
значение 1
и false
для 0
.
javascript
kiabbott
источник
источник
true
=1
(десятичное) =01
(двоичное), сдвинутое влево на единицу, приведет к10
двоичному или2
десятичному.notNotNot(2, true)
: оно вернетсяfalse
, но не верно (!!true
) должно бытьtrue
...false
разрешенииtrue
.notNotNot = (a,b) => !!((a%2)^b)
вместо этого ...(a, b) => !!((a + b) % 2)
?Ответы:
Функция, которую вы дали, не удовлетворяет требованиям. Сдвиг вправо не будет делать то, о чем просят. Например, ваше
notNotNot(6,true)
этоfalse
, неtrue
положено через вашу функцию.Ваш вопрос касается побитовой операции над логическим значением. Поскольку операторы любят
>>
и<<
работают с целыми числами, Javascript сначала преобразует логическое значение в целое число. Такtrue
становится 1 иfalse
становится 0. Чтобы увидеть это, вы можете сдвинуться на ноль:Использование
!!
- это удобный способ конвертировать что-либо в логическое значение. Он принимает все , что бы считать эквивалентом к ложным (например, 0,null
,undefined
или «») и возвращаетfalse
. Точно так же все, что является правдивым (как 14, "привет", [4], {a: 1}) и вернутьtrue
.!!
работает, потому что первый восклицательный знак дает «не» выражения, которое всегдаtrue
илиfalse
, тогда второй восклицательный знак дает противоположность этому (false
илиtrue
).Возвращаясь к задаче, он хочет применить не-оператор 'a' раз и сравнить со значением 'b'. Так что-то вроде этого будет работать:
источник
if (a % 2 === 1) return !b else return b
но, как показано в других ответах, есть способы сделать это без разветвлений или циклов.Побитовые операторы всегда преобразуют свои операнды в целое число. Таким образом,
4 >> true
это то же самое,4 >> 1
что будет делать сдвиг вправо на одну позициюТаким образом, использование
true
илиfalse
просто окольный способ использования1
или0
.notNotNot
Функция имеет очень простую операцию, в целом:a%2
преобразует первое число в0
четное или1
нечетное.>> b
сдвиг вправо либо на0
позиции дляfalse
или1
позиции дляtrue
.a
нечетно (1) , иb
этоfalse
=1
a
нечетно (1) , иb
этоtrue
=0
1
сдвигается вправо и отбрасывается.a
даже (0) , иb
этоfalse
=0
a
даже (0) , иb
этоtrue
=0
0
не имеет битов, поэтому сдвиг вправо на любую величину не изменит его.!!()
преобразует результат в логическое значение.С учетом сказанного, решение здесь неправильное, поскольку
notNotNot(2, true)
будет производитьfalse
-a
есть иb
естьtrue
. Ожидается, что он будет производитьtrue
с тех пор!!true = true
. Такая же проблема присутствует для любого четного числа иtrue
.Это можно легко исправить, используя битовое XOR вместо правого смещения:
a
нечетно (1) , иb
этоfalse
=1
0
a
нечетно (1) , иb
этоtrue
=0
1
a
даже (0) , иb
этоfalse
=0
0
a
даже (0) , иb
этоtrue
=1
1
Просто для полноты, на случай, если вы хотите полностью побитовую операцию:
Операция по модулю
%2
может быть изменена на побитовое И&1
получить младший бит. Для четных чисел это даст,0
так как вы будете вычислятькоторый равен нулю. И для нечетных чисел то же самое относится, но вы получите один в результате:
Так что результаты
a&1
иa%2
идентичны. Кроме того, хотя побитовые операции преобразуют число в 32-разрядное целое число со знаком, что не имеет значения, так как четность будет сохранена.Показать фрагмент кода
источник
Во-первых,
(a,b) => !!(a%2 >> b)
не совпадает с результатами примеров. Я разобью именно то, что он делает, используяnotNotNot(6, true) ➞ true
.a%2
, просто получиa
деление на 2, верни остаток. Таким образом, мы получим 0 для четного числа и 1 для нечетного числа.a = 6
a%2 = 0
в этом случае.0 >> b
сдвиньте 1 число справа, потому что, как вы сказали,true
оценивается как1
. Итак, мы получаем0 >> 1 = 0
.!!(0)
просто и может быть разбито так!0 = true
, тогда!true = false
.Так что, если мы думаем об этом до тех пор , как
b
этоtrue
, мы всегда будем получать возвращеныfalse
. Допустим, мы имеем = 5, Ь = верно вычисляемые5%2 = 1
,1 >> 1 = 0
. Вы можете видеть из-за мода (%2
) у нас будет только 1 или 0 (только когда-либо будет 1 цифра), и true будет всегда сдвигаться от 1, когда он у нас есть.Простой способ взглянуть на эту проблему подобен
isEvenOrNot
функции. Таким образом,a
число, которое мы проверяем,b
является логическим для проверки, является ли оно четным (true) или нет (false). Это работает, потому что каждаяnot
добавленная секунда будет правдой.Таким образом, решение с использованием побитового может быть что - то вроде:
(a,b) => !!(a&1 ^ b)
. Я позволю вам весело разобраться, почему это работает! :)Еще немного о том, как объяснить, как сдвиг работает с логическим значением. Таким образом,
true
как вы сказали, будет 1, а false будет 0. Итак, как показано в вашем примере,0101 >> true
это то же самое, что и0101 >> 1
.Надеюсь, это поможет.
Я использовал следующее в качестве ссылки для побитового: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
источник
NB. Для любого логического значения четное число NOT приводит к исходному логическому значению, а нечетное число NOT приводит к противоположному логическому значению.
Младший бит любого числа определяет, является ли число нечетным или четным (0 четным, 1 нечетным).
источник
Я вижу, что ваша задача:
Я не знаю, почему вы пишете
notnotnot
для меня функцию, а не то, что просит задача.Таким образом, в соответствии с задачей я сделал эту функцию
not
которая принимает ряд «неимущих» и оценивает их.Первый путь
Второй способ с использованием XOr (^)
Третий способ, используя Mod (%), указанный @VLAZ
Четвертый способ с использованием побитового А (&)
Тестовое задание
источник
n
- только о том, является ли оно четным или нечетным, так как любые два NOT отменяют, так!!!!!b
же как и!b
. Следовательно, нам не нужен цикл, если мы просто возьмемn%2
- мы бы получили1
за НЕ и0
за «оставь это прежним». Поскольку у нас есть число, мы можем просто выполнять побитовые операции.Давайте сначала проанализируем решение
Теперь анализ для
(a,b) => !!(a%2 >> b)
Thats означает , что это не работает для
notNotNot(6, true)
это ,true
но текущее решение даетfalse
.Мы можем
^
(XOR) оператор, чтобы это исправить(a,b) => !!(a%2 ^ b)
Теперь анализ для
(a,b) => !!(a%2 ^ b)
Пример:
источник