繁体   English   中英

.Net 中的往返格式说明符“R”失败

[英]Failure of the Round-trip format specifier “R” in .Net

文档建议我使用G17而不是R ,因为R有时无法往返。

然而, (1.0/10).ToString("G17")给出了"0.10000000000000001" ,这非常可怕。 而往返格式似乎工作得很好(并给出"0.1" )。 我很高兴花几个 cpu 周期来获得更美观的结果。 但潜在的往返故障更令人担忧。

对于哪种(双)值, R无法往返? 有多严重? .Net 版本(我们在 Net Framework 4.72 和 NetCore 3.1 上运行)会影响事情吗? 在一个平台上写作并在另一个平台上阅读是否会使往返失败更频繁?

我们正在考虑首先将 double 写入R ,解析以检查往返,只有在失败时才回退到G17 有没有更好的方法来获得格式良好、可靠的结果?

这里的往返将转换为字符串的数值解析回相同的数值

OP 对(1.0/10).ToString("G17")的失望给出了 "0.10000000000000001",这非常可怕。 是对往返成功的错误评估。 中间串只是往返行程的一半。

Double精确编码大约 2 64 个不同的值。 所有可编码值都是一些有限的整数* 2 some_power 0.1不是其中之一。 1.0/10 使数学商为 0.1,但Double值略有不同。 最近的Double值和它的两个壁橱Double邻居:

 Before     0.099999999999999991673... 
            0.100000000000000005551...
 After      0.100000000000000019428...
 OP report  0.10000000000000001
 Digit count  12345678901234567

OP 的例子应该是 <(0.100000000000000005551).ToString("G17") 给出 "0.10000000000000001"> 这是好的

使用G17打印Double提供 17 位有效数字,足以成功往返。


对于哪种(双)值,R 无法往返? 有多严重?

为此,我继续回忆。 R有时使用少于 17 个有效数字(如 15)来形成中间字符串。 用于确定位数的算法有时会有点短,因此“某些情况下无法成功往返原始值”。

使用G17始终有效。 对于某些值,小于 17 也会起作用。 G17正是在这种情况下。 少于 17 位数字会起作用并提供更令人愉悦、更短的中间字符串。

令人愉悦的人类可读字符串不是往返的目标。 目标是在从值到字符串到值后形成相同的Double ,即使中间字符串在某些情况下有额外的数字。


有没有更好的方法来获得格式良好、可靠的结果?

“格式良好”是往返的额外负担。 MS 尝试使用R这样做,但在某些情况下失败了,宁愿保留相同的损坏功能而不是修复它。

OP 明智的做法是避免该路径并放弃格式良好的中间字符串的目标,并专注于获取最终相同值的往返目标。

使用G17


我们正在考虑首先将 double 写入 R,解析以检查往返,只有在失败时才回退到 G17。

如果正确完成,那将起作用。 要评估正确性,请使用许多值测试您的代码,并发布它和用于代码审查的测试工具。

暂无
暂无

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

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