Look at the complement of C language from fibonacci sequence

First look at a demo that calculates the fibonacci sequence:

root@root:~/dsa/d_c$ cat fib_iterate.c
#include <stdio.h>
#include <time.h>

int main(int argc, char const *argv[]){
    time_t start_time, end_time;
    double time_diff;
    const int n = 64;
    for(int i = 1; i < n; i++){
        time(&start_time);

        int pre = 0;
        int res = 1;
        int ope = i;
        while (0 < ope--) {
            res = res + pre;
            pre = res - pre;
        }

        time(&end_time);
        time_diff = difftime(end_time, start_time);
        printf("fib(%d) = %d, 耗时%fs\n", i, res, time_diff);
    }
}

root@root:~/dsa/d_c$
root@root:~/dsa/d_c$ ./fib_iterate.out 
fib(1) = 1, 耗时0.000000s
fib(2) = 2, 耗时0.000000s
fib(3) = 3, 耗时0.000000s
fib(4) = 5, 耗时0.000000s
fib(5) = 8, 耗时0.000000s
fib(6) = 13, 耗时0.000000s
fib(7) = 21, 耗时0.000000s
fib(8) = 34, 耗时0.000000s
fib(9) = 55, 耗时0.000000s
fib(10) = 89, 耗时0.000000s
fib(11) = 144, 耗时0.000000s
fib(12) = 233, 耗时0.000000s
fib(13) = 377, 耗时0.000000s
fib(14) = 610, 耗时0.000000s
fib(15) = 987, 耗时0.000000s
fib(16) = 1597, 耗时0.000000s
fib(17) = 2584, 耗时0.000000s
fib(18) = 4181, 耗时0.000000s
fib(19) = 6765, 耗时0.000000s
fib(20) = 10946, 耗时0.000000s
fib(21) = 17711, 耗时0.000000s
fib(22) = 28657, 耗时0.000000s
fib(23) = 46368, 耗时0.000000s
fib(24) = 75025, 耗时0.000000s
fib(25) = 121393, 耗时0.000000s
fib(26) = 196418, 耗时0.000000s
fib(27) = 317811, 耗时0.000000s
fib(28) = 514229, 耗时0.000000s
fib(29) = 832040, 耗时0.000000s
fib(30) = 1346269, 耗时0.000000s
fib(31) = 2178309, 耗时0.000000s
fib(32) = 3524578, 耗时0.000000s
fib(33) = 5702887, 耗时0.000000s
fib(34) = 9227465, 耗时0.000000s
fib(35) = 14930352, 耗时0.000000s
fib(36) = 24157817, 耗时0.000000s
fib(37) = 39088169, 耗时0.000000s
fib(38) = 63245986, 耗时0.000000s
fib(39) = 102334155, 耗时0.000000s
fib(40) = 165580141, 耗时0.000000s
fib(41) = 267914296, 耗时0.000000s
fib(42) = 433494437, 耗时0.000000s
fib(43) = 701408733, 耗时0.000000s
fib(44) = 1134903170, 耗时0.000000s
fib(45) = 1836311903, 耗时0.000000s
fib(46) = -1323752223, 耗时0.000000s
fib(47) = 512559680, 耗时0.000000s
...

When the 46-bit element is calculated, the result becomes a negative number. The reason is that the variable res storing the result is of type int. The machine running this code is 64-bit. On a 64-bit machine, the length of the int type is 4 bytes. 32bit, the value range is -(2 31 +1)~2 31 :-2147483648 ~ 2147483647, and fib(46) = fib(45) + fib(44) = 1836311903 + 1134903170 = 2971215073> 2147483647.
So, how did the program produce -1323752223? It is because the C language is used to represent the complement operation of negative numbers: when the negative number of an integer is to be represented, the binary of the integer is inverted by bit and then 1 is added. For example, the binary of 3 is 00000011, then -3 is represented as 11111101.
Going back to the fibonacci sequence just now, fib(45) = 1836311903, the binary is 01101101011100111110010101011111;
fib(44) = 1134903170, the binary is 01000011101001010011111110000010; the two numbers add up to 10110001000110010010010011100001, you can see that this is a number whose first digit is 1 and a total of 32 , In the int type, it will be interpreted as a negative number. Subtracting 1 from this number and then bitwise inverts it to get 01001110111001101101101100011111, which is converted into a decimal number of 1323752223.
The solution can be to use unsigned int (0~2 32 , 0~4294967295) to store the calculation result:

#include <stdio.h>
#include <time.h>

int main(int argc, char const *argv[]){
    time_t start_time, end_time;
    double time_diff;
    const int n = 64;
    for(int i = 1; i < n; i++){
        time(&start_time);

        int pre = 0;
        unsigned int res = 1;
        int ope = i;
        while (0 < ope--) {
            res = res + pre;
            pre = res - pre;
        }

        time(&end_time);
        time_diff = difftime(end_time, start_time);
        printf("fib(%d) = %u, 耗时%fs\n", i, res, time_diff);
    }
}

Or use long int:

#include <stdio.h>
#include <time.h>

int main(int argc, char const *argv[]){
    time_t start_time, end_time;
    double time_diff;
    const int n = 64;
    for(int i = 1; i < n; i++){
        time(&start_time);

        int pre = 0;
        long int res = 1;
        int ope = i;
        while (0 < ope--) {
            res = res + pre;
            pre = res - pre;
        }

        time(&end_time);
        time_diff = difftime(end_time, start_time);
        printf("fib(%d) = %ld, 耗时%fs\n", i, res, time_diff);
    }
}

Guess you like

Origin blog.csdn.net/JosephThatwho/article/details/106663490