469,270 Members | 1,037 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,270 developers. It's quick & easy.

firefox global variables woes

Hi,
I hope someone can point out my error because I'm starting to lose my
hair over this. It's probably a very straigh forward error but after
only 4 hours sleep it's doing my head in. It's to do with global
variables in Firefox 1.

The following code works no problems and generates a whole bunch of
numbers

<script type="text/javascript">
function createCal(){
var dateObj = new Date();
for(var i=0;i<32;i++){
date = dateObj.getDate();

set_date = dateObj.setDate(i);
document.write(date);

}

}
</script>

but when I try to place the dateObj variable outside the function (with
or without the preceding "var") it tells me dateObj is not defined.
Aren't variables declared outside of a function supposed to be global?
It all works fine in IE 5 btw

<script type="text/javascript">

var dateObj = new Date();
function createCal(){

for(var i=0;i<32;i++){
date = dateObj.getDate();

set_date = dateObj.setDate(i);
document.write(date);

}

}
</script>

Interestingly when I replace the document.write() with an alert
everything works as it should.

Thanks

barabis

Jul 23 '05 #1
22 5180
Lee
in************@gmail.com said:
but when I try to place the dateObj variable outside the function (with
or without the preceding "var") it tells me dateObj is not defined.
Aren't variables declared outside of a function supposed to be global?
It all works fine in IE 5 btw

<script type="text/javascript">

var dateObj = new Date();
function createCal(){

for(var i=0;i<32;i++){
date = dateObj.getDate();

set_date = dateObj.setDate(i);
document.write(date);

}

}
</script>

Interestingly when I replace the document.write() with an alert
everything works as it should.


It's a matter of how/when your function createCal() is being called.
If it's called after the page has been rendered, the first invocation
of document.write() clears the current page, destroying your global
variables.

Jul 23 '05 #2
It's funny that it doesnt affect IE. No wonder a lot of the dhtml calendars
don't work in firefox tho.
"Lee" <RE**************@cox.net> wrote in message
news:cu*********@drn.newsguy.com...
in************@gmail.com said:
but when I try to place the dateObj variable outside the function (with
or without the preceding "var") it tells me dateObj is not defined.
Aren't variables declared outside of a function supposed to be global?
It all works fine in IE 5 btw

<script type="text/javascript">

var dateObj = new Date();
function createCal(){

for(var i=0;i<32;i++){
date = dateObj.getDate();

set_date = dateObj.setDate(i);
document.write(date);

}

}
</script>

Interestingly when I replace the document.write() with an alert
everything works as it should.


It's a matter of how/when your function createCal() is being called.
If it's called after the page has been rendered, the first invocation
of document.write() clears the current page, destroying your global
variables.

Jul 23 '05 #3
in************@gmail.com wrote:
Hi,
I hope someone can point out my error because I'm starting to lose my
hair over this. It's probably a very straigh forward error but after
only 4 hours sleep it's doing my head in. It's to do with global
variables in Firefox 1.


No, it's what Lee said.

Manipulating strings is a lot faster than date objects. Have a
look at the code below, it generates dates for any month given a
year and month. It times methods using date objects and plain
string methods. On my ancient laptop, the date object method
consistently took 60 to 70ms, the string method took around 10ms.

I got the idea to try this from Dr. J's site where he compares
methods of validating user-entered date strings:

<URL:http://www.merlyn.demon.co.uk/js-date4.htm#TDVal>

Whilst the code is somewhat longer, the overall effect is a
3-fold increase in speed.
<script type="text/javascript">
function createCal0(sMonth){

var o = document.getElementById('writeSpan');
var m = sMonth.split(/\D+/);
m[1]--; // Adjust month number
var dateObj = new Date(m[0],m[1]);
var t; // Only used 'cos appendChild line was too long

while (m[1] == dateObj.getMonth()){
t = addZ(dateObj.getDate());
o.appendChild(document.createTextNode(t + ','));
dateObj.setDate(dateObj.getDate()+1)
}
}

