¿Por qué el infinito se imprime como “8” en la consola de Windows 10?

Estaba probando lo que se devolvió de la división, incluyendo ceros, es decir, 0/1 , 1/0 y 0/0 . Para esto usé algo similar a lo siguiente:

 Console.WriteLine(1d / 0d); 

Sin embargo, este código imprime 8 no Infinity o alguna otra cadena constante como PositiveInfinity .

Para completar todo lo siguiente, imprima 8 :

 Console.WriteLine(1d / 0d); double value = 1d / 0d; Console.WriteLine(value); Console.WriteLine(Double.PositiveInfinity); 

Y Console.WriteLine(Double.NegativeInfinity); impresiones -8 .

¿Por qué este infinito imprime 8?


Para aquellos de ustedes que parecen pensar que este es un símbolo de infinito, no es un ocho el siguiente progtwig:

 Console.WriteLine(1d / 0d); double value = 1d / 0d; Console.WriteLine(value); Console.WriteLine(Double.PositiveInfinity); Console.WriteLine(8); 

Productos:

Salida de infinito

Ten por seguro que el valor del punto flotante es +Infinity si el numerador de una división de coma flotante por cero es positivo, -Infinity si el numerador de una división de punto flotante por cero es negativo, y NaN si es el numerador y el denominador de una división de punto flotante son ambos cero Eso está en la especificación de coma flotante IEEE754 , que es lo que C # usa.

En su caso, la consola está convirtiendo el símbolo de infinito (que a veces se representa tipográficamente como un 8 – ∞ horizontal) en un 8 vertical.

Dadas ciertas configuraciones (es decir, combinación de culturas, encoding de salida, etc.) .NET emitirá el carácter infinito Unicode ∞ (∞ / & # 8734;). El emulador de consola / terminal de Windows 10 (de nuevo, dada cierta configuración – vea la captura de pantalla a continuación) muestra este carácter Unicode como un 8.

Por ejemplo, en Windows 10, con las configuraciones a continuación (observe la página de códigos) simplemente pegando ∞ en la consola se muestra como 8.

Configuración para reproducirse

EDITAR

Con agradecimiento al comentario de Chris : parece que la fuente de salida en combinación con la página de códigos es responsable del problema ∞ => 8 en la consola. Al igual que él, tengo una visualización adecuada de ∞ en todas las fonts TrueType que he probado y solo veo 8 cuando se eligen las fonts de ttwig.

configuración de fuente

El símbolo 8 produce cuando Windows convierte Unicode en una encoding de caracteres heredada. Dado que no existe un símbolo de infinito en la encoding heredada , de manera predeterminada usa el mejor ajuste para ese símbolo , que en este caso es el número 8. Consulte un ejemplo para la encoding “windows-1252” de Microsoft . Aparentemente, Windows 10 aún usa codificaciones heredadas de caracteres de forma predeterminada en la consola (consulte “Páginas de códigos” ).

Nota: La llamada al método implícita .ToString() al escribir Double.PositiveInfinity en la consola es responsable de este comportamiento.

Llamando a Console.WriteLine(Double.PositiveInfinity.ToString(new CultureInfo("en-Us")));

resultados en la cadena “Infinito”

mientras Console.WriteLine(Double.PositiveInfinity.ToString(new CultureInfo("fr-Fr"))); resultados en “+ Infini”.

Editar: Como han señalado otros en los commets, no pueden confirmar completamente mis resultados. Probando esto en una máquina diferente, obtengo el carácter para ambas llamadas.

Salida para todas las culturas , gracias a vtortola en los comentarios.


Encontré una respuesta (probable):

Usando Console.OutputEncoding = Encoding.Unicode; Puedo recrear el comportamiento que está experimentando para varias culturas, por ejemplo, “ru”, “ru-RU” producen la salida 8 .

Código de reproducción:

 using System; using System.Text; class Program { static void Main(string[] args) { var infinity = "\u221e"; Console.OutputEncoding = Encoding.GetEncoding(1252); Console.WriteLine(infinity); Console.ReadLine(); } } 

La página de códigos 1252 es un accidente bastante común en Inglaterra ya que es la página de códigos de Windows predeterminada allí. Como lo es para Europa Occidental y las Américas. Muchos motivos para cambiar la propiedad Console.OutputEncoding predeterminada de forma programática, muchos archivos de texto se codificarán en 1252. O desde la línea de comando, escriba chcp 1252 (chcp == página de códigos de cambio) antes de iniciar el progtwig.

Como puede ver en el juego de caracteres admitido por 1252, el símbolo Infinito no está disponible. Entonces la Codificación tiene que venir con un sustituto. Eso es a menudo el ? glifo para puntos de código Unicode no soportados, el valor de la propiedad Encoding.EncoderFallback para codificaciones de 8 bits. Pero para 1252, y las páginas de códigos MS-Dos 850 y 858 heredadas, el progtwigdor de Microsoft decidió por 8 . Chico divertido.

El glifo es compatible en la página de códigos habitual para aplicaciones de consola en una máquina occidental. Que es 437, coincide con el conjunto de caracteres heredado de IBM . Tener este tipo de desastres de encoding es la razón por la que se inventó Unicode. Lamentablemente, demasiado tarde para rescatar las aplicaciones de la consola, había demasiados códigos que dependían de la página de códigos MS-Dos predeterminada.

Tener Double.PositiveInfinity convertido a “∞” es específico de Win10. Solía ​​ser “Infinito” en versiones anteriores de Windows. Este tipo de formatos normalmente se puede modificar con el Panel de control> Idioma> Cambiar fecha, hora o formato de número> botón Configuración adicional, pero la selección del símbolo de infinito no se incluye en el cuadro de diálogo. Además, no está cubierto por el registro (HKCU \ Control Panel \ International), sino como un gran descuido. Es LOCALE_SPOSINFINITY en los winapi nativos. En un progtwig .NET, puede sobrescribirlo mediante progtwigción clonando CultureInfo y cambiando su propiedad NumberFormatInfo.PositiveInfinitySymbol. Me gusta esto:

 using System; using System.Text; using System.Threading; using System.Globalization; class Program { static void Main(string[] args) { Console.OutputEncoding = Encoding.GetEncoding(1252); var ci = (CultureInfo)Thread.CurrentThread.CurrentCulture.Clone(); ci.NumberFormat.NegativeInfinitySymbol = "-Infinity"; ci.NumberFormat.PositiveInfinitySymbol = "And beyond"; Thread.CurrentThread.CurrentCulture = ci; Console.WriteLine(1 / 0.0); Console.ReadLine(); } } 

“8” para infinito se muestra en la consola cuando se ejecuta .Net 4 y superior, de lo contrario las versiones anteriores muestran “Infinito”.

Usando Console.OutputEncoding = Encoding.Unicode; en .Net 4 y superior tendrá infinito para mostrarse como ∞, pero arroja una IOException en versiones anteriores.

NOTA: ejecuto Visual Studio 2015 Community Edition en Windows 10 de 64 bits