Les opérateurs au niveau du bit convertissent toujours leurs opérandes en un entier. Donc, 4 >> truec'est la même chose que celle 4 >> 1qui fera un peu de décalage vers la droite d'une position
(decimal) 4 = (binary) 100
(binary) 100 >> 1 = (binary) 010
(binary) 010 = (decimal) 2
Donc, utiliser trueou falsen'est qu'un moyen détourné d'utiliser 1ou 0.
La notNotNotfonction a un fonctionnement très simple, dans l'ensemble:
a%2convertit le premier nombre en 0pair ou 1en impair.
>> bdécale vers la droite par des 0positions pour falseou une 1position pourtrue .
aest impair (1) et best false=1
- il n'y a aucun décalage vers la droite, donc le nombre reste le même.
aest impair (1) et best true=0
- le seul bit défini
1est décalé vers la droite et rejeté.
aest pair (0) et best false=0
- il n'y a aucun décalage vers la droite, donc le nombre reste le même.
aest pair (0) et best true=0
- le numéro de base est celui
0qui n'a pas de bits, donc le décalage vers la droite ne change rien.
!!() convertit le résultat en booléen.
Cela dit, la solution ici est fausse, car notNotNot(2, true)produira false- aest pair et best true. On s'attend à ce qu'il produise truedepuis !!true = true. Le même problème est présent pour tout nombre pair et true.
Il peut être facilement corrigé en utilisant XOR au niveau du bit au lieu du décalage vers la droite:
aest impair (1) et best false=1
- les deux correspondent, ils sont donc retournés à
0
aest impair (1) et best true=0
- ils ne correspondent pas, donc nous obtenons
1
aest pair (0) et best false=0
- les deux correspondent, donc nous obtenons
0
aest pair (0) et best true=1
- ils ne correspondent pas, donc nous obtenons
1
notNotNot = (a,b) => !!(a%2 ^ b);
console.log("!!true = ", notNotNot(2, true))
console.log("!!!true =", notNotNot(3, true))
console.log("!!false = ", notNotNot(2, false))
console.log("!!!false = ", notNotNot(3, false))
//bonus
console.log("true = ", notNotNot(0, true))
console.log("false = ", notNotNot(0, false))
Par souci d'exhaustivité, au cas où vous souhaiteriez une opération entièrement au niveau du bit:
L'opération modulo %2peut être changée en bit à bit ET &1obtenir le bit le plus bas. Pour les nombres pairs, cela donnerait 0puisque vous calculeriez
xxx0
&
0001
ce qui est nul. Et pour les nombres impairs, la même chose s'applique, mais vous en obtiendriez un en conséquence:
xxx1
&
0001
Les résultats de a&1et a%2sont donc identiques. De plus, même si les opérations au niveau du bit convertissent le nombre en un entier signé 32 bits, cela n'a pas d'importance car la parité serait préservée.
//larger than 31 bits
const largeValue = 2**31 + 1;
//larger than 32 bits
const veryLargeValue = 2**32 + 1
console.log("2**31 + 1 =", largeValue);
console.log("2**32 + 1 =", veryLargeValue);
console.log("2**31 + 1 to 32-bit signed integer =", largeValue | 0);
console.log("2**32 + 1 to 32-bit signed integer = ", veryLargeValue | 0);
const isOddModulo = number =>
console.log(`(${number} % 2) can detect an odd number: ${(number % 2) === 1}`);
const isOddBitwise = number =>
console.log(`(${number} & 1) can detect an odd number: ${(number & 1) === 1}`);
isOddModulo(largeValue);
isOddBitwise(largeValue);
isOddModulo(veryLargeValue);
isOddBitwise(veryLargeValue);
true=1(décimal) =01(binaire) décalé de gauche de un produirait du10binaire ou du2décimal.