繁体   English   中英

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

[英]Why is infinity printed as “8” in the Windows 10 console?

我正在测试从除法返回的内容,包括零,即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);

输出:

无穷大输出

请确保浮点值是+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 中指出的那样,他们不能完全证实我的结果。 在另一台机器上测试这个,我得到两个调用的字符

所有文化的输出,感谢评论中的vtortola


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

使用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 上测试过。我刚刚通过执行以下操作解决了这个问题:

  1. 通过在开始输入它转到“区域设置”。
  2. 单击“其他日期、时间和区域设置”
  3. 单击“更改日期、时间或数字格式”
  4. 转到“管理”选项卡
  5. 单击“更改系统区域设置”
  6. 选中“测试版:使用 Unicode UTF-8 以获得全球语言支持”复选框

重新启动您的 PC,现在您的 8 将打印为 ∞

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM