Ich bin auf Edabit auf diese Herausforderung gestoßen und konnte diese bitweise Operationslösung nicht ausarbeiten.
notNotNot = (a,b) => !!(a%2 >> b)
Die Herausforderung:
//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
Ich habe einige Nachforschungen angestellt, dass dieser Betreiber:
Verschiebt sich nach rechts, indem Kopien des am weitesten links liegenden Bits von links hineingeschoben werden und die am weitesten rechts liegenden Bits abfallen.
Das glaube ich verstanden zu haben (zB das 5 >> 1
gleiche wie das, 0101 >> 1
was ausgewertet wird 0010
), aber ich kann nicht sehen, wie das mit einem Booleschen Wert funktioniert? Ich weiß, true
bewertet zu 1
und false
zu 0
.
javascript
Kiabbott
quelle
quelle
true
=1
(dezimal) =01
(binär), um eins nach links verschoben,10
binär oder2
dezimal erzeugt wird.notNotNot(2, true)
: Es wird zurückkehrenfalse
, aber nicht wahr (!!true
) solltetrue
...false
zu auflösendentrue
.notNotNot = (a,b) => !!((a%2)^b)
stattdessen sagen ...(a, b) => !!((a + b) % 2)
?Antworten:
Die von Ihnen angegebene Funktion erfüllt die Herausforderung nicht. Rechtsverschiebung wird nicht das tun, was verlangt wird. Zum Beispiel Ihre
notNotNot(6,true)
heißtfalse
, nicht ,true
wenn sie durch Ihre Funktion setzen.Ihre Frage bezieht sich jedoch auf die bitweise Operation auf einem Booleschen Wert. Da Operatoren Ganzzahlen mögen
>>
und damit<<
arbeiten, konvertiert Javascript zuerst den booleschen Wert in eine Ganzzahl. Sotrue
wird 1 undfalse
wird 0. Um dies zu sehen, können Sie um Null verschieben:Die Verwendung
!!
ist eine praktische Möglichkeit, etwas in einen Booleschen Wert umzuwandeln. Es etwas nimmt , das entspricht falsch angesehen werden würde (wie 0,null
,undefined
oder „“) und gibt zurückfalse
. Ebenso alles, was wahr ist (wie 14, "Hallo", [4], {a: 1}) und zurückgebentrue
.!!
funktioniert, weil das erste Ausrufezeichen das 'nicht' des Ausdrucks angibt, der immertrue
oder istfalse
, und das zweite Ausrufezeichen das Gegenteil von dem (false
odertrue
) gibt.Um auf die Herausforderung zurückzukommen, möchte es den Nicht-Operator 'a' mal anwenden und mit dem 'b'-Wert vergleichen. So etwas würde funktionieren:
quelle
if (a % 2 === 1) return !b else return b
aber wie in anderen Antworten gezeigt, gibt es Möglichkeiten, dies ohne Verzweigung oder Schleifen zu tun.Bitweise Operatoren konvertieren ihre Operanden immer in eine Ganzzahl. Es
4 >> true
ist also dasselbe, mit4 >> 1
dem eine Bitverschiebung um eine Position nach rechts ausgeführt wirdDie Verwendung von
true
oderfalse
ist also nur ein Umweg, um1
oder zu verwenden0
.Die
notNotNot
Funktion ist insgesamt sehr einfach zu bedienen:a%2
wandelt die erste Zahl in0
gerade oder1
ungerade um.>> b
verschiebt sich entweder um0
Positionen fürfalse
oder1
Position für nach rechtstrue
.a
ist ungerade (1) undb
istfalse
=1
a
ist ungerade (1) undb
isttrue
=0
1
wird nach rechts verschoben und verworfen.a
ist gerade (0) undb
istfalse
=0
a
ist gerade (0) undb
isttrue
=0
0
die, für die keine Bits gesetzt sind. Wenn Sie also einen beliebigen Betrag nach rechts verschieben, ändert sich dies nicht.!!()
konvertiert das Ergebnis in einen Booleschen Wert.Trotzdem ist die Lösung hier falsch, da
notNotNot(2, true)
sie produzieren wirdfalse
-a
ist gerade undb
isttrue
. Die Erwartung ist, dass estrue
seitdem produzieren wird!!true = true
. Das gleiche Problem besteht für jede gerade Zahl undtrue
.Es kann leicht behoben werden, indem bitweises XOR anstelle der Rechtsverschiebung verwendet wird:
a
ist ungerade (1) undb
istfalse
=1
0
a
ist ungerade (1) undb
isttrue
=0
1
a
ist gerade (0) undb
istfalse
=0
0
a
ist gerade (0) undb
isttrue
=1
1
Nur der Vollständigkeit halber, falls Sie eine vollständig bitweise Operation wünschen:
Die Modulo-Operation
%2
kann bitweise geändert werden UND&1
das niedrigste Bit erhalten. Für gerade Zahlen würde dies ergeben,0
da Sie rechnen würdenDas ist Null. Und für ungerade Zahlen gilt das Gleiche, aber Sie erhalten eine als Ergebnis:
Die Ergebnisse von
a&1
unda%2
sind also identisch. Auch wenn bitweise Operationen die Zahl in eine 32-Bit-Ganzzahl mit Vorzeichen konvertieren , spielt dies keine Rolle, da die Parität erhalten bleibt.Code-Snippet anzeigen
quelle
Erstens
(a,b) => !!(a%2 >> b)
stimmt nicht mit den Ergebnissen der Beispiele überein. Ich werde genau aufschlüsseln, was es machtnotNotNot(6, true) ➞ true
.a%2
, einfacha
durch 2 teilen, den Rest zurückgeben. Wir erhalten also 0 für eine gerade Zahl und 1 für eine ungerade Zahl.a = 6
a%2 = 0
in diesem Fall.0 >> b
verschieben Sie 1 Zahl von rechts weg, weil, wie Sie sagten,true
ausgewertet wird1
. Also bekommen wir0 >> 1 = 0
.!!(0)
ist einfach und kann wie, so abgebaut werden!0 = true
, dann!true = false
.Also , wenn wir denken , dass dies etwa so lang wie
b
isttrue
, werden wir immer wieder bekommenfalse
. Nehmen wir an, wir haben a = 5, b = wahr, um zu bewerten5%2 = 1
,1 >> 1 = 0
. Sie können sehen, dass%2
wir aufgrund von mod ( ) immer nur 1 oder 0 haben (immer nur 1 Ziffer haben) und true immer die 1 abschaltet, wenn wir sie haben.Eine einfache Möglichkeit, dieses Problem zu betrachten, ist wie eine
isEvenOrNot
Funktion. Diesa
gilt auch für die Zahl, die wir überprüfen, undb
ist ein Boolescher Wert, um zu überprüfen, ob sie gerade (wahr) oder nicht gerade (falsch) ist. Dies funktioniert, weil jedenot
hinzugefügte Sekunde wahr ist.Eine Lösung mit bitweiser Lösung könnte also etwa so aussehen :
(a,b) => !!(a&1 ^ b)
. Ich werde Ihnen den Spaß machen, herauszufinden, warum es funktioniert! :) :)Ein bisschen mehr in die Erklärung, wie Shift mit einem Booleschen Wert funktioniert. So
true
wie Sie gesagt haben 1 sein und falsch wird in Ihrem Beispiel 0. So wie dargestellt sein,0101 >> true
ist das gleiche wie0101 >> 1
.Ich hoffe das hilft.
Ich habe Folgendes als Referenz für bitweise verwendet: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
quelle
Hinweis: Bei beiden Booleschen Werten führt eine gerade Anzahl von NOTs zum ursprünglichen Booleschen Wert. Eine ungerade Anzahl von NOTs führt zum entgegengesetzten Booleschen Wert
Das LSB einer beliebigen Zahl bestimmt, ob die Zahl ungerade oder gerade ist (0 gerade, 1 ungerade).
quelle
Ich sehe, dass Ihre Aufgabe ist:
Ich weiß nicht, warum Sie eine
notnotnot
Funktion für mich schreiben , die die Aufgabe nicht verlangt.Entsprechend der Aufgabe habe ich diese Funktion erstellt
not
, die eine Reihe von "Nots" akzeptiert und diese auswertet.Der erste Weg
Der zweite Weg mit XOr (^)
Der dritte Weg mit Mod (%), auf den @VLAZ zeigt
Der vierte Weg mit bitweisem And (&)
Prüfung
quelle
n
- nur ob er gerade oder ungerade ist, da sich zwei beliebige NOTs aufheben, also!!!!!b
dasselbe wie!b
. Daher brauchen wir keine Schleife, wenn wir nur nehmenn%2
- wir würden1
für NICHT und0
für "Gleich bleiben" bekommen. Da wir eine Nummer haben, können wir nur bitweise Operationen ausführen.Lässt zuerst die Analyselösung
Analysieren Sie nun das für
(a,b) => !!(a%2 >> b)
Das ist Mittel , dies ist nicht für die Arbeit
notNotNot(6, true)
isttrue
aber die aktuelle Lösung gibtfalse
.Wir können Sie
^
(XOR) Operator, um es richtig zu machen(a,b) => !!(a%2 ^ b)
Analysieren Sie nun das für
(a,b) => !!(a%2 ^ b)
Beispiel:
quelle