在 C 中比较两个相等的 unsigned long 计算结果为 false

标签 c comparison long-integer unsigned

我是 C 语言新手,正在尝试使用它。所以我最终实现了斐波那契代码(迭代和递归)。我编写了一个测试函数,它应该给我一个绿色(我的实现有效)或红色。它说我得到了正确的返回值,但它的状态是红色的。这两个值都应该是 unsigned long。我正在 OSX 上使用 make 进行编译

#include <stdio.h>

unsigned long fibonacci(unsigned long n);
void test_fibonacci(unsigned long n, unsigned long assertion);

int main(int argc, char* argv[])
{
    test_fibonacci(1, 1);
    test_fibonacci(2, 1);
    test_fibonacci(3, 2);
    test_fibonacci(10, 55);
    return 0;
}

unsigned long fibonacci(unsigned long n)
{
    unsigned long result = 1;
    unsigned long lastResult;
    for (unsigned long i = 2; i <= n; i++)
    {
        // save the current result to save it as the lastResult after this iteration
        unsigned long lastResultTmp = result;
        result = lastResult + result;
        lastResult = lastResultTmp;
    }
    return result;
}

void test_fibonacci(unsigned long n, unsigned long assertion)
{
    printf(
        "fibonacci(%lu): %lu    | %s | asserted: %lu\n",
        n,
        fibonacci(n),
        (fibonacci(n) == assertion) ? "green" : "red",
        assertion
    );
}

我的生成文件

CFLAGS=-Wall -g

all: main

clean:
    rm -f main
    rm -Rf *.dSYM

输出:

fibonacci(1): 1    | green | asserted: 1
fibonacci(2): 1    | red | asserted: 1
fibonacci(3): 2    | red | asserted: 2
fibonacci(10): 55    | red | asserted: 55

最佳答案

我没有得到你的输出。这是我所看到的:

fibonacci(1): 1    | green | asserted: 1
fibonacci(2): 2    | red | asserted: 1
fibonacci(3): 4    | red | asserted: 2
fibonacci(10): 3353    | red | asserted: 55

我很好奇为什么,所以我用 valgrind 运行它。很快就弹出了这个错误:

==5619== Conditional jump or move depends on uninitialised value(s)
==5619==    at 0x4005E7: test_fibonacci (fibonacci.c:31)
==5619==    by 0x400559: main (fibonacci.c:9)

所以看起来这与读取未初始化的变量有关,这会给你错误的值。这最终将我们指向这里:

unsigned long fibonacci(unsigned long n)
{
    unsigned long result = 1;
    unsigned long lastResult; // <---- LOOK HERE
    for (unsigned long i = 2; i <= n; i++)
    {
        // save the current result to save it as the lastResult after this iteration
        unsigned long lastResultTmp = result;
        result = lastResult + result;
        lastResult = lastResultTmp;
    }
    return result;
}

请注意,lastResult 尚未初始化,但已在行中读取

 result = lastResult + result;

所以看来您需要初始化该值。由于该值对应于之前的斐波那契数,因此您应该初始化为零。这样做会导致所有测试通过。

现在,究竟发生了什么导致您看起来得到了正确答案但仍然失败?请注意,您在测试代码中调用了两次斐波那契。我的猜测是,对 fibonacci 的第一次调用 - 被打印的那个 - 纯粹是随机的机会恰好工作正常,因为由于某种原因,第一个 lastResult 中的值调用恰好为 0。但是,我猜测对 fibonacci第二次调用(与预期结果进行比较的调用)没有返回相同的结果value 作为第一次调用,因为无论出于何种原因,在进行第二次调用时 lastResult 的值不为 0。这就是未定义行为的问题 - 可能会发生这样奇怪的事情!

关于在 C 中比较两个相等的 unsigned long 计算结果为 false,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37953949/

相关文章:

c - 传递一个结构进行比较

c++ - 在 C++ 中将 long 转换为 CString

c++ - 尝试使用 libjpeg 将 YUV 图像压缩为 jpeg 时出现奇怪的图像

C 删除字符串末尾的换行符,行为很奇怪

c - 在 C 中,如何在函数中动态构建字符串数组并返回给调用者

c# - C: 如何将 foreach_point(t->board) 转换为 for 循环?

database - 包含( float ,整数)元组的 100 万个向量的高效比较

php - 用于 PHP 开发的 Eclipse PDT 与 NetBeans

Java 8 - 将整数转换为长编译问题

java - 无法将字符串转换为 long(timestamp) 或 long 转换为字符串