Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. Richtig rechnen in JS

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    Richtig rechnen in JS

    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      h1ob last edited by h1ob

      Hallo zusammen,

      ich nutze ein Skript um meinen aktuellen Gasverbrauch / Gaszählerstand zu errechnen. Kurz zur Erklärung:
      Der Gaszähler ist mit einem Impulsgeber ausgestattet. Die Anzahl Impulse (Drehungen der letzten Nachkommastelle am Zähler = 0,01 m3) wird an einen ESP8266 geschickt und dann per MQTT an ioBroker.

      Ich setze inital den aktuellen Gaszählerstand mit zwei Nachkommastellen in den Datenpunkt, aktuell bspw. 51824.05 m³.
      Jeder Impuls vom Gaszähler erhöht den aktuellen Zählerstand um 0.01 m³. Da die Übertragung alle 15 Minuten stattfindet, kommen zwischen 1 und n Impulse rein.

      Das ist der relevante Teil aus dem Skript:

      const iImpuls = 0.01;        
      ...
      iZwSumme = liDelta * iImpuls; //m3
      var lfAktuellm3 = (getState(iAktuell).val) + iZwSumme; 
      

      Ich lasse mir aktuell noch die Zwischenschritte im Log ausgeben um zu sehen ob alles so funktioniert wie gewollt.
      Vorhin wurde ein Impuls gemeldet (=0.01 m³ verbraucht in den letzten 15 Minuten) . Der Datenpunkt stand bei 51824.05. Als neuen Wert hätte ich also 51824.06 erwartet. JS macht daraus aber 51824.060000000005. Ich habe es mit .toFixed und Math.round probiert, aber komme nicht wirklich weiter. Der Impuls ist ja eine Konstante, da gibt es nichts zu interpretieren oder zu runden.

      Wie kriege ich es hin, dass pro Impuls auch wirklich nur 0.01 addiert wird und das auf genau 2 Nachkommastellen?

      paul53 arteck 3 Replies Last reply Reply Quote 0
      • paul53
        paul53 @h1ob last edited by

        @h1ob sagte: JS macht daraus aber 51824.060000000005.

        0.01 muss binär gerundet werden. Vorschlag:

        iZwSumme = liDelta; // Integer
        var lfAktuellm3 = (getState(iAktuell).val) + iZwSumme / 100; 
        
        H 1 Reply Last reply Reply Quote 0
        • arteck
          arteck Developer Most Active @h1ob last edited by

          @h1ob sagte in Richtig rechnen in JS:

          Wie kriege ich es hin, dass pro Impuls auch wirklich nur 0.01 addiert wird und das auf genau 2 Nachkommastellen?

          guck

          https://www.w3schools.com/jsref/jsref_obj_math.asp

          1 Reply Last reply Reply Quote 0
          • H
            h1ob @paul53 last edited by

            @paul53 Das hat leider nicht funktioniert. Es sieht jetzt so aus:

            iZwSumme wird nicht gebraucht, weil liDelta denselben Wert hat.

            var lfAktuellm3 = (getState(iAktuell).val) + liDelta / 100;
            

            lfAktuellm3 hat trotzdem den Wert 51825.73000000005

            paul53 1 Reply Last reply Reply Quote 0
            • paul53
              paul53 @h1ob last edited by

              @h1ob sagte: lfAktuellm3 hat trotzdem den Wert 51825.73000000005

              Wenn einmal ein Wert mit vielen Nachkommastellen im Datenpunkt steht, bleibt es ohne Rundung auch so.

              var lfAktuellm3 = Math.round(getState(iAktuell).val * 100 + liDelta) / 100;
              
              H 1 Reply Last reply Reply Quote 0
              • H
                h1ob @paul53 last edited by h1ob

                @paul53

                Nein, ich habe den Wert vorher auf zwei Nachkommastellen manuell in den Datenpunk geschrieben. Das hat auch ein paar Stunden funktioniert. Irgendwann hatte die Zahl dann wieder 10 Nachkommastellen.

                67839b95-3226-41ef-82b8-b7b02922d16e-grafik.png

                Da runden keine Option ist, habe ich eine kleine Funktion geschrieben, die einfach alles ab der zweiten Nachkommastelle abschneidet.

                function CutFloat(str,val) {
                    str = str.toString();
                    str = str.slice(0, (str.indexOf(".")) + val + 1); 
                    return Number(str);   
                };
                
                paul53 1 Reply Last reply Reply Quote 0
                • paul53
                  paul53 @h1ob last edited by paul53

                  @h1ob sagte: Da runden keine Option ist

                  Weshalb nicht?

                  @h1ob sagte in Richtig rechnen in JS:

                  alles ab der zweiten Nachkommastelle abschneidet.

                  Das entspricht "abrunden".

                  H 1 Reply Last reply Reply Quote 0
                  • H
                    h1ob @paul53 last edited by h1ob

                    @paul53 Weil beim Runden die Gefahr besteht, dass trotz nur einem Impuls dann 0.02 m³ und nicht 0.01³ addiert werden.
                    Ich sehe Werte in der Tabelle, bei denen die dritte Stellen nach dem Komma 5 oder größer ist. Da hätte Math.round() aufgerundet, was schlicht zu einem falschen Ergebnis führen würde.

                    1 Reply Last reply Reply Quote 0
                    • paul53
                      paul53 @h1ob last edited by paul53

                      @h1ob sagte: Jeder Impuls vom Gaszähler erhöht den aktuellen Zählerstand um 0.01 m³. Da die Übertragung alle 15 Minuten stattfindet, kommen zwischen 1 und n Impulse rein.

                      Meine Lösung wäre:

                      var impulse = Math.round(100 * getState(idAktuell).val);
                      
                      on({id: idImpulse}, function(dp) {
                          impulse += dp.state.val;
                          setState(idAktuell, impulse / 100, true);
                      });
                      

                      Die Variable impulse enthält stets einen Integer-Wert.

                      1 Reply Last reply Reply Quote 0
                      • First post
                        Last post

                      Support us

                      ioBroker
                      Community Adapters
                      Donate

                      726
                      Online

                      31.9k
                      Users

                      80.1k
                      Topics

                      1.3m
                      Posts

                      3
                      9
                      527
                      Loading More Posts
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes
                      Reply
                      • Reply as topic
                      Log in to reply
                      Community
                      Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
                      The ioBroker Community 2014-2023
                      logo