Почему бесконечность печатается как "8" в консоли Windows 10?

Я тестировал, что было возвращено из деления, включая нули, т.е. 0/1, 1/0 и 0/0. Для этого я использовал что-то похожее на следующее:

Console.WriteLine(1d / 0d);

Однако этот код печатает 8 not Infinity или некоторую другую строковую константу, такую ​​как PositiveInfinity.

Для полноты всей следующей печати 8:

Console.WriteLine(1d / 0d);

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

Console.WriteLine(Double.PositiveInfinity);

И Console.WriteLine(Double.NegativeInfinity); печатает -8.

Почему эта бесконечность печатает 8?


Для тех из вас, кто, кажется, считает, что это символ бесконечности, а не восемь следующих программ:

Console.WriteLine(1d / 0d);

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

Console.WriteLine(Double.PositiveInfinity);

Console.WriteLine(8);

Выходы:

Inifinity output

Ответ 1

Будьте уверены, что значение с плавающей запятой +Infinity, если числитель деления с плавающей запятой на ноль положителен, -Infinity, если числитель деления с плавающей запятой на ноль отрицателен, а NaN, если числитель и знаменатель деления с плавающей запятой равны нулю. Это в спецификации IEEE754 с плавающей запятой, которую использует С#.

В вашем случае консоль преобразует символ бесконечности (который иногда представляется типографически как горизонтальный 8 - ∞) к вертикали 8.

Ответ 2

При определенных настройках (т.е. комбинации культур, выходной кодировке и т.д.).NET выведет символ бесконечности Unicode ∞ (∞/& # 8734;). Консольный/терминальный эмулятор Windows 10 (снова заданный некоторыми настройками - см. Снимок экрана ниже) отображает этот символ Юникода как 8.

Например, в Windows 10 с приведенными ниже настройками (обратите внимание на кодовую страницу) просто вставка ∞ в консоль отображается как 8.

Настройка для воспроизведения

ИЗМЕНИТЬ

Благодаря комментариям Chris: Кажется, что выходной шрифт в сочетании с кодовой страницей отвечает за проблему ∞ = > 8 на консоли. Как и он, я получаю надлежащее отображение ∞ во всех шрифтах TrueType, которые я пробовал, и вижу только 8, когда выбраны растровые шрифты.

настройки шрифта

Ответ 3

Символ 8 появляется, когда Windows преобразует Unicode в кодировку устаревшего символа. Поскольку в устаревшем кодировании нет символа бесконечности, он по умолчанию использует "наилучшим образом подходит" этому символу, который в этом случае является номер 8. См. пример Microsoft "windows-1252" кодировка. По-видимому, Windows 10 по-прежнему использует устаревшие кодировки символов по умолчанию в консоли (см. "Страницы кодов" ).

Ответ 4

Примечание. Неявный вызов метода .ToString() при записи Double.PositiveInfinity в консоль отвечает за это поведение.

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

выводит строку "Бесконечность"

while Console.WriteLine(Double.PositiveInfinity.ToString(new CultureInfo("fr-Fr"))); приводит к "+ Infini".

Изменить: как указывали другие в кометах, они не могут полностью подтвердить мои результаты. Проверяя это на другой машине, я получаю символ для обоих вызовов.

Выход для всех культур, благодаря vtortola в комментариях.


Я нашел (вероятный) ответ:

Используя Console.OutputEncoding = Encoding.Unicode;, я могу воссоздать поведение, которое вы испытываете для нескольких культур, например. "ru", "ru-RU" производят вывод 8.

Ответ 5

Код репрограммы:

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

Кодовая страница 1252 - довольно распространенная авария в Англии, поскольку она является кодовой страницей Windows по умолчанию. Как для Западной Европы, так и для Америки. Множество причин для изменения свойства Console.OutputEncoding по умолчанию программно, многие текстовые файлы будут закодированы в 1252. Или из командной строки, набрав chcp 1252 (chcp == изменить кодовую страницу) перед запуском программы.

Как вы можете узнать из набора символов, поддерживаемого 1252, символ Бесконечности недоступен. Таким образом, кодировка должна быть заменена. Это часто символ ? для неподдерживаемых кодов Unicode, значение свойства Encoding.EncoderFallback для 8-битных кодировок. Но для 1252 и старых кодовых страниц MS-Dos 850 и 858 программист Microsoft решил для 8. Забавный парень.

Символ поддерживается на обычной кодовой странице для консольных приложений на западной машине. Это 437, соответствует устаревшему набору символов IBM. Причиной такого рода ошибок при кодировании является то, что Unicode был изобретен. К сожалению слишком поздно, чтобы спасти консольные приложения, слишком много кода вокруг, который основывался на кодовой странице MS-Dos по умолчанию.

Наличие Double.PositiveInfinity, преобразованного в "∞", относится к Win10. Раньше это была "Бесконечность" в предыдущих версиях Windows. Эти форматы обычно могут быть изменены с помощью панели управления > Язык > Изменить дату, время или числовые форматы > Кнопка "Дополнительные настройки", но символ бесконечности не включен в диалог. Также не распространяется на реестр (HKCU\Control Panel\International), а большой надзор. Это LOCALE_SPOSINFINITY в родном winapi. В .NET-программе вы можете переопределить его программно, клонируя CultureInfo и изменяя его свойство NumberFormatInfo.PositiveInfinitySymbol. Вот так:

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

Ответ 6

"8" для бесконечности отображается в консоли при запуске .Net 4 и выше, в противном случае предыдущие версии отображают "Бесконечность".

Использование Console.OutputEncoding = Encoding.Unicode; в .Net 4 и выше получит бесконечность для отображения в виде ∞, но бросает исключение IOException в предыдущих версиях.

ПРИМЕЧАНИЕ. Я запускаю Visual Studio 2015 Community Edition в Windows 10 64-bit