为什么无限远在Windows 10控制台中打印为"8"?

The*_*der 144 .net c# windows

我正在测试从分区返回的内容,包括零0/1,1/00/0.为此,我使用了类似于以下内容的东西:

Console.WriteLine(1d / 0d);
Run Code Online (Sandbox Code Playgroud)

但是这段代码打印8不到Infinity或者其他一些字符串常量就像PositiveInfinity.

为了完整性,以下所有内容均为8:

Console.WriteLine(1d / 0d);

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

Console.WriteLine(Double.PositiveInfinity);
Run Code Online (Sandbox Code Playgroud)

Console.WriteLine(Double.NegativeInfinity);打印-8.

为什么这个无限打印8?


对于那些似乎认为这是一个无穷大符号而不是八个以下程序的人:

Console.WriteLine(1d / 0d);

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

Console.WriteLine(Double.PositiveInfinity);

Console.WriteLine(8);
Run Code Online (Sandbox Code Playgroud)

输出:

无限输出

Bat*_*eba 109

+Infinity如果浮点除以零-Infinity的分子为负,并且NaN浮点除法的分子和分母均为零,则确保浮点值是浮点除以零的分子为正.那就是IEEE754浮点规范,这是C#使用的规范.

在您的情况下,控制台将无穷大符号(有时以印刷方式表示为水平8 - ∞)转换为垂直8.

  • @TheLethalCoder图片并没有反驳这个答案,因为它是你的控制台的图片 (13认同)
  • 这可能解释了为什么Buzz Lightyear说"八点以上!" 当我在电脑上玩玩具总动员时.;) (12认同)
  • @Rob我误解了答案,然而这引起了问题,为什么它将它转换为8?为什么有些小提琴/控制台打印字符串文字 (9认同)
  • 它被称为"lemniscate".它具有unicode值:∞ (4认同)

tol*_*anj 70

给定某些设置(即文化组合,输出编码等).NET将输出Unicode无穷大字符∞(∞/∞).Windows 10控制台/终端仿真器(再次给出某些设置 - 请参见下面的屏幕截图)将此Unicode字符显示为8.

例如,在Windows 10上,使用以下设置(注意代码页)只需将∞粘贴到控制台中即显示为8.

设置重现

编辑

感谢Chris的评论:似乎输出字体代码页一起负责控制台上的∞=> 8问题.和他一样,我在我尝试的所有TrueType字体中都得到了正确的∞显示,只有在选择了光栅字体时才能看到8.

字体设置

  • 虽然答案是正确的,某些设置可能导致此显示问题,但后半部分不正确.我的选项目前看起来和你的选项完全一样,我得到的是正确的∞而不是8.如果我进入字体页面并从可用字体列表中选择"光栅字体",我只能显示8.Consolas,Courier New和其他人似乎都表现得很好...... (3认同)

Pet*_* O. 38

8Windows将Unicode转换为旧版字符编码时出现该符号.由于传统编码中没有无穷大符号,因此默认情况下它使用该符号"最佳拟合",在本例中为8号.请参阅Microsoft的"windows-1252"编码示例.显然,Windows 10 在控制台中默认使用旧版字符编码(请参阅"代码页").

  • 我想知道为什么"8"被认为是一个很好的选择,当它在语义上容易产生混淆时?代码页437中的其他字符看起来更合适,例如度数符号或per-mille符号(斜线下方两个o的%).这些都不如实际的无限标志那么好,但它们似乎不太容易引起混淆. (10认同)

Sør*_*æus 35

注意:.ToString()写入Double.PositiveInfinity控制台时的隐式方法调用负责此行为.

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

结果字符串"无限"

Console.WriteLine(Double.PositiveInfinity.ToString(new CultureInfo("fr-Fr"))); 结果是"+ Infini".

编辑:正如其他人在纪念中指出的那样,他们无法完全证实我的结果.在另一台机器上测试它,我得到?两个调用的字符.

所有文化的输出,归功于评论中的vtortola.


我找到了一个(可能的)答案:

使用Console.OutputEncoding = Encoding.Unicode;我可以重新创建您正在经历的几种文化行为,例如"ru","ru-RU"产生输出8.

  • @SørenD.Ptæusthh我看不到任何文化产生'8`https://dotnetfiddle.net/QYhXMu (8认同)

Han*_*ant 15

Repro代码:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

代码页1252在英格兰是一个非常常见的事故,因为它是那里的默认Windows代码页.与西欧和美洲一样.有很多理由以编程方式更改默认的Console.OutputEncoding属性,许多文本文件将在1252中编码.或者chcp 1252在启动程序之前通过键入(chcp == change code page)从命令行进行编码.

从1252支持的字符集可以看出,Infinity符号不可用.因此编码必须提出替代品.这通常是?不受支持的Unicode代码点的字形,即8位编码的Encoding.EncoderFallback属性值.但对于1252,以及传统的MS-Dos 850和858代码页,微软程序员决定8.有趣的家伙.

字形在控制台应用程序通常的代码页支持西方的机器上.这是437,与旧的IBM字符集匹配.发生这种编码灾难是Unicode发明的原因.可悲的是,为了拯救控制台应用程序已经太晚了,太多的代码依赖于默认的MS-Dos代码页.

将Double.PositiveInfinity转换为"∞"特定于Win10.它曾经是以前Windows版本中的"Infinity".通常可以使用"控制面板">"语言">"更改日期,时间或数字格式">"其他设置"按钮修改这些格式,但对话框中不包含无穷大符号选择.注册表(HKCU\Control Panel\International)也没有涵盖,而是一个很大的疏忽.在原生的winapi中它是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();
    }
}
Run Code Online (Sandbox Code Playgroud)