[Résolu] recherche d'une fonction qui fait la somme des chiffres d'un nombre

prepa75prepa75 Membre
mars 2010 modifié dans API AppKit #1
bonjour

je recherche une méthode qui me permet de faire la somme des chiffres d'un nombre (comme écrit dans le titre  :D )

je m'explique par ex je voudrais que f(123) = 6, quelqu'un a une idée ?
je n'avais pas trouvé en C à  l'époque.

en fait je souhaite l'utiliser pour générer des vrais nombre aléatoires et non des pseudo-aléatoires comme random.si je couple la fonction"somme" avec comme parametre un timer j'aurais un vrai nombre aléatoire compris entre 1 et 9 , a partir de la je met un switch de 9 cases avec un random sur chaque case.

je fait ça car mon programme génère des nombres aléatoires mais c'est toujours la meme suite et c'est prévisible ::)

si quelqu'un a une idée    :D

Réponses

  • CéroceCéroce Membre, Modérateur
    19:39 modifié #2
    Pour la génération des nombres aléatoires, nous en avons déjà  parlé, en expliquant même pourquoi c'est toujours la même suite.

    Pour la fonction, je n'ai pas trop le temps de m'y pencher, mais comme l'ordinateur calcule en base 2 et pas en base 10, il faudrait faire un peu de gymnastique avec les nombres.

  • AliGatorAliGator Membre, Modérateur
    19:39 modifié #3
    Heu faire la somme des chiffres d'un nombre pseudo-aléatoire ne te fera pas avoir des nombre encore plus pseudo-aléatoire. C'est même l'inverse, puisque :
    - Si tu pars d'une même suite à  chaque fois, la somme des chiffres d'une même suite de nombres te donnera toujours la même suite de chiffre de toute façon, donc à  partir de ton pseudo-aléatoire, tu arrivera toujours à  du pseudo-aléatoire
    - Si tu pars d'une suite réellement aléatoire, la somme des chiffres de ces nombres modifiera la répartition des probabilités des chiffres obtenus (puisque par exemple à  partir des nombres de 1 à  100, la valeur 1 ne peux être obtenue qu'à  partir des nombres 1,10,19,28,37,46,55,64,73,82,91 et 100... alors que d'autres chiffres comme 2 ou 3 peuvent être obtenue pas bien plus de nombres source). Du coup ça sera moins aléatoire que ta suite de départ. Partir d'aléatoire arrivera à  du pseudo-aléatoire également.

    La théorie des probabilités et la notion de nombre réellement aléatoire n'est pas si simple qu'il n'y parait, et le langage courant n'est pas toujours le plus révélateur de la réalité (dans le langage courant "aléatoire", "pseudo-aléatoire" et "chaotique" sont souvent synonymes, en tout cas recouvrent un concept bien moins précis que leur signification exacte en mathématique et théories probabilistes).

    Pour avoir un nombre réellement aléatoire et qui change à  chaque fois, le plus simple est d'utiliser la fonction arc4random qui a l'avantage non seulement d'être simple à  utiliser, mais en plus ne nécessitant pas d'initialiser son seed pour avoir des valeurs différentes à  chaque fois.

    Sinon, tu peux utiliser d'autres fonctions (fonctions C de base ou fonctions du framework Apple) mais la plupart nécessitent d'initialiser la graine (seed) la toute première fois avant de les utiliser, (en général on les initialise avec une valeur genre time(NULL) qui a l'avantage de changer toutes les secondes donc d'avoir une valeur différente à  chaque nouveau lancement du programme), sous peine d'avoir sinon toujours la même suite de nombre aléatoire.
    Par exemple, avec la méthode rand, que tu appelles autant de fois que tu as besoin de nombres aléatoires, si tu n'initialises pas avec srand au début de ton programme (avant d'appeler rand en boucle), tu auras toujours la même suite de nombres à  chaque exécution.
  • prepa75prepa75 Membre
    19:39 modifié #4
    En fait c'est bon AliGator , tu as repondu a ma question ;D
    je ne voulais pas faire la somme d'un nombre crée par un random,mais faire la somme de la valeur d'un timer pris entre le lancement de l'operation et la selection du nombre aleatoire.mais ce procedé suit la regle de gauss(je crois quelle s'apelle comme ça),dc il y aura plus de probabilite d'avoir des 4 5 et 6 plutot que des 2 ou 8 par ex(comme tu l'as si bien dit precedement ).j'avais oublier de mettre srand en debut dans mon code,c'est pour cela que lorsque je relance l'application j'ai toujours les meme valeurs. :P

    je me disais bien que les nombres parfaitement aleatoires ne peuvent exister car par defaut un ordinateur ne sait pas prendre des initiative comme celle la...a moins que je ne me trompe :P
  • AliGatorAliGator Membre, Modérateur
    19:39 modifié #5
    Si, /dev/random est le plus proche d'un générateur aléatoire, se basant sur le bruit (au sens électronique, pas acoustique ;)) généré par le hardware il me semble.
    Il suffit d'aller lire dans ce "device" factice pour récupérer une suite d'octets totalement aléatoires.

    Par contre rand (et srand) sont moins aléatoires que leurs comparses, car par exemple les bits de poids faible des nombres aléatoires peuvent vite se répéter comme un motif cyclique.
    Alors qu'avec random, contrairement à  rand, tous les bits du nombre aléatoire généré peuvent être utilisés comme source aléatoire, sans risque d'avoir une répétition ou une répartition de probabilités faussée. C'est pour ça qu'il faut préférer "random" (et "srandom") à  l'utilisation de "rand" (et "srand"), surtout si l'aspect aléatoire du tirage t'importe réellement
    (bon en pratique, utiliser "rand", du moment que tu l'initialises avec srand, est relativement suffisant, c'est surtout pour des applications comme la cryptographie pour générer des clées réellement aléatoires & co que c'est important)

    arc4random quant à  lui, a l'avantage d'être plus simple encore à  initialiser (puisqu'il s'initialise tout seul), et a été designé pour la cryptographie (à  la base son nom lui vient du cipher RC4, maintenant connu dans le domaine plublic sous le nom ARC4) pour faire des permutations aléatoires de cipher boxes. En plus il a un scope plus large puisqu'il opère sur un intervalle deux fois plus grand que rand et random.

    Du coup, il est simple d'emploi (pas de risque d'oublier de l'initialiser) et solide (l'init se base justement sur /dev/urandom donc du réel aléatoire, il a été fait pour la crypto, ...), et perso j'utilise presque plus que ça quand j'ai besoin d'aléatoire.
  • prepa75prepa75 Membre
    19:39 modifié #6
    Oki merci AliGator !!

    j'adore ce forum car on sent que vraiment tu parle de chose concrètes et qui ont du sens !! tu as étais clair et tu as épongé temporairement mon besoin de savoir  :P en un aprem je suis passé d'une photo de la fôret de ifs aux différents types de générateur ne nombre aléatoires  et je sais maintenant comment fonctionne (dans le principe...) un random, c'est tout bête mais je trouve que c'est super important de savoir ça et je t'en remercie de me l'avoir dit spontanement.
           
     
  • yoannyoann Membre
    19:39 modifié #7
    Une autre possibilité est de créer un tableau sans l'initialiser, tu récupère ainsi la mémoire en l'état et tu peut donc y lire des données que tu considère comme des int. ça peut être considéré comme un random et ne nécessite aucune lib particulière.
  • AliGatorAliGator Membre, Modérateur
    19:39 modifié #8
    Moui, ça risque d'être beaucoup moins random quand même, non ? Voire même être dangereux, non ?
    - Si le pointeur non initialisé pointe toujours vers une même zone mémoire, ou du moins dans les mêmes environs, comme certaines pages mémoire peu utilisées peuvent être remplies parfois d'un grand nombre de fois le même octet à  suivre (des pages mémoire remplires de FFFF partout par exemple)
    - Si le pointeur non initialisé se trouve pointer sur une zone mémoire protégée où tu n'es même pas sensé avoir le droit de lire (kernel zone, des trucs comme ça, ça doit bien exister, surtout si c'est dans une zone mémoire qui n'est pas dans la zone sandbox de l'application ni dans une zone de mémoire partagée, mais se trouve être une adresse mémoire qui correspond à  une autre application, qui ne va pas autoriser à  ce qu'on lise dans sa mémoire, vu que le système de OSX avec séparation des zones mémoire empêche ça il me semble)... là , kaboum :P


    Bref, je prendrais pas le risque... D'autant qu'un appel à  arc4random() est tellement simple (ou à  random() du moment qu'on a initialisé avec srandom()
  • prepa75prepa75 Membre
    19:39 modifié #9
    Outre le fait que ça peut causer des problemes comme le dit ALi, il y a aussi un autre truc,c'est que l'on ne peut pas choisir une plage de nombre aleatoire,dc oui ça peut etre aleatoire mais on ne peut pas savoir si ça rentre dans l'intervalle choisi.et si j'ai bien compris ça correspond à  la methode de random non?? :P

    en fait il y a plein de methodes pour generer un nombre aleatoire...
  • AliGatorAliGator Membre, Modérateur
    19:39 modifié #10
    Oui, il y en a pas mal de méthodes au final, mais chacune a ses spécificités.

    Spécificités qui échappent bien souvent au commun des mortels, je ne les connais pas toutes moi-même, mais comme tu as pu le voir, il reste quand même des différences d'après la description de chacune, certaines ayant plus d'entropie que d'autres (donc étant plus aléatoires que d'autres), d'autres ayant une plage plus ou moins large, certaines ayant autant d'entropie sur chacun des bits du nombre générés, d'autres qui deviennent cyclique si on ne considère que les bits de poids faible ou si on fait un modulo sur le résultat, ...

    Et encore, on n'a pas cité toutes les méthodes. Par exemple il se trouve que le SDK de l'iPhone contient dans le framework Security une méthode qui génère elle aussi une valeur aléatoire (mais bon elle lit /dev/random donc bon)
  • prepa75prepa75 Membre
    19:39 modifié #11
    dans 1269355160:


    Et encore, on n'a pas cité toutes les méthodes. Par exemple il se trouve que le SDK de l'iPhone contient dans le framework Security une méthode qui génère elle aussi une valeur aléatoire (mais bon elle lit /dev/random donc bon)


    c'est juste le nom de la méthode qui change mais ça correspond à  un random en fait... :P

    En tout cas je suis content de savoir que je vais pouvoir éviter de faire la somme des chiffres d'un nombre généré par un timer :D
    je me disais bien que y'avais un problème et que les programmeurs avaient forcement pensés et résolu ce problème 
Connectez-vous ou Inscrivez-vous pour répondre.