簡體   English   中英

序列化雙精度的最佳方法

[英]Best way to serialize a double

我正在將值序列化為 XML 文檔。 當我序列化一個double ,我想確保我不會失去任何精度,並且這種文化不會干擾。 或者我沒有想到的任何其他“陷阱”。

同樣對於DateTime ,我使用ToBinary()來獲取一個非常安全的序列化值。

那么,在 C# 中序列化/反序列化double值的最佳方法是什么?

為了解析回確切的值,您應該使用G17格式說明符,如此處所述

d.ToString("G17")

或者

$"{d:G17}"

請注意,這可能無法在低於 .NET Core 3.0 的版本上往返。


下面的原始答案; 提到的"r"格式說明符實際上有一個錯誤,因此文檔不正確


往返格式說明符 "r"保證如果您在字符串上使用double.Parse ,您將獲得完全相同的值:

d.ToString("r")

結帳XmlConvert.ToString(雙值)

這也處理無窮大:

如果值為 Double.PositiveInfinity 或 Double.NegativeInfinity,則此方法分別返回字符串 INF 或 -INF。

BitConverter.GetBytes(myValue)將給出一個 Byte 數組,然后可以在不損失精度的情況下對其進行序列化。

看起來這應該有效。 根據我的測試,它還可以很好地往返於無窮大和 NaN 等特殊值。

static string SerializeDouble(double d)
{
    return d.ToString("G17", CultureInfo.InvariantCulture);
}

static double DeserializeDouble(string s)
{
    return double.Parse(s, CultureInfo.InvariantCulture);
}

為什么是"G17"

來源: https : //docs.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings?redirectedfrom=MSDN#GFormatString

相關引述(在發帖時):

請注意,當與 Double 值一起使用時,“G17”格式說明符可確保原始 Double 值成功往返。 這是因為 Double 是符合 IEEE 754-2008 的雙精度 (binary64) 浮點數,可提供多達 17 位有效數字的精度。 我們建議使用它而不是“R”格式說明符,因為在某些情況下,“R”無法成功地往返雙精度浮點值。


為什么是CultureInfo.InvariantCulture

這會處理任何特定於文化的格式,否則會破壞您的往返行程。 例如,這個代碼片段給出了一些非常不受歡迎的結果!

double d0 = Math.PI;
Console.WriteLine("d0: " + d0); // prints 3.14159265358979
// Serialize in America
string s = d0.ToString("G17", new CultureInfo("en-us"));
Console.WriteLine("s: " + s); // prints 3.1415926535897931
// Deserialize in Germany
double d1 = double.Parse(s, new CultureInfo("de-de"));
Console.WriteLine("d1: " + d1); // prints 3.14159265358979E+16

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM