visual not net for false ejemplo bool vb.net boolean

vb.net - not - Al convertir un valor booleano en un entero, devuelve-1 en verdadero?



vb net object to boolean (9)

Estoy trabajando con algún código VB.NET que parece estar emitiendo un valor booleano a un entero que usa CInt(myBoolean) . Lo extraño que está sucediendo es que devuelve -1 si el valor es verdadero. Por ejemplo:

CInt(True) // returns -1 CInt(False) // returns 0

¿Es esto común en otros idiomas?

Pensé que un booleano sería 1 si es verdadero y 0 si es falso. Además, ¿hay alguna manera de hacer que Visual Basic asigne 1 a verdadero en lugar de asignar -1?


Espero que pueda ayudar a otros a trabajar con booleanos dentro de VB.NET. Solo como una mejor forma de escribir el VB.NET que escribió Roger:

Public Function BoolToMySql(bVal As Boolean) As Integer return If(bVal, 1, 0) End Function


He estado teniendo el mismo problema con MySQL ya que este no tiene ningún tipo booleano, solo un tinyint (1).

Mi solución fue escribir una función de conversión para garantizar que los valores sean correctos antes de insertarlos en la base de datos.

Public Function BoolToMySql(bVal As Boolean) As Integer Dim retVal As Integer If bVal = True Then retVal = 1 Else retVal = 0 End If BoolToMySql = retVal End Function


La documentación de MSDN proporciona información valiosa:

Los valores booleanos no se almacenan como números, y los valores almacenados no pretenden ser equivalentes a números. Nunca debe escribir código que dependa de valores numéricos equivalentes para True y False. Siempre que sea posible, debe restringir el uso de variables booleanas a los valores lógicos para los que están diseñadas.


Lo probé y obtuve los siguientes resultados:

Public Module BooleanTest Public Function GetTrue() As Boolean GetTrue = True End Function End Module

...

[StructLayout(LayoutKind.Explicit)] struct MyStruct { [FieldOffset(0)] public bool MyBool; [FieldOffset(0)] public int MyInt32; } static void Main(string[] args) { MyStruct b1, b2; b1.MyInt32 = 0; b2.MyInt32 = 0; b1.MyBool = BooleanTest.BooleanTest.GetTrue(); b2.MyBool = true; Console.WriteLine(b1.MyInt32); Console.WriteLine(b2.MyInt32); }

Esto dará como resultado:

1
1

Espero que esto demuestre que todos los valores True dentro de .NET son siempre los mismos. La razón es simple: todos los miembros de .NET deben comunicarse entre sí. Sería extraño si object.Equals(trueFromCSharp, trueFromVB) daría como resultado false (como lo hará trueFromCSharp == trueFromVB ).

CInt es solo una función que convertirá True en -1 . Otra función Int devolverá 1 . Pero estos son conversores, y no dicen nada sobre los valores binarios.


Muchas versiones de BASIC en los años 1970 y 1980 implementaron la aritmética bit a bit con sus operadores AND y OR , y las expresiones condicionales verdaderas se evalúan a -1 (que era el valor de "todos los conjuntos de bits"). No estoy seguro de por qué se tomó la decisión de hacer que las expresiones condicional verdaderas se evalúen a un valor de conjunto de bits; ser capaz de usar AND para enmascarar un entero contra una expresión condicional puede haber sido más rápido que multiplicar, pero dada la mecánica interna de los intérpretes la diferencia habría sido leve.

En cualquier caso, las primeras versiones de BASIC que Microsoft produjo para la PC siguieron en esa tradición de tener condicionales verdaderos evaluar a -1 (todos los conjuntos de bits); como se suponía que QuickBASIC era compatible con ellos, y se suponía que Visual Basic era compatible con QuickBASIC, usaban la misma representación. Aunque .Net reconoce números enteros y booleanos como tipos diferentes, vb.net quería ofrecer una ruta de migración para los programas VB6 que podrían depender del comportamiento anterior. Con "Option Strict Off", VB.Net convertirá implícitamente un valor booleano de True en un entero -1; mientras que la mayoría de los programadores usan Option Strict On , puede ser confuso tener el comportamiento de CInt() diferente del comportamiento de conversión implícito.


Parece una gotcha, y no conozco ningún otro ejemplo de este comportamiento.

msdn.microsoft.com/en-us/library/ae382yt8.aspx especifica este comportamiento, con un comentario "No hagas eso, mkay" sorta con él. Anota más abajo:

Conversión en el marco

El método ToInt32 de la clase Convert en el espacio de nombres del sistema convierte True en +1.

Si debe convertir un valor booleano en un tipo de datos numéricos, tenga cuidado con el método de conversión que use.


Típicamente, un valor de falso se representa por 0 y un valor de verdadero se representa por cualquier valor entero distinto de 0. El valor específico para verdadero y falso (entre otros) son cosas en las que no debe confiar: pueden ser potencialmente específicos de la implementación. No estoy seguro de lo que intenta hacer, pero probablemente sería mejor no confiar en que True o False tenga valores enteros específicos a menos que sea absolutamente necesario.

La mejor explicación que pude encontrar para el comportamiento específico de VB proviene de Wikipedia :

La constante booleana True tiene valor numérico -1. Esto se debe a que el tipo de datos Boolean se almacena como un entero con signo de 16 bits. En este constructo, -1 evalúa 16 binarios 1 (el valor booleano es verdadero) y 0 como 16 0 s (el valor booleano es falso). Esto es evidente cuando se realiza una operación Not en un valor entero con signo de 16 bits 0 que devolverá el valor entero -1, en otras palabras, True = Not False. Esta funcionalidad inherente se vuelve especialmente útil cuando se realizan operaciones lógicas en los bits individuales de un entero como Y, O, X o y. [4] Esta definición de True también es coherente con BASIC desde principios de la década de 1970 en la implementación BASIC de Microsoft y también está relacionada con las características de las instrucciones de la CPU en ese momento.


Tuve el mismo problema y Math.Abs función Math.Abs en el resultado :)


Una solución para su uso inicial sería:

Dim i As Integer = CInt(Int(False))

Esto devolverá un 0.

Dim i As Integer = CInt(Int(True))

Esto devolverá un 1.