Andreas: n-ten Tag des Jahres

0 46

n-ten Tag des Jahres

Andreas
  • javascript
  1. 0
    Hopsel
  2. 0
    Axel Richter
    1. 0
      Andreas
      1. 0
        Vinzenz Mai
        1. 0
          Axel Richter
          1. 0
            MudGuard
          2. 0
            Ingo Turski
            1. 0
              MudGuard
              1. 0
                Ingo Turski
                1. 0
                  Der Martin
                  1. 0
                    Vinzenz Mai
                  2. 0
                    Ingo Turski
                2. 0
                  MudGuard
  3. 0
    Thomas Meinike
    1. 1
      Christoph Zurnieden
      1. 0
        Thomas Meinike
        1. 0
          Christoph Zurnieden
          1. 0
            Cheatah
            1. 0
              Christoph Zurnieden
      2. 0
        MudGuard
        1. 0
          Christoph Zurnieden
      3. 0
        Gunnar Bittersmann
        1. 0
          Christoph Zurnieden
          1. 0
            Gunnar Bittersmann
            1. 0
              Der Martin
          2. 0
            Fabian St.
            1. 1
              Christoph Zurnieden
              1. 0
                Fabian St.
                1. 0
                  Christoph Zurnieden
                  1. 0
                    Christian Kruse
                    1. 0
                      Christoph Zurnieden
                      1. 0
                        Christian Kruse
                  2. 0
                    Fabian St.
                    1. 0
                      Christoph Zurnieden
  4. 0
    Gunnar Bittersmann
    1. 0
      Der Martin
      1. 1
        Gunnar Bittersmann
        1. 0
          Thomas Meinike
          1. 0
            Gunnar Bittersmann
            1. 0
              Thomas Meinike
          2. 0
            Swen Wacker
            1. 0
              MudGuard
            2. 0
              Thomas Meinike
            3. 0
              Gunnar Bittersmann
        2. 0
          Christian Kruse

Hallo,

Ich möchte gerne eine Funktion haben, die mir den n-ten Tag des Jahres ermittelt, also in Nichtschaltjahren soll die Funktion mir am 1. Januar die Zahl 0 auswerfen und am 31. Dezember die Zahl 364, in Schaltjahren 365.

Gibt es eine Funktion, die mir das automatisch ermittelt? Mit getDate kann man sich ja nur den Tag des Monats ermitteln lassen.

