Jens-Staufenberg: Multiplikation

Guten Tag,

ich bin absoluter Anfänger in PHP man möge mir daher Anfängerfehler verzeihen.
Folgendes Problem:
echo '"'.$datensatz->max.'"';
erzeugt "0.5" (man beachte Punkt nicht Komma, und keine Leerstellen)

echo '"'.$datensatz->max * 24.'"';
erzeugt "0"

echo '"'.($datensatz->max * 24).'"';
erzeugt "0"

echo '"'.(0.5 * 24).'"';
erzeugt "12" <- das gewünschte Ergebnis

Was mache ich denn falsch?

  1. Hi!

    echo '"'.$datensatz->max.'"';
    erzeugt "0.5" (man beachte Punkt nicht Komma, und keine Leerstellen)
    echo '"'.($datensatz->max * 24).'"';
    erzeugt "0"
    echo '"'.(0.5 * 24).'"';
    erzeugt "12" <- das gewünschte Ergebnis
    Was mache ich denn falsch?

    echo '"' . ('0.5' * 24) . '"';
    ergibt auch "12". Du hast was anderes in $datensatz->max stehen als angezeigt wird. Lass dir den Inhalt mit var_dump() anzeigen. Wenn dabei eine andere Länge als 3 angezeigt wird, gib zusätzlich den Wert mit echo urlencode($datensatz->max); aus.

    Lo!

    1. echo '"' . ('0.5' * 24) . '"';
      ergibt auch "12".

      Stimmt es kommt auch 12 bei mir heraus.

      Du hast was anderes in $datensatz->max stehen als angezeigt wird. Lass dir »» den Inhalt mit var_dump() anzeigen.

      object(SimpleXMLElement)#16 (1) { [0]=> string(3) "0.5" }

      »»Wenn dabei eine andere Länge als 3 angezeigt wird, gib zusätzlich den Wert »»mit echo urlencode($datensatz->max); aus.
      Es kommt ja 3 dabei heraus von daher!?

      Mein zweiter versuch war ein IF Anweisung
      IF ($datensatz->max == 0.5) {echo 'stimmt';}
      auch ist die IF Anwendung "TRUE" und das Ergebnis "stimmt" wird angezeigt.

      1. [latex]Mae  govannen![/latex]

        Du hast was anderes in $datensatz->max stehen als angezeigt wird. Lass dir »» den Inhalt mit var_dump() anzeigen.

        object(SimpleXMLElement)#16 (1) { [0]=> string(3) "0.5" }

        Also kein String oder eine Zahl, sondern ein SimpleXML-Objekt. Der Wert wird zwar bei der Ausgabe in einen String gewandelt, aber nicht bei Rechenoperationen.

        Typecasting sollte helfen.

        Stur lächeln und winken, Männer!
        Kai

        --
        Dank Hixies Idiotenbande geschieht grade eben wieder ein Umdenken
        in Richtung "Mess up the Web".(suit)
        SelfHTML-Forum-Stylesheet
      2. Hi!

        Du hast was anderes in $datensatz->max stehen als angezeigt wird. Lass dir den Inhalt mit var_dump() anzeigen.
        object(SimpleXMLElement)#16 (1) { [0]=> string(3) "0.5" }
        Wenn dabei eine andere Länge als 3 angezeigt wird, [...]
        Es kommt ja 3 dabei heraus von daher!?

        Ja und nein. Ich ging davon aus, dass es zwar ein String ist, aber da irgendwas Unsichtbares enthalten ist. Aber als String hättest du nur
          string(3) "0.5"
        oder etwas Ähnliches als Ausgabe von var_dump() bekommen. Du bekommst aber ein Objekt. Das Rätsel löst sich durch die Kontrollausgabe, weil nun herauskommt, dass SimpleXML seine Finger im Spiel hat. Dies hat eine Menge eingebaute Magie, die in manchen Situationen beispielsweise ein SimpleXMLElement wie ein String und manchmal wie ein Array aussehen lässt. Und da hilft dir die schon empfohlene Typumwandlung. Hier ein Beispiel zum Nachvollziehen:

        echo '<pre>';
        $x = simplexml_load_string('<root>0.5</root>');
        var_dump($x); # Ausgabe ähnlich wie bei dir

        Ausgabe: 0.5 - PHP erkennt Stringkontext und ruft __toString() vom SimpleXMLElement auf.

        echo $x, "\n";

        Ausgabe: float(0.5) - da es kein __toFloat() gibt, nehme ich an,

        dass __toString() aufgerufen wird und anschließend der Typecast nach float stattfindet.

        var_dump((float)$x);

        Ausgabe 12

        echo (float)$x * 24;

        Lo!

  2. Hi,

    Folgendes Problem:
    echo '"'.$datensatz->max.'"';
    erzeugt "0.5" (man beachte Punkt nicht Komma, und keine Leerstellen)

    echo '"'.$datensatz->max * 24.'"';
    erzeugt "0"

    echo '"'.($datensatz->max * 24).'"';
    erzeugt "0"

    echo '"'.(0.5 * 24).'"';
    erzeugt "12" <- das gewünschte Ergebnis

    Was mache ich denn falsch?

    Kannst du ein komplettes Beispiel posten, an dem man den Fehler nachvollziehen kann?
    Ich habe mir eins gebaut (s.u.), und bei mir funktioniert alles wie erwartet.

    <?PHP  
      
    class Datensatz {  
    	public $max = "0.5";  
    }  
      
    $datensatz = new Datensatz();  
      
    ?>  
    <!DOCTYPE html>  
    <html>  
    <head>  
    <meta charset='UTF-8' />  
    <title>Test</title>  
    </head>  
    <body>  
    <ul>  
    	<li>"<?PHP echo $datensatz->max; ?>"</li>  
    	<li>"<?PHP echo $datensatz->max*24; ?>"</li>  
    	<li><?PHP echo '"' . $datensatz->max*24 . '"'; ?></li>  
    </ul>  
    </body>  
    </html>  
    
    

    Bis die Tage,
    Matti

  3. Hi,

    echo '"'.$datensatz->max.'"';
    erzeugt "0.5" (man beachte Punkt nicht Komma, und keine Leerstellen)

    Der String wird direkt ausgegeben.

    echo '"'.$datensatz->max * 24.'"';
    erzeugt "0"

    Der String wird, um ihn mit dem Integer multiplizieren zu können, in einen Integer gewandelt.
    Welche Locale hast Du eingestellt? Ich hätte hier 24 erwartet - aber vielleicht ist  in der verwendeten Locale der . kein Dezimaltrennzeichen ...
    Oder es wird bei String->Integer-Umwandlung beim ersten nicht-Integer-Zeichen abgebrochen ...

    echo '"'.($datensatz->max * 24).'"';
    erzeugt "0"

    Die Klammern dürfen keinen Unterschied zum vorherigen Fall machen.

    echo '"'.(0.5 * 24).'"';
    erzeugt "12" <- das gewünschte Ergebnis

    Der Integer 24 wird für die Multiplikation mit dem Float nach Float gewandelt, dann gerechnet.

    Was mache ich denn falsch?

    Vermutlich ist der Fehler, daß $datensatz->max ein String ist.

    cu,
    Andreas

    --
    Warum nennt sich Andreas hier MudGuard?
    O o ostern ...
    Fachfragen per Mail sind frech, werden ignoriert. Das Forum existiert.
    1. Hi,

      echo '"'.$datensatz->max * 24.'"';
      erzeugt "0"

      Der String wird, um ihn mit dem Integer multiplizieren zu können, in einen Integer gewandelt.

      Nein, ich habe ein komplettes Beispiel gepostet (und auch dedlfix hat das als Fehlerquelle eliminiert). Selbst wenn $datensatz->max ein String ist, kommt dabei 12 raus. Der Fehler ist woanders.

      Bis die Tage,
      Matti

    2. Moin MudGuard,

      […]
      Der String wird, um ihn mit dem Integer multiplizieren zu können, in einen Integer gewandelt.
      Welche Locale hast Du eingestellt?

      Das ist locale-Unabhängig:

        
      ckruse@hermes ~ $ php -r 'setlocale(LC_ALL,"de_DE.UTF-8"); echo 0.5,"\n";'  
      0,5  
      ckruse@hermes ~ $ php -r 'setlocale(LC_ALL,"de_DE.UTF-8"); echo "0.5" * 2,"\n";'  
      1  
      ckruse@hermes ~ $ php -r 'setlocale(LC_ALL,"de_DE.UTF-8"); echo "0,5" * 2,"\n";'  
      0  
      ckruse@hermes ~ $ php -v  
      PHP 5.3.3 (cli) (built: Jan  7 2011 19:14:34)  
      Copyright (c) 1997-2010 The PHP Group  
      Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies  
      ckruse@hermes ~ $  
      
      

      Lediglich bei der Ausgabe wird das Trennzeichen aus dem Locale genutzt. Hm, und scheinbar auch das nur, wenn das Locale im Script explizit gesetzt wurde…

        
      ckruse@hermes ~ $ locale  
      LANG="de_DE.UTF-8"  
      LC_COLLATE="de_DE.UTF-8"  
      LC_CTYPE="de_DE.UTF-8"  
      LC_MESSAGES="de_DE.UTF-8"  
      LC_MONETARY="de_DE.UTF-8"  
      LC_NUMERIC="de_DE.UTF-8"  
      LC_TIME="de_DE.UTF-8"  
      LC_ALL="de_DE.UTF-8"  
      ckruse@hermes ~ $ php -r 'echo 0.5,"\n";'  
      0\.5  
      ckruse@hermes ~ $ php -r 'echo setlocale(LC_ALL,NULL)," ",0.5,"\n";'  
      de_DE.UTF-8 0,5  
      ckruse@hermes ~ $  
      
      

      Wirklich merkwürdig. Und irgendwie typisch PHP, die Sprache nervt mich seit geraumer Zeit gewaltig…

      Ich hätte hier 24 erwartet - aber vielleicht ist  in der verwendeten Locale der . kein Dezimaltrennzeichen ...
      Oder es wird bei String->Integer-Umwandlung beim ersten nicht-Integer-Zeichen abgebrochen ...

      Beim parsen von Zahlen wird nur der Punkt als Dezimal-Trennzeichen akzeptiert. s.o. :)

      LG,
       CK