Sortieren Sie 3 Zahlen ohne Verwendung von logischen Operatoren.



  • out schrieb:

    Tachyon schrieb:

    Sone schrieb:

    Ich stelle mich nicht doof! Was soll er denn sonst darunter meinen, da fällt mir echt nichts ein 😞

    < ist aber kein logischer, sondern ein relationaler Operator.

    Wenn das so ist, dann erzählt deutsches Wiki mal wieder Schrott 😡

    Ist aber so. Logische Operatoren haben typischerweise Wahrheitswerte als Operanden. Die englische Wikiseite hat eine korrekte Auflistung.



  • Hä? Logische Operatoren sind einfach nur Operatoren, die einen Wahrheitswert liefern. Und darunter fallen halt auch relationale Operatoren.

    < ist also ein logischer Operator. Speziell halt nur ein relationaler.



  • Incocnito schrieb:

    Logische Operatoren sind einfach nur Operatoren, die einen Wahrheitswert liefern.

    Nein, logische Operatoren modellieren Verknüpfungen der Aussagenlogik. In C++ wären das Konjunktion (Und), Disjunktion (Oder) und Negation (Nicht).



  • out schrieb:

    Tachyon schrieb:

    Sone schrieb:

    Ich stelle mich nicht doof! Was soll er denn sonst darunter meinen, da fällt mir echt nichts ein 😞

    < ist aber kein logischer, sondern ein relationaler Operator.

    Wenn das so ist, dann erzählt deutsches Wiki mal wieder Schrott 😡

    Seit wann gibt man was auf Wikipedia wenn die Infos wirklich richtig sein sollen?



  • Achso, jetzt hab ichs auch gecheckt.
    Dann muss also nur die Zeile "Vergleiche" aus der Tabelle in dem Artikel entfernt werden (de.wikipedia.org/wiki/Logischer_Operator).



  • [Rewind] schrieb:

    hustbaer schrieb:

    @[Rewind]
    Bei x==y kommt bei dir 0 raus würde ich sagen.

    Würde ich nicht sagen. Genau aus diesem Grund multipliziere ich am Ende noch mit der Differenz der beiden Zahlen.

    Argh - ich hab mir da einer Klammer eingebildet die gar nicht da ist - es wird ja nur der y * ... Teil mit bool(x-y) multipliziert, nicht die Summe. Ja, dann geht das natürlich.

    [Rewind] schrieb:

    hustbaer schrieb:

    Und mit negativen Zahlen wird das auch nicht funktionieren.

    Jein. Es gibt, glaube ich, nur einen Fall, wo das nicht funktioniert, und zwar wenn x + y = 0 .

    Entweder ich stehe schon wieder auf dem Schlauch, oder...
    Beispiel:
    x = -10
    y = 1

    max(x,y) = x * bool(int(x / y)) + y * bool(int(y / x)) * (bool (x-y));
    = -10 * bool(-10/1) + 1 * bool(1/-10) * bool(-10-1)
    = -10 * 1 + 1 * 0 * 1
    = -10
    = falsch
    


  • SeppJ schrieb:

    hustbaer schrieb:

    "Betrag" ist ein verstecktes "if", genau so wie "cast nach bool" eines ist.

    Für den Betrag gibt es Bittricks:
    http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs

    Ist mir schon klar, ich kenne die Seite.

    Ist jetzt natürlich die Frage, ob man bitweise Operationen als logische Operationen ansieht. Ich würde es nicht tun. Sie sind eher Rechenoperationen wie Addition.

    Naja man kann die als Rechenoperationen sehen. Man kann logische Operationen aber auch als Rechenoperationen auf einem beschränkten Alphabet sehen.
    Ich sehe hier die bitweisen Operationen eher als SIMD Variante der logischen Operationen.



  • hustbaer schrieb:

    ...

    So ein Mist! Du hast recht wege den neg. Zahlen. Muss mir was überlegen.



  • Negative Zahlen sind doch kein Problem. Einfach INT_MIN subtrahieren und als unsigned darstellen. Dann sortieren und am Schluss wieder jeweils INT_MIN addieren.



  • int my_min(int a, int b)
    {
    	int r[2] = {a, b};
    
    	return r[(b + (~a + 1)) >> 31 & 1];
    }
    


  • Ist sowas auf heutigen Architekturen wirklich schneller als

    return r[b < a];
    

    ?

    Ich meine, da werden Unmengen an Operationen aufgerufen: Shift, And, Not, 3 mal Addition (inklusive Index-Operator).


  • Mod

    Spinne auf dem Transistor schrieb:

    Ist sowas auf heutigen Architekturen wirklich schneller als

    return r[b < a];
    

    ?

    Ich meine, da werden Unmengen an Operationen aufgerufen: Shift, And, Not, 3 mal Addition (inklusive Index-Operator).

    Wahrscheinlich nein. Das ist eher eine Optimierung aus Pentiumzeiten. Eventuell bei einigen neuen Prozessoren mit extrem langen Pipelines aber wieder (glaube ich aber nicht wirklich).

    P.S.: Den ganzen Arrayhack würde ich heutzutage ganz sein lassen.



  • int a,b,c,n=0,m=0,o=0;
    cout << "Bitte 3 ganze Zahlen eingeben:" << endl;
    cin >> a;
    cin >> b;
    cin >> c;
    cout << "Aufsteigend sortiert:" << endl;
    do {
    n = n + 1;
    m = m + 1;
    o = o + 1;
    }
    while (n < a && m < b && o < c);
    cout << n << endl;
    do {
    n = n + 1;
    m = m + 1;
    o = o + 1;
    }
    while (n < a && m < b && o < c);
    cout << n << endl;
    do {
    n = n + 1;
    m = m + 1;
    o = o + 1;
    }
    while (n < a && m < b && o < c);
    cout << n << endl;

    Ich habe dies so gelöst. Habe jedoch einen Fehler drinnen, denn ich nicht erkennen kann. Kann mir jemand helfen?[cpp]


  • Mod

    Na, da hast du aber jede Menge Logikoperatoren drin. Außerdem: Kommt dir die Vorgehensweise nicht ein kleines bisschen umständlich vor?

    Einer der Fehler ist, dass die Abbruchbedingung, nachdem die erste Schleife abgebrochen ist, bei den darauf folgenden Schleifen natürlich ebenfalls sofort abbricht.



  • SeppJ schrieb:

    P.S.: Den ganzen Arrayhack würde ich heutzutage ganz sein lassen.

    Der bringt nur was wenn der Compiler kein CMOV generieren kann.
    Dann allerdings ist der auch auf halbwegs aktuellen CPUs z.T. noch spürbar. Allerdings vermutlich auch nur wenn die Branch-Prediction mit dem taken/not-taken Muster des ohne CMOV nötigen Sprungs nicht klarkommt.


Anmelden zum Antworten