簡體   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