atof Genauigkeit



  • Servus,

    Ich verzweifle gerade. Ich möchte einfach nur ein Char-Array in einen Double umweandeln. Das mache ich folgendermassen:

    cout.precision(2);
    
    double *ist = new double[6];
    char number[]={"123.4568"};
    ist[0]=atof(number);
    
    cout << "Text: " << number << endl;
    cout << "Double: " << fixed << ist[0] << endl;
    

    Da bekomme ich nun in der Ausgabe:

    Text: 123.4568
    Double: 123.00
    

    Ihr versteht meine Verzweiflung? Hoffentlich habt ihr auch einen Tipp für mich.

    Gruss
    flambert



  • flambert schrieb:

    Da bekomme ich nun in der Ausgabe:

    Text: 123.4568
    Double: 123.00
    

    Ich nicht.
    Dein Compiler? Dein komplettes Beispiel?

    Ansonsten kann man in C++ auch ganz schön mit streams arbeiten:

    #include <stdexcept>
    #include <sstream>
    #include <iostream>
    
    int main(int argc, char* argv[])
    {
        using namespace std;
    	double ist = 0;
    	char number[]="123.4568";
    
    	stringstream ss(number);
    	if (!(ss >> ist))
    		throw runtime_error("conversion failed");
    
    	cout << "Text: " << number << endl;
    	cout << "Double: " << fixed << ist << endl;
    
    	return 0;
    }
    

    Oder generischer zu haben in boost::lexical_cast



  • Danke für die schnelle Antwort. Ja... wenn ich nur dieses kleine Beispiel code funktioniert es auch bei mir. Aber bei meiner eigentlichen Funktion geht es nicht. Hier ist die ganze Funktion:

    double* RTDB::extractSolPosition(char text[], int receiveSize)
    {
       double *ist = new double[6];
       char number[9];
    
       int size = receiveSize;
    
       int t=0;
       bool negativ=false;
       for(int i=0;i<size;i++)
       {
    	if(text[i]=='R')
    	{
               if(text[i+1]=='S')
    	   {
    	      if(text[i+2]=='o')
    	      {
    		   i=i+8;
    		   for(int k=0;k<6;k++)
    		   {
    		      t=0;
    		      negativ=false;
    		      while((int(text[i])<58 && int(text[i])>47) || text[i]=='.' || text[i]=='-')
    		      {
    			 if(text[i]=='-')
    			 {
    			    negativ=true;
    			    i++;
    			 }
    			 else
    			 {
    			    number[t]=text[i];
    			    i++;
    			    t++;
    			 }
    		      }
    		      number[t]='\0';
    		      ist[k]=atof(number);
    		      if(negativ)
    		      {
    			 ist[k]=ist[k]*(-1);
    		      }
    			 i=i+5;
    		      }
    		   }
    	      }
    	   }
       }
    return ist;
    }
    

    Ist den das mit dem Streamen genauso schnell wie atof? Bei mir spielt Geschwindigkeit eine große Rolle. Bzw. ist an meiner Funktion etwas nicht in ordnung?



  • Wieso man einen fehlerfreien Code postet und von einem Fehler darin erzählt... 🙄

    Bist du mal mit einem Debugger durchgegangen? Ich weiß ja nicht womit die Funktion aufgerufen wird um einen Fehler zu reproduzieren und um das durch darufgucken zu lösen ist das Ding zu unübersichtlich.

    Nochmal als tipp... Wichtig ist was DU genau für eine Funktion aufrufst und wie. Nicht dass atof was falsch macht.



  • Lass dir number ausgeben, bevor du sie atof übergibst. Dann siehst du, ob das drinsteht, was du denkst.

    Ist dir außerdem bewußt, dass dir deine Funktion um die Ohren fliegt, wenn der Text nicht so aufgebaut ist, wie du das erwartest?



  • brotbernd schrieb:

    Wieso man einen fehlerfreien Code postet und von einem Fehler darin erzählt... 🙄

    Bist du mal mit einem Debugger durchgegangen? Ich weiß ja nicht womit die Funktion aufgerufen wird um einen Fehler zu reproduzieren und um das durch darufgucken zu lösen ist das Ding zu unübersichtlich.

    Deshalb habe ich versucht die Funktion auf das nötige runter zu brechen. Der gesamte Code ist viel zu unübersichtlich. Ich habe gerade auch versucht die Funktion in ein Miniprojekt einzubinden. Aber selbst da funktioniert es. Es klappt nur im Hauptprojekt nicht.
    Debuggen kann ich leider nicht. Läuft alles in Threads.

    Nochmal als tipp... Wichtig ist was DU genau für eine Funktion aufrufst und wie. Nicht dass atof was falsch macht.

    Kann es am Compiler liegen? Ich verwende Qt und Realzeitbibliotheken.

    Lass dir number ausgeben, bevor du sie atof übergibst. Dann siehst du, ob das drinsteht, was du denkst.

    Ist dir außerdem bewußt, dass dir deine Funktion um die Ohren fliegt, wenn der Text nicht so aufgebaut ist, wie du das erwartest?

    Ich lasse mir das Char-Array ausgeben. So wie im ersten Post beschrieben. Da bekomme ich genau das richtige Ergebniss. Der Text muss 100%ig so aufgebaut sein. Der wird auf der Gegenseite von einem Embeddetsystem geschickt (desen Verhalten wir sehr genau vorraussagen können).



  • Wir brauchen ein Bsp. wie man den Fehler reproduzieren kann.
    Funktion + Argumente => Fehler xyz



  • Hier der Code nochmal nach einer Schönheits-OP und Entschlackungskur:

    double* RTDB::extractSolPosition(const char text[], int size)
    {
        double* ist = new double[6];
        char number[32];
    
        for(int i=0; i<size; i++)
        {
            if(text[i]=='R' && text[i+1]=='S' && text[i+2]=='o')
            {
                i+=8;
                for(int k=0; k<6; k++)
                {
                    int t=0;
                    while((text[i]>='0' && text[i]<='9') || text[i]=='.' || text[i]=='-')
                    {
                        number[t++]=text[i++];
                    }
                    number[t]='\0';
                    ist[k]=atof(number);
                    i+=5;
                }
            }
        }
        return ist;
    }
    

    Der funktioniert so auch:

    int main()
    {
      string text="RSo     16.4     -3.14     5     0     4442     -7.23444";
      double* test=extractSolPosition(text.c_str(),text.length());
      for (int i=0;i<6;i++)cout << test[i] << endl;
    }
    

    Ausgabe:

    16.4
    -3.14
    5
    0
    4442
    -7.23444
    


  • Ist das jetzt fehlerhaft oder korrekt?



  • Wurde die C-Locale vielleicht irgendwo so gesetzt, dass atof ein Komma erwartet?

    Beispiel (C-Code):

    #include <locale.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    int main(int argc, char *argv[]) {
      double d;
    
      if(argc > 1) {
        setlocale(LC_ALL, argv[1]);
      }
    
      d = atof("123.456");
      printf("%lf\n", d);
    
      return 0;
    }
    
    /* Ausgabe:
     *
     * $ ./a.out
     * 123.456000
     * $ ./a.out de_DE.UTF-8
     * 123,000000
     */
    


  • Danke euch allen und entschuldigt, dass ich den Code nicht vernünftig geliefert habe. Aber seldon hat Recht:

    seldon schrieb:

    Wurde die C-Locale vielleicht irgendwo so gesetzt, dass atof ein Komma erwartet?

    Beispiel (C-Code):

    #include <locale.h>
    #include <stdlib.h>
    #include <stdio.h>
    
    int main(int argc, char *argv[]) {
      double d;
    
      if(argc > 1) {
        setlocale(LC_ALL, argv[1]);
      }
    
      d = atof("123.456");
      printf("%lf\n", d);
    
      return 0;
    }
    
    /* Ausgabe:
     *
     * $ ./a.out
     * 123.456000
     * $ ./a.out de_DE.UTF-8
     * 123,000000
     */
    

    Als ich es mit Komma probiert habe hat es auf Anhieb funktioniert.

    Danke und einen schönen Abend euch.
    flambert


Anmelden zum Antworten