2009-04-13 10 views
29

Prenez le code suivant:Convertir booléenne en entier VB.NET

Sub Main() 

    Dim i As Integer 
    Dim b As Boolean 

    i = 1 
    b = i 
    i = b 
    Console.WriteLine(i) 

    i = Convert.ToInt32(b) 
    Console.WriteLine(i) 

End Sub 

Imprime les suivantes:

-1 
1 

Pourquoi?

(juste une blague :) Vous pouvez obtenir 0 aussi ...

Int32.TryParse("True", i) 
Console.WriteLine(i) 

Répondre

43

Qu'est-ce que vous voyez est un peu de code existant montrant sa tête.

Au cœur de la question est le type de VT_BOOL. Visual Basic 6.0 utilisait le type VT_BOOL (AKA VARIANT_BOOL) pour ses valeurs booléennes. True pour un VARIANT_BOOL est représenté avec la valeur VARIANT_TRUE qui a la valeur entière -1. Au cours de la conversion en .NET il a été décidé que lors de l'utilisation des routines de conversion Visual Basic pour convertir une valeur booléenne à une valeur Integer, Visual Basic 6.0 sémantique serait maintenue sur la valeur de retour; ce serait -1.

La première conversion implicite se produit avec le b = i lignes. Sous le capot, cela fait une conversion implicite d'entier en booléen. Toute valeur non nulle est considérée comme vraie, donc la valeur résultante est vraie.

Cependant, la ligne de code suivante effectue une conversion implicite en un type entier.

Sous le capot celui-ci utilise l'une des routines de conversion Visual Basic (CType ou CInt) pour convertir la valeur à un nombre entier. En tant que telle sémantique Visual Basic sont en jeu et la valeur renvoyée est -1.

La prochaine ligne intéressante est la ligne Convert.ToInt32(). Cela utilise une routine de conversion .NET qui n'utilise pas la sémantique Visual Basic. Au lieu de cela, il retourne la représentation sous-jacente BCL pour une valeur booléenne vraie qui est 1.

+4

Vous voudrez peut-être ajouter quelque chose à propos de WHY VT_BOOL a été utilisé, et pourquoi sa valeur est -1. VB 6 ne disposait que d'un ensemble d'opérateurs "and" et "or", qui effectuaient des opérations logiques et binaires (la plupart des langages ont 2 ensembles). Cela a fonctionné en faisant "et" implémenté comme "&" et ont la valeur par défaut littérale à -1. –

+0

De cette façon "true et x" est non nul à tout moment "x" est non nul. –

+0

Vous pouvez avoir une idée du "pourquoi" dans ma réponse à une question la plupart du temps ici: https://stackoverflow.com/a/46331671/3043 –

25

Certaines langues considèrent booléen vrai être -1 plutôt que 1. Je dois faire des recherches pour voir pourquoi, Je ne m'en souviens pas. En VB6, la constante True a pour valeur -1.

Cependant, Convert.ToInt32(Boolean) est documented comme retournant "Le numéro 1 si la valeur est vraie, sinon, 0." De cette façon, c'est la même chose quel que soit le langage que vous utilisez.

Edit: Voir la question boolean true -- positive 1 or negative 1

+0

Certaines langues utilisent '-1' comme'on', parce qu'il est' 0b11111111', de sorte que chaque bit est à l'opposé de la représentation binaire de zéro, de sorte que l'utilisation une opération NOT un bit sur l'un aboutirait à l'autre. – mbomb007

1

C'est parce que dans VB.NET, les valeurs booléennes sont -1 pour vrai et 0 pour faux par défaut. Je ne sais pas pourquoi il imprime en 1 la deuxième fois, mais ...

7

A partir de MSDN Documentation Visual Basic:

Type Conversions

Lorsque Visual Basic convertit les valeurs de type de données numériques à Boolean, 0 devient faux et toutes les autres valeurs deviennent True. Lorsque Visual Basic convertit valeurs booléennes pour les types numériques, Faux devient 0 et devient vrai -1.

Et pour Convert.ToInt32(value):

le numéro 1 retour précis ou chiffré si la valeur est vrai; sinon, 0.

Donc, pour votre code:

i = 1 
b = i // b becomes true 
i = b // true = -1 
Console.WriteLine(i) // i is -1 

i = Convert.ToInt32(b) // Convert.ToInt32(true) = 1 
Console.WriteLine(i) // i is 1 
+0

Ajouter un lien pour ces citations de doc et je vais upmod. –

10

Pour ce qui est de la raison pour laquelle -1 est utilisé pour True, je crois que c'est parce qu'il est littéralement (PAS 0).

Commencez avec zéro, retournez tous les bits et lisez-le comme complément à deux - en sort un négatif. Donc comme tout ce qui n'est pas False est True et False vaut 0, le (NOT False) est représenté par -1.

Cela peut être juste une coïncidence, si ....

+3

C'est exactement pourquoi VB utilise -1 pour True. :) –

+1

+1. Il est intéressant de noter que si "true" vaut -1, les mêmes opérateurs peuvent être utilisés pour la logique booléenne et le masquage de bit entier. Il est également intéressant de noter que la question de savoir s'il faut court-circuiter "et" et "ou" est indépendante de la question de savoir si les opérandes "vrais" doivent être forcés à une seule valeur. – supercat

1

Tous les types de données numériques peuvent servir Boolean! Le résultat dépend du type de données utilisé.

Exemples:

Dim i As Byte ' Byte is non-signed! 
Dim b As Boolean = True 

i = b   ' Set first (lowest) bit of i (non-signed byte) 
' i is now binary 0000 0001 = 1! 


Dim i As SByte ' SByte is signed! 
Dim b As Boolean = True 

i = b   ' Set all bits of i (signed byte) 
' i is now FF (binary 1111 1111 = -1 ! 

Entier est signé, fidèle à Integer -> -1.

UInteger est non signé, à vrai UInt -> 1.

Et ainsi de suite ...

Une fausse valeur efface le bit de valeurs numériques signés, et le plus bas numerics non signé.

Par conséquent False est 0 dans tous les types de données numériques. "Vrai" est une négation de la valeur 0 d'un type de données numérique!

2

Non (0) pour les types non-signés retourne 1.

Non (0) pour les types signés renvoie -1.

Je ne connais pas votre code, peut-être que votre code effectue une conversion de données interne la deuxième fois.

1

Ceci est une réponse louches mais:

Dim b As Boolean 
    b = False 
    Dim i As Integer 
    i = IIf(b, 1, 0) 
Questions connexes