String to Long



  • Hi

    Wie lese ich den Long richtig ein und gebe ihn richtig aus?

    unsigned long ul;
    ul = strtoul(argv[1],NULL,10);
    printf("%ul\n",ul);
    

    MfG Joe



  • find' ich toll, dass du deine frage selbst beantwortest 🙂



  • Hi

    Wenn argv[1] = 1001011112222222 ist gibt printf 4294967295l aus.

    MfG Joe



  • [JoE] schrieb:

    Wenn argv[1] = 1001011112222222 ist gibt printf 4294967295l aus.

    1001011112222222 ist ja auch ein astronomischer wert, der passt nimmer nicht in ein 'unsigned long'.
    4294967295 ist übrigens 0xffffffff -> oberster anschlag des wertebereichs eines (32 bittigen) unsigned longs
    🙂



  • Schon auf die Idee gekommen, dass ein long auf deinem System einfach nicht groß genug ist um den geforderten Wert darzustellen?

    edit: zu langsam



  • Hi

    Danke. Welche Datentypen gibt es denn, welche bis zu 20 Stellen im Zehnersystem fassen?

    MfG Joe



  • Der größte Datentyp in C (C99) ist unsigned long long. Er kann mindestens 0 bis 18446744073709551615 darstellen. Mehr ist zwar theoretisch möglich, aber unüblich. Sollte der nicht ausreichen gibts noch Bibliotheken wie die GMP.



  • Ich benötige solche Variablen für eine Zahlenfaktorisierung:

    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>
    #include <sys/wait.h>
    #include <math.h>
    
    typedef enum {false,true} bool;
    
    int jobsize = 500;
    bool debug = false;
    
    int main(int argc, char* const argv[]) {
    
     if(argc<2){
       printf("Usage: fac <NUMBER>\nNUMBER has to bigger than 1000\n");
       exit(1);
     }
    
     unsigned long long primecandidate;
    
     primecandidate = strtoull(argv[1],NULL,10);
    
     if (primecandidate < jobsize){
       printf("Usage: fac <NUMBER>\nNUMBER has to bigger than 1000\n");
       exit(1);              
     }
    
     pid_t fork_res[20];
     pid_t wait_res;
    
     unsigned long min;
     unsigned long max;
     unsigned long i = 2;
     unsigned long l = 0;
    
     printf("Begin of factorization of: %s\n",argv[1]);
    
     while(i*i <= primecandidate){
    
         min = i;
         max = min + jobsize;
    
         if(max*max > primecandidate){
             break;      
         }
    
         if (debug)
            printf("Job from %d to %d\n",min,max);
    
         fork_res[l] = fork();
    
         if(fork_res[l]==0)
         { 
    
           if (debug)
              printf("New fork-process calcing...%llu\n",primecandidate);
    
           while (min <= max){
    
                 if (debug){
                    printf("Check %llu %llu\n",min,primecandidate);
                    sleep(1);
                 }
    
                 if (primecandidate%min==0){
                       primecandidate = primecandidate/min;
                       printf("Found factor: %llu\n",min);
                 } else {
                   if (min==2) min = 3;
                   else min += 2;       
                 }
    
           }
    
           if (debug){
              printf("Process done\n");
              sleep(1);
           }
    
           exit(0);
         } else if (fork_res[l] == -1) {
           perror("Fork:");
         }
    
         if(l == 20){
              int m;
              for (m = 0; m < l; ++m){
                  int status;
                  waitpid(fork_res[m],&status,0);  
              }
              l = 0;     
         } else {
              ++l;
         }
    
         i = max;
     }
    
     int m;
     for (m = 0; m < l; ++m){
         int status;
         waitpid(fork_res[m],&status,0);  
     }
    
     if(debug)
       printf("Mainloop finished\n");
    
     exit(0);
    
    }
    

    Ich benötige fork() da ich den Algorithmus auf einem Cluster testen möchte. Leider erhalte ich jedoch immer andere Faktoren.

    MfG Joe



  • [JoE] schrieb:

    while(i*i <= primecandidate)
    

    i ist 'long', aber 'primecandidate' ist 'long long'
    kann sein dass es daran liegt.

    btw: primfaktorzerlegung usw..
    --> http://www.troubleshooters.com/codecorn/primenumbers/primenumbers.htm



  • Hi

    unsigned long long min;
     unsigned long long max;
     unsigned long long i = 2;
    

    Ändert nichts an der Sache. Komisch ist aber das manchmal primecandidate 0 ist nach dem fork() ausgeführt wurde.

    MfG Joe



  • vielleicht 'ne race condition?
    mach das ganze doch mal in einem prozess (ist dann auch einfacher zu debuggen)



  • Hi

    Nun dass fertige funktionierende Programm:

    #include <stdlib.h>
    #include <stdio.h>
    #include <math.h>
    #include <stdint.h>
    #include <stdio.h>
    
    typedef enum {false,true} bool;
    
    int jobsize = 50000;
    int anzproz = 50;
    bool debug = false;
    unsigned long long primecandidate;
    
    bool isprime(long long number);
    
    int main(int argc, char* const argv[]) {
    
     if(argc<2){
       printf("Usage: fac <NUMBER>\n");
       exit(1);
     }
    
     primecandidate = strtoull(argv[1],NULL,10);
    
     if (primecandidate > UINT64_MAX ){
       printf("Usage: fac <NUMBER>\n");
       exit(1);              
     }
    
     pid_t fork_res[anzproz];
     pid_t wait_res;
    
     FILE * file;
     file = fopen("fact","wa");
    
     unsigned long long min;
     unsigned long long max;
     unsigned long long i = 2;
     unsigned long l = 0;
    
     printf("Begin of factorization: %s\n",argv[1]);
    
     bool last = false;
    
     while(i*i <= primecandidate && !last){
    
         min = i;
         max = min + jobsize + 1;
    
         if(max*max > primecandidate){
             max = (unsigned long)(sqrt(primecandidate));     
             last = true;
         }
    
         if (debug)
            printf("Job from %llu to %llu\n",min,max);
    
         fork_res[l] = fork();
    
         if(fork_res[l]==0)
         { 
           if (debug)
              printf("New fork-process, calcing number: %llu\n",primecandidate);
    
           while (min <= max){
    
                 if (debug){
                    printf("Check %llu %llu\n",min,primecandidate);
                    sleep(1);
                 }
    
                 if (isprime(min) && primecandidate%min==0){
                       primecandidate = primecandidate/min;
                       printf("Found factor: %llu\n",min);
                       fprintf(file,"%llu\n",min);
                 } else {
                   if (min==2) min = 3;
                   else min += 2;       
                 }
    
           }
    
           if (debug){
              printf("Job done\n");
              sleep(1);
           }
    
           exit(0);
         } else if (fork_res[l] == -1) {
           perror("Fork:");
         }
    
         if(l == anzproz){
              if (debug)printf("wait\n");
              int m;
              for (m = 0; m <= l; ++m){
                  int status;
                  waitpid(fork_res[m],&status,0);  
              }
              l = 0;     
              if (debug)printf("end wait\n");
         } else {
              ++l;
         }
    
         i = max;
     }
    
     int m;
     for (m = 0; m < l; ++m){
         int status;
         waitpid(fork_res[m],&status,0);  
     }
    
     fclose(file);
    
     file = fopen("fact","r");
     char puf[30];
    
     while(fgets(puf, 30, file)){
         primecandidate = primecandidate/strtoull(puf,NULL,10);            
     }
    
     fclose(file);
    
     if(debug)
       printf("Mainloop finished\n");
    
     printf("Last factor %llu\n",primecandidate);
    
     exit(0);
    
    }
    
    bool isprime(long long number) {
        if (number <= 3) return true;
        if ((number % 2) == 0) return false;
        long l;
        for (l = 5; l * l <= number; l+=2)
            if ((number % l) == 0) return false;
        return true;
    }
    

Anmelden zum Antworten