Wie komme ich auf x und y bei id = x << 16 + y?



  • Hallo,

    ich kenne mich leider mit Bit-Operatoren nicht sehr gut aus.
    Kann mir jemand bei folgender Formel helfen:

    Ich habe die Zahl id und will nun auf y und x kommen:

    id = x << 16 + y

    Wie löse ich das richtig auf?

    Danke



  • ich schreibe mal anders:
    id = x*65536+y
    dann ist
    x=id/65536
    und
    y=id%65536



  • Der Ausdruck "x << 16" heißt "x um sechzehn Stellen nach links verschoben", im Fall von 5 = 101 binär wäre das 101,00000000,00000000 binär = 5 * 2^16 = 327680.

    Das Problem ist dementsprechend mehrlösig. Es kann z.B. auch y = id und x = 0 sein. Versuch mal, rauszukriegen, wie viele verschiedene Lösungen es gibt (kleiner Tipp: Es ist vom höchstwertigen Bit von id abhängig).



  • 0xdeadbeef schrieb:

    Das Problem ist dementsprechend mehrlösig. Es kann z.B. auch y = id und x = 0 sein. Versuch mal, rauszukriegen, wie viele verschiedene Lösungen es gibt (kleiner Tipp: Es ist vom höchstwertigen Bit von id abhängig).

    falsch.



  • volkard schrieb:

    0xdeadbeef schrieb:

    Das Problem ist dementsprechend mehrlösig...

    falsch.

    seit wann haben lineare gleichungen in mehr als einer variablen eine eindeutige lösung?

    da mach ich doch mal ein beispiel:

    id = 3*65536+5

    die gleichung ist dann erfüllt für:

    x=3 und y=5
    x=2 und y=65536+5
    x=1 und y=265536+5
    x=0 und y=3
    65536+5
    .
    .
    .

    wenn das nicht mehrdeutig ist 🙄



  • gehen wir zur vereinfachung davon aus, dass:
    id ein long unsigned int ist (32 bit)
    x und y short unsigned ints sind (16 bit)

    dann gibt es immer nur eine lösung:
    y = id & 0x0000FFFF; // ich maskiere die letzten 2 bytes von id und erhalte die beiden niederwertigen bytes
    x = id / 65536; // so bekomme ich die beiden höherwertigen bytes ohne bitshifting (was er ja erklärt haben wollte)

    mehr wollte er doch nicht wissen, also wieso sich das leben schwer machen mit purer mathematik, wenn ein computer eh natürliche grenzen hat?



  • volkard schrieb:

    ich schreibe mal anders:
    id = x*65536+y
    dann ist
    x=id/65536
    und
    y=id%65536

    Die Shift-Operatoren haben eine niedrigere Priorität als die arithmetischen Operatoren.



  • c.rackwitz schrieb:

    mehr wollte er doch nicht wissen, also wieso sich das leben schwer machen mit purer mathematik, wenn ein computer eh natürliche grenzen hat?

    steht das hier irgendwo im thread? nein. in anbetracht der tatsachen die in diesem thread erwähnt wurden hatte 0xdeadbeef recht und volkards kommentarloser widerspruch ist daher ungerechtfertigt.



  • Dann wärs vielleicht sinnvoll gewesen, dazu zu sagen, dass x und y 16-bittig sein sollen... So wies da steht ist es jedenfalls mehrlösig, und auch abhängig vom höchsten gesetzten Bit von id (höchstwertig war vielleicht ungenau ausgedrückt), und zwar insofern, als dass man (ausgegangen davon, dass id 32 bit hat) beliebige Teile von id & 0xFFFF0000 aus x rauslassen und in y einfassen kann. Ich machs grad mal an 4 bit deutlich:

    id = x << 2 + y

    1111 = 0011 << 2 + 0011 = 1100 + 0011
    1111 = 0010 << 2 + 0111 = 1000 + 0111
    1111 = 0001 << 2 + 1011 = 0100 + 1011
    1111 = 0000 << 2 + 1111 = 0000 + 1111



  • \begin{eqnarray*} id & =& x << 16 + y & \\ & & =& x << (16+y) & \\ & & = &x\cdot 2^{16+y} & \\ & & = & x\cdot 2^16\cdot 2^y & \end{eqnarray*}

    folgt: x=id/(65536y)x = id/(65536\cdot y) für x
    Und:

    \begin{eqnarray*} lb(id) & = & lb(2^{16}\cdot 2^y\cdot x) & \\ &&=& lb(2^{16})+lb(2^y)+lb(x) & \\ &&=& 16+y+lb\left(x\right) & \end{eqnarray*}

    Also: y=lb(id)lb(x)16=lb(idx)16y = lb(id)-lb(x)-16 = lb(\frac{id}{x})-16

    Falls ich mich nich irgendwo verlaufen hab 😉

    P.S. Der Additionsoperator geht vor dem Shift-Operator.



  • japro schrieb:

    nein. in anbetracht der tatsachen die in diesem thread erwähnt wurden hatte 0xdeadbeef recht und volkards kommentarloser widerspruch ist daher ungerechtfertigt.

    ok. ich hätte nicht "falsch" schreiben sollen. in der tat sind weitere lösungen möglich. irgendwie war mir aus dem kontext ganz klar, daß x und y stets klein genug sein sollen, um eindeutigkeit zu garantieren.

    [quote=Shlo]Die Shift-Operatoren haben eine niedrigere Priorität als die arithmetischen Operatoren.[/quote]
    was soll mir das sagen?



  • volkard schrieb:

    was soll mir das sagen?

    ...dass 2*2+1 nicht gleich 2*(2+1) ist.



  • also bei x = y<<7 + y<<9;
    werden aber zuerst die shifts ausgerechnet und _dann_ das + ...



  • Ganz sicher?

    #include <cassert>
    
    int main() {
            int x, y = 1;
            x = y << 7 + y << 9;
            assert(x == 0x280);
    }
    

    Dann müsste das ja eigentlich funktionieren 🙄 🙄



  • k1ro schrieb:

    also bei x = y<<7 + y<<9;
    werden aber zuerst die shifts ausgerechnet und _dann_ das + ...

    das kommt ganz auf y an. habe es mit 234881024, 436207616, 637534208 und noch vielen weiteren zahlen ausprobiert. dabei wurde sets << vor + ausgewertet.
    aber bei manchen zahlen (wie bashars 1) wird + vor << ausgewertet.
    es scheint so, daß bashars zahlen ein wenig häufiger sind. ungefähr im verhältnis 4294967296 zu 128.


Anmelden zum Antworten