【问题标题】:Why does this program loop forever?为什么这个程序永远循环?
【发布时间】:2021-03-20 23:57:28
【问题描述】:

该程序的目标是按以下方式执行校验和:每隔一个数字乘以 2,从数字的倒数第二个数字开始,然后将这些乘积的数字相加。 将总和添加到未乘以 2 的数字的总和。如果总模 10 为 0,则该数字有效我的代码的问题是它永远运行,因此我认为循环有问题,关于为什么会发生这种情况以及如何解决它的任何建议?注意:

#include <stdio.h>
#include <cs50.h>
#include <math.h>

double input(void);

int main(void)
{
    double number = input();
    double sum = 0;
    double i = 1;
    double current_digit;
    do
    {
        current_digit = (fmod(number, pow(10,i)) - fmod(number, pow(10, i-1)))/pow(10, i-1); //formula to calculate the ith digit in a number
        if (fmod(i,2) != 0)
        {
            sum += current_digit;
        }
        else
        {
            double second_number = 2*current_digit;
            double j = 1;
            do
            {
                double second_current_digit = (fmod(second_number, pow(10,j)) -fmod(second_number,pow(10, j-1)))/pow(10, j-1);
                sum += second_current_digit;
                j++;
            }
            while (fmod(second_number, pow(10,j)) == number);
        i++;
        }
    }
    while (fmod(number,pow(10, i)) != number);
    if (fmod(sum,10) == 0)
    {
        printf("true");
    }
    else
    {
        printf("false");
    }
}

double input(void)
{
    double number = get_double("Number: ");
    return number;
}

【问题讨论】:

  • 您是否尝试使用调试器来逐步执行并跟踪对number 的更改?如果这不可用,您是否添加了打印一些文本的说明,以便您跟踪事后发生的事情?我们不是调试服务……而且,浮点值的精确比较总是值得怀疑的。也许您缺少的细微差别?最后,当您关心精确表示时,为什么要使用浮点值?
  • pow(10, i) 不保证产生1000...0000,可能会提供类似999...999.997653213 的东西
  • @einpoklum 如果使用浮点数是指使用双精度数,程序将不得不采用 16 位甚至更多位,我不知道如何处理更大的整数,可能很长类型?无论如何,谢谢您的打印提示,我会尝试
  • 不要使用数学库pow()。写你自己的long unsigned integer_pow(unsigned base, unsigned exp) { long unsigned v = 1; while (exp--) v *= base; return v; }
  • 在你的程序中,是的。如果您不想处理乱七八糟的浮点值,请使用 integers (int, long unsigned, ...) (并去掉 &lt;math.h&gt;包含)。

标签: c loops infinite-loop cs50


【解决方案1】:

double 的用法...程序需要 16 位甚至更多,我不知道如何处理更大的整数,也许是 long 类型?

如今,大多数计算机本身都支持 64 位整数。这些可以给你多达 floor(log_10(2^64)) = 19 个十进制数字。如果够用,请使用 &lt;stdint.h&gt; 中的 uint64_t(这是 C 标准中定义的类型)。

如果这还不够,请考虑使用数字数组,或更复杂的“大整数”数据类型,如here

无论如何,我敢打赌,确切的浮点比较是在咬你,因为pow(10,i) 的值可能不是 10 的精确幂,所以fmod() 会稍微改变number。但是 - 不要相信我的猜测,只需使用调试器:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-04
    • 1970-01-01
    • 2021-11-28
    相关资源
    最近更新 更多