[英]Why is infinity printed as “8” in the Windows 10 console?
我正在测试从除法返回的内容,包括零,即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?
对于那些似乎认为这是一个无穷大符号而不是 8 的人,请使用以下程序:
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 无穷大字符 ∞ (∞ / ∞)。 Windows 10 控制台/终端模拟器将(再次给定某些设置 - 请参见下面的屏幕截图)将此 Unicode 字符显示为 8。
例如,在 Windows 10 上,使用以下设置(注意代码页),只需将 ∞ 粘贴到控制台显示为 8。
编辑
感谢Chris 的评论:似乎输出字体与代码页相结合是导致控制台上 ∞ => 8 问题的原因。 像他一样,我在我尝试过的所有 TrueType 字体中都能正确显示 ∞ 并且在选择光栅字体时只能看到 8。
当 Windows 将 Unicode 转换为旧字符编码时,会出现8
符号。 由于旧编码中没有无穷大符号,因此默认情况下它使用该符号的“最佳拟合” ,在本例中为数字 8。请参阅Microsoft 的“windows-1252”编码示例。 显然,Windows 10 在控制台中默认仍然使用旧字符编码(请参阅“代码页” )。
注意:将Double.PositiveInfinity
写入控制台时隐式.ToString()
方法调用负责此行为。
调用Console.WriteLine(Double.PositiveInfinity.ToString(new CultureInfo("en-Us")));
结果是字符串“Infinity”
而Console.WriteLine(Double.PositiveInfinity.ToString(new CultureInfo("fr-Fr")));
结果为“+Infini”。
编辑:正如其他人在 commets 中指出的那样,他们不能完全证实我的结果。 在另一台机器上测试这个,我得到两个调用的字符∞
。
我找到了一个(可能的)答案:
使用Console.OutputEncoding = Encoding.Unicode;
我可以重新创建您在多种文化中遇到的行为,例如“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 符号不可用。 所以 Encoding 必须想出一个替代品。 那往往是?
不支持的 Unicode 代码点的字形,8 位编码的 Encoding.EncoderFallback 属性值。 但是对于 1252 以及遗留的 MS-Dos 850 和 858 代码页,Microsoft 程序员决定使用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();
}
}
运行 .Net 4 及更高版本时,控制台中会显示“8”表示无穷大,否则以前的版本显示“无穷大”。
使用 Console.OutputEncoding = Encoding.Unicode; 在 .Net 4 及更高版本中将无穷大显示为 ∞,但在以前的版本中会抛出 IOException。
注意:我在 Windows 10 64 位上运行 Visual Studio 2015 Community Edition
这与您的 Windows 10 区域设置有关。
在 Windows 10 Pro version 2004 上测试过。我刚刚通过执行以下操作解决了这个问题:
重新启动您的 PC,现在您的 8 将打印为 ∞
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.