【问题标题】:C++ converting string to float/double without loss of dataC ++将字符串转换为浮点/双精度而不丢失数据
【发布时间】:2013-06-24 13:43:14
【问题描述】:

我希望在不丢失数据的情况下将字符串转换为浮点数;例如,如果我使用 istringstream 或 ::atof(x.c_str()) 我猜我会因为四舍五入而丢失数据。

通常这对我来说不是问题,但我使用的数据必须与其读取的数据相同。 这是一个数字及其转换为的示例。

-8.000001 -> -8
-0.6257381 -> -0.625738
12.0 -> 12 (drops the .0) 

如果有人能帮助我,我将不胜感激

谢谢马特

【问题讨论】:

  • 您确定不只是以较低的精度打印它们吗?我建议使用一些东西来转换其错误不是有效结果。
  • 一般来说,这是不可能的,因为由于浮点数/双精度数的位数有限,您总是会出现舍入错误。此外,Base 10 中的舍入误差与 Base 2 中的舍入误差不同。另外,12.0 与二进制表示中的 12 相同,因此它们之间没有区别
  • 本诺夫斯认为你的权利
  • 对于初学者,您正在使用以 2 为底的数学进行以 10 为底的假设。计算机通常不做以 10 为基础的数学运算。如果你想要以 10 为基础的数学,那么你需要自己做,基于字符串或其他。

标签: c++ string floating-point


【解决方案1】:

您的问题存在三个潜在问题:

  1. 显示的精度数量。要控制使用的精度,请包含 #include <iomanip> 并使用 std::cout << std::setprecision(17); 设置要使用的位数。

  2. 格式化。如果想要“12.0”作为“12.0”,您应该知道“.0”不存储在floatdouble 中。 double 只包含值 12;它不包含有关原始精度或错误间隔的任何信息。正好是 12 点,仅此而已。如果您希望以特定方式对其进行格式化,则必须使用 I/O 流的格式标志或编写自己的代码来进行格式化。

  3. 准确度。常见的 floatdouble 类型不能准确表示 8.000001 或 0.6257381。它们使用二进制来表示浮点值,十进制数字转换为二进制时会有轻微的错误。如果您对浮点的使用非常简单,并且使用的位数明显少于floatdouble 的限制,那么您可以忽略这一点,只需使用有限的位数格式化数字。如果超出了简单的情况,则需要进行错误分析,这可能非常复杂。

【讨论】:

    【解决方案2】:

    您将需要不同的数据类型。

    浮点十进制类型将允许您以您想要的方式存储数字。在这种类型中,数字存储为一对(尾数,指数),就像科学记数法和 IEEE 二进制浮点一样。

    您的示例将存储为

    (-8000001, -6)
    (-6257381, -7)
    (120, -1)
    

    例如,医疗设备通信的 ISO 11073 标准使用这种格式。

    缺点是算术会很慢,因为所有浮点算术硬件都设计为使用以 2 为底的指数处理数字。

    【讨论】:

      【解决方案3】:

      根据经验,float 仅精确到 6 个有效数字。因此,如果您的字符串中有更多数字,您将达到精度限制。

      double 会毫不奇怪地为您提供大约两倍的精度;即 12 位有效数字。

      更多评论请见Number of significant digits for a floating point type

      【讨论】:

      • 我认为这可能是问题所在,但我在网上查了一下,得出的结论是我使用的双精度应该没问题,我认为这只是无法解决的 c++ 舍入问题:/
      • 哦,如果您使用的是双精度数,那么肯定会出现其他问题。我会研究打印精度;见@chris' cmets。
      猜你喜欢
      • 2011-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多