Tengo un código donde la conversión de tipos devuelve un valor muy diferente del valor más grande.
static void Main(string[] args) { double a = 345.09; byte c = (byte) a; Console.WriteLine(c); Console.ReadLine(); } Esto devuelve el valor 89 . ¿Cuál es la razón detrás de esto?
El rango de bytes comienza de 0 a 255, está obteniendo un resultado de 89 porque comienza a contar nuevamente desde 0 una vez que va más allá de 255. es decir
byte c = (byte) a; //345 - 255 (consider `0` as well) Console.WriteLine(c); // ie 89La razón detrás del rango de bytes:
bytealmacena datos de 8 bits. Los valores0000 0000y1111 1111(datos binarios de 8 bits) se pueden definir como valorMinyMaxpara la variable debyterespectivamente, por lo que en entero se convierte en0y255
lo que sucede es que solo se toman los últimos 8 bits cuando lanzas el número. Permítanme explicar con un ejemplo usando ints. Yo uso int para simplificar, porque si lanzas el double a una representación de número no flotante, los lugares decimales se descartan de todos modos.
Primero nos fijamos en la representación binaria del número 345:
string binaryInt = Convert.ToString(345, 2); Console.WriteLine(binaryInt);La salida es:
1 0101 1001
Cuando ahora tomamos solo los últimos 8 bits, que es el tamaño de un tipo de byte :
string eightLastBits = binaryInt.Substring(binaryInt.Length-8); Console.WriteLine(eightLastBits);Obtenemos:
0101 1001
Si volvemos a convertir esto a byte verás que el resultado es 89:
byte backAgain = Convert.ToByte(eightLastBits, 2); Console.WriteLine(backAgain);Producción:
89
EDITAR:
Como lo señaló InBetween, el ejemplo int es el verdadero negocio y lo que realmente sucede durante la transmisión.
Mirando la implementación de la conversión de doble a byte:
/// <internalonly/> byte IConvertible.ToByte(IFormatProvider provider) { return Convert.ToByte(m_value); }Si observamos la implementación del método Convert.ToByte : vemos que el doble se convierte primero en un número entero:
public static byte ToByte(double value) { return ToByte(ToInt32(value)); }Tenga en cuenta que este es uno de los pocos casos en los que no se especifica el resultado.
De la especificación de idioma , omitiendo los casos irrelevantes
Para una conversión de tipo
floatodoublea un tipo integral, el procesamiento depende del contexto de comprobación de desbordamiento (los operadores marcados y no marcados) en el que tiene lugar la conversión:En un contexto no verificado, la conversión siempre tiene éxito y procede de la siguiente manera.
Si el valor del operando es NaN o infinito, [...]
De lo contrario, el operando de origen se redondea hacia cero al valor integral más cercano. Si este valor integral está dentro del rango del tipo de destino, [...]
De lo contrario, el resultado de la conversión es un valor no especificado del tipo de destino
Presumiblemente, la implementación simplemente eliminó los bits más altos después de convertirlos al valor integral más cercano, dejando solo los 8 bits menos significativos, ya que probablemente sea lo más conveniente en ese momento. Pero tenga en cuenta que, según esta especificación, 0 es un valor tan válido como 89 para esta conversión.