function createCal1(sMonth){
var o = document.getElementById('writeSpan');
var m = sMonth.split(/\D+/);
var limit;
var ds = [];
if ( m[1]==4 || m[1]==6 || m[1]==9 || m[1]==10) {
limit = 30;
} else if (m[1]==1 || m[1]==3 || m[1]==5
|| m[1]==7 || m[1]==8 || m[1]==10 || m[1]==12){
limit = 31;
} else {
limit = 28;
if ( m[0]%4 == 0 ) limit = 29;
if ( m[0]%100 == 0 ) limit = 28;
if ( m[0]%400 == 0 ) limit = 29;
}
for (var i=1; i<=limit; i++) {
ds.push(addZ(i));
}
o.innerHTML = ds.join(',');
}

function addZ(x){
return (x<10)?'0'+x:x;
}
</script>
<form>
<input name="ym" value="2005-02">Enter a year
and month (yyyy-mm)<br>
<button onclick="
var s = new Date();
createCal0(this.form.ym.value);
var f = new Date();
var t = f - s;
alert('That took ' + t + ' ms');
return false;
">write dates 0</button>
<br>
<button onclick="
var s = new Date();
createCal1(this.form.ym.value);
var f = new Date()
var t = f - s;
alert('That took ' + t + ' ms');
return false;
">write dates 1</button>
<br>
</form>
<span id="writeSpan"></span>
--
Rob
Jul 23 '05 #4
Lee
barabis said:

It's funny that it doesnt affect IE. No wonder a lot of the dhtml calendars
don't work in firefox tho.


Yes. There is a lot of bad code out there.

Jul 23 '05 #5
JRS: In article <420a2052$0$10200$5a62ac22@per-qv1-newsreader-
01.iinet.net.au>, dated Thu, 10 Feb 2005 00:33:22, seen in
news:comp.lang.javascript, RobG <rg***@iinet.net.auau> posted :

function createCal1(sMonth){
var o = document.getElementById('writeSpan');
var m = sMonth.split(/\D+/);
var limit;
var ds = [];
if ( m[1]==4 || m[1]==6 || m[1]==9 || m[1]==10) {
limit = 30;
} else if (m[1]==1 || m[1]==3 || m[1]==5
|| m[1]==7 || m[1]==8 || m[1]==10 || m[1]==12){
limit = 31;
} else {
limit = 28;
if ( m[0]%4 == 0 ) limit = 29;
if ( m[0]%100 == 0 ) limit = 28;
if ( m[0]%400 == 0 ) limit = 29;
}
for (var i=1; i<=limit; i++) {
ds.push(addZ(i));
}
o.innerHTML = ds.join(',');
}

Probably quicker to declare var limit=31 and then overwrite it if
(Apr Jun Sep Nov) / Feb ; avoids 7 tests.

You have half-transferred a day from Oct to Nov - that is an Emperor-of-
Rome grade decision!

I'd try changing to M = m[1] ; ... if (M==4 || M==6 || ... to reduce
indexing.

To avoid all that pushing and joining, you could try a substring
operation on "01,02,03,04, ... ,31". Or start ds="01,02, ... ,28" .

Your Leap Year test tries all three divisors every time, which is
readily avoidable.

The month lengths can be computed, except for Feb, by adapting Zeller's
Congruence <URL:http://www.merlyn.demon.co.uk/zeller-c.htm>; or, for
Martin Honnen &c., <URL:http://www.merlyn.demon.co.uk/zel-86px.htm>.

Or global var ML = [31,0,31,30, ...,31]
and limit = ML[m[1]] ; if (!limit) limit = <28 or 29>.

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 MIME.
Web <URL:http://www.merlyn.demon.co.uk/> - w. FAQish topics, links, acronyms
PAS EXE etc : <URL:http://www.merlyn.demon.co.uk/programs/> - see 00index.htm
Dates - miscdate.htm moredate.htm js-dates.htm pas-time.htm critdate.htm etc.
Jul 23 '05 #6
Dr John Stockton wrote:
JRS: In article <420a2052$0$10200$5a62ac22@per-qv1-newsreader-
01.iinet.net.au>, dated Thu, 10 Feb 2005 00:33:22, seen in
news:comp.lang.javascript, RobG <rg***@iinet.net.auau> posted :
function createCal1(sMonth){
var o = document.getElementById('writeSpan');
var m = sMonth.split(/\D+/);
var limit;
var ds = [];
if ( m[1]==4 || m[1]==6 || m[1]==9 || m[1]==10) {
limit = 30;
} else if (m[1]==1 || m[1]==3 || m[1]==5
|| m[1]==7 || m[1]==8 || m[1]==10 || m[1]==12){
limit = 31;
} else {
limit = 28;
if ( m[0]%4 == 0 ) limit = 29;
if ( m[0]%100 == 0 ) limit = 28;
if ( m[0]%400 == 0 ) limit = 29;
}
for (var i=1; i<=limit; i++) {
ds.push(addZ(i));
}
o.innerHTML = ds.join(',');
}


