[英]64 vs 32 bit double parsing issue with the round-trip format specifier “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.