Чому на консолі Windows 10 друкується нескінченність як "8"?


146

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

Console.WriteLine(1d / 0d);

Однак цей код друкує 8ні, 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);

Виходи:

Вихід з нескінченності


69
Ви бачите, це знак нескінченності. просто переверніть його на 90 градусів, щоб побачити його 8
Мохіт Шрівастава

23
Ви впевнені, що це дійсний 8, а не якийсь дивний персонаж Unicode для нескінченності, який обертається на 90 градусів? Це може змінитися залежно від вашої мови. Я спробував це на dotnetfiddle.net і він друкує Infinity.
Кролтан

4
@TheLethalCoder Будь ласка, зробіть те, що запропонував Sinatr, або надрукуйте вихід Double.PositiveInfinity.ToString()[0] == '8'. Є деякі екзотичні персонажі, які в деяких шрифтах дуже схожі на інших. Також на якій мові налаштовано ваш комп’ютер?
Кролтан

15
Здається, це проблема Windows 10. У Windows 8.1 у мене був символ нескінченності. Оновлено кілька днів тому до Windows 10, і тепер у мене 8теж є (німецька мова).
Рене Фогт

13
Швидкий перевір був би, щоб побачити, що відбуваєтьсяConsole.Write("∞");
Джон Ханна

Відповіді:


110

Будьте впевнені, що значення з плаваючою комою є, +Infinityякщо чисельник поділу плаваючої точки на нуль позитивний, -Infinityякщо чисельник поділу плаваючої точки на нуль від'ємний, а NaNтакож чисельник і знаменник поділу з плаваючою комою - нуль. Це в специфікації IEEE754 з плаваючою точкою , для чого використовується C #.

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


13
@TheLethalCoder Зображення не спростує цю відповідь, оскільки це зображення вашої консолі
Роб

9
@Rob Я неправильно прочитав відповідь, однак, коли вона задає питання, чому вона перетворює її на 8? І чому деякі загадки / консолі друкують рядковий літерал
TheLethalCoder

1
Це, мабуть, так, використовуючи налагоджувач, я бачу символ нескінченності (тобто горизонтальний 8), чи є якась причина, щоб моя консоль перетворилася на 8, хоча всі інші, здається, використовують Infinityабо подібні, навіть якщо я використовую код з відповіді Soren, вказавши культуру
TheLethalCoder

4
Це називається "лемнікат". Має значення унікоду: ∞
BlueRaja - Danny Pflughoeft

14
Це, мабуть, пояснює, чому Buzz Lightyear каже "На вісім і далі!" коли я граю Toy Story на своєму ПК. ;)
DeanOC

70