Probably quicker to declare var limit=31 and then overwrite it if
(Apr Jun Sep Nov) / Feb ; avoids 7 tests.

You have half-transferred a day from Oct to Nov - that is an Emperor-of-
Rome grade decision!

I'd try changing to M = m[1] ; ... if (M==4 || M==6 || ... to reduce
indexing.

To avoid all that pushing and joining, you could try a substring
operation on "01,02,03,04, ... ,31". Or start ds="01,02, ... ,28" .

Your Leap Year test tries all three divisors every time, which is
readily avoidable.

The month lengths can be computed, except for Feb, by adapting Zeller's
Congruence <URL:http://www.merlyn.demon.co.uk/zeller-c.htm>; or, for
Martin Honnen &c., <URL:http://www.merlyn.demon.co.uk/zel-86px.htm>.

Or global var ML = [31,0,31,30, ...,31]
and limit = ML[m[1]] ; if (!limit) limit = <28 or 29>.


Great, thanks for the tips.

Given that Zeller's Congruence twisted my brain somewhat and
code should be maintainable (I'm not sure anyone reading that
stuff as code would understand it) and that the following
consistently ran in less than 15ms on page load and 0ms after
that, further optimisation is gilding the lilly.

I've used push to "top up" the days of the month rather than
create separate arrays for 28, 29, 30 & 31 day months.

It's noted however that Zeller's stuff for day-of-week looks
pretty handy.

function createCal1(sMonth){
var o = document.getElementById('writeSpan');
var m = sMonth.split(/\D+/);
var Y = m[0];
var M = m[1];
var limit = 31;
var MD = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,
18,19,20,21,22,23,24,25,26,27,28];

if ( M==4 || M==6 || M==9 || M==10) {
MD.push(29,30);
} else if (M == 2){
if ((Y%4==0 && Y%100!=0) || (Y%4==0 && Y%400==0)) {
MD.push(29);
}
} else {
MD.push(29,30,31);
}
o.innerHTML = MD.join(' ');
}


--
Rob
Jul 23 '05 #7
JRS: In article <ZA*****************@news.optus.net.au>, dated Thu, 10
Feb 2005 06:56:57, seen in news:comp.lang.javascript, RobG
<rg***@iinet.net.auau> posted :
Dr John Stockton wrote:
The month lengths can be computed, except for Feb, by adapting Zeller's
Congruence <URL:http://www.merlyn.demon.co.uk/zeller-c.htm>; or, for
Martin Honnen &c., <URL:http://www.merlyn.demon.co.uk/zel-86px.htm>.

Given that Zeller's Congruence twisted my brain somewhat and
code should be maintainable (I'm not sure anyone reading that
stuff as code would understand it) and that the following
consistently ran in less than 15ms on page load and 0ms after
that, further optimisation is gilding the lilly.
But the exercise helps develop skills.
I've used push to "top up" the days of the month rather than
create separate arrays for 28, 29, 30 & 31 day months.

It's noted however that Zeller's stuff for day-of-week looks
pretty handy.
I have empirically found the following way of calculating the lengths of
the months, except February; January must be entered as 13 :-

function GMLen() { var A = [], m
for (m=3; m<14; m++) A[m] = 30 + ((3*m+1)%5 < 3)
document.write(A) }

,,,31,30,31,30,31,31,30,31,30,31,31

Can it be improved?

It's worth remembering that wherever one has a sequence of integers that
maintains a non-integer average, something Zellerish can compute the
integers and/or their sum; and, the regrettable Augustan intervention
notwithstanding, the month-lengths Mar..Jan more or less do so.
else if (M == 2){
if ((Y%4==0 && Y%100!=0) || (Y%4==0 && Y%400==0)) {
MD.push(29);
}
}

