C - nombres narcissiques

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 ?

--
Contributeur CCM.
"Si vous savez, répondez a ce message, sinon, abstenez vous, merci !"
Configuration: Windows Vista
Firefox 3.0

13 réponses

  1. Contributeur
    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
    1. Contributeur
      Codeblocks ou DevCpp

      Ce sont les logiciels utilisés par mes profs et celui utilisé en TP et evaluations...
      0
      1. Contributeur
        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
        1. 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
          1. Contributeur
            Ca marche, en effet.

            Les voies de l'informatique sont impénétrables !
            0
            1. Contributeur
              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
              1. 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
            2. Contributeur
              Ton programme marche chez moi.
              Et t'as oublié 0 dans ta liste ;)
              -1
              1. Contributeur
                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
                1. 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
                  1. Contributeur
                    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
                2. Contributeur
                  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
                  1. 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
                    1. Contributeur
                      Logique, tu ne fait que des opérations entre entiers
                      -1
                  2. Contributeur
                    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
                    1. Contributeur
                      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
                    2. Contributeur
                      @Char SnipeurIl est chercheur CNRS en informatique...
                      -1
                  3. Contributeur
                    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