2016-06-02 5 views
-3

J'ai écrit d'un simple générateur de séquence de Fibonacci qui ressemble à:Les nombres longs de Fibonacci non signés sont-ils négatifs?

#include <iostream> 

void print(int c, int r) { 
    std::cout << c << "\t\t" << r << std::endl; 
} 

int main() { 
    unsigned long long int a = 0, b = 1, c = 1; 
    for (int r = 1; r <= 1e3; r += 1) { 
     print(c, r); 
     a = b; 
     b = c; 
     c = a + b; 
    } 
} 

Cependant, comme r obtient autour de la valeur de 40, les choses étranges commencent à se produire. La valeur de c oscille entre négatif et positif, en dépit du fait qu'il est un entier de unsigned, et bien sûr la séquence de Fibonacci ne peut pas être exactement celle-là.

Que se passe-t-il avec les entiers unsigned long long?

Est-ce que c devient trop grand même pour un entier long long?

+3

Donc, vous envisagez de stocker 1000e numéro de fibonacci dans un (éventuellement) nombre de 64 bits? 1000e fibonacci nombre FYI est: 4346655768693745643564660517371780402481729089536555417949051890403879840079255169295922593080322634775209689623239873322471161642996440906533187938298969649928516003704476137795166849228875. Vous devez utiliser un type de données bigint personnalisé. –

+0

Si c'est une option, python est un bon choix de langue car il a le support de bigint intégré. –

Répondre

5

Vous avez une conversion de rétrécissement ici print(c, r); où vous avez défini print pour ne prendre que int « s et ici vous passez un unsigned long long. C'est l'implémentation définie.

Citant le projet de norme C de:

4.4.7:3: Si le type de destination est signé, la valeur est inchangée si elle peut être représentée dans le type de destination; sinon, la valeur est définie par l'implémentation.

Mais ce qui se passe généralement est que: du unsigned long long, seuls les bits qui sont juste assez pour entrer dans un int sont copiés dans votre fonction. Le tronquéint est stocké dans Twos complements, en fonction de la valeur du Most Significant Bit. vous obtenez une telle alternance.

Changer votre signature de fonction pour capturer unsigned long long

void print(unsigned long long c, int r) { 
    std::cout << c << "\t\t" << r << std::endl; 
} 

BTW, voir Mohit Jain's comment à votre question.

+0

Awww Je me sens stupide :( – user6245072

+0

@ user6245072 Pour ne pas se sentir stupide, vous devriez commencer à lire les avertissements du compilateur. – Drop