else if (M == 2 && Y%4==0) {
if (Y%100!=0 || Y%400==0) {
MD.push(29);
}
} // <G>

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 MIME.
Web <URL:http://www.merlyn.demon.co.uk/> - w. FAQish topics, links, acronyms
PAS EXE etc : <URL:http://www.merlyn.demon.co.uk/programs/> - see 00index.htm
Dates - miscdate.htm moredate.htm js-dates.htm pas-time.htm critdate.htm etc.
Jul 23 '05 #8
rh
Dr John Stockton wrote:
JRS: In article <ZA*****************@news.optus.net.au>, dated Thu, 10 Feb 2005 06:56:57, seen in news:comp.lang.javascript, RobG
<rg***@iinet.net.auau> posted :
Dr John Stockton wrote:

<...>
I have empirically found the following way of calculating the lengths of the months, except February; January must be entered as 13 :-

function GMLen() { var A = [], m
for (m=3; m<14; m++) A[m] = 30 + ((3*m+1)%5 < 3)
document.write(A) }

,,,31,30,31,30,31,31,30,31,30,31,31

Can it be improved?


Excluding February:

function GMLen2() { var A = [], m
for (var m=1; m<13; m++) A[m] = 30 | (m>>3^m);
document.write("<P>"+A) }

(with improvement by Richard Cornford).

Including February:

function GMLen3() { var A = [], m, y=2005
for (var m=1; m<13; m++) A[m] = 29 + (m>>3^m&1)
+ (m != 2 || -(y&3 || y&15 && !(y%25)));
document.write("<P>"+A) }

Leap year calculation courtesy of JRS/Gabor in this group.

Regards,

.../rh

Jul 23 '05 #9
rh wrote:

[snip]

Including February:

function GMLen3() { var A = [], m, y=2005
for (var m=1; m<13; m++) A[m] = 29 + (m>>3^m&1)
+ (m != 2 || -(y&3 || y&15 && !(y%25)));
document.write("<P>"+A) }

Leap year calculation courtesy of JRS/Gabor in this group.

Why not hard code it?
function GMLen(m,yyyy){//m 0-11
return [31,yy%4==0?new
Date(yyyy,m+1,0).getDate():28,31,30,31,30,31,31,30 ,31,30,31][m]
}

Mick
Jul 23 '05 #10
rh
Mick White wrote:
rh wrote:

[snip]

Including February:

function GMLen3() { var A = [], m, y=2005
for (var m=1; m<13; m++) A[m] = 29 + (m>>3^m&1)
+ (m != 2 || -(y&3 || y&15 && !(y%25))); document.write("<P>"+A) }

Leap year calculation courtesy of JRS/Gabor in this group.

Why not hard code it?
function GMLen(m,yyyy){//m 0-11
return [31,yy%4==0?new
Date(yyyy,m+1,0).getDate():28,31,30,31,30,31,31,30 ,31,30,31][m]
}


First of all, what you've presented doesn't fit my definition of "hard
code". Secondly, it wouldn't appear to have been tested. And thirdly,
it doesn't account for leap years properly.

Implementation approaches are usually chosen based on taking into
account correctness, simplicity and efficiency. Often trade-offs in the
latter two are weighed in making a decision.

This is a case where efficiency happened to be predominant in the
choice, particularly given the context in which the response was made.

Moreover, it was coded to parallel the example given by JRS. Obviously
it would be structured differently if the intent was to produce a date
utilility.

Regards,

../rh

Jul 23 '05 #11
rh wrote:
Mick White wrote:
rh wrote:

[snip]
Including February:

function GMLen3() { var A = [], m, y=2005
for (var m=1; m<13; m++) A[m] = 29 + (m>>3^m&1)
+ (m != 2 || -(y&3 || y&15 &&
!(y%25)));
document.write("<P>"+A) }

Leap year calculation courtesy of JRS/Gabor in this group.
Why not hard code it?
function GMLen(m,yyyy){//m 0-11
return [31,yy%4==0?new
Date(yyyy,m+1,0).getDate():28,31,30,31,30,31,31, 30,31,30,31][m]
}

