[英]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.