为什么在 Windows10控制台中无穷大被打印为“8”?

我在测试从除法返回的数据包括零,也就是 0/11/00/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);

产出:

Inifinity output

24781 次浏览

如果浮点除以零的分子为正,则确保浮点值为 +Infinity; 如果浮点除以零的分子为负,则确保浮点值为 -Infinity; 如果浮点除以零的分子和分母都为零,则确保浮点值为 NaN。这是在 IEEE754浮点数规范中,这是 C # 使用的。

在您的示例中,控制台正在将无穷大符号(有时用字体表示为水平8ー∞)转换为垂直8。

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

呼叫 Console.WriteLine(Double.PositiveInfinity.ToString(new CultureInfo("en-Us")));

结果是字符串“ Infinity”

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

编辑: 正如其他人在评论中指出的,他们不能完全证实我的结果。在不同的机器上测试这个函数,我得到了两个调用的字符

所有区域性 的输出,感谢评论中的 Vtortola


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

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

给定某些设置(即区域性组合、输出编码等)。NET 将输出 Unicode 无穷大字符∞(& # 8734;/& # 8734;)。Windows10控制台/虚拟终端(同样给定一些设置——见下面的截图)将把这个 Unicode字符显示为8。

例如,在 Windows10上,使用下面的设置(注意代码页) ,只需将∞粘贴到控制台中即可显示为8。

Setting to reproduce

剪辑

感谢 克里斯的评论: 似乎输出字体 与... 结合在一起的代码页负责控制台上的∞ = > 8问题。像他一样,我在所有我试过的 TrueType 字体中都能正确显示∞ ,当选择光栅字体时,只能看到8。

font settings

当 Windows 将 Unicode 转换为旧的字符编码时,会出现 8符号。因为在遗留编码中没有无穷大符号,所以它使用 “最适合”这个符号,默认情况下,在本例中是数字8。请参见 微软的“ windows-1252”编码的示例。显然,Windows10还是在控制台中默认使用遗留字符编码(参见 “密码页”)。

复制代码:

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 代码页。西欧和美洲也是如此。更改默认控制台的原因有很多。属性,许多文本文件将以1252编码。或者在启动程序之前从命令行键入 chcp 1252(chcp = = change code page)。

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

西方机器上控制台应用程序通常代码页中支持的字形 。也就是437 匹配遗留的 IBM 字符集。这种编码灾难就是 Unicode 发明的原因。遗憾的是,拯救控制台应用程序为时已晚,太多的代码依赖于默认的 MS-Dos 代码页。

生双胞胎。转换为“∞”的正无穷大是特定于 Win10的。在以前的 Windows 版本中,它曾经是“ Infinity”。这些格式通常可以通过“控制面板”> “语言”> “更改日期、时间或数字格式”> “附加设置”按钮进行修改,但对话框中不包括无穷大的符号选择。也不包括在注册(港大控制面板国际) ,相当大的疏忽。它是本地 winapi 中的 LOCALE _ SPOSINFINITY。在一个。NET 程序,您可以通过克隆 CultureInfo 并更改其 NumberFormatInfo 来以编程方式重写它。属性。像这样:

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”。

使用控制台。输出编码 = 编码。Unicode; 在。Net 4及以上版本将获得无穷大作为∞显示,但在以前的版本中抛出 IOException。

注意: 我正在 Windows1064位上运行 VisualStudio2015社区版

这与您的 Windows10区域设置有关。

在 Windows10 Pro 2004版本上进行了测试,我通过以下方法解决了这个问题:

  1. 在开始键入“区域设置”。
  2. 点击“附加日期,时间和地区设置”
  3. 点击“更改日期、时间或数字格式”
  4. 前往“管理”标签
  5. 点击‘ Change system locale’
  6. 选中“ Beta: 使用 Unicode UTF-8提供全球语言支持”框

重新启动你的电脑,现在你的8将打印为∞