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

我正在testing从包括0,即1/0 / 0/0 1/00/0分区返回的内容。 为此,我使用了类似于以下内容的内容:

 Console.WriteLine(1d / 0d); 

然而,这个代码打印8Infinity或像PositiveInfinity其他string常量。

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

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

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

为什么这个无限打印8?


对于那些似乎认为这是一个无限符号的人,不是以下八个scheme:

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

输出:

无边的输出

如果浮点除以零的分子是正的,那么浮点值是+Infinity如果浮点除以零的分子为负,则为+Infinity如果是浮点除法的分子和分母,则为NaN都是零。 这就是IEEE754浮点规范 ,这是C#使用的。

在你的情况下, 控制台正在将无穷大符号(有时用横向8 – ∞表示)转换为垂直8。

给定某些设置(即文化组合,输出编码等),.NET将输出Unicode无穷大字符∞(∞/#8734;)。 Windows 10控制台/terminal仿真程序将(再次给予某些设置 – 请参见下面的截图)将此Unicode字符显示为8。

例如,在Windows 10中,使用下面的设置(注意代码页)简单地将∞粘贴到控制台显示为8。

设置重现

编辑

感谢来自Chris的评论:看起来输出字体代码页结合在一起对控制台上的∞=> 8问题负责。 像他一样,我可以在所有我尝试过的TrueType字体中正确显示∞,只有在select光栅字体时才会看到8。

字体设置

Windows将Unicode转换为传统字符编码时,会出现8符号。 由于在传统编码中没有无穷大符号,所以默认情况下 ,它使用“最适合”符号,在这种情况下是数字8.请参阅Microsoft的“windows-1252”编码示例。 显然,Windows 10在控制台中默认使用遗留字符编码(参见“代码页” )。

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

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

导致string“Infinity”

Console.WriteLine(Double.PositiveInfinity.ToString(new CultureInfo("fr-Fr"))); 导致“+ Infini”。

编辑:正如其他人所指出的,他们不能完全确认我的结果。 在另一台机器上testing,我得到两个调用的字符

输出所有文化 ,感谢vtortola在评论。


我发现了一个(可能的)答案:

使用Console.OutputEncoding = Encoding.Unicode; 我可以重新创build你在几种文化中所经历的行为,例如“ru”,“ru-RU”产生输出8

代码:

 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符号不可用。 所以编码必须提供一个替代品。 那通常是? 不受支持的Unicode代码点的字形,用于8位编码的Encoding.EncoderFallback属性值。 但是对于1252以及传统的MS-Dos 850和858代码页,微软程序员决定了8 。 有趣的家伙。

西方机器上控制台应用程序的常用代码页支持字形。 这是437, 匹配旧版IBM字符集 。 有这样的编码灾难是为什么Unicode发明。 遗憾的是,为了挽救控制台应用程序,太多的代码依赖于默认的MS-DOS代码页。

将Double.PositiveInfinity转换为“∞”是Win10特有的。 在以前的Windows版本中,它曾经是“无限”。 这些格式通常可以通过控制面板>语言>更改date,时间或数字格式>附加设置button进行修改,但无限符号select不包括在对话框中。 还没有被registry(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(); } } 

运行.Net 4及以上版本时,控制台中会显示“8”,否则以前的版本将显示“Infinity”。

使用Console.OutputEncoding = Encoding.Unicode; 在.Net 4及以上版本中将无限显示为∞,但在以前的版本中抛出IOException。

注:我在Windows 10 64位上运行Visual Studio 2015年社区版