Враховуючи певні налаштування (тобто комбінацію культур, кодування виводу тощо) .NET виведе символ Unicode нескінченності ∞ (∞ / & # 8734;). Емулятор консолі / терміналу Windows 10 (знову з урахуванням певних параметрів - див. Скріншот нижче) відображатиме цей символ Unicode як 8.

Наприклад, у Windows 10 із наведеними нижче параметрами (зверніть увагу на кодову сторінку) просто вставлення ∞ у консоль відображається як 8.

Налаштування для відтворення

EDIT

Завдяки коментарям від Chris : Схоже, що вихідний шрифт у поєднанні з кодовою сторінкою відповідає за питання issue => 8 на консолі. Як і він, я отримую належне відображення ∞ у всіх шрифтах TrueType, які я пробував, і бачу лише 8, коли вибрано растрові шрифти.

налаштування шрифту


1
Міна фактично показує знак нескінченності на його боці замість "8", коли вставляється в консоль, хоча я використовую "437 (OEM - США)"
Derek 朕 會 功夫

3
Хоча відповідь правильна, що певні налаштування можуть спричинити проблему відображення, друга половина невірна. В даний час мої параметри виглядають точно так само, як і вище, і я отримую правильний ∞, а не 8. Я можу змусити його показати лише 8, якщо перейти на сторінку шрифтів і вибрати зі списку доступних шрифтів "растрові шрифти". "Консоли", "Кур'єр Новий" та інші, здається, все це чудово показують ...
Кріс

Це, безумовно, поєднання двох факторів, тому що встановлення шрифту на Raster, коли сторінка коду 437, все ще показує символ правильно. Тільки за умови дотримання обох умов це здається (принаймні для мене).
Моше Кац

39

8Символ відбувається , коли Windows , перетворює Unicode в кодування символів спадщини. Оскільки в застарілому кодуванні немає символу нескінченності, він за замовчуванням використовує "найкраще" до цього символу , який у цьому випадку є числом 8. Дивіться приклад кодування "Windows-1252" від Microsoft . Мабуть, Windows 10 все ще використовує застарілі кодування символів у консолі (див. "Сторінки коду" ).


11
Цікаво, чому "8" вважається гарним пристосуванням, коли це семантично так вдається викликати плутанину? Інші символи на кодовій сторінці 437 здаються більш підходящими, як знак градуса або знак проміле (% із двома о. Нижче косої риски). Жоден із них не був би таким хорошим, як фактичний знак нескінченності, але вони здадуться менш схильними викликати плутанину.
supercat

"Мабуть, Windows 10 все ще використовує застарілі кодування символів за умовчанням у консолі" Ні, у мого Windows 10 cmd.exe застаріле кодування вимкнено поза коробкою.
Гонки легкості на орбіті

Це найкраща відповідь ІМХО. Насправді, ви також можете бачити символ 8 у позиції 0x2440 принаймні у вікні Windows 10 у файлі c: \ windows \ system32 \ c_1252.nls ( нескінченність 0x221E, а у файлі є заголовок, який пояснює зміщення) . Усі кодування сторінок мають відповідний .nls файл. За замовчуванням консоль використовує кодову сторінку 1252 (Windows 1252). Зверніть увагу, що ці відображення не підтримуватимуться, перевірте це: blogs.msdn.microsoft.com/shawnste/2007/09/24/…
Simon Mourier

35

Примітка: неявний .ToString()виклик методу під час запису Double.PositiveInfinityна консоль відповідає за цю поведінку.

Дзвінок Console.WriteLine(Double.PositiveInfinity.ToString(new CultureInfo("en-Us")));

результати в рядку "Нескінченність"

в той час як Console.WriteLine(Double.PositiveInfinity.ToString(new CultureInfo("fr-Fr"))); результат "+ Інфіні".

Редагувати: Як уже вказували інші в кометах, вони не можуть повністю підтвердити мої результати. Тестуючи це на іншій машині, я отримую персонаж для обох дзвінків.

Результати для всіх культур , завдяки vtortola в коментарях.


Я знайшов (ймовірно) відповідь:

Використовуючи Console.OutputEncoding = Encoding.Unicode;я, можна відтворити поведінку, яку ви відчуваєте для декількох культур, наприклад "ru", "ru-RU" дають результат 8.


1
З інтересу я спробував ваші приклади, і вони обидва друкують 8
TheLethalCoder

1
@TheLethalCoder я отримую Infinityв обох. Яку культуру працює ваш додаток? Перевірте Thread.CurrentThread.CurrentCultureі Thread.CurrentThread.CurrentUICulture.
vtortola

8
@ Søren D. Ptæus tbh Я не бачу жодної культури, що породжує 8 dotnetfiddle.net/QYhXMu
vtortola

1
Ви маєте рацію щодо неявного .ToString(). Зрештою, ToString()поверне .PositiveInfinitySymbolвідповідне NumberFormatInfo. Вони, схоже, залежать від версії часу виконання та / або версії Windows (або будь-якої іншої ОС). За старих часів це CultureInfo.GetCultureInfo("en-US").NumberFormat.PositiveInfinitySymbolбуло б рівно "Infinity", але з новішими версіями часу виконання та операційної системи це "∞"замість цього. Я щойно запитав про це у коментарі до відповіді Ганса Пассанта в цій темі.
Jeppe Stig Nielsen

16

Код запиту:

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, символ Infinity недоступний. Отже, Encoding повинен придумати заміну. Це часто ?гліф для непідтримуваних кодових точок 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 у рідних винах. У програмі .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();
    }
}

Ваш код дозволив мені підтвердити, що WinXP використовує кодову сторінку 437, яка в Windows 10 тепер друкується ýзамість . Це також показало мені, що використання нерастрових шрифтів дозволяє уникнути проблеми.
Марк Херд

Чи визначає, CultureInfo.GetCultureInfo("en-US").NumberFormat.PositiveInfinitySymbolдає "Infinity"чи "∞"(чи щось інше) версія виконання .NET, або версія Windows (чи іншої ОС) чи комбінація ? Ви кажете вище, що це специфічно для Windows 10, і я згоден, що це було змінено в якийсь час. Але якщо я запускаю додаток для Windows 8 із "тією ж" версією .NET Framework , чи отримаю я інший результат, ніж у Windows 10?
Джеппе Стіг Нільсен

Ця проблема починається з Windows, потім відкриває хитрість у .NET. Win8 все ще виступає за "Нескінченність"
Ганс Пасант

1
Підтверджено! Я щойно увійшов до машини Windows Server 2012 R2 (приблизно відповідає Windows 8.1), і я знаю, що вона має найновіший .NET Framework, а також новітню Windows PowerShell. У PowerShell $PSVersionTableвиявляє, що версія PS - це щось із 5.1. Цей PowerShell націлений на .NET Framework (CLR) версії 4. *, що я знаю, є новим на цій машині. Все-таки [cultureinfo]::GetCultureInfo("en-US").NumberFormat.PositiveInfinitySymbolз Windows PowerShell дає Infinity, ні (нинішня культура є en-US). Висновок: версія Windows вирішує, а не .NET версія.
Джеппе Стіг Нільсен

0

"8" для нескінченності відображається на консолі під час роботи .Net 4 і вище, інакше попередні версії відображають "Нескінченність".

Використання Console.OutputEncoding = Encoding.Unicode; в .Net 4 і вище отримає нескінченність для відображення як ∞, але кидає IOException у попередніх версіях.

ПРИМІТКА. У 64-розрядному Windows 10 запускається Visual Studio 2015 Community Edition

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.