为什么无限在Windows 10控制台中打印为“8”?
我正在testing从包括0,即1/0
/ 0/0
1/0
和0/0
分区返回的内容。 为此,我使用了类似于以下内容的内容:
Console.WriteLine(1d / 0d);
然而,这个代码打印8
非Infinity
或像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年社区版