C - nombres narcissiques

kwaio Messages postés 3423 Date d'inscription   Statut Contributeur Dernière intervention   -  
kwaio Messages postés 3423 Date d'inscription   Statut Contributeur Dernière intervention   -
Bonjour,
J'ai un exercice.
Le but est de trouver les 4 nombres 3-narcissiques c'es a dite les nombre don't somme des subes des chiffres donnent lui même.
Ce sont 153 370 371 et 407

Sauf que mon programme ne trouve PAS 407...

code :

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

int main ()
{

int i,j,k;
int c;

for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
for(k=0;k<10;k++)
{
c= i*100 + j*10 + k ;

if(c == pow(i,3)+pow(j,3)+pow(k,3))
{
printf("%d ",c);
}
}
}
}

system("pause");
return 0;
}


Une idée ?
A voir également:

13 réponses

fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
Bah, a priori ce n'est pas un problème dans ton programme ^^.
Voici ce que me sort ton programme.
0 1 153 370 371 407 

Et ton algorithme est bon.
Remarque : si le nombre doit être supérieur à 100, n'oublie pas de le mentionner dans ta condition.

Sinon avec quoi codes-tu ?
0
kwaio Messages postés 3423 Date d'inscription   Statut Contributeur Dernière intervention   681
 
Codeblocks ou DevCpp

Ce sont les logiciels utilisés par mes profs et celui utilisé en TP et evaluations...
0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
C'est étrange.
Si tu sais utiliser un débuggueur, utilise le.
Sinon, dans ton programme, lorsque i=4, j=0 et k=7, affiche, i, j, k, c, et pow(i,3)+...
Ca t'aidera sûrement à localiser d'où vient le problème.
0
bizu53 Messages postés 1274 Date d'inscription   Statut Membre Dernière intervention   861
 
Rien qu'à la vue du code j'ai eu l'idée, et je viens de vérifier : tu compares un int avec un double.
cast le double en int et ça fonctionne ;-)

if(c == (int)(pow(i,3)+pow(j,3)+pow(k,3)))

edit : parcontre je ne saurais pas t'expliquer pourquoi pour les autres la comparaison ça se fait bien, je ne sais pas comment sont gérées les comparaisons int/double.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
kwaio Messages postés 3423 Date d'inscription   Statut Contributeur Dernière intervention   681
 
Ca marche, en effet.

Les voies de l'informatique sont impénétrables !
0
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
Je pense pas que l'erreur vienne de là bien que ça semble corrige le problème.
Certe pow renvoie un double, mais 2.0 == 2. Donc il n'y a pas de souci.
Le seul cas qui pourrait faire échouer ta comparaison est que la décimale de la somme des cubes des chiffres ne se termine ne soit pas 0. En faisant le cast, tu caches cette erreur.

Pourrais-tu tester juste par curiosité si t'as le temps sur ta machine ?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main ()
{

    int i,j,k;
    int c;
    if (5==5.0) puts("ok");
    for(i=0;i<10;i++)
    {
        for(j=0;j<10;j++)
        {
            for(k=0;k<10;k++)
            {
                c= i*100 + j*10 + k ;
                if(i==4 && j==0 && k==7){
                    printf("%d\n",pow(i,3)+pow(j,3)+pow(k,3));
                    printf("%d\n",c == pow(i,3)+pow(j,3)+pow(k,3));
                }
                if(c == pow(i,3)+pow(j,3)+pow(k,3))
                {
                    printf("%d ",c);
                }
            }
        }
    }

    system("pause");
    return 0;
}

0
bizu53 Messages postés 1274 Date d'inscription   Statut Membre Dernière intervention   861
 
Ton debug sort ça :

ok
0 1 153 370 371 0
0

Pour le 0 qui suit le 371, c'est normal, c'est un %f qu'il faut pour la somme des pow, en mettant juste ce %f ça donne bien :

ok
0 1 153 370 371 407.000000
0
-1
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
Ton programme marche chez moi.
Et t'as oublié 0 dans ta liste ;)
-1
kwaio Messages postés 3423 Date d'inscription   Statut Contributeur Dernière intervention   681
 
Moi il marche, mais donne seulement 0 1 153 370 et 371

407 ne sort pas j'essaie de comprendre pourquoi.

