C+中标记双精度丢失的算法+;没有标记正确的位置 作为我的一个类的一部分,我应该演示通过C++将结果的 1。/ 3。/COD>打印到20位小数点并标记数字不为3的位置。

C+中标记双精度丢失的算法+;没有标记正确的位置 作为我的一个类的一部分,我应该演示通过C++将结果的 1。/ 3。/COD>打印到20位小数点并标记数字不为3的位置。,c++,c++11,C++,C++11,然而,我的算法(我在下面列出)似乎一直运行在相同的运行时错误中 我在下面留下了代码以及预期和实际输出。有办法解决这个问题吗?我尝试过其他方法(包括中的ostringstream),但这是迄今为止我能想到的最准确的方法 算法 将1./3.的结果存储到变量中 将1./3.打印到小数点后20位,并添加适当的间隔符 将步骤1中的变量乘以10(即将所有数字左移一位) 检查1位数是否为3。如果是,则打印;否则,请打印^ 减小“一”的位置,直到“一”的位置为0 再重复步骤3-6 19次 预期产出 1./3

然而,我的算法(我在下面列出)似乎一直运行在相同的运行时错误中

我在下面留下了代码以及预期和实际输出。有办法解决这个问题吗?我尝试过其他方法(包括
中的
ostringstream
),但这是迄今为止我能想到的最准确的方法


算法

  • 1./3.
    的结果存储到变量中
  • 1./3.
    打印到小数点后20位,并添加适当的间隔符
  • 将步骤1中的变量乘以10(即将所有数字左移一位)
  • 检查1位数是否为3。如果是,则打印
    ;否则,请打印
    ^
  • 减小“一”的位置,直到“一”的位置为0
  • 再重复步骤3-6 19次

  • 预期产出

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

    实际输出(带调试输出)


    #包括
    #包括
    #包括
    #包括
    使用名称空间std;
    int main()
    {
    双三分之一=1./3。;
    
    cout您陷入了精度问题的陷阱。如果您反复将1/3乘以10,您将得到以下结果:

        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
    
    请注意,最后的数字正在更改。您需要先转换为字符串,如下所示:

        double third = 1. / 3.;
        cout << "1./3. Precision test" << endl;
        ostringstream s;
        cout << setw(7) << "1./3.: ";
        s << setprecision(20) << third << endl;
        string str = s.str();
        cout << str;
        cout << "         ";
        for (int i = 2; i <= 21; i++) {
            if (str[i] == '3')
                cout << " ";
            else
                cout << "^";
        }
        cout << endl;
    
    double third=1./3。;
    
    cout您陷入了精度问题的陷阱。如果您反复将1/3乘以10,您将得到以下结果:

        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
    
    请注意,最后的数字正在更改。您需要先转换为字符串,如下所示:

        double third = 1. / 3.;
        cout << "1./3. Precision test" << endl;
        ostringstream s;
        cout << setw(7) << "1./3.: ";
        s << setprecision(20) << third << endl;
        string str = s.str();
        cout << str;
        cout << "         ";
        for (int i = 2; i <= 21; i++) {
            if (str[i] == '3')
                cout << " ";
            else
                cout << "^";
        }
        cout << endl;
    
    double third=1./3。;
    
    cout首先,您可以通过以下方法获得双精度:

    #include <limits>
    std::cout<<std::numeric_limits<double>::digits10;
    
    #包括
    
    std::cout首先,您可以通过以下方式获得双精度:

    #include <limits>
    std::cout<<std::numeric_limits<double>::digits10;
    
    #包括
    
    标准::cout@Drop我以前没有这样做,但在运行调试器后,似乎在第一次迭代
    third*=10;
    后,数字会发生变化。您的预期输出很奇怪……在
    0.3333333333 1483
    中,最终的
    3
    4
    或更多更糟糕-为什么在开始后停止下划线ed是否偏离3?好吧,在发布问题之前,您应该始终运行调试器会话。还要注意,您测量的是1除法的精度损失,但忽略了乘法的10精度损失。@Tony教授希望这样做。因为他是最终负责给我评分的人,所以他说的是正确的。取决于w正如您的老师所期望的,您可以将此数字转换为字符串,并对其进行操作(如@RobL所述),或者您可以操作双精度
    类型的二进制表示法。如果您的课程教学大纲中提到了第二种解决方案,则第二种解决方案更可能是预期的。@Drop我以前没有这样做,但在运行调试程序后,在第一次迭代
    third*=10;
    后,数字似乎会发生变化。您预期的输出是bizar关于……在
    0.3333333333 1483
    中,最后的
    3
    4
    或更多更糟糕-为什么在它开始偏离3后,你会停止下划线?好吧,在发布问题之前,你应该始终运行一个调试器会话。另外请注意,你正在测量1个除法的精度损失,但忽略10个精度损失“乘法的倍数”。@托尼教授希望如此。因为他是最终负责给我评分的人,所以他说的就行了。根据你老师的期望,你可以将这个数字转换成字符串,并对它进行运算(如@RobL所述),或者你可以使用双精度的二进制表示法。如果你的课程大纲中提到了第二种解决方案,那么第二种解决方案就更可能出现。我觉得自己像个该死的白痴。我以前试过使用
    中的
    ostringstream
    ,但最终没有成功。现在它成功了。我一定是把我的ea搞砸了rlier尝试。谢谢。我觉得自己像个该死的白痴。我以前尝试过使用
    中的
    ostringstream
    ,但最终没有成功。现在成功了。我一定是在我之前的尝试中出了问题。谢谢。