problem mit Brüchen bei C++

pointhi

Erfahrenes Mitglied
hy,
ich progge noch immer bei meiner sateliten"ortungs"software, und zurzeit bin ich bei einer kleinen nebenfunktion zum ermitteln der Geographischen Länge und Breite aus einem QTH Locator.
Die ersten 4 Größesnfelder (2*die Längenfelder und 2*die Breitenfelder) werden korrekt ermitteln, wenn das programm aber zu den Felden kommt die kleiner als 1 sind gibt es probleme. Wegen der genauigkeit sind sie in Brüche angeschrieben, und wenn ich z.b. statt dem bruch 0.01 hineinschreibe funkioniert das rechnen korrekt.

Der aktuelle code der Funktion ist:

C++:
/*###########################################################
Funktionsname:      satpos::geop::LocatorIn
Übergabewerte:      char *Locator
Rückgabewerte:      0   ... Erfolg
                    1   ... Fehler
Erstellungsdatum:   12.12.2011
Letzte Änderung:    17.12.2011
Programmierer:      pointhi
Beschreibung:       Funktion die den QRH-Locator in geographische Länge und breite umrechntet. Es werden QRH-Kenner mit einer genauigkeit von 2-10 feldern erlaubt
###########################################################*/
int geop::LocatorIn(char *Locator) {

double Latitude = 0;
double Longitude = 0;
char    Character;

for(int i=0;(i<10)&&(Locator[i]!='\0');i++)
    {
    if(Locator[i]>='a'&& Locator[i]<='z')    // Umwandlung der buchstaben in Großbuchstaben für erweiterte kompilität
    {
        Character=Locator[i]-32;
    }
    else
    {
        Character=Locator[i];
    }
    switch(i)
        {
        case 0: // Geographische Länge in 20° Schritte
            if(Character >= 'A' && Character<='R')
            {
                Longitude = 20*(Character-65)-180;
            }
            else
                {return 1;}
            break;
        case 1: // Geographische Breite in 10° Schritte
            if(Character >= 'A' && Character<='R')
            {
                Latitude = 10*(Character-65)-90;
            }
            else
                {return 1;}
            break;
        case 2: // Geographische Länge in 2° Schritte
            if(Character >= '0' && Character<='9')
            {
                Longitude += 2*(Character-48);
            }
            else
                {return 1;}
            break;
        case 3: // Geographische Breite in 1° Schritte
            if(Character >= '0' && Character<='9')
            {
                Latitude += (Character-48);
            }
            else
                {return 1;}
            break;
        case 4: // Geographische Länge in 1/12 Schritte
            if(Character >= 'A' && Character<='X')
            {
                Longitude += (1/12)*(Character-65);
            }
            else
                {return 1;}
            break;
        case 5: // Geographische Breite in 1/24 Schritte
            if(Character >= 'A' && Character<='X')
            {
                Latitude += (1/24)*(Character-65);
            }
            else
                {return 1;}
            break;
        /*case 6:
            if(Locator[6] >= '0' && Locator[6]<='9')
            {
                Latitude += (Locator[6]-48);
            }
            else
                {return 0;}
            break;
        case 7:
            break;
        case 9:
            break;
        case 8:
            break;*/
        default:
            return 1;
            break;
        }
    }

std::cout << "\n long:"<< Longitude;
std::cout << "\n Lath:" <<Latitude;

this->Longitude = Longitude;
this->Latitude = Latitude;

// Umrechnen der Geographischen in die Geozentrische Breite
this->GeocentricLatitude = Latitude - (11.5/60 *  std::sin((Latitude*M_PI/90))) ;
return 0;
}

Sie ist noch nicht komplett und die fehlererkennung wird auch noch komplett umgeschrieben, mir geht es jetzt mal nur um das eine problem mit den brüchen 1/12 und 1/24.

mfg. pointhi
 
Hallöle,

das sieht starkt nach Integer-Division aus, auch wenn du das Ergebnis dann auf eine Variable des Typs "double" legst.
Bei der Integer-Division fallen die Nachkommastellen weg, und dein Ergebnis wäre bei diesen Brüchen immer 0.

Mich würde mal interessieren, ob es funktioniert, wenn du die Zeile so abwandelst:

C++:
Longitude += (1.0/12.0)*(Character-65.0);

Latitude natürlich analog.
 
bei mir wird das hier:
C++:
 Longitude += (1/12)*(Character-65);
nicht korrekt übersetzt:

statt die 1/12 in ein double umzurechenen und das dann mit dem "Indexwert" zu multiplizieren kommt immer 0 heraus.

Wenn ich:

C++:
std::cout << (1/12);

mache kommt auch 0 als ausgabe, wenn ich aber:

C++:
std::cout << 0.0833333;

eingebe ist die ausgabe korrekt.

mfg. pointhi
 
Habs gelöst indem ich einfach mal 1.0 statt 1 geschrieben habe. war wohl ein fehler vom compiler bei der optimierung.

C++:
         {
                Longitude += (1.0/12)*(Character-65);
            }
            else
                {return 1;}
            break;
        case 5: // Geographische Breite in 1/24 Schritte
            if(Character >= 'A' && Character<='X')
            {
                Latitude += (1.0/24)*(Character-65);
            }

mfg. pointhi

tschuldigung ALEX_T, hab deinen beitrag wohl übersehen
 
Zuletzt bearbeitet:
Habs gelöst indem ich einfach mal 1.0 statt 1 geschrieben habe. war wohl ein fehler vom compiler bei der optimierung.

Ist kein Fehler des Compilers (was es allgemein nur sehr selten gibt ;)), sondern korrektes Verhalten. Bei der Division von 1/12 entsteht eine Kommazahl, aber aus der Division von zwei Integern wird keine Kommazahl generiert, sondern wieder ein Integer. Aus diesem Grund ist der Compiler gezwungen das Ergebnis auch wieder als Integer aufzufassen. Aus 0.0833333 wird als Ganzzahl 0 - man lässt einfach den Kommateil weg. Wenn du 1.0 schreibst ist das ein double-Literal was den Compiler dazu zwingt den anderen Rechenoperator (12) auch als double aufzufassen. Dadurch entsteht dann ein double mit dem Wert 0.083333. Aus (Character - 65) wird wieder ein Integer, da beides Integer sind, der dann multipliziert wird mit 0.083333. Da erstes ein double ist wird zweites dann automatisch auch zu einem double befördert und das Endergebnis ist dann ein double mit Kommastellen. Eigentlich ganz einfach, du musst dir nur merken, dass aus zwei Integern nie eine Kommazahl wird, aber sobald eine involviert ist die anderen zu Kommazahlen befördert werden.
 
tja, man lernt nie aus. Hab das problem heute noch ein paar mal gehabt, weil ich endlich eine neue pre-alpha version online bringen will. Hab seit 1. Monat nicht mehr daran gearbeitet da die Festplatte gecrasht ist und ich noch andere Projekte hab die auch wichtig sind.

Falls es jemanden interresiert, das ist das projekt:

http://sourceforge.net/projects/satpos/

Dafür das es pre-alpha ist hatte ich schon relativ viele downloads quer über den globus verstreut. von deutschland zur usa bis nach china. Und meine kommentare sind noch immer in deutsch :eek:, muss ich bei der nächsten version ändern.

mfg. pointhi
 
Zurück