Mathématiquement, il faut que le nombre soit supérieur à 100.
Mais bref, c'est étrange
-1
bizu53 Messages postés 1274 Date d'inscription   Statut Membre Dernière intervention   861
 
Je viens de me rendre compte en effet que le problème est résolu par le cast mais c'est bien pas de là que vient le problème.

Code de recherche du bug :

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

int main ()
{
int i,j,k,c;

for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
for(k=0;k<10;k++)
{
c= i*100 + j*10 + k ;
if(c == 407){
printf("c=%d ; i=%d ; j=%d ; k=%d ; sommes pow:%f ; test:%d\n", c, i, j, k, pow(i,3)+pow(j,3)+pow(k,3), c == pow(i,3)+pow(j,3)+pow(k,3));
printf("c=%d ; i=%d ; j=%d ; k=%d ; sommes pow:%f ; test:%d\n", c, i, j, k, pow(4,3)+pow(0,3)+pow(7,3), c == pow(4,3)+pow(0,3)+pow(7,3));
}
}
}
}

system("pause");
return 0;
}

Voilà ce qu'il m'affiche :
c=407 ; i=4 ; j=0 ; k=7 ; sommes pow:407.000000 ; test:0
c=407 ; i=4 ; j=0 ; k=7 ; sommes pow:407.000000 ; test:1

Je trouve ça vraiment curieux.
Je poserai la question à un de mes anciens profs d'info si j'y pense.
-1
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
Oui, c'est cela qui m'interpellait ^^.
D'autant plus que sur ma machine, tout marche bien, même ton programme.
Le problème doit être au niveau de la représentation interne de la mantisse. Il suffit qu'un seul bit change pour faire foirer l'égalité. Un bon coup de GDB pour dumper la mémoire afin de voir la représentation interne des bits pourrait valider ou non l'hypothèse.
Il serait intéressant que tu testes par i*i*i+j*j*j+k*k*k à la place des pows. Je pense que ça devrait marcher.
Sinon, bizu53, n'oublie pas de poster un code en utilisant le bouton de conservation de code ( à droite de souligner), maintenant que tu viens souvent ;)
Tiens moi au courant
-1
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
Marrant ça.
un bon test serait peut être de faire 407-"somme pow" voir si il reste quelque chose.
Après la différence entre les différents comportement peu venir des options de compilation, typiquement, de l'utilisation ou non d'optimisation. Un collègue avait remarqué que le résultat d'une somme dépendait de l'ordre dans lequel on la faisait (à conditions qu'il y ai suffisament d'écart entre les nombres).
Depuis que je fait de l'informatique scientifique, on m'a toujours dit de bannir les '==' avec les réel et lui préférer une forme genre :
a==b -> a-b<1e-10
-1
dindoun Messages postés 1028 Date d'inscription   Statut Membre Dernière intervention   135
 
salut,
j'ai pas lu les commentaires , mais

if(c == i*i*i+j*j*j+k*k*k)

marche dès le premier programme :
0 1 153 370 371 407
-1
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
Logique, tu ne fait que des opérations entre entiers
-1
kwaio Messages postés 3423 Date d'inscription   Statut Contributeur Dernière intervention   681
 
C'est peut etre plus sûr de mettre le a-b<1e-10 mais le prof aurait pas aimé
Interro cette après midi, cet exo n'y était pas.

Comparaison de réels, equation du second degré, code ascii et tri d'un tableau...
Basique de chez basique.
-1
Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
Je dit pas que c'est bien ni quoi, je dit juste que c'est comme ça que c'est fait en pratique dans les logiciels scientifiques.
Après, est-ce que le prof a déjà eu une occasion de programmer un vrai logiciel ??
-1
kwaio Messages postés 3423 Date d'inscription   Statut Contributeur Dernière intervention   681 > Char Snipeur Messages postés 9813 Date d'inscription   Statut Contributeur Dernière intervention  
 
Il est chercheur CNRS en informatique...
-1
fiddy Messages postés 11069 Date d'inscription   Statut Contributeur Dernière intervention   1 846
 
Oui, si tu travailles en double, vaut mieux utiliser 1e-10. Par contre dans ton cas, t'avais pas vraiment besoin d'utiliser la bibliothèque math pour pow. Tu pouvais très bien utiliser i*i*i+j*j*j+k*k*k pour calculer la somme des cubes et travailler en integer. Et dans ce cas, pas besoin de 1e-10 ;)
-1