First of all, what you've presented doesn't fit my definition of "hard
code". Secondly, it wouldn't appear to have been tested. And thirdly,
it doesn't account for leap years properly.


oops, typo:
function GMLen(m,yyyy){//m 0-11
return [31,yyyy%4==0?new
Date(yyyy,m+1,0).getDate():28,31,30,31,30,31,31,30 ,31,30,31][m]
}

Implementation approaches are usually chosen based on taking into
account correctness, simplicity and efficiency. Often trade-offs in the
latter two are weighed in making a decision.

This is a case where efficiency happened to be predominant in the
choice, particularly given the context in which the response was made.

Moreover, it was coded to parallel the example given by JRS. Obviously
it would be structured differently if the intent was to produce a date
utilility.


You're right, but you come off sounding a little pompous. My point is
that we need only to calculate February length since it is the only
month whose length varies, in that sense 11/12 may be hard coded.
Semantics.
Mick

Jul 23 '05 #12
rh
Mick White wrote:
rh wrote:
Mick White wrote:

<...>
You're right, but you come off sounding a little pompous. My point is that we need only to calculate February length since it is the only
month whose length varies, in that sense 11/12 may be hard coded.
Semantics.


Quite right, a more patient response would have been appropriate -- you
have my apology.

Regards,

../rh

Jul 23 '05 #13
rh wrote:
[snip]
need only to calculate February length since it is the only
month whose length varies, in that sense 11/12 may be hard coded.
Semantics.

Quite right, a more patient response would have been appropriate -- you
have my apology.


No problem
y=2004
feblen=[28,29][+(new Date(y,1,29).getMonth()==1)]

Inspiration from Dr. JS (How appropriate)
Mick
Jul 23 '05 #14
rh
Mick White wrote:
rh wrote:
[snip]
need only to calculate February length since it is the only
month whose length varies, in that sense 11/12 may be hard coded.
Semantics.

Quite right, a more patient response would have been appropriate -- you have my apology.


No problem
y=2004
feblen=[28,29][+(new Date(y,1,29).getMonth()==1)]


<...>

Which is a fine example of how to get the most out of the built-in Date
function, but doesn't really pertain the earlier question posed by JRS
in this thread. Nor, necessarily did my response, as he may have been
looking for the possibility an algorithmic improvement, or a range
improvement, or both, to the example he provided.

Nonetheless, here's yet another predominantly bitwise-operation/logic
approach for m = 0..11, February included:

daysInMo = 28 | ( m^1 && ++m>>3^m|2 || !(y&3 || y&15 && !(y%25)) );

../rh

Jul 23 '05 #15
JRS: In article <11**********************@o13g2000cwo.googlegroups .com>
, dated Thu, 10 Feb 2005 13:38:29, seen in news:comp.lang.javascript, rh
<co********@yahoo.ca> posted :
Mick White wrote:
Why not hard code it?
function GMLen(m,yyyy){//m 0-11
return [31,yy%4==0?new
Date(yyyy,m+1,0).getDate():28,31,30,31,30,31,31,30 ,31,30,31][m]
}

First of all, what you've presented doesn't fit my definition of "hard
code". Secondly, it wouldn't appear to have been tested. And thirdly,
it doesn't account for leap years properly.
It has a couple of missing 'y's; but, with that fixed, it handles
Gregorian leap year properly AFAICS.

This is a case where efficiency happened to be predominant in the
choice, particularly given the context in which the response was made.


ISTM that the above constructs a whole 12-element array whenever called,
including the calculation of an element not wanted 11 times out of 12.

In expression yyyy%4==0?new Date(yyyy,m+1,0).getDate():28 the %4 does
optimise 3 out of 4 years; but

Y%4 != 0 ? 28 : Y%100 !=0 ? 29 : Y%400 != 0 ? 28 : 29

seems easy enough and must be cheaper than a Date Object.
For aesthetic but presumably inefficient expressions,

28 + (y%4==0) ^ (y%100==0) ^ (y%400==0)
or 28 + (!(y%4)) ^ (!(y%100)) ^ (!(y%400))
or 28 | !(y%4)^!(y%100)^!(y%400)
But I was asking whether = 30 + ((3*m+1)%5 < 3) could be improved,
not whether any better routines existed; in other words, I was after
something generating the lengths arithmetically, as Zeller would.