Grüße
Andreas

  1. Hi Andreas!

    Gibt es eine Funktion, die mir das automatisch ermittelt?

    AFAIK nicht. PHP bietet sowas...

    Mit getDate kann man sich ja nur den Tag des Monats ermitteln lassen.

    Aber dann kannst du dir ja eine wunderschöne Funktion GetTagDesJahres() schreiben. Du musst halt nur noch wissen, in welchem Monat sicher der ermittelte Tag befindet. :)

    MfG H☼psel

    --
    "It's amazing I won. I was running against peace, prosperity, and incumbency."
    George W. Bush speaking to Swedish Prime Minister unaware a live television camera was still rolling, June 14, 2001
    Selfcode: ie:% fl:( br:> va:) ls:& fo:) rl:? n4:& ss:| de:] js:| ch:? sh:( mo:) zu:)
  2. Hallo,

    Ich möchte gerne eine Funktion haben, die mir den n-ten Tag des Jahres ermittelt, also in Nichtschaltjahren soll die Funktion mir am 1. Januar die Zahl 0 auswerfen und am 31. Dezember die Zahl 364, in Schaltjahren 365.

    Erzeuge ein Datumsobjekt mit dem Neujahrstag des zu betrachtenden Jahres. Erzeuge ein zweites Datumsobjekt mit dem zu betrachtenden Tag im zu betrachtenden Jahr. Subtrahiere beide Werte. Das Ergebnis ist in Millisekunden. Teile das Ergebnis durch 1000, dann hast Du Sekunden, nochmal durch 60, dann hast Du Minuten ...

    viele Grüße

    Axel

    1. Vielen Dank, das hat mir geholfen. Hier nochmal meine Lösung fürs Archiv:

      /* ermittelt für "tag", welcher Tag im Jahr momentan ist, wenn der erste Januar die Zahl 0 zugewiesen bekommt. */

      var datum = new Date();
      var datumNeujahr = new Date(datum.getYear(), 0, 1, 0, 0, 0);
      var datumHeute   = new Date(datum.getYear(), datum.getMonth(), datum.getDate(), 0, 0, 0);
      var tag = (datumHeute - datumNeujahr) / 86400000;

      1. Hallo Andreas,

        Vielen Dank, das hat mir geholfen. Hier nochmal meine Lösung fürs Archiv:
        var datum = new Date();
        var datumNeujahr = new Date(datum.getYear(), 0, 1, 0, 0, 0);
        var datumHeute   = new Date(datum.getYear(), datum.getMonth(), datum.getDate(), 0, 0, 0);
        var tag = (datumHeute - datumNeujahr) / 86400000;

        bitte teste Deine Lösung z.B. mit dem 1. Juni.
        Ich fürchte, Du hast ein bestimmtes derzeit jährliches Ereignis vergessen.

        Freundliche Grüße

        Vinzenz

        1. Hallo,

          Ich fürchte, Du hast ein bestimmtes derzeit jährliches Ereignis vergessen.

          Wenn man wirklich nur die Tageszahl (gerundet auf Ganzzahl) braucht und immer mit 0:00 Uhr am Tag rechnet, dann sollte die +/- eine Stunde um 3:00 Uhr nicht ins Gewicht fallen. Eben deshalb wurde die Umstellung ja, soweit ich weiß, auf 3:00 Uhr gelegt.

          viele Grüße

          Axel

          1. Hi,

            Eben deshalb wurde die Umstellung ja, soweit ich weiß, auf 3:00 Uhr gelegt.

            Nicht nur deswegen:

            um die Zeit (2 bzw. 3 Uhr) ist in den meisten Städten der ÖPNV in der Ruhepause und auch sonst ist vieles am frühen Morgen auf Pause, so daß die Zeitverschiebung keine allzu großen Auswirkungen hat.

            cu,
            Andreas

            --
            Warum nennt sich Andreas hier MudGuard?
            Schreinerei Waechter
            Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
          2. Hi,

            Ich fürchte, Du hast ein bestimmtes derzeit jährliches Ereignis vergessen.
            Wenn man wirklich nur die Tageszahl (gerundet auf Ganzzahl) braucht und immer mit 0:00 Uhr am Tag rechnet, dann sollte die +/- eine Stunde um 3:00 Uhr nicht ins Gewicht fallen.

            Oh doch... Am 27.03.05 gibt das Script den Tag 85 aus und am 28.03.05 den Tag 85.95833333333333 - dies zieht sich bis zum 30.10.05 durch.

            freundliche Grüße
            Ingo

            1. Hi,

              Wenn man wirklich nur die Tageszahl (gerundet auf Ganzzahl) braucht und immer mit 0:00 Uhr am Tag rechnet, dann sollte die +/- eine Stunde um 3:00 Uhr nicht ins Gewicht fallen.
              Oh doch... Am 27.03.05 gibt das Script den Tag 85 aus und am 28.03.05 den Tag 85.95833333333333 - dies zieht sich bis zum 30.10.05 durch.

              Du hast das "gerundet auf Ganzzahl" gelesen?

              cu,
              Andreas

              --
              Warum nennt sich Andreas hier MudGuard?
              Schreinerei Waechter
              Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
              1. Hi,

                Du hast das "gerundet auf Ganzzahl" gelesen?

                erwischt. ;-)
                Mit round() sollte das sogar in der südlichen Hemisphäre funktionieren.

                freundliche Grüße
                Ingo

                1. Hallo Ingo,

                  Mit round() sollte das sogar in der südlichen Hemisphäre funktionieren.

                  meinst du, die haben da eine andere Zeitrechnung oder warum?
                  Nach meiner Kenntnis ist die geographische Breite für die Zeitrechnung belanglos. Nur die geographische Länge (Ost-West-Lage) ist ausschlaggebend.

                  Eine ganz andere Sache ist, dass für einen Beobachter auf der Südhalbkugel die Sonne im Osten aufgeht, dann gegen den Uhrzeigersinn wandert, mittags im Norden steht und abends im Westen wieder untergeht.

                  Schönen Abend noch,

                  Martin

                  --
                  Wer im Glashaus sitzt, sollte sich nur im Dunkeln ausziehen.
                  1. Hallo Martin,

                    Mit round() sollte das sogar in der südlichen Hemisphäre funktionieren.

                    meinst du, die haben da eine andere Zeitrechnung oder warum?
                    Nach meiner Kenntnis ist die geographische Breite für die Zeitrechnung belanglos. Nur die geographische Länge (Ost-West-Lage) ist ausschlaggebend.

                    überleg' Dir mal. Wir haben jetzt de facto Winter, unsere Tage sind kurz. Wie sieht es ganz viel weiter südlich aus, so im Bereich um Kapstadt (ja ich weiß, das ist weiter östlich)? Haben die zur gleichen Zeit wie wir Sommerzeit? So ungefähr um die gleiche Zeit - wenn die überhaupt Sommerzeit haben. Ich bin zu faul zum Nachsehen. Das könntest Du für mich erledigen.

                    Freundliche Grüße

                    Vinzenz

                  2. Hi,

                    Mit round() sollte das sogar in der südlichen Hemisphäre funktionieren.

                    meinst du, die haben da eine andere Zeitrechnung oder warum?

                    Ja, die haben jetzt Sommer(-zeit).

                    freundliche Grüße
                    Ingo

                2. Hi,

                  Mit round() sollte das sogar in der südlichen Hemisphäre funktionieren.

                  Kommt drauf an, von welchem Planeten ... ;-)

                  cu,
                  Andreas

                  --
                  Warum nennt sich Andreas hier MudGuard?
                  Schreinerei Waechter
                  Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
  3. Hallo,

    Gibt es eine Funktion, die mir das automatisch ermittelt? Mit getDate kann man sich ja nur den Tag des Monats ermitteln lassen.

    Siehe Archiv.

    MfG, Thomas

    1. Hi,

      Gibt es eine Funktion, die mir das automatisch ermittelt? Mit getDate kann man sich ja nur den Tag des Monats ermitteln lassen.

      Siehe Archiv.

      Ist das Schleifchen dafuer da, damit es schoener aussieht? ;-)

        
      Date.prototype.getYearDate = function(){  
        var d           = this;  
        
        var Day         = d.getDate();  
        var Month       = d.getMonth();  
        var Year        = d.getFullYear();  
        
        /*  
          Papst Gregor XIII strich die Tage vom 4.10-15.10.1582.  
          Wer es benoetigt kann das natuerlich auch noch einbauen.  
          Vorher war uebrigens jedes vierte Jahr Schaltjahr, ohne Ausnahmen.  
        */  
        
        var isLeap      = (Year % 400 == 0 || (Year % 4 == 0 && Year % 100 != 0));  
        var monthArray  = (isLeap)?[0,31,60,91,121,152,182,213,244,274,305,335,366]  
                   :[0,31,59,90,120,151,181,212,243,273,304,334,365];  
        
        return (monthArray[Month-1] + Day);  
      }  
      
      

      Na, hoffentlich habe ich mich da jetzt nirgendwo vertan ;-)

      so short

      Christoph Zurnieden

      1. Hallo,

        Siehe Archiv.

        Ist das Schleifchen dafuer da, damit es schoener aussieht? ;-)

        Naja, spart mir nur das genannte Array und die paar Berechnungen kann man durchaus dem Date-Objekt zumuten. Die Ermittlung des Schaltjahres ist ja gleich dabei.

        return (monthArray[Month-1] + Day);

        return (monthArray[Month] + Day);

        denn Month ist ja bereits im Bereich von 0-11.

        So kommt dann mit beiden Loesungen aktuell 331 heraus.

        MfG, Thomas

        1. Hi,

          Ist das Schleifchen dafuer da, damit es schoener aussieht? ;-)

          Naja, spart mir nur das genannte Array und die paar Berechnungen kann man durchaus dem Date-Objekt zumuten. Die Ermittlung des Schaltjahres ist ja gleich dabei.

          Ja, es ist natuerlich Geschmacksache, mir war das halt zu unelegant, mit dem mehrfachem Erzeugen eines Date-Objektes ;-)

          return (monthArray[Month-1] + Day);

          Autsch, das kommt davon!
          Aber frag' mich jetzt nicht wovon; tippe mal auf C&P.
          Ne, was peinlich wieder!

          so short

          Chrstoph Zurnieden

          1. Hi,

            Naja, spart mir nur das genannte Array und die paar Berechnungen kann man durchaus dem Date-Objekt zumuten. Die Ermittlung des Schaltjahres ist ja gleich dabei.
            Ja, es ist natuerlich Geschmacksache, mir war das halt zu unelegant, mit dem mehrfachem Erzeugen eines Date-Objektes ;-)

            füg die Funktion doch dem Date-Objekt per Prototyping hinzu, dann sind alle glücklich ;-)

            Cheatah

            --
            X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
            X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
            X-Will-Answer-Email: No
            X-Please-Search-Archive-First: Absolutely Yes
            1. Hi,

              Ja, es ist natuerlich Geschmacksache, mir war das halt zu unelegant, mit dem mehrfachem Erzeugen eines Date-Objektes ;-)

              füg die Funktion doch dem Date-Objekt per Prototyping hinzu, dann sind alle glücklich ;-)

              Ich weiss ja, das ich nicht gerade der Javascript-Guru bin, aber was um Gottes Willen habe ich denn dabei falsch gemacht?

              Oder moechtest Du mir mit dem Grinsemaennchen etwas bestimmtes sagen? ;-)

              so short

              Christoph Zurnieden

      2. Hi,

        /*
            Papst Gregor XIII strich die Tage vom 4.10-15.10.1582.

        In welcher Farbe? ;-)

        Wer es benoetigt kann das natuerlich auch noch einbauen.

        Dann müßte man aber noch berücksichtigen, daß der gregorianische Kalender nicht weltweit gleichzeitig eingeführt wurde ...

        cu,
        Andreas

        --
        Warum nennt sich Andreas hier MudGuard?
        Schreinerei Waechter
        Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
        1. Hi,

          Papst Gregor XIII strich die Tage vom 4.10-15.10.1582.

          In welcher Farbe? ;-)

          In Sepia (Tintenfischtinte).

          Wer es benoetigt kann das natuerlich auch noch einbauen.

          Dann müßte man aber noch berücksichtigen, daß der gregorianische Kalender nicht weltweit gleichzeitig eingeführt wurde ...

          Das habe ich:"Wer es benoetigt..."

          so short

          Christoph Zurnieden

      3. var isLeap      = (Year % 400 == 0 || (Year % 4 == 0 && Year % 100 != 0));

        Christoph,
        Wozu die Vergleiche gegen 0?

        var isLeap = (!(Year % 4) && (!(Year % 400) || (Year % 100)));

        http://forum.de.selfhtml.org/archiv/2005/10/t117328/#m751312

        Live long and prosper,
        Gunnar

        --
        „Weisheit ist nicht das Ergebnis der Schulbildung, sondern des lebenslangen Versuchs, sie zu erwerben.“ (Albert Einstein)
        1. Hi,

          var isLeap      = (Year % 400 == 0 || (Year % 4 == 0 && Year % 100 != 0));

          Christoph,
          Wozu die Vergleiche gegen 0?

          Damit es deutlicher lesbar ist.
          Normalerweise erledige ich sowas naemlich teilweise per Bit-Juggling und das waere ein wenig hart fuer Anfaenger.

          Man kann das Schaltjahr aber auch noch auf mehrere andere Arten herausfinden z.B. auf diese ziemlich krumme hier:

            
          var isLeap = ((new Date(Year, 1, 29 ).getDate()) == 29);  
          
          

          so short

          Christoph Zurnieden

          1. Man kann das Schaltjahr aber auch noch auf mehrere andere Arten herausfinden z.B. auf diese ziemlich krumme hier:
            var isLeap = ((new Date(Year, 1, 29 ).getDate()) == 29);

            Christoph,
            Du willst zwischendurch einen Kaffee trinken, während du auf das Ergebnis wartest? ;-)

            Live long and prosper,
            Gunnar

            --
            „Weisheit ist nicht das Ergebnis der Schulbildung, sondern des lebenslangen Versuchs, sie zu erwerben.“ (Albert Einstein)
            1. n'Abend Gunnar,

              var isLeap = ((new Date(Year, 1, 29 ).getDate()) == 29);
              Du willst zwischendurch einen Kaffee trinken, während du auf das Ergebnis wartest? ;-)

              lass ihn doch! Immer mit der Ruhe. Warum denn dauernd so hetzen?
              Nur übertreiben sollte er's auch nicht. Zuviel Kaffee ist ja denn auch wieder ungesund.  *scnr*

              Schönen Abend noch,

              Martin

              --
              Success should be measured not so much by the position that one has reached in life,
              but by the obstacles one has overcome while trying to succeed.
          2. Hi Christoph!

            var isLeap      = (Year % 400 == 0 || (Year % 4 == 0 && Year % 100 != 0));

            Christoph,
            Wozu die Vergleiche gegen 0?

            Damit es deutlicher lesbar ist.
            Normalerweise erledige ich sowas naemlich teilweise per Bit-Juggling und das waere ein wenig hart fuer Anfaenger.

            Wie würde das dann ausschauen?

            [...]

            Grüße,
            Fabian St.

            1. Hi,

              var isLeap      = (Year % 400 == 0 || (Year % 4 == 0 && Year % 100 != 0));
              Normalerweise erledige ich sowas naemlich teilweise per Bit-Juggling und das waere ein wenig hart fuer Anfaenger.

              Wie würde das dann ausschauen?

              Damit koenntest Du als Anfaenger eh nichts anfangen. Du bist kein Anfaenger? Na, dann weist Du ja selbst wie's geht.

              -;>

              Aber Scherz beiseite und der Reihe nach durch das Dingen.
              Das einfachste ist hier wohl das Modulo 4, denn 4 = 2^2, d.h. ein Rightshift tut hier seinen Teil (ist bei Javascript ein klein wenig umstaendlicher alles, aber das soll hier nicht stoeren.) zusammen mit einem Leftshift und einem XOR. Bei so einer kleinen Zahl geht auch AND; hier waere es also: Year&3.
              Zudem darf das Jahr nicht durch 100 teilbar sein, das ist schon etwas komplizierter. Nein, eigentlich nicht, das laesst sich alles mit Shifts und Additionen erledigen, hier mal eine kleine Uebersicht (gemeinerweise als Multiplikation ;-) und in C-Syntax:

                
              result =   number << 1;                 // number * 2  
              result =  (number << 1) + number;       // number * 3  
              result =  (number << 2) + number;       // number * 5  
              [...]  
              result = ((number << 2) + number) << 1; // number * 10  
              [...]  
              
              

              (Ja, ich weiss auch das 10 keine Primzahl ist ;-)

              Was fehlt noch? Ah ja, die 400, mit der kann man natuerlich nach gleichem Muster verfahren. Das fuehrt dann zu (MOD stehe hier fuer die oben beschriebene Fummelei):

                
              isLeap = (((Year & 3) ^ (Year MOD 100) ^ (Year MOD 400)) == 0);  
              
              

              Das ist aber natuerlich immer noch die gleiche Formel, nur wurde die teure direkte Division entfernt, das ist schlichte und daher total bloedsinnige Microoptimierung, wenn in Javascript implementiert. (Anders natuerlich wenn Du direkt auf oder sogar in der Hardware arbeiten musst)

              Da ist die Frage nur natuerlich, ob sich das nicht vereinfachen laesst. Kleiner Tip: XOR ist im Grunde Modulo 2 auf Bitebene. Na, bekommst Du die Moduloregeln noch zusammen? Gut, bei Wikipedia schmuhen ist hier durchaus mal erlaubt ;-)

              so short

              Christoph Zurnieden

              1. Hi Christoph!

                var isLeap      = (Year % 400 == 0 || (Year % 4 == 0 && Year % 100 != 0));
                Normalerweise erledige ich sowas naemlich teilweise per Bit-Juggling und das waere ein wenig hart fuer Anfaenger.

                Wie würde das dann ausschauen?

                Damit koenntest Du als Anfaenger eh nichts anfangen. Du bist kein Anfaenger? Na, dann weist Du ja selbst wie's geht.

                -;>

                Naja, die Frage ist wohl eher, was du als »Anfänger« definierst. Aber ich gebe ja zu, auf dem Gebiet der verschiedenen Bit-Operationen (Shifting, etc.) kenne ich mich (noch) kaum aus und sehe bisher noch nicht wirklich einen Sinn darin, was ich aber zu ändern gedenke. Genau aus diesem Grunde frage ich hier auch nach.

                In der letzten Zeit versuche ich zum Beispiel die verschiedenen Hash-Algorithmen zu verstehen und diese selber zu implementieren. Dabei wird ja beinahe ausschließlich mit den einzelnen Bits gearbeitet, aber insbesondere das Verständnis »warum so, und nichts anders« bereitet mir im Moment noch einige Probleme.

                Right- und Leftshift habe ich mittlerweile glaube ich verstanden: Ein Rightshift um n Bits ist ja nichts anderes als eine Division durch 2^n, weil die einzelnen Bits nach Rechts verschoben werden. Ein Leftshift ist dementsprechend eine Multiplikation mit 2^n. Was bringt mir das nun aber genau, d.h. wann schreibe ich

                  
                int result, i  
                i = 8  
                result = i << 2 // result ist nun 32  
                
                

                und wann

                  
                int result, i  
                i = 8  
                result = 8 * pow(2, 2)  
                
                

                Es ist letzten Endes nur für die Geschwindigkeit der Operation zum Vorteil (auch wenn diese Beispiel wohl hierfür unglücklich gewählt sind) oder gibt es noch weitere Gründe, bei der man das Beispiel bevorzugen würde?

                Aber Scherz beiseite und der Reihe nach durch das Dingen.
                Das einfachste ist hier wohl das Modulo 4, denn 4 = 2^2, d.h. ein Rightshift tut hier seinen Teil (ist bei Javascript ein klein wenig umstaendlicher alles, aber das soll hier nicht stoeren.) zusammen mit einem Leftshift und einem XOR. Bei so einer kleinen Zahl geht auch AND; hier waere es also: Year&3.

                Das »Year & 3« entspricht wohl dem »Year % 4«, wobei sich die 3 aus folgenden Überlegungen herleitet:

                [latex]
                3_{(10)} = 1 * 2 + 1 * 1 = 11_{(2)}
                [/latex]

                Eine Zahl im Dualsystem ist genau dann durch 4 teilbar, wenn die letzten zwei Ziffern eine Null sind. Insofern sollte bei »Year % 3« immer 0 herauskommen weil eine »&«-Verknüpfung der Bits dann z.B. so aussieht:

                [latex]
                1101_{(2)} & 0011_{(2)} = 0001_{(2)} \not= 0 \rightarrow 1101_{(2)} = 13_{(10)} ist nicht durch 4 teilbar
                [/latex]

                Sind meine Gedankengänge soweit richtig?

                Ab hier steige ich dann aus, kannst du das nachfolgende bitte nochmal genauer (ohne eventuelle Spielereien, die das ganze »feiner«, aber auch schwieriger machen) erklären? D.h. was bezweckst du mit untenstehenden Bit-Shifting?

                Zudem darf das Jahr nicht durch 100 teilbar sein, das ist schon etwas komplizierter. Nein, eigentlich nicht, das laesst sich alles mit Shifts und Additionen erledigen, hier mal eine kleine Uebersicht (gemeinerweise als Multiplikation ;-) und in C-Syntax:

                result =   number << 1;                 // number * 2
                result =  (number << 1) + number;       // number * 3
                result =  (number << 2) + number;       // number * 5
                [...]
                result = ((number << 2) + number) << 1; // number * 10
                [...]

                
                >   
                > (Ja, ich weiss auch das 10 keine Primzahl ist ;-)  
                  
                  
                Grüße,  
                Fabian St.
                
                -- 
                Selfcode: [ie:{ fl:( br:> va:) ls:\[ fo:) rl:( n4:( ss:) de:> js:| ch:? mo:) zu:)](http://www.peter.in-berlin.de/projekte/selfcode/?code=ie%3A%7B+fl%3A%28+br%3A%3E+va%3A%29+ls%3A%5B+fo%3A%29+rl%3A%28+n4%3A%28+ss%3A%29+de%3A%3E+js%3A%7C+ch%3A%3F+mo%3A%29+zu%3A%29)
                
                1. Hi,

                  (abschicken sollte man das dann auch noch, Christoph ;-)

                  Naja, die Frage ist wohl eher, was du als »Anfänger« definierst.

                  Jeden, der dem Woertchem "noch" besondere Betonung gibt.

                  Aber ich gebe ja zu, auf dem Gebiet der verschiedenen Bit-Operationen (Shifting, etc.) kenne ich mich (noch) kaum aus und sehe bisher noch nicht wirklich einen Sinn darin, was ich aber zu ändern gedenke.

                  Man sollte es verstehen koennen. Sinn in der Anwendung macht das aber heutzutage eigentlich nur noch im hardwarenahem Bereich oder beim Numbercrunching.

                  In der letzten Zeit versuche ich zum Beispiel die verschiedenen Hash-Algorithmen zu verstehen und diese selber zu implementieren.

                  Die Algorithmen zu implementieren ist meist leicht, sie zu verstehen erfordert aber hoehere Mathematik und da fragst Du besser jemanden, der sich damit auskennt ;-)

                  Aber ich nehme mal an, das Du unter "Verstehen" hier nur die Implementation meinst.

                  Dabei wird ja beinahe ausschließlich mit den einzelnen Bits gearbeitet, aber insbesondere das Verständnis »warum so, und nichts anders« bereitet mir im Moment noch einige Probleme.

                  Prinzipiell weil es einfacher in Hardware zu implementieren ist. Deshalb sind solche Implementationen bei mancher Architektur auch schneller.
                  Diese Reihenfolge ist nach Moeglichkeit einzuhalten, Ausnahmen duerfen nicht zur Regel werden.

                  Right- und Leftshift habe ich mittlerweile glaube ich verstanden: Ein Rightshift um n Bits ist ja nichts anderes als eine Division durch 2^n, weil die einzelnen Bits nach Rechts verschoben werden. Ein Leftshift ist dementsprechend eine Multiplikation mit 2^n.

                  Beim Bitverschieben ist auch noch zusaetzlich bei einigen Architekturen das Vorzeichen und die "Fuellung" zu beachten.
                  Fuellung ist inbesondere beim Rightshift wichtig, deshalb gibt es in einigen Sprachen auch noch zusaetzlich die Moeglichkeit des Rightshift mit "Nullen links auffuellen" mitunter dargestellt als '>>>'. Mitunter ist das Shifting auch zirkular: was an einer Seite rausfaellt wird an der anderen Seite wieder angefuegt.
                  Es sind beim -- falsch: natuerlich _vor_ dem Einsatz die Implementation des Shiftings in Sprache und Architektur zu pruefen. Aufgrund dieser Architekturabhaengigkeit ist Bitjuggling auch alles andere als portabel.

                  Was bringt mir das nun aber genau, d.h. wann schreibe ich

                  int result, i
                  i = 8
                  result = i << 2 // result ist nun 32

                    
                  Wenn Du den Code in Hardware implementieren moechtest, direkt auf der bekannten(!) Hardware (Kernel, Graphikengine u.ae.) oder tatsaechlich auf Bitebene arbeitest. Mitunter kann der Geschwindigkeitsvorteil auch anderweitig Vorteil bringen und in manchen Faellen ist es auch schlicht einfacher lesbar, da die Shiftingsymbolik dem Leser direkt klarmacht, das da Bitjuggling passiert.  
                    
                  
                  > und wann  
                  >   
                  > ~~~c
                    
                  
                  > int result, i  
                  > i = 8  
                  > result = 8 * pow(2, 2)  
                  > 
                  
                  

                  »

                  Wenn es portabel sein soll.

                  Das »Year & 3« entspricht wohl dem »Year % 4«, wobei sich die 3 aus folgenden Überlegungen herleitet:

                  [latex]
                  3_{(10)} = 1 * 2 + 1 * 1 = 11_{(2)}
                  [/latex]

                  (Was denn, LaTeX kaputtgespielt, Christian? ;-)

                  Eine Zahl im Dualsystem ist genau dann durch 4 teilbar, wenn die letzten zwei Ziffern eine Null sind.

                  Ganz genau: binaer 100 ist dezimal 4.

                  Insofern sollte bei »Year % 3« immer 0 herauskommen weil eine »&«-Verknüpfung der Bits dann z.B. so aussieht:

                  [latex]
                  1101_{(2)} & 0011_{(2)} = 0001_{(2)} \not= 0 \rightarrow 1101_{(2)} = 13_{(10)} ist nicht durch 4 teilbar
                  [/latex]

                  Sind meine Gedankengänge soweit richtig?

                  Ja.
                  Problem hier: es wird vorausgesetzt, das alle anderen Bits der binaeren Darstellung der dezimalen Zahl '3' auf Null gesetzt sind, das ist nicht ueberall der Fall. Ist hier egal, ich wollt's nur noch mal erwaehnt wissen.

                  Ab hier steige ich dann aus, kannst du das nachfolgende bitte nochmal genauer (ohne eventuelle Spielereien, die das ganze »feiner«, aber auch schwieriger machen) erklären? D.h. was bezweckst du mit untenstehenden Bit-Shifting?

                  Steht doch daneben?
                  Aber gut, kein Problem.

                  Die Loesung ist normalerweise fuer Hardware gedacht, als Approximationshilfe fuer Flieskommazahlen und hat da auch einen Namen: "Reziproke Multiplikation". Beim Namen bin ich mir allerdings nicht so sicher. Ausgangspunkt ist dabei, das sich alle Multiplikationen mit SHIFT und ADD ausfueheren lassen; zwei Funktionen, die sich leicht in Hardware nachbilden lassen.

                  result =   number << 1;                 // number * 2
                  result =  (number << 1) + number;       // number * 3
                  result =  (number << 2) + number;       // number * 5
                  [...]
                  result = ((number << 2) + number) << 1; // number * 10
                  [...]

                    
                  Die Multiplikationen koennen ja auch als reine Additionen dargestellt werden:  
                  a\*3 = a+a+a  
                  Wir muessen also nur den Multiplikator faktorieren (eine gerade Zahl ist ideal also bei Bedarf vor dem Faktorieren 1 abziehen). Der Faktor '2' kann per SHIFT direkt implementiert werden, der Rest wird addiert.  
                    
                  fakt(2)  = 2  
                  fakt(3)  = 3     = fakt(2) + 1 = 2 + 1  
                  fakt(5)  = 5     = fakt(4) + 1 = 2 \* 2 + 1  
                  fakt(10) = 2 \* 5 = 2 \* fakt(5) = 2 \* (fakt(4) + 1) = 2 \* (2 \* 2 + 1)  
                    
                  Wie man sieht: die Klammern sind hier entscheidend ;-)  
                    
                  
                  > > (Ja, ich weiss auch das 10 keine Primzahl ist ;-)  
                    
                  Das war eigentlich als kleiner Tip gedacht, aber war wohl doch zu versteckt.  
                    
                    
                  so short  
                    
                  Christoph Zurnieden
                  
                  1. 你好 Christoph,

                    Dabei wird ja beinahe ausschließlich mit den einzelnen Bits gearbeitet,
                    aber insbesondere das Verständnis »warum so, und nichts anders«
                    bereitet mir im Moment noch einige Probleme.

                    Prinzipiell weil es einfacher in Hardware zu implementieren ist. Deshalb
                    sind solche Implementationen bei mancher Architektur auch schneller.

                    Jupp, auf IA32 (also einem 386er) braucht z. B. ein DIV (Division) zwischen
                    14 und 41 Zyklen, ein IDIV (vorzeichenbehaftete Integer-Division) zwischen
                    19 und 46 Zyklen, je nach Operanden-Typ.

                    Ein MUL (vorzeichenlose Multiplikation) braucht zwischen 9 und 21 Zyklen,
                    ein IMUL (vorzeichenbehaftete Multiplikation) zwischen 9 und 41 Zyklen.

                    Ein Modulo gibt es nicht, das ist eine Division (IDIV); bei der Division
                    wird immer Quotient und Rest in zwei Registern abgelegt, abhängig von den
                    Quell-Operanden (also entweder Quotient in AL und Rest in AH, oder
                    Quotient in AL und Rest in DX).

                    Ein SHL/SAL (SHIFT LOGICAL LEFT/SHIFT ARITHMETIC LEFT) braucht dagegen
                    zwischen 3 und 7 Zyklen, abhängig von den Operanden, ein SHR/SAR (SHIFT
                    LOGICAL RIGHT/SHIFT ARITHMETICAL RIGHT) braucht 3 bis 7 Zyklen.

                    Das variiert ein wenig von Prozessor zu Prozessor, aber die Tendenzen sind
                    klar.

                    Problem hier: es wird vorausgesetzt, das alle anderen Bits der binaeren
                    Darstellung der dezimalen Zahl '3' auf Null gesetzt sind, das ist nicht
                    ueberall der Fall. Ist hier egal, ich wollt's nur noch mal erwaehnt
                    wissen.

                    Ja, ich hab da von ganz kranken Sachen gehört, die Intel-Architektur
                    enthält z. B. diverse Anweisungen, um mit BCD zu rechnen… *schüttel*

                    fakt(10) = 2 * 5 = 2 * fakt(5) = 2 * (fakt(4) + 1) = 2 * (2 * 2 + 1)

                    Wie man sieht: die Klammern sind hier entscheidend ;-)

                    Hehe, du weisst sicher, dass

                    2 * (2 * 2 + 1) = 2 * 2 * 2 + 1

                    da die Multiplikation in |R assoziativ ist.

                    再见,
                     克里斯蒂安

                    --
                    Wundert euch nicht, … | Noch eine Block-Installation: SELFHTML Aktuell
                    Wenn gewöhnliche Menschen Wissen erlangen, sind sie weise. Wenn Weise Einsicht erlangen, sind sie gewöhlnliche Menschen.
                    http://wwwtech.de/
                    1. Hi,

                      ah, endlich jemand, der sich damit wirklich auskennt!

                      Wenn auch nicht so ganz mit Mathe, wie's scheint ;-)

                      fakt(10) = 2 * 5 = 2 * fakt(5) = 2 * (fakt(4) + 1) = 2 * (2 * 2 + 1)

                      Wie man sieht: die Klammern sind hier entscheidend ;-)

                      Hehe, du weisst sicher, dass

                      2 * (2 * 2 + 1) = 2 * 2 * 2 + 1

                      da die Multiplikation in |R assoziativ ist.

                      Ja, das ist mir bekannt. Es gibt aber auch noch die Regel, das "Punktrechnung vor Strichrechnung" kommt, somit gilt:

                      2 * (2 * 2 + 1) = 10
                      2 * 2 * 2 + 1   = 9

                      War das zu frueh fuer Dich heute morgen? ;-)

                      so short

                      Christoph Zurnieden

                      1. 你好 Christoph,

                        ah, endlich jemand, der sich damit wirklich auskennt!

                        Hehe, danke ;)

                        Wenn auch nicht so ganz mit Mathe, wie's scheint ;-)

                        Hehe, ja, ich glaube, das war etwas früh heute morgen *g* Ausserdem war ich
                        in Hektik, ich hätte schon lange weg sein müssen ;)

                        War das zu frueh fuer Dich heute morgen? ;-)

                        Ja, vermutlich ;)

                        Schlimmer Patzer, auatsch *g*

                        再见,
                         克里斯蒂安

                  2. Hi Christoph!

                    [...]

                    Vielen Dank erstmal soweit für deine Hilfe, damit komme ich schon mal weiter. Im Moment habe ich nur so viel andere Sachen um die Ohren (z.B. Schule ;-)), dass ich bis zum WE wohl nicht dazukommen werde, mich damit noch einmal eingehender zu befassen.

                    Dürfte ich mich, wenn dieser Thread bereits im Archiv verschwunden ist und ich noch kleinere Fragen habe, mich bei dir direkt per Mail melden?

                    Grüße,
                    Fabian St.

                    1. Hi,

                      Dürfte ich mich, wenn dieser Thread bereits im Archiv verschwunden ist und ich noch kleinere Fragen habe, mich bei dir direkt per Mail melden?

                      Ja.
                      Kannst es aber auch hier im Forum probieren, wenn Du moechtest.

                      so short

                      Christoph Zurnieden

  4. Ich möchte gerne eine Funktion haben, die mir den n-ten Tag des Jahres ermittelt, also in Nichtschaltjahren soll die Funktion mir am 1. Januar die Zahl 0 auswerfen und am 31. Dezember die Zahl 364, in Schaltjahren 365.

    Andreas,
    Laut ISO 8601 fängt die Zählung bei 1 an:
    2006-01-01 = 2006-001
    2006-12-31 = 2006-365
    2008-12-31 = 2008-366

    Live long and prosper,
    Gunnar

    --
    „Weisheit ist nicht das Ergebnis der Schulbildung, sondern des lebenslangen Versuchs, sie zu erwerben.“ (Albert Einstein)
    1. Hallo,

      Laut ISO 8601 fängt die Zählung bei 1 an:
      2006-01-01 = 2006-001
      2006-12-31 = 2006-365
      2008-12-31 = 2008-366

      das mag wohl stimmen - aber auch mir ist eine null-basierte Zählung i.a. sympathischer. Und meistens auch praktischer.
      Außerdem weißt du ja nicht, wozu der OP seine Tages-Indizierung braucht. Offensichtlich passt ihm die null-basierte Zählung auch besser in den Kram.

      Schönen Tag noch,

      Martin

      --
      Faulheit ist, mit dem Cocktailshaker in der hand auf das nächste Erdbeben zu warten.
      1. Laut ISO 8601 fängt die Zählung bei 1 an:

        das mag wohl stimmen - aber auch mir ist eine null-basierte Zählung i.a. sympathischer. Und meistens auch praktischer.

        Martin,
        Ich finde absolut nichts Praktisches daran, dass in JavaScript die Zählung der Monate von 0 (Januar) bis 11 (Dezember) geht. Im Gegenteil, ich halte das für horrenden Schwachsinn. Der das mal implementiert hat sollte zu fünf Jahren Aufenthalt in der realen Welt verdonnert werden.

        Wenn es schon eine übliche bei 1 beginnende Zählung gibt, sollte sie sich auch in Implementierungen niederschlagen. Gibt es keine solche, kann man je nach Sympathie auch bei 0 anfangen.

        Live long and prosper,
        Gunnar

        --
        „Weisheit ist nicht das Ergebnis der Schulbildung, sondern des lebenslangen Versuchs, sie zu erwerben.“ (Albert Einstein)
        1. Hallo,

          Ich finde absolut nichts Praktisches daran, dass in JavaScript die Zählung der Monate von 0 (Januar) bis 11 (Dezember) geht. Im Gegenteil, ich halte das für horrenden Schwachsinn. Der das mal implementiert hat sollte zu fünf Jahren Aufenthalt in der realen Welt verdonnert werden.

          Das ist durchaus praktisch, denn eine typische Anwendung ist das Zuweisen eines Monatsnamens zum ermittelten Index und die Namen schreibt man ja gern in ein Array und somit korrespondieren Monats- und Array-Index direkt.

          Bei den Wochentagen ist das ganz aehnlich, dort ist 0 --> Sonntag.

          MfG, Thomas

          1. Das ist durchaus praktisch, denn eine typische Anwendung ist das Zuweisen eines Monatsnamens zum ermittelten Index und die Namen schreibt man ja gern in ein Array und somit korrespondieren Monats- und Array-Index direkt.

            Thomas,
            Mir wär’s lieber, die Monate hätten dieselbe Numerierung wie sie auch im Kalender steht.

            Monatsname = new Array("", "Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"); wo ist das Problem?

            Live long and prosper,
            Gunnar

            --
            „Weisheit ist nicht das Ergebnis der Schulbildung, sondern des lebenslangen Versuchs, sie zu erwerben.“ (Albert Einstein)
            1. Hallo,

              Mir wär’s lieber, die Monate hätten dieselbe Numerierung wie sie auch im Kalender steht.

              Monatsname = new Array("", "Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember");
              

              wo ist das Problem?

              Das Problem liegt offenbar bei Dir. Ein zwanghaft leeres Arrayelement wuerde es doch auch nicht einfacher -- sprich konsistenter -- machen.

              MfG, Thomas

          2. Moin,

            Bei den Wochentagen ist das ganz aehnlich, dort ist 0 --> Sonntag.

            Fängt die Woche nicht am Montag an?

            Viele Grüße

            Swen Wacker

            1. Hi,

              Bei den Wochentagen ist das ganz aehnlich, dort ist 0 --> Sonntag.
              Fängt die Woche nicht am Montag an?

              Erst seit ein paar Jahr[zehnt]en: 1976 wurde die DIN 1355 geändert, so daß nicht mehr der Sonntag, sondern jetzt der Montag der erste Tag der Woche ist.

              cu,
              Andreas

              --
              Warum nennt sich Andreas hier MudGuard?
              Schreinerei Waechter
              Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
            2. Hallo,

              Bei den Wochentagen ist das ganz aehnlich, dort ist 0 --> Sonntag.

              Fängt die Woche nicht am Montag an?

              Aehnlich (naja nicht ganz ;-) war im Sinne von 0-6 statt 0-11 gemeint, mit der Besonderheit, dass dem Index 0 der Sonntag zugeordnet ist.

              MfG, Thomas

            3. Fängt die Woche nicht am Montag an?

              Swen,
              AFAIK in US-amerikanischen Kalendern nicht.

              Gemäß ISO 8601 allerdings: Montag ist 1, Sonntag ist 7.
              Heute ist 2005-W48-1 (Montag der 48. Kalenderwoche).

              Live long and prosper,
              Gunnar

              --
              „Weisheit ist nicht das Ergebnis der Schulbildung, sondern des lebenslangen Versuchs, sie zu erwerben.“ (Albert Einstein)
        2. 你好 Gunnar,

          Ich finde absolut nichts Praktisches daran, dass in JavaScript die
          Zählung der Monate von 0 (Januar) bis 11 (Dezember) geht.

          Ich schon – das Praktische daran hat Thomas ja bereits erwähnt ;)

          Im Gegenteil, ich halte das für horrenden Schwachsinn. Der das mal
          implementiert hat sollte zu fünf Jahren Aufenthalt in der realen Welt
          verdonnert werden.

          Dann musst du bei der Open Group
          anfangen – die POSIX-Version der Datums-Funktionen machen es nämlich genau
          so, und so ist es auch im Standard definiert ;)

          Vermutlich wirst du sogar noch weiter zurückgehen müssen, auf die ersten
          Implementationen von UNIX, also Ken Thompson und Dennis Ritchie ;)

          再见,
           克里斯蒂安