在C ++中标记双精度丢失的算法不标记正确的位置

时间:2016-02-22 04:43:18

标签: c++ c++11

作为我的一个课程的一部分,我应该通过将1./3.的结果打印到20个小数位并标记数字所在的位置来证明使用C ++进行双重分割可能会导致精度损失。不是3。

但是,我所拥有的算法(我在下面列出)似乎一直在运行相同的运行时错误。

我已将下面的代码和下面的预期和实际输出保留下来。有没有解决的办法?我已经尝试了其他方法(包括来自ostringstream的{​​{1}}),但这是迄今为止我能够提出的最准确的方法。

算法

  1. <sstream>的结果存储到变量。
  2. 打印1./3.到20位小数&amp;添加一个合适的垫片。
  3. 将步骤1中的变量乘以10(即将所有数字移到一处)。
  4. 检查那些数字是否为3.如果是,则打印1./3.;否则,请打印
  5. 减少那些位置,直到位置为0。
  6. 重复步骤3-6 19次。
  7. 预期输出

    ^

    实际输出(带调试输出)

    1./3. Precision test
    1./3.: 0.33333333333333331483
                             ^^^
    
    1./3. Precision test
    1./3.: 0.33333333333333331483
                             ^ ^^
             33333333333333330372
    

2 个答案:

答案 0 :(得分:4)

你陷入精确问题陷阱。如果你反复将1/3乘以10,这就是你得到的:

url

请注意,最后的数字正在改变。您需要先转换为字符串,如下所示:

    0.33333333333333331483
    3.3333333333333330373
    33.333333333333328596
    333.33333333333325754
    3333.3333333333325754
    33333.333333333328483
    333333.33333333325572
    3333333.3333333325572
    33333333.333333324641
    333333333.33333325386
    3333333333.3333325386
    33333333333.333324432
    333333333333.33325195
    3333333333333.3325195
    33333333333333.324219
    333333333333333.25
    3333333333333332.5
    33333333333333324
    333333333333333248
    3333333333333332480
    33333333333333323776

答案 1 :(得分:0)

首先,您可以使用以下方法访问double的精度:

#include <limits>
std::cout<<std::numeric_limits<double>::digits10;

这在我的linux 64位机器上提供了15个。

然后,当你乘以10时,你改变了数字,因为只乘以2是base2中的一个精确运算,它是数字的内部表示。