Perché infinity è stampato come "8" nella console di Windows 10?


146

Stavo testando ciò che è stato restituito dalla divisione compresi gli zero 0/1, 1/0e cioè 0/0. Per questo ho usato qualcosa di simile al seguente:

Console.WriteLine(1d / 0d);

Tuttavia questo codice 8non stampa Infinityo qualche altra costante stringa come PositiveInfinity.

Per completezza tutte le seguenti stampe 8:

Console.WriteLine(1d / 0d);

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

Console.WriteLine(Double.PositiveInfinity);

E Console.WriteLine(Double.NegativeInfinity);stampe -8.

Perché questo infinity stampa 8?


Per quelli di voi che sembrano pensare che questo sia un simbolo di infinito e non un otto il seguente programma:

Console.WriteLine(1d / 0d);

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

Console.WriteLine(Double.PositiveInfinity);

Console.WriteLine(8);

Uscite:

Inifinity output


69
Vedi è il segno dell'infinito. basta capovolgerlo di 90 gradi per vederlo 8
Mohit Shrivastava,

23
Sei sicuro che sia un vero 8e proprio personaggio Unicode per l'infinito, ruotato di 90 gradi? Questo potrebbe cambiare in base alla tua lingua. L'ho provato su dotnetfiddle.net e stampa Infinity.
Kroltan,

4
@TheLethalCoder Fai ciò che Sinatr ha suggerito o stampa l'output di Double.PositiveInfinity.ToString()[0] == '8'. Ci sono alcuni personaggi esotici che sembrano molto simili ad altri in alcuni caratteri. Inoltre, in quale lingua è configurato il tuo computer?
Kroltan,

15
Questo sembra essere un problema di Windows 10. In Windows 8.1 avevo un simbolo di infinito. Aggiornato pochi giorni fa a Windows 10 e ora ho anche un 8(locale tedesco).
René Vogt,

13
Un rapido controllo sarebbe per vedere cosa succedeConsole.Write("∞");
Jon Hanna,

Risposte:


110

Assicurarsi che il valore in virgola mobile sia +Infinityse il numeratore di una divisione in virgola mobile per zero è positivo, -Infinityse il numeratore di una divisione in virgola mobile per zero è negativo e NaNse il numeratore e il denominatore di una divisione in virgola mobile sono entrambi zero. Questo è nelle specifiche IEEE754 in virgola mobile , che è ciò che usa C #.

Nel tuo caso, la console sta convertendo il simbolo dell'infinito (che a volte viene rappresentato tipograficamente come un 8 - horizontal orizzontale) in un 8 verticale.


13
@TheLethalCoder L'immagine non confuta questa risposta, dal momento che è un'immagine della tua console
Rob

9
@Rob Ho letto male la risposta, tuttavia ciò pone le domande, perché lo converte in un 8? E perché alcuni violini / console stampano letteralmente la stringa
TheLethalCoder

1
Questo sembra essere il caso usando il debugger vedo un simbolo di infinito (cioè l'8 orizzontale), c'è qualche ragione per cui la mia console si converte in un 8 mentre tutti gli altri sembrano usare Infinityo simili anche se uso il codice dalla risposta di Soren specificando la cultura
TheLethalCoder

4
Si chiama "lemniscato". Ha un valore unicode: ∞
BlueRaja - Danny Pflughoeft

14
Questo probabilmente spiega perché Buzz Lightyear dice "To Eight And Beyond!" quando gioco a Toy Story sul mio PC. ;)
DecanoOC

70

