2009-04-13 10 views
29

Tomemos el siguiente código:Convertir Boole a entero en 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 

Esto imprime los siguientes:

-1 
1 

¿Por qué es esto?

(sólo una broma :) Usted puede obtener también ... 0

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

Respuesta

43

Lo que están viendo es un poco de código heredado mostrando su cabeza.

En el corazón del asunto está el tipo VT_BOOL. Visual Basic 6.0 utilizó el tipo VT_BOOL (AKA VARIANT_BOOL) para sus valores booleanos. Verdadero para un VARIANT_BOOL se representa con el valor VARIANT_TRUE que tiene el valor entero -1. Durante la conversión a .NET, se decidió que al usar las rutinas de conversión de Visual Basic para convertir un valor booleano a un valor entero, la semántica de Visual Basic 6.0 se mantendría en el valor de retorno; sería -1.

La primera conversión implícita se produce con la línea b = i. Debajo del capó esto hace una conversión implícita de entero a booleano. Cualquier valor distinto de cero se considera verdadero, por lo tanto, el valor resultante es verdadero.

Sin embargo, la siguiente línea de código está realizando una conversión implícita a un tipo entero.

Bajo el capó esta utiliza una de las rutinas de conversión de Visual Basic (CType o CInt) para convertir el valor a un número entero. Como tal, la semántica de Visual Basic está en juego y el valor devuelto es -1.

La siguiente línea interesante es la línea Convert.ToInt32(). Esto está usando una rutina de conversión .NET que no usa la semántica de Visual Basic. En cambio, devuelve la representación subyacente BCL para un valor booleano verdadero que es 1.

+4

Es posible que desee agregar algo acerca de POR QUÉ se usó VT_BOOL, y por qué su valor es -1. VB 6 solo tenía 1 conjunto de operadores "y" y "o", que realizaban operaciones lógicas y en modo bit (la mayoría de los idiomas tienen 2 juegos). Esto funcionó haciendo "y" implementado como "&" y tiene el valor predeterminado literal en -1. –

+0

De esa manera "verdadero y x" no es cero en cualquier momento "x" no es cero. –

+0

Puede obtener una idea del "por qué" en mi respuesta a una pregunta en gran parte no relacionada aquí: https://stackoverflow.com/a/46331671/3043 –

25

Algunos consideran lenguas booleano verdadero ser -1 en lugar de 1. Tendría que hacer una investigación para ver por qué, como No recuerdo.

En VB6, la constante True tiene el valor -1.

Sin embargo, Convert.ToInt32(Boolean) es documented como regresar "El número 1 si el valor es verdadero; de lo contrario, 0." De esta forma, es lo mismo sin importar qué lenguaje de framework estás usando.

Editar: Véase la pregunta boolean true -- positive 1 or negative 1

+0

Algunos idiomas utilizan '' -1' como TRUE, porque es '0b11111111', por lo que cada bit es lo contrario de la representación binaria de cero, de manera que el uso de una operación NOT bit a bit en uno daría lugar a la otra. – mbomb007

1

Eso es porque en VB.NET, valores booleanos son -1 para el verdadero y 0 para false por defecto. No estoy seguro de por qué se imprime como 1 por segunda vez, aunque ...

7

De MSDN documentación de Visual Basic:

Type Conversions

Cuando Visual Basic convierte numéricos valores de tipo de datos a Boole, 0 se convierte en False y todos los demás valores se convierten en True. Cuando Visual Basic convierte valores booleanos en tipos numéricos, False se convierte en 0 y True se convierte en -1.

Y para Convert.ToInt32(value):

Retuns el número 1 si el valor es verdadero; lo contrario, 0.

Así que para su código:

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

Agregue un enlace para esas citas de documentos y voy a modificar. –

10

En cuanto a por qué -1 se usa para True, creo que es porque es literalmente (NO 0).

Comience con cero, voltee todos los bits y léalo como complemento de dos: sale negativo.

Así que como todo lo que no es False es Verdadero y False es 0, el (NO False) está representado por -1.

Esto puede ser sólo una coincidencia, aunque ....

+3

Es exactamente por eso que VB usa -1 para True. :) –

+1

+1. Es interesante observar que si "verdadero" es -1, los mismos operadores se pueden usar para lógica booleana y enmascaramiento de bits entero. También es interesante observar que la cuestión de si cortocircuitar "y" y "o" es independiente de la pregunta de si los operandos "verdaderos" deben ser forzados a un solo valor. – supercat

1

Todos los tipos de datos numéricos se pueden utilizar como booleana! El resultado depende del tipo de datos usados.

Ejemplos:

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 ! 

entero se firme, fiel a Entero -> -1.

UInteger es no firmado, Fiel a UInt -> 1.

Y así sucesivamente ...

un valor falso borra el bit más alto de los valores numéricos firmados, y la más baja en los valores numéricos no firmado.

Por lo tanto, False es 0 en todos los tipos de datos numéricos.

2

"Verdadero" es una negación del valor 0 de un tipo de datos numérico.

No (0) para los tipos no firmado devuelve 1.

No (0) para los tipos firmados devuelve -1.

No conozco su código, tal vez su código realiza una conversión de datos interna por segunda vez.

1

Ésta es una respuesta dudosa pero:

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