Dominique <z...@aol.com.invalid> writes:
>> Je comprends mal le comportement de ~ (le tilde) :
>>
>> soit a,b=5,7
>>
>> a>b False normal
>>
>> a>~b True, résultat attendu
>>
>> b<a False, normal, mais
>>
>> b<~a False aussi, et là, je ne comprends pas. Voyez-vous pourquoi
>> j'ai ce résultat inattendu ? Je suppose que, à la question « b pas
>> inférieur à a », je devrais obtenir True...
[...]
> Bon, mon fils m'a apporté une explication que je ne comprends pas bien
> mais je vois que not a==0 rend True, quelle que soit la valeur de a.
Ben non, si a vaut 0, "not a == 0" vaut False.
> Je déduis que « not une variable » retourne toujours 0, or 0 est
> False.
Hmmm. Il n'y a rien de tel. "not" est la négation booléenne (qui change
True and False et vice-versa). Son opérande devrait en toute rigueur
être toujours une valeur booléenne.
> Mais si x='' (string vide), not x donne True. pourquoi ?
Normalement "not" s'applique à un booléen (comme "a == 0"), donc quand
on applique "not" à autre chose, le choix a été fait de transformer
cette autre chose en booléen. Cela n'a aucune signification universelle,
c'est juste une commodité, avec des conventions plus ou moins
arbitraire. En gros, "not x" vaut :
- si x est None, il est considéré avoir la valeur booléenne False (donc
"not None" vaut True)
- si x est un entier, la valeur 0 est False et toute autre valeur est
True ; donc "not x" équivaut à "x == 0"
- si x est une chaîne de caractères, la valeur vide '' vaut False et
toute autre valeur vaut True ; donc "not x" équivaut à "len(x) == 0"
etc.
Les détails sont à
https://docs.python.org/3/reference/expressions.html#comparisons
Tout ça pout économiser quelques caractères...
> Pour revenir au tilde, soit a=5, ~a donne -6 et ~-5 donne 4...
> Pourquoi ? On voit comme un effet miroir avec une réduction de la
> valeur relative d'une unité (~5 donne -5-1 et ~-6 donne 6-1)...
Le tilde est l'opération de négation bit-à-bit (*pas* la négation
booléenne, une sorte de micro-négation appliquée ndividuellement sur les
bits qui composent une valeur). Elle change chaque bit en son
complément. Ce que tu oberves est le résultat de l'opération appliquée à
des données qui représentent des entiers. C'est lié au codage des
entiers en "complément à deux". Cf. par exemple (plutôt la page en
anglais) :
https://fr.wikipedia.org/wiki/Compl%C3%A9ment_%C3%A0_deux
https://en.wikipedia.org/wiki/Two%27s_complement
Et effectivement, ~x est égal à -(x+1). C'est une propriété de cette
représentation (~0 -> -1, ~1 -> -2, etc.), mais c'est une propriété
arithmétique, disons, anecdotique : l'opération ~ inverse
individuellement les bits de l'entier, c'est tout. Il existe des
microprocesseurs utilisant une autre représentation et cette propriété
n'est pas vraie sur ces processeurs.
Pour comprendre ce qui se passe, il faut se souvenir que les entiers
sont représentés sur un nombre fini de bits (en général 32 ou 64), et
que tous les bits sont inversés. Par exemple, sur 32 bits :
5 est représenté par 0...0101 (32 bits en tout, donc 29 fois 0 en tête).
~5 est donc 1...1010 (avec donc 29 fois 1 en tête)
Et 1...1010 c'est la représentation de -6.
(En python, le nombre de bits pour représenter un entier n'est pas fixé,
mais c'est une autre histoire et ça ne change rien à notre propos. Tu
peux imaginer qu'il y a toujours quelques zéros en tête d'une valeur
positive -- et quelques uns en tête d'une valeur négative.)
Le tilde n'est utile que quand on travaille sur des bits individuels
(qu'on regroupe en général dans des entiers, parce qu'on n'a pas mieux).
Les autres opérations apparentées sont & | ^ (autres opérations binaires
bit-à-bit : "and" "or" "xor"), ainsi que << et >> (décalages). Exercice
pour le lecteur : pourquoi est-ce que "-1 >> d" vaut -1 quelle que soit
la valeur de d ?
-- Alain.