Date alcune impostazioni (ad es. Combinazione di culture, codifica di output, ecc.). NET produrrà il carattere infinito Unicode ∞ (∞ / & # 8734;). L'emulatore di console / terminale di Windows 10 (di nuovo con alcune impostazioni - vedi screenshot sotto) mostrerà questo carattere Unicode come un 8.

Ad esempio, su Windows 10, con le impostazioni seguenti (notare la tabella codici) semplicemente incollando ∞ nella console viene visualizzato come 8.

Impostazione per la riproduzione

MODIFICARE

Grazie al commento di Chris : sembra che il carattere di output in combinazione con la tabella codici sia responsabile del problema ∞ => 8 sulla console. Come lui, visualizzo correttamente ∞ in tutti i caratteri TrueType che ho provato e vedo solo 8 quando vengono scelti i caratteri raster.

impostazioni del carattere


1
Il mio in realtà mostra il segno di infinito sul suo lato invece di un "8" quando incollato nella console, anche se sto usando "437 (OEM - Stati Uniti)"
Derek 朕 會 功夫

3
Sebbene la risposta sia corretta, poiché alcune impostazioni possono causare questo problema di visualizzazione, la seconda metà non è corretta. Le mie opzioni al momento sono esattamente identiche alle tue sopra e ottengo il than corretto invece di un 8. Posso solo mostrarlo 8 se vado nella pagina dei caratteri e scelgo "caratteri raster" dall'elenco dei caratteri disponibili. Consolas, Courier New e altri sembrano mostrarlo bene ...
Chris,

È sicuramente una combinazione dei due fattori, perché l'impostazione del carattere su Raster quando la tabella codici è 437 mostra ancora il simbolo correttamente. Solo se entrambe le condizioni sono soddisfatte sembra che ciò accada (almeno per me).
Moshe Katz,

39

Il 8simbolo si verifica quando Windows converte Unicode in una codifica di caratteri legacy. Poiché non esiste un simbolo di infinito nella codifica legacy , per impostazione predefinita utilizza un "adattamento ottimale" a quel simbolo , che in questo caso è il numero 8. Vedere un esempio per la codifica "windows-1252" di Microsoft . Apparentemente, Windows 10 utilizza ancora codifiche di caratteri legacy per impostazione predefinita nella console (consultare "Pagine di codice" ).


11
Mi chiedo perché "8" sia considerato adatto, quando è semanticamente così adatto a generare confusione? Altri caratteri nella tabella codici 437 sembrano adattarsi meglio, come il segno del grado o il segno per mille (una% con due o sotto la barra). Nessuno di questi sarebbe buono come un vero segno di infinito, ma sembrerebbero meno inclini a creare confusione.
supercat

"Apparentemente, Windows 10 utilizza ancora codifiche di caratteri legacy per impostazione predefinita nella console" No, il mio cmd.exe di Windows 10 ha la codifica legacy disattivata.
Razze di leggerezza in orbita

Questa è la risposta migliore IMHO. In realtà, puoi anche vedere il carattere '8' nella posizione 0x2440 almeno sulla mia casella di Windows 10 nel file c: \ windows \ system32 \ c_1252.nls (l' infinito è 0x221E e il file ha un'intestazione che spiega l'offset) . Tutta la codifica della tabella codici ha un file .nls corrispondente. Per impostazione predefinita, la console utilizza la tabella codici 1252 (Windows 1252). Nota che questi mapping non verranno mantenuti, controlla questo: blogs.msdn.microsoft.com/shawnste/2007/09/24/…
Simon Mourier,

35

Nota: la .ToString()chiamata al metodo implicito durante la scritturaDouble.PositiveInfinity sulla console è responsabile di questo comportamento.

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

risulta nella stringa "Infinito"

mentre Console.WriteLine(Double.PositiveInfinity.ToString(new CultureInfo("fr-Fr"))); risulta "+ Infini".

Modifica: come altri hanno sottolineato nelle comete, non possono confermare del tutto i miei risultati. Provando questo su un'altra macchina, ottengo il personaggio per entrambe le chiamate.

Uscita per tutte le culture , grazie a vtortola nei commenti.


Ho trovato una (probabile) risposta:

Utilizzando Console.OutputEncoding = Encoding.Unicode;I posso ricreare il comportamento che stai vivendo per diverse culture, ad esempio "ru", "ru-RU" produce l'output 8.


1
Per interesse ho provato i tuoi esempi ed entrambi stampano 8
TheLethalCoder il

1
@TheLethalCoder Ottengo Infinityentrambi. Qual è la cultura della tua app? Controlla Thread.CurrentThread.CurrentCulturee Thread.CurrentThread.CurrentUICulture.
vtortola,

8
@ Søren D. Ptæus tbh Non riesco a vedere alcuna cultura che generi un 8 dotnetfiddle.net/QYhXMu
vtortola il

1
Hai ragione sull'implicito .ToString(). Alla fine, ToString()restituirà .PositiveInfinitySymbolil relativo NumberFormatInfo. Questi sembrano dipendere dalla versione del runtime e / o dalla versione di Windows (o di qualunque sistema operativo). Ai vecchi tempi, CultureInfo.GetCultureInfo("en-US").NumberFormat.PositiveInfinitySymbolsarebbe uguale "Infinity", ma con le versioni più recenti del runtime e del sistema operativo lo è"∞" invece. L'ho appena chiesto in un commento alla risposta di Hans Passant in questa discussione.
Jeppe Stig Nielsen,

16

Codice di riproduzione:

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 tabella codici 1252 è un incidente abbastanza comune in Inghilterra poiché è la tabella codici Windows predefinita lì. Come per l'Europa occidentale e le Americhe. Molte ragioni per modificare la proprietà Console.OutputEncoding predefinita a livello di codice, molti file di testo verranno codificati nel 1252. O dalla riga di comando digitandochcp 1252 (chcp == cambia la tabella codici) prima di avviare il programma.

Come si può vedere dal set di caratteri supportato da 1252, il simbolo Infinito non è disponibile. Quindi la codifica deve inventare un sostituto. Questo è spesso il ?glifo di punti di codice Unicode non supportati, il valore della proprietà Encoding.EncoderFallback per le codifiche a 8 bit. Ma per il 1252 e le pagine di codice MS-Dos 850 e 858 legacy, il programmatore Microsoft ha deciso8 . Ragazzo divertente.

Il glifo è supportato nella consueta tabella codici per le app della console su un computer occidentale. Che è 437, corrisponde al set di caratteri IBM legacy . Avere questo tipo di disastri di codifica è il motivo per cui Unicode è stato inventato. Purtroppo troppo tardi per salvare le app della console, troppi codici in giro si basavano sulla tabella codici MS-Dos predefinita.

La conversione di Double.PositiveInfinity in "∞" è specifica per Win10. Era "Infinity" nelle precedenti versioni di Windows. Questo tipo di formati può normalmente essere modificato con Pannello di controllo> Lingua> Cambia formato data, ora o numeri> pulsante Impostazioni aggiuntive ma la selezione del simbolo di infinito non è inclusa nella finestra di dialogo. Inoltre non coperto dal registro (HKCU \ Control Panel \ International), piuttosto una grande svista. È LOCALE_SPOSINFINITY nel winapi nativo. In un programma .NET è possibile sovrascriverlo a livello di codice clonando CultureInfo e modificando la proprietà NumberFormatInfo.PositiveInfinitySymbol. Come questo:

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();
    }
}

