[英]Best way to serialize a double
I am serializing values to an XML document.我正在将值序列化为 XML 文档。 When I serialize a
double
, I want to make sure I am not losing any precision, and that culture will not interfere.当我序列化一个
double
,我想确保我不会失去任何精度,并且这种文化不会干扰。 Or any other "gotchas" that I haven't thought of.或者我没有想到的任何其他“陷阱”。
Similarly for DateTime
, I use ToBinary()
to get a value that's very safe to serialize.同样对于
DateTime
,我使用ToBinary()
来获取一个非常安全的序列化值。
So, what is the best method to serialize / deserialize a double
value in C#?那么,在 C# 中序列化/反序列化
double
值的最佳方法是什么?
In order to parse back the exact value, you should use the G17
format specifier, as documented here :为了解析回确切的值,您应该使用
G17
格式说明符,如此处所述:
d.ToString("G17")
or或者
$"{d:G17}"
Note that this can fail to roundtrip on versions below .NET Core 3.0 .请注意,这可能无法在低于 .NET Core 3.0 的版本上往返。
Original answer below ;下面的原始答案; the
"r"
format specifier mentioned actually has a bug so the documentation was incorrect .提到的
"r"
格式说明符实际上有一个错误,因此文档不正确。
The round-trip format specifier "r" guarantees that if you use double.Parse
on the string, you will get back the exact same value: 往返格式说明符 "r"保证如果您在字符串上使用
double.Parse
,您将获得完全相同的值:
d.ToString("r")
Checkout XmlConvert.ToString(double value)结帐XmlConvert.ToString(双值)
This handles infinity too:这也处理无穷大:
If value is Double.PositiveInfinity or Double.NegativeInfinity, this method returns the string INF or -INF respectively.
如果值为 Double.PositiveInfinity 或 Double.NegativeInfinity,则此方法分别返回字符串 INF 或 -INF。
BitConverter.GetBytes(myValue)
将给出一个 Byte 数组,然后可以在不损失精度的情况下对其进行序列化。
It looks like this should work.看起来这应该有效。 According to my tests, it also round-trips special values like infinity and NaN just fine.
根据我的测试,它还可以很好地往返于无穷大和 NaN 等特殊值。
static string SerializeDouble(double d)
{
return d.ToString("G17", CultureInfo.InvariantCulture);
}
static double DeserializeDouble(string s)
{
return double.Parse(s, CultureInfo.InvariantCulture);
}
"G17"
?"G17"
? Source: https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings?redirectedfrom=MSDN#GFormatString来源: https : //docs.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings?redirectedfrom=MSDN#GFormatString
Relevant quote (at the time of this post):相关引述(在发帖时):
Note that, when used with a Double value, the "G17" format specifier ensures that the original Double value successfully round-trips.
请注意,当与 Double 值一起使用时,“G17”格式说明符可确保原始 Double 值成功往返。 This is because Double is an IEEE 754-2008-compliant double-precision (binary64) floating point number that gives up to 17 significant digits of precision.
这是因为 Double 是符合 IEEE 754-2008 的双精度 (binary64) 浮点数,可提供多达 17 位有效数字的精度。 We recommend its use instead of the "R" format specifier, since in some cases "R" fails to successfully round-trip double-precision floating point values.
我们建议使用它而不是“R”格式说明符,因为在某些情况下,“R”无法成功地往返双精度浮点值。
CultureInfo.InvariantCulture
?CultureInfo.InvariantCulture
? This takes care of any culture-specific formatting that would otherwise break your round-trip.这会处理任何特定于文化的格式,否则会破坏您的往返行程。 For example, this code snippet gives some very undesirable results!
例如,这个代码片段给出了一些非常不受欢迎的结果!
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.