That = 30 | (m>>3^m) is indeed good, covering 1,3-12 as it does.

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 MIME.
Web <URL:http://www.merlyn.demon.co.uk/> - w. FAQish topics, links, acronyms
PAS EXE etc : <URL:http://www.merlyn.demon.co.uk/programs/> - see 00index.htm
Dates - miscdate.htm moredate.htm js-dates.htm pas-time.htm critdate.htm etc.
Jul 23 '05 #16
JRS: In article <k_************@twister.nyroc.rr.com>, dated Fri, 11
Feb 2005 20:56:48, seen in news:comp.lang.javascript, Mick White
<mw***********@rochester.rr.com> posted :
rh wrote:
[snip]
need only to calculate February length since it is the only
month whose length varies, in that sense 11/12 may be hard coded.
Semantics.

Quite right, a more patient response would have been appropriate -- you
have my apology.


No problem
y=2004
feblen=[28,29][+(new Date(y,1,29).getMonth()==1)]


feblen = new Date(y, 2, 0).getDate()

should beat that; moreover, it works for all values of 2.

It might not work in NS4, in which case

feblen = new Date(y, m+1, 1, -9).getDate()

could be better.

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 MIME.
Web <URL:http://www.merlyn.demon.co.uk/> - FAQqish topics, acronyms & links;
some Astro stuff via astro.htm, gravity0.htm ; quotings.htm, pascal.htm, etc.
No Encoding. Quotes before replies. Snip well. Write clearly. Don't Mail News.
Jul 23 '05 #17
JRS: In article <11**********************@g14g2000cwa.googlegroups .com>
, dated Thu, 10 Feb 2005 11:26:50, seen in news:comp.lang.javascript, rh
<co********@yahoo.ca> posted :

function GMLen3() { var A = [], m, y=2005
for (var m=1; m<13; m++) A[m] = 29 + (m>>3^m&1)
+ (m != 2 || -(y&3 || y&15 && !(y%25)));
document.write("<P>"+A) }


Gives 27 for Feb 2006.

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 MIME.
Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
Proper <= 4-line sig. separator as above, a line exactly "-- " (SonOfRFC1036)
Do not Mail News to me. Before a reply, quote with ">" or "> " (SonOfRFC1036)
Jul 23 '05 #18
rh
Dr John Stockton wrote:
JRS: In article <11**********************@g14g2000cwa.googlegroups .com> , dated Thu, 10 Feb 2005 11:26:50, seen in news:comp.lang.javascript, rh <co********@yahoo.ca> posted :

function GMLen3() { var A = [], m, y=2005
for (var m=1; m<13; m++) A[m] = 29 + (m>>3^m&1)
+ (m != 2 || -(y&3 || y&15 && !(y%25)));
document.write("<P>"+A) }


Gives 27 for Feb 2006.


And so it does. It appears that the coercion to Boolean got dropped
when introducing the subtraction. The continued line would better read:

+ (m != 2 || -!!(y&3 || y&15 && !(y%25)));

However, the expression I prefer is the subsequent, with range m=
0...11:

daysInMo = 28 | ( m^1 && ++m>>3^m|2 || !(y&3 || y&15 && !(y%25)) );

or for range m= 1...12:

daysInMo = 28 | ( m^2 && m>>3^m|2 || !(y&3 || y&15 && !(y%25)) );

which is leaves the % as the single dependence on direct arithimetic
operation.

By the way, you may also recall that Lasse provided a concise
expression that used a shift and mask in a pre-coded integer to
effectively do the lookup for the tail-length of non-February months.

<url:http://groups-beta.google.com/group/comp.lang.javascript/browse_frm/thread/ce9c9637ac5e2034/9f4c440664c393ff>

Regards,

../rh

Jul 23 '05 #19
JRS: In article <11*********************@f14g2000cwb.googlegroups. com>,
dated Sat, 12 Feb 2005 18:06:26, seen in news:comp.lang.javascript, rh
<co********@yahoo.ca> posted :
However, the expression I prefer is the subsequent, with range m=
0...11:

daysInMo = 28 | ( m^1 && ++m>>3^m|2 || !(y&3 || y&15 && !(y%25)) );