Il tuo codice mi ha permesso di confermare che WinXP utilizza la code page 437, che, in Windows 10, ora stampa ýanziché . Mi ha anche mostrato che l'uso di caratteri non raster evita il problema.
Mark Hurd,

È la versione del runtime .NET, o la versione di Windows (o qualunque sistema operativo), o una combinazione, che determina se CultureInfo.GetCultureInfo("en-US").NumberFormat.PositiveInfinitySymbol"Infinity"o "∞"(o qualcos'altro)? Dici sopra che è specifico per Windows 10, e sono d'accordo che è stato modificato in qualche momento. Ma se eseguo un'applicazione su Windows 8 con la "stessa" versione di .NET Framework , otterrò un risultato diverso rispetto a Windows 10?
Jeppe Stig Nielsen,

Questo problema inizia con Windows, quindi espone una stranezza in .NET. Win8 preferisce ancora "Infinity"
Hans Passant,

1
Confermato! Ho appena effettuato l'accesso a una macchina Windows Server 2012 R2 (corrisponde all'incirca a Windows 8.1) e so che ha il .NET Framework più recente e ha anche il Windows PowerShell più recente. In PowerShell, $PSVersionTablerivela che la versione PS è qualcosa con 5.1. Che PowerShell sia destinato a .NET Framework (CLR) versione 4. * che so sia nuovo su quella macchina. Ancora [cultureinfo]::GetCultureInfo("en-US").NumberFormat.PositiveInfinitySymbolda Windows PowerShell dà Infinity, non (la cultura attuale è en-US). Conclusione: la versione di Windows decide, non la versione .NET.
Jeppe Stig Nielsen,

0

"8" per infinito viene visualizzato nella console quando si esegue .Net 4 e versioni successive, altrimenti le versioni precedenti visualizzano "Infinito".

Utilizzando Console.OutputEncoding = Encoding.Unicode; in .Net 4 e versioni successive otterrà l'infinito da visualizzare come ∞, ma genera un'eccezione IOException nelle versioni precedenti.

NOTA: sto eseguendo Visual Studio 2015 Community Edition su Windows 10 a 64 bit

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.