所以我已经得到了我最后一个问题的答案(我不知道为什么我没有想到这一点).当我没想到它的时候,我正在打印一个圆润的double使用cout.如何使用全精度cout打印double?
最近我不得不将双序列化为文本,然后将其取回.该值似乎不相等:
double d1 = 0.84551240822557006;
string s = d1.ToString("R");
double d2 = double.Parse(s);
bool s1 = d1 == d2;
// -> s1 is False
Run Code Online (Sandbox Code Playgroud)
但根据MSDN:标准数字格式字符串,"R"选项应该保证往返安全.
往返("R")格式说明符用于确保转换为字符串的数值将被解析回相同的数值
为什么会这样?
double是否有任何流操纵器(或标准 C++ 中的任何其他方法)的组合可以让我在 C++ 中打印时获得“正确”的位数?
我所说的“正确”数字是指此处定义的位数:
m 或 a 的小数部分必须打印多少位数字?必须至少有一位数字来表示小数部分,除此之外,还必须有尽可能多的数字来唯一区分参数值与 double 类型的相邻值。也就是说,假设 x 是由此方法针对有限非零参数 d 生成的十进制表示形式所表示的精确数学值。那么 d 必须是最接近 x 的 double 值;或者如果两个 double 值与 x 同样接近,则 d 必须是其中之一,并且 d 的有效数的最低有效位必须为 0。
在一个简单的例子中,假设我们有三个double值:DD、D0 和 D1。DD 是“中间”,D1 尾数大 1,D0 尾数小 1。
当打印到一些非常大的任意精度时,它们会产生以下值(示例中的数字完全不合常理):
D0 => 1.299999999701323987
DD => 1.300000000124034353
D1 => 1.300000000524034353
Run Code Online (Sandbox Code Playgroud)
(EPSILON,0 指数处尾数的最低有效位的值约为 0.0000000004)
在这种情况下,上述方法将产生
D0 => 1.2999999997
DD => 1.3
DD => 1.3000000005
Run Code Online (Sandbox Code Playgroud) 我有一个 double 的文本表示,想知道将它往返于 double 和 back 是否安全。如果我也想接受任何类型的输入类型,我怎么知道这一点?或者我怎么知道当用 Double.Parse 解析双字符串时是否有任何精度丢失?或者我如何 ToString a double 以匹配与另一个双字符串相同的格式?对这些问题中的任何一个的回答将是我认为的解决方案。
在JavaScript中,每个人都知道着名的计算:0.1 + 0.2 = 0.30000000000000004.但是为什么JavaScript打印这个值而不是打印更准确和精确0.300000000000000044408920985006?