or for range m= 1...12:

daysInMo = 28 | ( m^2 && m>>3^m|2 || !(y&3 || y&15 && !(y%25)) );

which is leaves the % as the single dependence on direct arithimetic
operation.

It would be more readable, and might be better, to work along the lines
of (/* ++ */ implies conversion of range 1..12 to 0..11)

daysInMo = /* ++ */ m==2 ? expression(y) : expression(m)

++m==2 ? 28 + !(y&3 || y&15 && !(y%25)) : 28 | m>>3^m|2 }
or 28 | ( ++m==2 ? !(y&3 || y&15 && !(y%25)) : m>>3^m|2 ) }

which seem slightly faster than

28 | ( m^1 && ++m>>3^m|2 || !(y&3 || y&15 && !(y%25)) )

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 MIME.
Web <URL:http://www.merlyn.demon.co.uk/> - w. FAQish topics, links, acronyms
PAS EXE etc : <URL:http://www.merlyn.demon.co.uk/programs/> - see 00index.htm
Dates - miscdate.htm moredate.htm js-dates.htm pas-time.htm critdate.htm etc.
Jul 23 '05 #20
rh
Dr John Stockton wrote:
JRS: In article <11*********************@f14g2000cwb.googlegroups. com>, dated Sat, 12 Feb 2005 18:06:26, seen in news:comp.lang.javascript, rh <co********@yahoo.ca> posted :
However, the expression I prefer is the subsequent, with range m=
0...11:

daysInMo = 28 | ( m^1 && ++m>>3^m|2 || !(y&3 || y&15 && !(y%25)) );

or for range m= 1...12:

daysInMo = 28 | ( m^2 && m>>3^m|2 || !(y&3 || y&15 && !(y%25)) );

which is leaves the % as the single dependence on direct arithimetic
operation.

It would be more readable, and might be better, to work along the

lines of (/* ++ */ implies conversion of range 1..12 to 0..11)

daysInMo = /* ++ */ m==2 ? expression(y) : expression(m)

++m==2 ? 28 + !(y&3 || y&15 && !(y%25)) : 28 | m>>3^m|2 }
or 28 | ( ++m==2 ? !(y&3 || y&15 && !(y%25)) : m>>3^m|2 ) }

which seem slightly faster than

28 | ( m^1 && ++m>>3^m|2 || !(y&3 || y&15 && !(y%25)) )


Right, but if utmost speed is the predominant criteria, then Lasse's
method is really the one of choice.

Also, in terms of speed of the above, I believe I can provide another
incarnation which brings a similar marginal speed advantage over the
tertiary form, and provides a clearer separation of the Feb
calculation.

But it all depends on what the goal is. Mine, in this case, happened to
be to achieve a succinct, efficient computation by taking an
interesting departure from the usual arithmetical approach in producing
a result. And I think it's good that some may wonder how that somewhat
obscure expression can possibly provide the correct result. Those
wishing to find out, aren't going to get much of a leg up with it
converted to tertiary form, which necessarily removes some of the
intentional bit mangling shortcut logic.

Your criteria may, and quite likely will, differ.

../rh

Jul 23 '05 #21
JRS: In article <11**********************@c13g2000cwb.googlegroups .com>
, dated Sun, 13 Feb 2005 20:36:50, seen in news:comp.lang.javascript, rh
<co********@yahoo.ca> posted :

Right, but if utmost speed is the predominant criteria, then Lasse's
method is really the one of choice.
I've lost track of that one; is it the one using something like

(0xeefbb3>>(2*m))&3

for the lengths of the non-Feb months?

My present implementation of that seems of similar speed to the best of
the others; but my simple testing is better on the slower routines of a
set than on the faster ones.

Also, in terms of speed of the above, I believe I can provide another
incarnation which brings a similar marginal speed advantage over the
tertiary form, and provides a clearer separation of the Feb
calculation.

But it all depends on what the goal is. Mine, in this case, happened to
be to achieve a succinct, efficient computation by taking an
interesting departure from the usual arithmetical approach in producing
a result. And I think it's good that some may wonder how that somewhat
obscure expression can possibly provide the correct result. Those
wishing to find out, aren't going to get much of a leg up with it
converted to tertiary form, which necessarily removes some of the
intentional bit mangling shortcut logic.


