IF-Abfrage seltsames verhalten

  • IF-Abfrage seltsames verhalten

    Hey,

    Ich habe eine If Abfrage mit 2 Variablen :

    beide sind vom Type Double

    onlineVersion = 1.4
    offlineVersion = 1.3



    Quellcode

    1. if (onlineVersion != offlineVersion) {
    2. NSLog (@"Es ist ein Update verfügbar.");
    3. // Neue Datenbank einspielen
    4. } else .....



    Beim ersten mal sollte es in das erste Statement gesprungen werden. Soweit so gut. Wenn ich den Code aber danach erneut durch gehe sieht es wie folgt aus :

    onlineVersion = 1.4
    offlineVersion = 1.4


    Eigentlich sollte nun das "else"-Statement angesteuert werden , wird es aber nicht.

    Hat jemand ne Idee ?

    Danke :)
  • zerm schrieb:

    Doubles und Floats kann man nicht mit == und != vergleichen. Such mal hier im Forum oder im Internet, wills jetz nich nochmal erklären :)


    Danke , gut das war mir bisher nicht bekannt und dadrauf bin ich auch nicht bei der Recherche gestoßen , wieso auch immer , danke.


    gritsch schrieb:

    so ein vergleich ist generell nicht sinnvoll weil es zb auch versionsnummern a la "1.4.2" gibt etc.
    am besten ist deshalb man hat eine zusätzliche build-nummer die einfach vergleichbar ist, oder schreibt sich eine methode die versionsnummern KORREKT vergleicht.

    gritsch schrieb:

    so ein vergleich ist generell nicht sinnvoll weil es zb auch versionsnummern a la "1.4.2" gibt etc.
    am besten ist deshalb man hat eine zusätzliche build-nummer die einfach vergleichbar ist, oder schreibt sich eine methode die versionsnummern KORREKT vergleicht.


    Ja diese Versionsnummern wird es bei mir aber nicht geben 1.X , 2.X , 3.X
  • TianBao schrieb:

    zerm schrieb:

    Doubles und Floats kann man nicht mit == und != vergleichen. Such mal hier im Forum oder im Internet, wills jetz nich nochmal erklären :)


    Danke , gut das war mir bisher nicht bekannt und dadrauf bin ich auch nicht bei der Recherche gestoßen , wieso auch immer , danke.


    gritsch schrieb:

    so ein vergleich ist generell nicht sinnvoll weil es zb auch versionsnummern a la "1.4.2" gibt etc.
    am besten ist deshalb man hat eine zusätzliche build-nummer die einfach vergleichbar ist, oder schreibt sich eine methode die versionsnummern KORREKT vergleicht.

    gritsch schrieb:

    so ein vergleich ist generell nicht sinnvoll weil es zb auch versionsnummern a la "1.4.2" gibt etc.
    am besten ist deshalb man hat eine zusätzliche build-nummer die einfach vergleichbar ist, oder schreibt sich eine methode die versionsnummern KORREKT vergleicht.


    Ja diese Versionsnummern wird es bei mir aber nicht geben 1.X , 2.X , 3.X


    klar gibts die: 1.4 ist ja bereits 1.X, wenn du aber 1.X.Y meinst dann frage ich dich woher du dir so sicher sein kannst?
    was ist wenn du nach release der 1.4 einen groben schnitzer feststellst? machst du dann 1.5er update oder doch sinnvollerweise nur ein 1.4.1er?
  • macmoonshine schrieb:

    Warum verwendest Du für die Versionsnummern nicht einfach Strings?


    naja, meist gehts ja nicht auf gleichheit zu prüfen sondern ob eine version neuer oder älter ist und dann ist ein einfacher string-vergleich nicht optimal. auch wenn man über numericallycompare (oder wie das heißt) das mit den zahlen gebacken bekommt, wird zb "1.4" und 1.4.0" nicht als equal eingestuft (was es ja aber ist)
  • gritsch schrieb:


    klar gibts die: 1.4 ist ja bereits 1.X, wenn du aber 1.X.Y meinst dann frage ich dich woher du dir so sicher sein kannst?
    was ist wenn du nach release der 1.4 einen groben schnitzer feststellst? machst du dann 1.5er update oder doch sinnvollerweise nur ein 1.4.1er?




    Es geht dabei um eine kleine Datenbank , diese bekommt unregelmäßig ein Update , diese Versionsnummer kommt aus der Datenbank , welche sich in der App und auf dem Webserver befindet.

    Eine Erhöhung der Version gibt es nur dann , wenn es neue Einträge gibt . Wie ich an dieser Stelle hochzähle ist doch egal . Z.B. 1 - 999XX.. oder 1.1 - 1.9 - 2.0 - XXXX.X

    Ich habe Double halt immer in VB.Net verwendet und dachte mir "wieso hier nicht auch" . Die Lösung wurde mir gegeben Float bzw. Double ist hier nicht vergleichbar .
  • TianBao schrieb:

    gritsch schrieb:


    klar gibts die: 1.4 ist ja bereits 1.X, wenn du aber 1.X.Y meinst dann frage ich dich woher du dir so sicher sein kannst?
    was ist wenn du nach release der 1.4 einen groben schnitzer feststellst? machst du dann 1.5er update oder doch sinnvollerweise nur ein 1.4.1er?




    Es geht dabei um eine kleine Datenbank , diese bekommt unregelmäßig ein Update , diese Versionsnummer kommt aus der Datenbank , welche sich in der App und auf dem Webserver befindet.

    Eine Erhöhung der Version gibt es nur dann , wenn es neue Einträge gibt . Wie ich an dieser Stelle hochzähle ist doch egal . Z.B. 1 - 999XX.. oder 1.1 - 1.9 - 2.0 - XXXX.X

    Ich habe Double halt immer in VB.Net verwendet und dachte mir "wieso hier nicht auch" . Die Lösung wurde mir gegeben Float bzw. Double ist hier nicht vergleichbar .


    wie du siehst ist es eben nicht egal. vor allem bei versionen die der user nicht zu gesicht bekommt ist eine ganzzahl immer vorzuziehen.
  • gritsch schrieb:

    naja, meist gehts ja nicht auf gleichheit zu prüfen sondern ob eine version neuer oder älter ist und dann ist ein einfacher string-vergleich nicht optimal.

    Wieso?

    Quellcode

    1. if([theOldVersion doubleVaue] < [theNewVersion doubleValue]) {
    2. // ...
    3. }

    gritsch schrieb:

    wird zb "1.4" und 1.4.0" nicht als equal eingestuft (was es ja aber ist)

    TianBao hat nur Versionsnummern mit einem Punkt. Wenn man Versionsnummern vergleichen will, sollte man sich ein festes Format überlegen, dass man immer einhält bzw. wo man ggf. zu kurze Nummern korrigiert. Bei dem Beispiel "1.4" und "1.4.0" bringen Fließpunktzahlen auch keinen Vorteil.

    TianBao schrieb:

    Die Lösung wurde mir gegeben Float bzw. Double ist hier nicht vergleichbar .

    Für die Vergleiche von Fließpunktzahlen gelten in fast allen Programmiersprachen die gleichen Regeln; da macht VB.Net keine Ausnahme.
    „Meine Komplikation hatte eine Komplikation.“
  • TianBao schrieb:

    Die Lösung wurde mir gegeben Float bzw. Double ist hier nicht vergleichbar .

    Das ist so nicht ganz korrekt.

    Im Allgemeinen läuft if(12.1f != 13.1f) prima.
    Doch sobald irgendwo irgendwas berechnet oder gecastet wird, muss das Ganze nicht mehr so sauber hinkommen.

    Deshalb solltest Du nach Möglichkeit davon absehen zwei Werte selbst vergleichen zu wollen. Du solltest dann lieber ihre Differenz vergleichen.

    Beispiel:

    C-Quellcode

    1. if((neueVersion - gesicherteVersion) >= 0.09) {
    2. // Es steht höchst wahrscheinlich ein Update bereit.
    3. }
    4. else {
    5. // Vermutlich kein Update verfügbar.
    6. }


    Wenn neueVersion = 1.399999973 und gesicherteVersion = 1.40000001 ist die Differenz kleiner 0.09 und damit gibt es kein Update, obwohl 1.399999973 ganz offenkundig != 1.40000001 ist.
    Wenn neueVersion = 1.499999912 und gesicherteVersion = 1.40000001 ist die Differenz ungefähr 0.099999902 und damit >= 0.09

    Du musst in dem Fall also Wertebereiche vergleichen, dann klappt das auch.

    Und wenn Du dann spontan doch noch eine Subversion einbauen möchtest, änderst Du den Wertebereich entsprechend. Beispielsweise auf 0.009 bei Version 1.53
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • Marco Feltmann schrieb:

    TianBao schrieb:

    Die Lösung wurde mir gegeben Float bzw. Double ist hier nicht vergleichbar .

    Das ist so nicht ganz korrekt.

    Im Allgemeinen läuft if(12.1f != 13.1f) prima.
    Doch sobald irgendwo irgendwas berechnet oder gecastet wird, muss das Ganze nicht mehr so sauber hinkommen.

    Deshalb solltest Du nach Möglichkeit davon absehen zwei Werte selbst vergleichen zu wollen. Du solltest dann lieber ihre Differenz vergleichen.

    Beispiel:

    C-Quellcode

    1. if((neueVersion - gesicherteVersion) >= 0.09) {
    2. // Es steht höchst wahrscheinlich ein Update bereit.
    3. }
    4. else {
    5. // Vermutlich kein Update verfügbar.
    6. }


    Wenn neueVersion = 1.399999973 und gesicherteVersion = 1.40000001 ist die Differenz kleiner 0.09 und damit gibt es kein Update, obwohl 1.399999973 ganz offenkundig != 1.40000001 ist.
    Wenn neueVersion = 1.499999912 und gesicherteVersion = 1.40000001 ist die Differenz ungefähr 0.099999902 und damit >= 0.09

    Du musst in dem Fall also Wertebereiche vergleichen, dann klappt das auch.

    Und wenn Du dann spontan doch noch eine Subversion einbauen möchtest, änderst Du den Wertebereich entsprechend. Beispielsweise auf 0.009 bei Version 1.53


    äm, 1.53 ist aber nicht korrekt in dem fall. es müsste 1.5.3 heißen (kann man dann aber nicht mehr als float darstellen warum man das ganze auch nicht machen solle.

    ich verwende meist ein unsigned (32 bit) um versionsnummern zu speichern (string durch punkte auftrennen, 3te stelle + 2te stelle mal 1000 + 1te stelle *1000 * 1000)
  • gritsch schrieb:

    Michael schrieb:

    gritsch schrieb:

    äm, 1.53 ist aber nicht korrekt in dem fall. es müsste 1.5.3 heißen

    Wer sagt, dass es keine Version 1.53 geben kann?

    Michael


    klar kanns die geben. es ist aber nicht das was er wollte: eine subversion von 1.5!


    Das ist doch nur eine Definitionsfrage. Ich mache es immer so. Version wird mit Version erhöht die eine Menge neue Funktionalität bietet (kostenpflichtig). Erste Stelle hinter dem Komma wird erhöht für kleinere Funktionserweiterungen (Kostenlos) und die zweite hinter dem Komma bei Bugfixes. Schlimmstenfalls muss ich dann noch eine dritte hinter dem Komma hinzunehmen wenn ich mehr als 10 Bugfixes machen muss aber in meinen über 25 Jahren als Programmiere ist mir das noch nie passiert das ich 10 Versionen nur mit Bugfixes veröffentlicht habe ohne das sich funktionell auch was geändert hätte.

    Gruß

    Claus
    2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

    Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
  • Thallius schrieb:

    gritsch schrieb:

    Michael schrieb:

    gritsch schrieb:

    äm, 1.53 ist aber nicht korrekt in dem fall. es müsste 1.5.3 heißen

    Wer sagt, dass es keine Version 1.53 geben kann?

    Michael


    klar kanns die geben. es ist aber nicht das was er wollte: eine subversion von 1.5!


    Das ist doch nur eine Definitionsfrage. Ich mache es immer so. Version wird mit Version erhöht die eine Menge neue Funktionalität bietet (kostenpflichtig). Erste Stelle hinter dem Komma wird erhöht für kleinere Funktionserweiterungen (Kostenlos) und die zweite hinter dem Komma bei Bugfixes. Schlimmstenfalls muss ich dann noch eine dritte hinter dem Komma hinzunehmen wenn ich mehr als 10 Bugfixes machen muss aber in meinen über 25 Jahren als Programmiere ist mir das noch nie passiert das ich 10 Versionen nur mit Bugfixes veröffentlicht habe ohne das sich funktionell auch was geändert hätte.

    Gruß

    Claus


    apple schon, man denke an 10.4.11 ;)

    außerdem denken wohl die meisten leute dass X.11 neuer ist als X.7 (was meiner meinung nach ja auch richtig ist).
  • also ich persönlich denke, dass auch eine notation in der form "1.x.x" z.b. besser wäre als nur "1.x". vergleichen würde ich das als String und die zahlenoperation wie auch schon vorgeschlagen mit ganzen zahlen machen. Dann hast du ne klare linie drin und es ist simpel zu handlen.
  • C-Quellcode

    1. struct version {
    2. NSUInteger release;
    3. NSUInteger major;
    4. NSUInteger minor;
    5. };
    6. typedef struct version version;
    7. bool isStoredVersionOlderThanGainedVersion(version stored, version gained);
    8. NSInteger compareInteger(NSUInteger one, NSUInteger two);
    9. bool isStoredVersionOlderThanGainedVersion(version stored, version gained) {
    10. if(compareInteger(stored.release, gained.release) == -1) {
    11. return YES;
    12. }
    13. if(compareInteger(stored.major, gained.major) == -1) {
    14. return YES;
    15. }
    16. if(compareInteger(stored.minor, gained.minor) == -1) {
    17. return YES;
    18. }
    19. return NO;
    20. }
    21. NSInteger compareInteger(NSUInteger one, NSUInteger two) {
    22. if(one == two) return (NSInteger)0;
    23. if(one > two) return (NSInteger)1;
    24. return (NSInteger)-1;
    25. }
    Alles anzeigen

    Noch jemand nen Vorschlag? ;)
    (Ne Funktion zur vernünftigen Anzeige der Versionsnummer als String und zum vernünftigen Erstellen der Versionsnummer aus einem String darf selbst gebastelt werden.)
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P