Automatisches Runden von Nachkommastellen

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Automatisches Runden von Nachkommastellen

    Hallo in die Runde! (<- im wahrsten Sinne)

    Ich habe am WE etwas herumgespielt und ein kleines sinnloses Script geschrieben. Dabei habe ich einen Wert exponentiell steigen lassen.

    Was mir auffiel ist das es ab einen bestimmten Wert die Nachkommastellen rundet.

    Jetzt bin ich interessiert an was das liegt und wie (oder ob) man das beheben kann!?

    Hier der Link: Exponentialfunktion Von Zeile 57 auf 58!
    Für den Code findet ihr ganz unten einen Link!
    Zuletzt geändert von Nendilo; 01.10.2012, 17:09.

  • #2
    Zitat von Nendilo Beitrag anzeigen
    an was das liegt
    PHP: Fließkommazahlen - Manual

    Zitat von Nendilo Beitrag anzeigen
    und wie (oder ob) man das beheben kann!?
    PHP: BC Math - Manual

    Kommentar


    • #3
      BC Math verwende ich bereits. Macht keinen Unterschied!

      Kommentar


      • #4
        Dann zeig mal deinen Code. Bei mir wird nix gerundet:

        PHP-Code:
        for ($i 0$i <= 60$i++) {
            echo (
        $i 1) . ': ' bcpow(2$i) . PHP_EOL;

        Code:
        57: 72057594037927936
        58: 144115188075855872
        59: 288230376151711744

        Kommentar


        • #5
          Zitat von h3ll Beitrag anzeigen
          Dann zeig mal deinen Code. Bei mir wird nix gerundet:
          PHP-Code:
          <?php
              setlocale
          (LC_MONETARY'de_DE.UTF-8');
              
          header('content-type:text/html; charset=utf-8');
              echo 
          '<!DOCTYPE html>
          <html>
              <head>
              <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
              <title>Exponentialfunktion</title>
              <style type="text/css">
                  *{margin: 0; padding: 0;}
                  html, body{width: auto;}
                  h1{text-align: center;}
                  h2, p{margin: .5em 20px;}
                  table{width: 100%;border-spacing: 0;}
                  .first{width: 2.5%;;text-align: right;}
                  .second{width: 7.5%;text-align: center;}
                  .third{width: 2.5%;text-align: right;}
                  .fourth{width: 80%;text-align: right;}
                  .fifth{width: 7.5%;text-align: center;}
                  .row0{background-color: #e1e8f1;}
                  .row1{background-color: #fff;}
                  .bold{font-weight: bold;}
              </style>
              </head>
              <body>
                  <h1>Exponentialfunktion</h1>
                  <p><strong>Beispiel:</strong> Ich gebe jemanden am 1.1.2013 einen Cent. Am darauf folgenden Tag  das doppelte, also 2 Cent. Am nächsten Tag wieder das doppelte, also 4 Cent usw. Wieviel Euro müßte ich ihn dann am 31.12.2013 geben?</p>
                  <h2>Ergebnis:</h2>
                  <table>
                      <tr>
                          <th class="first">Tag</th>
                          <th class="second">Datum</th>
                          <th class="third"></th>
                          <th class="fourth">Betrag</th>
                          <th class="fifth">Anzahl der Stellen</th>
                      </tr>'
          ;
          function 
          countDigits($number){
              
          $number abs($number);
              if (
          $number && $number >= 0) {
                  return 
          1;
              } else {
                  return 
          + (int)(log10($number));
              }
          }
          function 
          moneyFormat($number){
              if(
          function_exists('money_format')){
                  return 
          money_format('%.2n'$number);
              } else{
                  return 
          number_format($number2',''.') . ' €';
              }
          }
          $x 0;
          $y mktime(000112013);
          $z '.01';
          $total '0';
          while(
          $x 365){
              
          $add = ($x 0) ? '+' '';
              echo 
          '
                      <tr class="row' 
          $x '">
                          <td class="first">' 
          . ($x+1) . '.</td>
                          <td class="second">' 
          date('d.m.Y'$y) . '</td>
                          <td class="third">' 
          $add '</td>
                          <td class="fourth">' 
          moneyFormat($z) . '</td>
                          <td class="fifth">(' 
          countDigits($z) . ')</td>
                      </tr>'
          ;
              
          $x++;
              
          $y += 86400;
              
          $total    bcadd($z$total2);
              
          $z    bcmul($z'2'2);
          }
          echo 
          '
                      <tr class="row' 
          $x '">
                          <td class="first bold"></td>
                          <td class="second bold">Gesamt</td>
                          <td class="third bold">=</td>
                          <td class="fourth bold">' 
          moneyFormat($total) . '</td>
                          <td class="fifth">(' 
          countDigits($total) . ')</td>
                      </tr>
                  </table>
                  <p>
                      <small><a href="expowachs.txt">Hier</a> zum Überprüfen der Code des Scripts.</small>
                  </p>
              </body>
          </html>'
          ;
          ?>

          Kommentar


          • #6
            money_format() und number_format() können nur Float-Werte verarbeiten, somit werden Nachkommastellen abgeschnitten.

            Du solltest übrigens sinnvolle Variablennamen vergeben. $x, $y und $z sind gut für Ratspielchen, aber nicht für die Lesbarkeit des Programmcodes.
            Zuletzt geändert von h3ll; 01.10.2012, 20:23.

            Kommentar


            • #7
              Stimmt! Danke!

              Aber mit den Formatieren wird es dann nichts, außer man schreibt eine eigene Funktion!?

              Kommentar


              • #8
                Zitat von Nendilo Beitrag anzeigen
                Aber mit den Formatieren wird es dann nichts, außer man schreibt eine eigene Funktion!?
                Ja, zumindest mit den PHP-Hausmitteln.

                Eventuell bekommt es ja Zend_Locale_Format hin.

                Kommentar


                • #9
                  Zitat von Nendilo Beitrag anzeigen
                  Aber mit den Formatieren wird es dann nichts, außer man schreibt eine eigene Funktion!?
                  Nicht doch! Ein echter PHP-ler baut sich niemals etwa Eigenes, wenn es das fertiggebacken als Extension (geschrieben in hochoptimierbarem C-Quellcode) gibt. So wie den von vorn bis hinten durchkonfigurierbaren Numberformatter der Intl-Extension.
                  Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

                  Kommentar


                  • #10
                    Zitat von fireweasel Beitrag anzeigen
                    Nicht doch! Ein echter PHP-ler baut sich niemals etwa Eigenes, ...
                    Ist aber langweilig!

                    Habs mal so gelöst:
                    PHP-Code:
                    function moneyFormat($number){
                        
                    $temp    preg_split('/\./'$number);
                        
                    $temp2    strrev($temp[0]);
                        
                    $temp2    str_split($temp23);
                        
                    $temp2    implode('.'$temp2);
                        
                    $temp2    strrev($temp2);
                        return 
                    $temp2 ',' $temp[1];

                    Kommentar


                    • #11
                      Zitat von fireweasel Beitrag anzeigen
                      Nicht doch! Ein echter PHP-ler baut sich niemals etwa Eigenes, wenn es das fertiggebacken als Extension (geschrieben in hochoptimierbarem C-Quellcode) gibt. So wie den von vorn bis hinten durchkonfigurierbaren Numberformatter der Intl-Extension.
                      Das war auch mein erster Gedanke, aber laut Doku nimmt die format-Methode aber auch nur integer oder float als Parameter entgegen.

                      Kommentar


                      • #12
                        Zitat von nendilo;
                        Ist aber langweilig!
                        Jaein: Mein Kommentar war nur halb ironisch gemeint. Viele PHP-Bastler begeben sich auch ohne Not gern in Abhängigkeit von in C geschriebenen Libraries. Trotzdem ist es sinnvoll, erstmal zu schauen, ob jemand anders das Problem schon gelöst hat, bevor man selbst herumdokt(o|e)rt. Das Zend-Framework (in der Version 1.x) scheint mir ausreichend praxisgetestet, so dass ich eine dort vorhandene Lösung einer eigenen vorziehen würde.

                        Es sei denn, ich habe Zeit zum Spielen oder|und will herausfinden, wie Zahlenformatierung so funktioniert ...

                        Zitat von nendilo;
                        Habs mal so gelöst:

                        (...)
                        Die Komplexität der Lösung hängt davon ab, wie "fehlerhaft" der Input-String ist, den du formatieren möchtest. Kannst du sicher sein, dass nur maximal ein Dezimalpunkt und sonst ausschließlich Ziffern vorkommen, genügt eventuell auch ein preg_replace().

                        B.T.W.: Dein verlinktes Script begrüßt mich mit unzähligen array_key_exists() Fehlermeldungen. Und die Spalte "Betrag" ist entweder falsch formatiert oder es fehlt das Komma (je nachdem ob dort Euro oder Cent stehen sollen).

                        Zitat von h3ll Beitrag anzeigen
                        Das war auch mein erster Gedanke, aber laut Doku nimmt die format-Methode aber auch nur integer oder float als Parameter entgegen.
                        Im PHP-Quelltext steht als Typ "misc", was mich vermuten ließ, dass man bspw. auch einen String übergeben kann. Leider werden Strings immer nach Integer oder Double konvertiert, bevor sie einer der ICU-Formatierungsfunktionen zugeführt werden. Diese machen dann aus dem numerischen Typ wieder eine Zeichenkette, von der schließlich eine formatierte Kopie erzeugt wird. Umständlicher geht es scheinbar nicht.

                        Prinzipiell beherrschen die ICU-Libraries das Formatieren von Zeichenketten (was man von einer Unicode-String-Library auch erwarten kann). Nur leider nutzt die PHP-Intl-Extension diese Fähigkeit (unum_formatDecimal()) nicht, sondern nur die speziellen Formatierfunktionen für int32, dbl und int64.

                        Das von dir vorgeschlagene Zend_Locale_Format scheint dagegen auf String-Bearbeitung zu setzen und wäre damit auf der sicheren Seite. Dummerweise wurde das in der Version 2 der Zend-Framework-Library wegrationalisiert. Dort finde ich nur eine Klasse NumberFormat, die auf (*tada*) die NumberFormatter-Klasse aufsetzt. (Es sei denn, ich habe etwas übersehen)
                        Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

                        Kommentar

                        Lädt...
                        X