Well, I have two distinct interests.

One is to find the fastest reasonably-short and compact javascript
implementation - for example, the following may be fast but is not
necessarily compact in use of storage :-

function SomeOtherRoutine(y, m) { var x = y + '' + m // Demo only
alert(x)
return x }

A = []

function ML(y, m) { var T, U
if (!(T=A[y])) A[y] = T = []
if (!(U=T[m])) T[m] = U = SomeOtherRoutine(y, m)
return U }

x = [ML(2, 4), ML(2, 4), ML(3, 5), ML(2, 4)]

which Alerts only twice but sets x to [24,24,35,24]

so clearly if SomeOtherRoutine (a stand-in for DaysinMonth) was lengthy
in execution in comparison with failing the two IF conditions AND if ML
were called repeatedly for a limited number of parameters, them ML could
beat direct use of SomeOtherRoutine. But for many combinations of y & m
with little repetition, ML is a waste of both time and space.
The other, in this specific case, is to find the "algebraically-best"
routine that uses the approximate numerical regularity of the months
(like Zeller) rather than doing bit-juggling.


I have found a published efficient-looking routine to get Week Number
(ISO 8601) from CJD (days from Julian BC 4713-01-01 00:00:00h local
time) by arithmetic without going via explicit YMD; getting day-of-week
is easy (indeed, that day was a Monday), and I have bodged Year. Has
anyone seen a routine of similar nature to do the reverse, YWD to CJD
(not necessarily in javascript)?

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4
<URL:http://www.jibbering.com/faq/> JL/RC: FAQ of news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
Jul 23 '05 #22
rh
Dr John Stockton wrote:
JRS: In article <11**********************@c13g2000cwb.googlegroups .com> , dated Sun, 13 Feb 2005 20:36:50, seen in news:comp.lang.javascript, rh <co********@yahoo.ca> posted :

Right, but if utmost speed is the predominant criteria, then Lasse's
method is really the one of choice.
I've lost track of that one; is it the one using something like

(0xeefbb3>>(2*m))&3

for the lengths of the non-Feb months?


That's right, except his implementation used a shift to accomplish the
multiplication by 2. However, the change doesn't appear to affect the
speed significantly.
My present implementation of that seems of similar speed to the best of the others; but my simple testing is better on the slower routines of a set than on the faster ones.

My timing tests, adjusting for the loop overhead, show Lasse's version
to be almost twice the speed of the others.

<...>

Well, I have two distinct interests.

One is to find the fastest reasonably-short and compact javascript
implementation - for example, the following may be fast but is not
necessarily compact in use of storage :-

function SomeOtherRoutine(y, m) { var x = y + '' + m // Demo only
alert(x)
return x }

A = []

function ML(y, m) { var T, U
if (!(T=A[y])) A[y] = T = []
if (!(U=T[m])) T[m] = U = SomeOtherRoutine(y, m)
return U }

x = [ML(2, 4), ML(2, 4), ML(3, 5), ML(2, 4)]

which Alerts only twice but sets x to [24,24,35,24]

so clearly if SomeOtherRoutine (a stand-in for DaysinMonth) was lengthy in execution in comparison with failing the two IF conditions AND if ML were called repeatedly for a limited number of parameters, them ML could beat direct use of SomeOtherRoutine. But for many combinations of y & m with little repetition, ML is a waste of both time and space.

As you say, that depends entirely on how time consuming
someOtherRoutine is. In this specific case, the computation is highly
efficient, and re-computation would surely be more appropriate, both in
time and space, than caching values.
The other, in this specific case, is to find the "algebraically-best"
routine that uses the approximate numerical regularity of the months
(like Zeller) rather than doing bit-juggling.


That sounds like fun, but I think I'll content myself with bit-munging
for the present. ;-)

<...>

../rh

Jul 23 '05 #23

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by Stuart Perryman | last post: by
15 posts views Thread by Dan | last post: by
23 posts views Thread by Markus | last post: by
3 posts views Thread by jimmygoogle | last post: by
10 posts views Thread by Danny | last post: by
7 posts views Thread by Coder | last post: by
3 posts views Thread by littleark | last post: by
6 posts views Thread by scotty | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.