C++ 如何在c++;

C++ 如何在c++;,c++,string,double,type-conversion,representation,C++,String,Double,Type Conversion,Representation,当表示双精度数字时,其精度在一定程度上会降低。例如,数字37.3可以表示为37.2999999991 我需要重新建立损坏的doublenumber(我的项目需要)。一种方法是将double转换为CString double d = 37.3; CString str; str.Format("%.10f", d); Output: str = 37.3; 通过这种方式,我可以重建损坏的d。然而,我发现了一个反例。如果我设定 d = 37.3500; 然后它的double表示有时等于37.3

当表示双精度数字时,其精度在一定程度上会降低。例如,数字37.3可以表示为37.2999999991

我需要重新建立损坏的
double
number(我的项目需要)。一种方法是将
double
转换为
CString

double d = 37.3;
CString str;
str.Format("%.10f", d);

Output: str = 37.3;
通过这种方式,我可以重建损坏的
d
。然而,我发现了一个反例。如果我设定

d = 37.3500;
然后它的
double
表示有时等于37.349998474121094。将
d
转换为
CString
时,输出仍为37.3499984741,实际不等于37.3500

为什么37.3500没有给出期望的答案,而37.3给出了期望的答案?有没有什么办法可以重建双重身份

谢谢

为什么37.3500没有给出期望的答案,而37.3给出了期望的答案

是偶然的。
37.3
的表示恰好足够接近,四舍五入到小数点后10位可以得到预期的结果,而
37.3499984741
没有

有没有什么办法可以重建双重身份

不,一旦信息丢失,您就无法恢复。如果需要十进制数的精确表示,则需要与二进制浮点不同的格式。在C++语言或标准库中没有合适的十进制类型;根据您的需要,您可能会考虑诸如OR或OR之类的库。或者,如果可以限制所需的小数位数,则可以将所有数字乘以该小数位数,并使用精确整数

为什么37.3500没有给出期望的答案,而37.3给出了期望的答案

是偶然的。
37.3
的表示恰好足够接近,四舍五入到小数点后10位可以得到预期的结果,而
37.3499984741
没有

有没有什么办法可以重建双重身份


不,一旦信息丢失,您就无法恢复。如果需要十进制数的精确表示,则需要与二进制浮点不同的格式。在C++语言或标准库中没有合适的十进制类型;根据您的需要,您可能会考虑诸如OR或OR之类的库。或者,如果您可以限制所需的小数位数,则可以将所有数字乘以该小数位数,并使用精确整数。

这可以在一定程度上完成,但并不容易。由于字符串表示法是以10为基数的,而内部表示法是以2为基数的,因此在将一种表示法转换为另一种表示法时需要舍入。因此,当您将十进制“37.35”转换为双精度时,结果与原始数字不同。当将该数字转换回字符串时,计算机无法确定第一位的数字是什么,因为有几个十进制数字会导致相同的双精度。但是,您可以添加一个约束,即希望得到最短的十进制字符串,从而得到给定的double,那么它很有可能精确地恢复原始字符串。David Gay开发了一种使用该约束的算法,您需要g_fmt.c和dtoa.c,以及。这是使用的默认算法。

可以在一定程度上完成,但并不容易。由于字符串表示法是以10为基数的,而内部表示法是以2为基数的,因此在将一种表示法转换为另一种表示法时需要舍入。因此,当您将十进制“37.35”转换为双精度时,结果与原始数字不同。当将该数字转换回字符串时,计算机无法确定第一位的数字是什么,因为有几个十进制数字会导致相同的双精度。但是,您可以添加一个约束,即希望得到最短的十进制字符串,从而得到给定的double,那么它很有可能精确地恢复原始字符串。David Gay开发了一种使用该约束的算法,您需要g_fmt.c和dtoa.c,以及。这是使用的默认算法。

您可以使用
%g
尝试
snprintf
。它不是“损坏的”,而是浮点表示。无法取消浮点精度的损坏。如果您需要小数精度,那么您需要一个专用的小数类型。否,@chris,snprintf加上%g最多四位小数。我至少需要10个小数位..那么你会怎么处理37.2999999991呢?如果您将其四舍五入到37.3(使用
sprintf
或任何方法),它也将被“损坏”…您可以尝试使用
%g
使用
snprintf
。它不是“损坏”,而是浮点表示。无法取消浮点精度的损坏。如果您需要小数精度,那么您需要一个专用的小数类型。否,@chris,snprintf加上%g最多四位小数。我至少需要10个小数位..那么你会怎么处理37.2999999991呢?如果你将它四舍五入到37.3(使用
sprintf
或任何方法),它也会被“损坏”。。。