tutorials.de Buch-Aktion 05/2012
Like Tree2Danke
  • 1 Beitrag von Dennis Wronka
  • 1 Beitrag von Matthias Reitinger
ERLEDIGT
JA
ANTWORTEN
5
ZUGRIFFE
339
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    Avatar von nop0x90
    nop0x90 nop0x90 ist offline Mitglied Bronze
    Registriert seit
    Mar 2008
    Ort
    NRW/Düsseldorf
    Beiträge
    42
    Hi,
    nach nun einiger Zeit brauche ich mal wieder eure kompetente Hilfe


    Das Problem ist folgender C++ Source Code
    Code :
    1
    2
    3
    4
    5
    
    unsigned __int64 out;
    void Test(unsigned __int64 input)
    {
     out = ((input ^ 0x00000005DEECE66Dui64) & 0x0000FFFFFFFFFFFFui64);
    }
    So wie er hier steht gibt er der Variable out, nach Aufruf mit einem Parameter, der den Wert 1147 hat, den Wert 25214902806.
    Meine Lösungsansetze in PHP möchte ich euch ersparen, denn ich komme auf die wildesten Sachen (-270675368, 825302713, 55489, 97).

    Falls also jemand von euch das bisschen Source Code in PHP übersetzen kann, oder mir wenigstens Hilfestellung (Tipps) geben könnte, würde ich mich über eine Antwort dieser Person sehr freuen


    Danke aber schonmal fürs Lesen
     

  2. #2
    Avatar von Dennis Wronka
    Dennis Wronka Dennis Wronka ist offline Soulcollector
    Registriert seit
    Apr 2002
    Ort
    Hong Kong
    Beiträge
    12.296
    Blog-Einträge
    231
    Okay, das Problem sieht wohl wie folgt aus: Der Integer ist zu klein.

    Gib mal die Konstante PHP_INT_MAX aus, diese wird wohl kleiner sein als der von Dir erwartete Wert. Entsprechend gibt es einen Ueberlauf.
    Zudem scheinen AND, OR, etc. grundsaetzlich nur mit Integer-Werten zu arbeiten, sodass selbst das erzwingen von Float-Variablen nicht zum gewuenschten Erfolg fuehrt.

    Uebrigens, auf einem 64-Bit-System, wo ja der Integer entsprechend breiter ist als auf einem 32-Bit-System, funktioniert der Code
    PHP-Code:
    $resval=(($inval $xorval) & $andval); 
    wunderbar.

    Eine Loesung, also fuer 32-Bit-Systeme, sehe ich hier im Moment nicht.
    nop0x90 bedankt sich. 
    PHP Class Collection - PHP-Klassen fuer PHP 5 (und Teilweise auch fuer PHP 4)
    Updates: Catcher 1.1, FTPConnection 1.2, MultiSQL 1.1, RSS2 1.1, SMTPConnection 1.4
    __________________
    EasyLFS - Hintergrundinformationen, Installationsanleitung, Softwareliste und Download
    EasyLFS Projektthread - Informationen, Status und Diskussion zu meiner Linux-Distribution
    __________________
    Ich bin die Schildkroete, mein Sohn. Ich habe das Universum erschaffen, aber bitte mach mir daraus keinen Vorwurf; ich hatte Bauchschmerzen.
    __________________
    Zitat Zitat von Friedrich Nietzsche
    Man muss noch Chaos in sich haben, um einen tanzenden Stern gebaeren zu koennen.

  3. #3
    Avatar von nop0x90
    nop0x90 nop0x90 ist offline Mitglied Bronze
    Registriert seit
    Mar 2008
    Ort
    NRW/Düsseldorf
    Beiträge
    42
    Hi Dennis,

    danke für Deine Antwort! Die hat mir schon sehr geholfen. An einen Speicherüberlauf habe ich kurz auch gedacht, wusste aber zu dem Zeitpunkt noch gar nicht wirklich was das ist (so lächerlich das klingt), deswegen bin ich darauf nicht weiter eingegangen. Nun habe ich mir etwas mehr Wissen angeeignet und bin zu dem Entschluss gekommen, dass ich nicht ohne die GMP (GNU Multiple Precision) Erweiterung auskommen werde. Ich habe eine provisorische Klasse geschrieben, die auch schon teilweise funktioniert. Ich komme nun zum gewünschten Ergebnis von 25214902806, doch der zweite Teil des C++ Source Codes, der mir Probleme bereitet, hat es richtig in sich.

    Teil aus der C++ Klasse:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
        double NextDouble()
        {
            unsigned __int64 z1;
     
            this->seed = (((this->seed * 0x00000005DEECE66Dui64) + 0x000000000000000Bui64) & 0x0000FFFFFFFFFFFFui64);
            z1         = (this->seed >> 22); z1 <<= (27);
            this->seed = (((this->seed * 0x00000005DEECE66Dui64) + 0x000000000000000Bui64) & 0x0000FFFFFFFFFFFFui64);
            z1        += (this->seed >> 21);
     
            return ((double) z1 / (double) 0x0020000000000000ui64);
        }
    Meine provisorische PHP Übersetzung ("NextDouble", aka der problematische Teil, heißt hier "getNext"):
    PHP-Code:
    <?php
    class nRand
    {
      var 
    $gSeed null;
      
      function 
    nRand($uInit)
      {
        if(!
    function_exists(gmp_init))
          return 
    false;
        
        
    $vSeed gmp_init($uInit);
        
    $vXOR  gmp_init((string) 25214903917);   // 0x00000005DEECE66D
        
        
    $this->gSeed gmp_xor($vSeed$vXOR);
      }
      
      function 
    getSeed()
      {
        return (float) 
    gmp_strval($this->gSeed);
      }
      
      function 
    getNext()
      {
        if(
    $this->gSeed == null)
          return 
    false;
        
        
    $t1 gmp_init((string) 9007199254740992); // 0x0020000000000000
        
    $t2 gmp_init((string) 25214903917);      // 0x00000005DEECE66D
        
    $t3 gmp_init((string) 11);               // 0x000000000000000B
        
    $t4 null;
        
        
    $this->gSeed   gmp_add(gmp_mul($this->gSeed$t2), $t3);
        
    $t4            = (gmp_strval($this->gSeed) >> 22);
        
    $t4          <<= 27;                       // Hier wird der Wert negativ!
        
    $this->gSeed   gmp_add(gmp_mul($this->gSeed$t2), $t3);
        
    $t4           += (gmp_strval($this->gSeed) >> 21);
        
        return 
    gmp_strval(gmp_div_q(gmp_init($t4), $t1));          
      }
    }
    ?>
    Aufruf und Problem:
    PHP-Code:
    <?php
    //...
    $a = new nRand(1147);
    echo 
    $a->getSeed() . "\n";
    echo 
    $a->getNext(); //Sollte den Wert 0.631443 ausgeben
    ?>
    Hoffe, dass Du mir helfen kannst, denn ich kenne keine GMP Funktion die das "<<=" ersetzen könnte.

    Bis dann!
     

  4. #4
    Registriert seit
    Dec 2001
    Ort
    Bayern
    Beiträge
    5.806
    Blog-Einträge
    5
    Zitat Zitat von nop0x90 Beitrag anzeigen
    PHP-Code:
        $t1 gmp_init((string) 9007199254740992); // 0x0020000000000000 
    Das geht ziemlich sicher schief. Diese Konstante passt nicht mehr in einen 32-Bit-Integer und wird von PHP deswegen als Fließkommazahl interpretiert. Schreib das ganze doch einfach gleich als String, in dem Falle also
    PHP-Code:
    gmp_init("0x0020000000000000"); 
    (ebenso an allen anderen Stellen!).

    Zitat Zitat von nop0x90 Beitrag anzeigen
    PHP-Code:
        $this->gSeed   gmp_add(gmp_mul($this->gSeed$t2), $t3); 
    Hier hast du das binäre Und vergessen.

    Zitat Zitat von nop0x90 Beitrag anzeigen
    PHP-Code:
        $t4            = (gmp_strval($this->gSeed) >> 22);
        
    $t4          <<= 27;                       // Hier wird der Wert negativ! 
    Ein Bitshift um x Stellen nach links/rechts entspricht nichts anderem als einer Multiplikation mit/Division durch 2^x.

    Zitat Zitat von nop0x90 Beitrag anzeigen
    PHP-Code:
        return gmp_strval(gmp_div_q(gmp_init($t4), $t1)); 
    Auf diese Weise wird immer 0 rauskommen, da hier eine Ganzzahldivision durchgeführt wird. Besser wäre also
    PHP-Code:
    return gmp_strval($t4) / gmp_strval($t1
    Grüße,
    Matthias
    nop0x90 bedankt sich. 
    „Gib einem Menschen einen Fisch, und er wird für einen Tag satt. Lehre ihn Fischen, und er wird ein Leben lang satt.“
    “For every complex problem, there is an answer that is short, simple and wrong.”
    “Pessimism is safe, but optimism is a lot faster!”


    Aktuelles Coding Quiz: #17 - Wörter kreuz und quer

  5. #5
    Avatar von Dennis Wronka
    Dennis Wronka Dennis Wronka ist offline Soulcollector
    Registriert seit
    Apr 2002
    Ort
    Hong Kong
    Beiträge
    12.296
    Blog-Einträge
    231
    Sorry, mein C++ ist ein wenig beschraenkt, und zudem noch arg eingerostet. Was ist <<, ein Links-Shift?

    Also in der Dokumentation zur GMP-Extension konnte ich jetzt nichts von einem Shift sehen. PHP selbst kann zwar shiften, dort duerftest Du dann aber wohl wieder in die gleiche Einschraenkung rennen wie es bereits zuvor der Fall war.
     
    PHP Class Collection - PHP-Klassen fuer PHP 5 (und Teilweise auch fuer PHP 4)
    Updates: Catcher 1.1, FTPConnection 1.2, MultiSQL 1.1, RSS2 1.1, SMTPConnection 1.4
    __________________
    EasyLFS - Hintergrundinformationen, Installationsanleitung, Softwareliste und Download
    EasyLFS Projektthread - Informationen, Status und Diskussion zu meiner Linux-Distribution
    __________________
    Ich bin die Schildkroete, mein Sohn. Ich habe das Universum erschaffen, aber bitte mach mir daraus keinen Vorwurf; ich hatte Bauchschmerzen.
    __________________
    Zitat Zitat von Friedrich Nietzsche
    Man muss noch Chaos in sich haben, um einen tanzenden Stern gebaeren zu koennen.

  6. #6
    Avatar von nop0x90
    nop0x90 nop0x90 ist offline Mitglied Bronze
    Registriert seit
    Mar 2008
    Ort
    NRW/Düsseldorf
    Beiträge
    42
    Dennis: Ja, das ist ein Links-Bitshift. Wobei $t4 <<= 27; gleich $t4 = $t4 << 27; ist.
    Matthias: Mist, ich wusste gar nicht, dass man dort sogar hexadezimale Werte angeben kann. Und das AND habe ich komplett vergessen!

    Großes Dankeschön an euch!


    OffTopic: Ich fühle mich richtig komisch, wenn ich eure Benutzernamen sehe, dass ich mich nicht traue meinen richtigen Namen zu verwenden
     

Ähnliche Themen

  1. Antworten: 11
    Letzter Beitrag: 22.08.10, 18:27
  2. übersetzung eines tutorials
    Von Grayparrot im Forum Cinema 4D
    Antworten: 5
    Letzter Beitrag: 06.12.08, 21:22
  3. Antworten: 1
    Letzter Beitrag: 17.12.07, 10:33
  4. Assambler Source Codes
    Von AtomSoldier im Forum Sonstige Sprachen
    Antworten: 3
    Letzter Beitrag: 09.02.05, 17:26
  5. AFX - Übersetzung eines englischen Tuts
    Von Polle im Forum Sonstige Grafik-Programme
    Antworten: 1
    Letzter Beitrag: 22.07.04, 14:32