Sophie: PHP rechnet falsch?

Hallo,

was macht PHP oder was mache ich falsch?

$gewicht_mV = 0;
$gewicht_oV = 0;
$gewicht 	  = 0;

$gewicht_mV += str_ireplace(",", ".", $array['gewichtinklverpackung'])*$array['menge'];
$gewicht_oV += str_ireplace(",", ".", $array['gewicht'])*$array['menge'];
$gewicht = $gewicht_mV + $gewicht_oV;

Als Ausgabe erhalte ich:
1769.8 kg

Lass ich mir die Variablen ausgeben erhalte ich bei:
mV = 1673.8
oV = 96

Und da haben wir schon den Fehler, denn so steht es in der Tabelle:

Was bringt PHP hier so durcheinander? Ich sehe den Fehler nicht.

  1. Hello,

    hast Du eventuell die Funktionen in der falschen Schachtelung (Reihenfolge) benutzt?

    Das Ersetzen des Dezimaltrenners muss doch für jeden übergebenen Parameter zuerst durchgeführt werden und nicht erst nach der Multiplikation.

    Benutze für solche Fälle die PHP-Filter-Funktionen und deren Sanitize-Option.

    Liebe Grüße
    Tom S.

    --
    Es gibt nichts Gutes, außer man tut es
    Andersdenkende waren noch nie beliebt, aber meistens diejenigen, die die Freiheit vorangebracht haben.
    1. Hallo TS,

      wenn ich ehrlich bin, verstehe ich gerade deine Frage nicht.

      1. Hello,

        wenn ich ehrlich bin, verstehe ich gerade deine Frage nicht.

        Du benutzt die Funktion str_ireplace(). Kannst Du mir bitte für Doofe verständlich erklären, warum Du die einsetzt?

        Liebe Grüße
        Tom S.

        --
        Es gibt nichts Gutes, außer man tut es
        Andersdenkende waren noch nie beliebt, aber meistens diejenigen, die die Freiheit vorangebracht haben.
        1. Hallo Tom,

          Du benutzt die Funktion str_ireplace(). Kannst Du mir bitte für Doofe verständlich erklären, warum Du die einsetzt?

          das kann ich gerne machen, aber ich behaupte nicht dass du Doof bist! In meiner Datenbank stehen leider die Werte mit einem Komme, mit der Funktion str_replace ersetzte ich diese, da ich mit einem , keine Werte zusammen zählen kann.

          1. Hello,

            Du benutzt die Funktion str_ireplace(). Kannst Du mir bitte für Doofe verständlich erklären, warum Du die einsetzt?

            das kann ich gerne machen, aber ich behaupte nicht dass du Doof bist! In meiner Datenbank stehen leider die Werte mit einem Komme, mit der Funktion str_replace ersetzte ich diese, da ich mit einem , keine Werte zusammen zählen kann.

            Tust Du eben nicht!

            Deshalb versuch es doch nochmal, mir so klein, klein zu erklären, was da im Einzelnen passieren soll, als wäre ich doof ;-P

            Liebe Grüße
            Tom S.

            --
            Es gibt nichts Gutes, außer man tut es
            Andersdenkende waren noch nie beliebt, aber meistens diejenigen, die die Freiheit vorangebracht haben.
            1. Hallo Tom,

              da hast sich gerade meine Antwort mit deiner Antwort überschnitten. Hier habe ich es dir erklärt:

              https://forum.selfhtml.org/self/2017/aug/3/php-rechnet-falsch/1700761#m1700761

              1. Hello,

                Hier habe ich es dir erklärt:

                https://forum.selfhtml.org/self/2017/aug/3/php-rechnet-falsch/1700761#m1700761

                Leider hast Du es nicht Schrit für Schritt erklärt, sondern beim Programmieren Gedankensprünge gemacht.

                Liebe Grüße
                Tom S.

                --
                Es gibt nichts Gutes, außer man tut es
                Andersdenkende waren noch nie beliebt, aber meistens diejenigen, die die Freiheit vorangebracht haben.
                1. Hallo Tom,

                  hab es jetzt mal so getestet

                  $A = str_replace(",", ".", $array['gewichtinklverpackung']);
                  $B = str_replace(",", ".", $array['gewicht']);
                  
                  $gewicht_mV += $A*$array['menge'];
                  $gewicht_oV += $B*$array['menge'];
                  
                  $gewicht = $gewicht_mV + $gewicht_oV;
                  
                  

                  ändert aber nichts an der Ausgabe.

  2. Hallo

    $gewicht_mV = 0;
    $gewicht_oV = 0;
    $gewicht 	  = 0;
    
    $gewicht_mV += str_ireplace(",", ".", $array['gewichtinklverpackung'])*$array['menge'];
    $gewicht_oV += str_ireplace(",", ".", $array['gewicht'])*$array['menge'];
    $gewicht = $gewicht_mV + $gewicht_oV;
    

    Als Ausgabe erhalte ich:
    1769.8 kg

    Lass ich mir die Variablen ausgeben erhalte ich bei:
    mV = 1673.8
    oV = 96

    Und da haben wir schon den Fehler, denn so steht es in der Tabelle:

    Die Werte ind einem Screenshot stehen mit den Ausgangswerten und Ergebnissen deiner Berechnung in welcher Beziehung? Wie sehen denn die Ausgangswerte in dem Array aus?

    Tschö, Auge

    --
    Wenn man ausreichende Vorsichtsmaßnahmen trifft, muss man keine Vorsichtsmaßnahmen mehr treffen.
    Toller Dampf voraus von Terry Pratchett
    1. Hallo Auge,

      Die Werte ind einem Screenshot stehen mit den Ausgangswerten und Ergebnissen deiner Berechnung in welcher Beziehung? Wie sehen denn die Ausgangswerte in dem Array aus?

      die Werte in der Tabelle (das Bild) das sind die Werte, die Zusammengezählt werden sollen. Das mit Verpackung stimmt. Es gibt nur Probleme bei den Werten ohne Verpackung.

  3. Hallo Sophie,

    number_format() wäre dafür eigentlich prädestiniert.

    Gruß, Martl

    1. Hello,

      number_format() wäre dafür eigentlich prädestiniert.

      Genaugenommen liefert das aber auch erst wieder einen String. Und der muss dann (hier) erst wieder in einen Float umgewandelt werden, um damit rechnen zu können. Das tut PHP aber ggf. eigenständig, wenn das Ziel schon ein Float ist.

      Wenn man die Übergabeparameter schon anfasst, sollte man sie gelich in den passenden Datentyp wandeln, bevor man mit ihnen rechnet - und zwar jeden einzeln.

      Das schließt nicht aus. dass man mit geeigneten Arrayfunktionen mittels einer einzigen Anweisung auf alle Values einzeln zugreifen lässt.

      Liebe Grüße
      Tom S.

      --
      Es gibt nichts Gutes, außer man tut es
      Andersdenkende waren noch nie beliebt, aber meistens diejenigen, die die Freiheit vorangebracht haben.
      1. Hallo Tom,

        die Werte aus mit Verpackung, also diese Coder

        $gewicht_mV += str_replace(",", ".", $array['gewichtinklverpackung'])*$array['menge'];
        

        funktioniert richtig: 73,8 + 1600 = 1673,8

        Dieser Bereich

        $gewicht_oV += str_replace(",", ".", $array['gewicht'])*$array['menge'];
        

        macht Probleme. Hier wird 24 + 4,2 = 96 und das ist definitiv falsch. Zusammen müsste dieses 28,2 geben.

        1. Hello,

          die Werte aus mit Verpackung, also diese Coder

          $gewicht_mV += str_replace(",", ".", $array['gewichtinklverpackung'])*$array['menge'];
          

          funktioniert richtig: 73,8 + 1600 = 1673,8

          Das sieht für Dich leider nur so aus, als hättest Du es richtig programmiert.

          Dann ändere doch mal den Value von $array['gewichtinklverpackung'] auf eine Kommazahl und prüfe dann nochmal ;-)

          Liebe Grüße
          Tom S.

          --
          Es gibt nichts Gutes, außer man tut es
          Andersdenkende waren noch nie beliebt, aber meistens diejenigen, die die Freiheit vorangebracht haben.
          1. Hallo Tom,

            ich glaube ich stehe gerade total auf dem Schlauch, oder die Hitze steigt mir zu Kopf 😉

            73,8 da ist doch ein Komme drin?

            1. Hello,

              Kinder der Nacht...

              mach ein separates Testprogramm daraus und lass dir vor der Berechnung von jedem Operanden mittels var_dump() den Typ und Value anzeigen.

              Dann sollte es klar werden, wo der Fehler steckt.

              Liebe Grüße
              Tom S.

              --
              Es gibt nichts Gutes, außer man tut es
              Andersdenkende waren noch nie beliebt, aber meistens diejenigen, die die Freiheit vorangebracht haben.
              1. Hallo Tom,

                dann erhalte ich folgendes

                
                $A = str_replace(",", ".", $array['gewichtinklverpackung']);
                $B = str_replace(",", ".", $array['gewicht']);
                
                $gewicht_mV += $A*$array['menge'];
                $gewicht_oV += $B*$array['menge'];
                
                var_dump($gewicht_mV);
                echo "<br>";
                var_dump($gewicht_oV);
                
                int(0) 
                int(24) int(0) 
                float(28.2) float(73.8) 
                float(96) float(1673.8) 
                float(96)
                
        2. Hallo

          die Werte aus mit Verpackung, also diese Coder

          $gewicht_mV += str_replace(",", ".", $array['gewichtinklverpackung'])*$array['menge'];
          

          funktioniert richtig: 73,8 + 1600 = 1673,8

          Wo kommt denn dieses Ergebnis her? Es wird 0 + 73.8 * $array['menge'] (was auch immer in $array['menge'] drinsteht) oder 0 + 1600 * $array['menge'] gerechnet. In den Code ist nirgendwo eine Addition von 73.8 und 1600 zu sehen.

          Dieser Bereich

          $gewicht_oV += str_replace(",", ".", $array['gewicht'])*$array['menge'];
          

          macht Probleme. Hier wird 24 + 4,2 = 96 und das ist definitiv falsch. Zusammen müsste dieses 28,2 geben.

          Auch hier gibt es keine Addition außer der mit dem im Eröffnungsposting gezeigten Ausgangswert von $gewicht_oV (0). Du zeigst uns ganz offensichtlich nicht den gesamten relevanten Code.

          Tschö, Auge

          --
          Wenn man ausreichende Vorsichtsmaßnahmen trifft, muss man keine Vorsichtsmaßnahmen mehr treffen.
          Toller Dampf voraus von Terry Pratchett
          1. Hallo,

            mehr Code ist es nicht

            <?php foreach($temporaer as $array){
            
            	$A = str_replace(",", ".", $array['gewichtinklverpackung']);
            	$B = str_replace(",", ".", $array['gewicht']);
            
            	$gewicht_mV += $A*$array['menge'];
            	$gewicht_oV += $B*$array['menge'];
            
            	var_dump($gewicht_mV);
            	echo "<br>";
            	var_dump($gewicht_oV);
            
            	$gewicht 	 = $gewicht_mV+$gewicht_oV;
            }
            ?>
            
            1. Hallo Sophie,

              so langsam kommen wir der Sache näher.

              Wie wär's mit einem var_dump($temporaer) VOR der Schleife? Damit wir mit der Hand am Arm nachrechnen können, was passieren sollte?

              Weil - dein Code sieht für mich nicht so aus, als würde er dieses Problem bauen. Vielleicht hast Du bei deiner Erwartung falsch hingeguckt?

              Rolf

              --
              Dosen sind silbern
              1. Hallo Rolf,

                ich glaube, wir kommen der Sache näher. Hab mir mal folgendes ausgeben lassen

                echo $A . " - " . $B . "<br>";
                

                Da erhalte ich folgendes Ergebnis:

                - 2
                - 2.10
                6.15 - 5.65
                800 - 
                

                Der erste Wert vor dem - ist mV das nach dem - ist oV

                Die ersten beiden Werte, also die 2 und die 2.10 haben jeweils kein mV der vierte hat keinen Eintrag bei _oV und der dritte macht Probleme, denn da steht ein Wert bei oV und mV. Wenn ich beiden ein Wert steht, soll immer der Wert genommen werden, der bei mV steht.

                Ansonsten stimmen die Zahlen, denn

                12 x 2 = 24
                2 x 2,10 = 4,2
                12 x 6,15= 73,8
                2 x 800 = 1600

                $A = str_replace(",", ".", $array['gewichtinklverpackung']);
                $B = str_replace(",", ".", $array['gewicht']);
                							
                echo $A . " - " . $B . "<br>";
                
                $gewicht_mV += $A*$array['menge'];
                $gewicht_oV += $B*$array['menge'];
                
                $gewicht 	 = $gewicht_mV+$gewicht_oV;
                
                1. Hallo Sophie,

                  ein Leerstring wird bei der Multiplikation wie 0 interpretiert (gibt allerdings eine PHP Warnung. Die unterdrückst Du möglicherweise).

                  Wenn (bei) beiden ein Wert steht, soll _immer der Wert genommen werden, der bei mV steht.

                  Jetzt bin ich baff. Der Code, den Du bisher gezeigt hast, hat mit diesem Satz nun gar nichts zu tun.

                  Rolf

                  --
                  Dosen sind silbern
                  1. Hall Rolf,

                    Jetzt bin ich baff. Der Code, den Du bisher gezeigt hast, hat mit diesem Satz nun gar nichts zu tun.

                    nja das ist mir auch erst gerade aufgefallen was überhaupt raus kommt. Jetzt stelle ich mir die Frage wie kann ich dieses umsetzten dass wenn beide Werte Vorhanden sind nur der mV genommen wird. Aber dieses Problem hat nichts mit dem Rechnen zu tun, denn mein Problem liegt ja bei oV.

                    1. Hallo Sophie,

                      empty(trim(...)) oder trim(...) == '' oder strlen(trim(...)) == 0

                      Rolf

                      --
                      Dosen sind silbern
                      1. Hallo Rolf,

                        hier war mein Fehler

                        if ($array['gewichtinklverpackung'] != "") {
                        		$A = str_replace(",", ".", $array['gewichtinklverpackung']);
                        } else {
                        		$A = str_replace(",", ".", $array['gewicht']);
                        }
                        							
                        $gewicht += $A*$array['menge'];
                        

                        Jetzt kommt 1702,00 raus. Das habe ich auch in Excel ausgerechnet.

                        Mein alter Code lautete

                        $A = str_replace(",", ".", $array['gewichtinklverpackung']);
                        $B = str_replace(",", ".", $array['gewicht']);
                        
                        $gewicht_mV += $A*$array['menge'];
                        $gewicht_oV += $B*$array['menge'];
                        
                        $gewicht 	 = $gewicht_mV+$gewicht_oV;
                        

                        Ich verstehe noch immer nicht was er da gerechnet hat, dass ich auf so eine falsche Summe gekommen bin.

                        1. Hallo Sophie,

                          $$12 \cdot 2 + 2 \cdot 2{,}1 + 12 \cdot 5{,}65 + 2\cdot0 = 96$$ - die Rechnung war völlig korrekt. Es fehlte nur die Logik für die Werteauswahl. Dein alter Code hat immer ALLE Gewichtsangaben addiert.

                          Du könntest in der Abfrage auf leer noch einen trim() einsetzen, sonst führt eine Leerstelle im Bruttogewicht-Feld dazu, dass er das Nettogewicht nicht nimmt. Oder kann das auf Grund des Kontextes nicht vorkommen?

                          Rolf

                          --
                          Dosen sind silbern
                          1. Hallo Rolf,

                            eigentlich kann es nicht vorkommen, aber ich habe es noch eingefügt

                            if ($array['gewichtinklverpackung'] != "") {
                            	$A = str_replace(",", ".", trim($array['gewichtinklverpackung']));
                            } else {
                            	$A = str_replace(",", ".", trim($array['gewicht']));
                            }
                            							
                            $gewicht += $A*$array['menge'];
                            

                            müsste strim() nicht auch noch um die Menge? Denn da könnte der User 12 Leerzeichen eingeben dann würde auch etwas verfälscht werden?

                            1. Hallo Sophie,

                              rolf->set_patience_level("ultra");
                              sophie->set_attention_level("high");
                              

                              Es ging darum, bei der Abfrage auf leer zu trim()-en. Beim Multiplizieren ist es egal, da schmeißt PHP die Leerstellen drumherum weg.

                              Bei der Menge ist es wurscht, wenn der User 12 Spaces eingibt. Das wird als 0 interpretiert.

                              Rolf

                              --
                              Dosen sind silbern
                              1. Hallo Rolf,

                                du meinst so?

                                if (trim($array['gewichtinklverpackung'] != "")) {
                                	$A = str_replace(",", ".",$array['gewichtinklverpackung']);
                                } else {
                                	$A = str_replace(",", ".", $array['gewicht']);
                                }
                                
                                1. Hallo Sophie,

                                  fast. Mit trim() verarbeitet man Zeichenketten, keine Vergleichsergebnisse. Sprich: da ist Dir eine Klammer verrutscht.

                                  Rolf

                                  --
                                  Dosen sind silbern
                                  1. Hallo Rolf,

                                    ach das macht irgendwie mein Sublime Text 3. Wenn ich eine Klammer anfange dann wird die zum Schluss wieder beendet. Keine Ahnung, hab da wohl irgendwas verstellt.

                                    Hab es jetzt hoffentlich richtig

                                    if (trim($array['gewichtinklverpackung']) != "") {
                                       $A = str_replace(",", ".",$array['gewichtinklverpackung']);
                                    } else {
                                       $A = str_replace(",", ".", $array['gewicht']);
                                    }
                                    
                                    1. Hallo Sophie,

                                      ja, so sollte es laufen.

                                      Rolf

                                      --
                                      Dosen sind silbern
                                      1. Hallo Rolf,

                                        danke für deine Hilfe

  4. Hi,

    Du zeigst weder den vollständigen Code (da scheint ja noch eine Schleife zu existieren um die Summierung herum) noch die vollständigen Daten (was steht z.B. in $array['menge']?).

    Wie soll man da erraten, welchen Fehler Du in Dein Programm eingebaut hast?

    Abgesehen davon: $array halte ich nicht für einen sinnvollen Variablennamen. Aber das nur am Rande.

    cu,
    Andreas a/k/a MudGuard

    1. Hallo,

      in Menge steht einfach eine Zahl wie z.B.

      12
      2
      12
      2

      Wie du auf dem ersten Bild zu sehen ist, werden die Werte auch richtig zusammengezählt also pro Spalte. Er addiert nur nicht richtig.

  5. Ich habe nicht alle anderen Beiträge gelesen, man vergebe mir falls das schon wo steht.

    Du vermischst bunt Strings und Zahlen, das ist das ekelhafte an nicht typsicheren Sprachen. Man kann alles mögliche durcheinander machen ohne dass man Fehlermeldungen kriegt. Man kriegt nur still und leise falsche Ergebnisse, ohne Anhaltspunkt warum. Du solltest die alles einfach mal ausgeben lassen und prüfen.

    Was in $array steht weiß ich nicht, genausowenig was menge für eine Zahl ist. Und erst recht nicht was da wie in der Tabelle steht und wie du das ausliest.

    Das einzige das mir auffällt ist 4*24=96. Vielleicht hakt es da irgendwo, dass die 4.2 nur als 4 erkannt wird und das dann mit der 96 multipliziert wird?