On Fri, Jul 13, 2012 at 10:51 AM, Camillo Bruni <camillobr...@gmail.com>wrote:
> Cool thanks everyone for the references :D > > We will pu that into the sources > > On 2012-07-13, at 19:47, Nicolas Cellier wrote: > > > The first numbers are quite easy to guess without reading any reference : > > if you have a major in astronomy, sure :P > > > - 400 years span 146097 days in gregorian calendar. > > - 100 years span 36524 days, except every 400 years. > > - 4 years span 1461 days, except every 100 years. > > - 1 year span 365 days, except every four years > > well indeed, not that hard :P, but when you're in midst of a mind-boggling > refactoring > you don't waste time to understand these details :P > :) Here's an analogous method in VisualWorks. They don't bother to document seconds per day (86400). TimeZone>>timestampToSeconds: aTimestamp " Convert a Timestamp in to seconds starting from the Smalltalk epoch in UTC. Since we do not know leap-seconds in UTC, Answer the number of seconds since January 1, 1901. Same as 'self asDate asSeconds + self asTime asSeconds' " | yearIndex absDays seconds | yearIndex := aTimestamp year - 1901. absDays := yearIndex * 365 "elapsed years" + (yearIndex // 4) "ordinary leap years" + ((yearIndex + 300) // 400) "leap centuries, first one is 2000, i.e. yearIndex = 99" - (yearIndex // 100) "non-leap centuries" + aTimestamp day - 1 + (aTimestamp firstDayOf: aTimestamp month). seconds := aTimestamp hour * 60 + aTimestamp minute * 60 + aTimestamp second. "do it this way to minimize large arithmetic" ^absDays * 86400 + seconds But I like "Same as 'self asDate asSeconds + self asTime asSeconds'" since Date>asSeconds "Answer the seconds between the time that 1901 began and the same time in the receiver's day." ^self asTimestamp asSeconds and Timestamp>asSeconds "Answer the number of seconds since January 1, 1901." "Same as 'self asDate asSeconds + self asTime asSeconds'" ^TimeZone default timestampToSeconds: self So the documentation still leaves something to be desired :) It is perhaps unfortunate that manifest constants in class variables cost more than literals because of the indirection through the association. I did an inlining scheme in VisualWorks many years ago that depended on automatic recompilation when read-only bindings were changed (since the scope of these bindings is limited its quick to find affected methods). It depended on the method including the binding in its literals even though the compiler inlined the value of the binding, and it depended on access to source (since the points where the variable is inlined are not marked in the bytecode). I still think there's benefit here; even a JIT needs to know what bindings are read-only and a write-barrier to be able to inline the values of globals. But it has a lot of impact for not very much performance (given that in performance-critical parts of the system people have already inlined by hand, as in the above). So I suppose it will remain a fun experiment. > For months and days, the tricks are less trivial... > > > > Nicolas > > > > > > 2012/7/13 Sven Van Caekenberghe <s...@beta9.be>: > >> Yeah, but sometimes a clever algorithm comes from a book, so to speak. > >> > >> Giving the variables long names, or the constants names, would not make > that much difference, it would still be pretty hard to understand. > >> > >> ZTimestamp class>>withJdn: jdn dayMonthYearDo: block > >> "Return the value of executing block with the Gregorian Calender > day, month and year as arguments, > >> as computed from my Julian Day Number, jdn. > >> See > http://en.wikipedia.org/wiki/Julian_date#Gregorian_calendar_from_Julian_day_number > " > >> > >> | j g dg c dc b db a da y m d | > >> j := jdn + 32044. > >> g := j // 146097. > >> dg := j \\ 146097. > >> c := ((dg // 36524) + 1) * 3 // 4. > >> dc := dg - (c * 36524). > >> b := dc // 1461. > >> db := dc \\ 1461. > >> a := ((db // 365) + 1) * 3 // 4. > >> da := db - (a * 365). > >> y := (g * 400) + (c * 100) + (b * 4) + a. > >> m := ((((da * 5) + 308)) // 153) - 2. > >> d := da - ((m + 4) * 153 // 5) + 122. > >> ^ block > >> value: d + 1 > >> value: ((m + 2) \\ 12) + 1 > >> value: (y - 4800 + ((m * 2) // 12)) > >> > >> On 13 Jul 2012, at 17:53, Camillo Bruni wrote: > >> > >>> comments? decent variable names? no magic numbers? > >>> NOW you can find NONE of that in dayMonthYearDo! > >>> > >>> > >>> ================================================================== > >>> dayMonthYearDo: aBlock > >>> "Evaluation the block with three arguments: day month, year." > >>> > >>> | l n i j dd mm yyyy | > >>> l := jdn + 68569. > >>> n := 4 * l // 146097. > >>> l := l - (146097 * n + 3 // 4). > >>> i := 4000 * (l + 1) // 1461001. > >>> l := l - (1461 * i // 4) + 31. > >>> j := 80 * l // 2447. > >>> dd := l - (2447 * j // 80). > >>> l := j // 11. > >>> mm := j + 2 - (12 * l). > >>> yyyy := 100 * (n - 49) + i + l. > >>> > >>> ^ aBlock > >>> value: dd > >>> value: mm > >>> value: yyyy. > >>> > >>> ================================================================== > >>> > >>> so can anyone explain me the magic numbers here?? > >>> > >> > >> > > > > > -- best, Eliot