我知道字符串 2.34 永远不会等于双 2.34。无论您尝试使用哪种库或算法(lexical_cast、atof)。2.3400 也不能表示为双精度型。相反,它将等于 2.3399999999999999 。一点背景我正在开发一个应用程序,该应用程序使用其 api 将值传递给外部应用程序。将其视为某种交易应用程序。用户可以使用应用程序 api 传递值,或者用户可以直接使用应用程序传递值。现在当用户直接使用应用程序并且用户输入 2.34 时,值被处理为 2.34 但是当我使用需要双精度的 API 时作为参数,我传递 2.34,它传递为 2.3399999999999999,这是不可接受的。我的问题是应用程序将如何处理这个问题,有没有办法存储 2.34000..
3 回答
如果您需要通过 API 传递十进制值,double
但您需要获取确切的值,则没有太大问题:只要不使用超过std::numeric_limits<double>::digits10
位数,您可以恢复原始十进制值,尽管不一定相同的表示(尾随小数零将丢失)。为此,您需要将原始十进制字符串转换为最接近的表示,double
然后使用合适的算法再次恢复最佳十进制表示。C 和 C++ 标准库中的解析和格式化函数将为您正确执行此操作。
double
请注意,当您想要恢复原始十进制值时,不应尝试对这些值进行任何算术运算:double
算术结果将使用二进制舍入,并且这些值不会是最接近的十进制值。但是,只要您只传输double
值,就没有问题。
由于您提到“交易应用程序”,我将得出结论,这些数字代表货币。如果是这种情况,您可能也在处理固定数量的小数位数。在这种情况下,您可以通过将浮点数乘以 来缩放浮点数10 ^ number_of_fractional_digits
,基本上使它们成为整数值。浮点数可以准确地存储整数值(只要它们不超出浮点类型的范围)。
另一种可能性——如果上面的假设是正确的——是使用Binary-coded decimals。
解决浮点精度问题的一种方法是使用制作精良的分数类。您可以自己编写一个代码,也可以使用常用数学库提供的代码。这些类将在内部代表您的2.34
as 234/100
,与单个浮点数相比,这将导致更高的内存消耗量。