IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Nombres premiers/Mon premier programme/cherche conseils


Sujet :

C

  1. #21
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    C'est vrai, l'une des différences étant que la norme ne requiert pas que *scanf lève ERANGE en cas de dépassement de capacité.

    À titre d'exemple, voici comment faire en sorte que les deux méthodes aient un comportement similaire :

    Code conv.c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    #include <errno.h>
    #include <inttypes.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
     
    int toui64_scanf(uint64_t *num, const char *s) {
        int c;
        uint64_t n;
        const int ret = sscanf(s, "%" SCNu64 "%n", &n, &c);
        if (ret != 1)
            return 1;
     
        if ((size_t)c != strlen(s))
            return 2;
     
        *num = n;
     
        return 0;
    }
     
    int toui64_strtoul(uint64_t *num, const char *s) {
        _Static_assert(sizeof(unsigned long long) <= sizeof(uint64_t), "possible overflow");
     
        errno = 0;
        char *end;
        const uint64_t n = (uint64_t)strtoull(s, &end, 10);
        if (errno == ERANGE)
            return 1;
     
        if (end - s != (ssize_t)strlen(s))
            return 2;
     
        *num = n;
        errno = 0;
     
        return 0;
    }
     
    void dump(int (*toui64)(uint64_t *, const char *), const char *from[], size_t size) {
        uint64_t u64 = UINT64_C(0);
        for (size_t i = 0; i < size; ++i) {
            const int ret = toui64(&u64, from[i]);
     
            printf("  %10s: ", from[i]);
     
            if (ret)
                printf("parsing failed\n");
            else
                printf("successfully parsed %" PRIu64 "\n", u64);
        }
    }
     
     
    const char *test[] = {
        "64junk",
        "zzz64junk",
        ";64",
        "..64.2",
        "3.141592",
        "18",
        "abc",
        "-18",
        "-18a42"
    };
     
    int main(int argc, char *argv[]) {
        (void)argc; (void)argv;
     
        puts("sscanf:");
        dump(toui64_scanf, test, sizeof test / sizeof *test);
     
        puts("\nstrtoull:");
        dump(toui64_strtoul, test, sizeof test / sizeof *test);
     
        return 0;
    }

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    $ gcc -std=c11 -pedantic -Wall -Wextra conv.c
    $ ./a.out
    sscanf:
          64junk: parsing failed
       zzz64junk: parsing failed
             ;64: parsing failed
          ..64.2: parsing failed
        3.141592: parsing failed
              18: successfully parsed 18
             abc: parsing failed
             -18: successfully parsed 18446744073709551598
          -18a42: parsing failed
     
    strtoull:
          64junk: parsing failed
       zzz64junk: parsing failed
             ;64: parsing failed
          ..64.2: parsing failed
        3.141592: parsing failed
              18: successfully parsed 18
             abc: parsing failed
             -18: successfully parsed 18446744073709551598
          -18a42: parsing failed

  2. #22
    Futur Membre du Club Avatar de Jaenne
    Femme Profil pro
    AVS
    Inscrit en
    Décembre 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : AVS

    Informations forums :
    Inscription : Décembre 2008
    Messages : 15
    Points : 7
    Points
    7
    Par défaut
    Salut, bon, strtoull, toujours pas :-/ remplacée par atoll.

    Par contre argc-argv c'est bon !

    Ça veut dire quoi OP ?

    Ne désespérez pas et continuez de me donnez des conseils. Je ne suis pas de ceux qui comprennent vite mais c'est pas grave, j'ai du temps libre :p
    Je garde tout sous le coude. Merci encore.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    #include <stdio.h>
    #include <stdlib.h>
    #include "primesCalc.h"
     
    int main (int argc, char* argv[]) {
     
    	if (argc !=3){
    		printf("\n\tNeeds 2 intergers :\n\t0 <= startInt <= endInt \n\n");
    		return 0;
    	}
     
    	unsigned long long int start = atoll (argv[1]);
    	unsigned long long int end = atoll (argv[2]);
    	unsigned long long int testedNumber =1;
    	unsigned long long int i = 0;
     
    	start = conv (start);
    	end = conv (end);
     
    	if (end<start)
    		end=start;
     
    	printf("\nSearch primes from : %llu to %llu.\nIt could take less than a second or many hours !\n\n",start,end);
    	for (testedNumber=start;testedNumber<=end;testedNumber++){
    		if (testedNumber>4){
    			if (primeTest(testedNumber)==1){
    				//primes > 4.
    				printf ("%llu ", testedNumber);
    				i++;
    			}
    			else 
    				printf(". ");
    		}		
    		else{
     			if (testedNumber>1 && testedNumber<=3){
    				//2 and 3.
    				printf ("%llu ", testedNumber);
    				i++;
    			}
    			else 
    				printf(". ");
    		}
    	}
    	printf ("\n\nFrom %lld to %llu, %llu primes found.\n\n",start,end, i);
     	return 0;
    }

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    #include <stdio.h>
     
    unsigned int primeTest( unsigned long long int number) {
    	unsigned long long int divisor =2;
    	unsigned long long int modulo= 1 ;
    	//To avoid waste of time.
    	while (divisor <= number/2 && modulo !=0) {
    		modulo = number%divisor;
    		divisor++;
    	}
    	return (modulo!=0);
    }
     
     
    unsigned long long int conv(long long int number){
    	if (number<0) 
    		number*= -1 ;
    	number = (unsigned long long int) number;
    	return number;
    }

  3. #23
    Membre émérite
    Homme Profil pro
    sans emploi
    Inscrit en
    Janvier 2014
    Messages
    539
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : sans emploi
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2014
    Messages : 539
    Points : 2 601
    Points
    2 601
    Par défaut
    Juste pour revenir sur un de tes commentaires dans le code «Pour eviter une perte de temps en calculs.»

    Tu peux revoir ton algo, tu n'as pas besoin de tous les nombres entre 1 et n/2 pour tester la primalité de n, tu peux t'arrêter à √n. Quand n est impair tu peux ne pas tester un diviseur pair ...
    Tu peux aussi remarquer que pour tout nombre premier supérieur ou égal à 5, un nombre ne peut être premier que si son modulo 6 vaut 1 ou 5. Cette remarque est valable aussi pour la boucle pour détecter un diviseur.

    Tu peux aussi t'intéresser à d'autres algorithmes qui sont ultra rapides, comme par exemple un test de miller-rabin que tu rends déterministe.

    OP = posteur originel = toi.

  4. #24
    Futur Membre du Club Avatar de Jaenne
    Femme Profil pro
    AVS
    Inscrit en
    Décembre 2008
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : AVS

    Informations forums :
    Inscription : Décembre 2008
    Messages : 15
    Points : 7
    Points
    7
    Par défaut
    Ok merci. Je me trouvais super maligne avec mon calcul

    Ce serait génial que ce programme travaille plus vite. Je prendrais le temps de regarder ça. On verra si j'arrive a tout mettre en place.

    J'ai édité mon code pour tenter une traduction en anglais.

  5. #25
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Tu peux ajouter d'autres algorithmes en tant que fonctions supplémentaires à ton programme, puis comparer les différents traitements.

    Attention aux membres de la famille ato* qui ne détectent pas les erreurs de conversion. Tu peux alternativement utiliser / adapter les fonctions du programme que j'ai fourni, basées soit sur *scanf, soit sur strto*. Ces fonctions retournent zéro et modifient leur premier paramètre lorsque la conversion a réussi.

Discussions similaires

  1. [Conseils/Aide] Structure de mon premier programme
    Par Invité2 dans le forum Débuter
    Réponses: 44
    Dernier message: 13/09/2008, 14h08
  2. mon premier programme j2me
    Par adilo dans le forum Java ME
    Réponses: 1
    Dernier message: 14/09/2006, 08h43
  3. [JDOM] Mon premier programme java-xml
    Par adilo dans le forum Format d'échange (XML, JSON...)
    Réponses: 3
    Dernier message: 12/07/2006, 13h12
  4. [Language] Aide sur mon premier programme Java?
    Par hash2zo dans le forum Langage
    Réponses: 15
    Dernier message: 27/09/2005, 19h26
  5. [Débutant] Mon premier programme: rien ne va...
    Par vincent0 dans le forum OpenGL
    Réponses: 10
    Dernier message: 02/08/2005, 13h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo