Mira el complemento del lenguaje C de la secuencia de fibonacci

Primero mire una demostración que calcula la secuencia de fibonacci:

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
...

Cuando se calcula el elemento de 46 bits, el resultado se convierte en un número negativo. La razón es que la variable res que almacena el resultado es de tipo int. La máquina que ejecuta este código es de 64 bits. En una máquina de 64 bits, la longitud del tipo int es 4 bytes. 32 bits, el rango de valores es - (2 31 +1) ~ 2 31 : -2147483648 ~ 2147483647, y fib (46) = fib (45) + fib (44) = 1836311903 + 1134903170 = 2971215073> 2147483647.
Entonces, ¿cómo produjo el programa -1323752223? Es porque el lenguaje C se usa para representar la operación de complemento de números negativos: cuando se va a representar el número negativo de un entero, el binario del entero se invierte y luego se suma por 1. Por ejemplo, el binario de 3 es 00000011, luego -3 se representa como 11111101.
De vuelta a la secuencia de fibonacci, fib (45) = 1836311903, el binario es 01101101011100111110010101011111;
fib (44) = 1134903170, el binario es 01000011101001010011111110000010; los dos números suman 10110001000110010010010011100001, puede ver que este es un número cuyo primer dígito es 1, y un total de 32, En el tipo int, se interpretará como un número negativo. Restando 1 de este número y luego lo invierte bit a bit para obtener 01001110111001101101101100011111, que se convierte en un número decimal de 1323752223.
La solución puede ser utilizar unsigned int (0 ~ 2 32 , 0 ~ 4294967295) para almacenar el resultado del cálculo:

#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);
    }
}

O use int largo:

#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);
    }
}

Supongo que te gusta

Origin blog.csdn.net/JosephThatwho/article/details/106663490
Recomendado
Clasificación