The function clscal() was originally obtained in Fortran, then later converted here to JavaScript, which is used to scale the spectrum of CO.

The `<plaintext>`

tag has previously been used to display code and
avoid any problems with handling the `"<"`

and `">"`

characters in the code, but this tag is now deprecated, and once opened it cannot be
closed. An alternative method of using jQuery is applied applied here, and the code is
in ../js/jquery-showcode.js.

/** ----- clscal() ----- * This is a JavaScript static class that can be used to calculate sensible * values for the upper and lower limits of some range to be plotted, together * with sensible intervals that can be used to mark an axis. After calling * clscal(a,b,z,f), the returned values can be obtained from clscal.error, * clscal.x, clscal.dx, clscal.ndx, and clscal.y. The original code was in * Fortran, then converted here to JavaScript with some significant improvements, * and calls the maths rounding utility rnd(x,d) in the file rnd.js. * * The input arguments have the following meanings: * a - The lower limit to be considered. * b - The upper limit to be considered. * z - The number of significant figures for rounding, and calls rnd(). See * the notes on rnd(). * f - A boolean flag to handle the case when the error code is 2, see below. * * The returned values are as follows: * error === 0: Successfully found a range, so x, dx, ndx, and y, return with * the following values: * x <= a: This is chosen to be a "nice" lower value. * dx: This is chosen to be a "nice" interval to divide up the range. * ndx: This the number of intervals that divide the range. * y >= b: This is chosen to be a "nice" upper value, such that y = x + dx*ndx. * error === -1: At least one of the input values is blank. The other returned * values are meaningless. * error === -2: At least one of the input values is non-numeric. The other * returned values are meaningless. * error === 1: The upper limit b <= the lower limit a. The other returned * values are meaningless. * error === 2: Although b > a, they are the same to within 4 significant * figures. The outcome depends on the flag f set as follows: * false: Returns with this error code and do nothing more. The other values * are meaningless. * true: Repeats calculating with the lower limit set to zero and the upper * limit set to b-a. This then tries to divide up the range between 0 * and b-a. The following output will be returned: * error === 0: If successful, otherwise error === 2. * x === 0: This should always be the case. * dx: This is chosen to be a "nice" interval to divide up the range. * ndx: This the number of intervals that divide the range. * y >= b-a: In general y can be larger than the difference. * error === 3: ndx could not be chosen while keeping dx to a valid value. The * other values are meaningless. * * Thus the returned error code should be tested first, and of it is 0 the other * returned values can be used. For other values of the error code the other * returned values are meaningless, except if the error code is 2 and the flag f is * set to true, then difference range b-a may have been divided successfully, but * this is not guaranteed. */ function clscal(a,b,z,f) { a = a.toString(); // Convert a and b to a string in case they are not. b = b.toString(); // If they are not strings, the code below is redundant, a = a.trim(); // and they are converted back to numbers. b = b.trim(); if (a === "" || b === "") { // ----- ERROR -1: At least one input field is empty clscal.error = -1; return; } if (isNaN(a) || isNaN(b)) { // ----- ERROR -2: At least one input field contains non-numeric input clscal.error = -2; return; } a = Number(a); b = Number(b); var ivs = [1,2,5,10,20,50,100,200,500,1000,2000,5000]; var npref = [5,6,4,7,8,3,2,9,10,1]; var ndxs = new Array(12); var dxs = new Array(12); var xs = new Array(12); var n1,n2,m,ma,mb,mx,nb,nx; var x,dx,ndx,xx,yy; var smallDiff = false; // This is set to true for error code 2 when f is set to true var p = a; // Store a and b for later use in case of error code 2 with f var q = b; // set to true do { // do-while loop which is never executed more than twice x = a; dx = b; ndx = 1; if (b <= a) { // ----- ERROR 1: a <= b if (!smallDiff) clscal.error = 1; return; } var l = 0; if (a >= 0.0) l = 1; if (b <= 0.0) l = 2; if (l > 0) { if (l === 2) { var temp = a; a = -b; b = -temp; } nb = 0; while (b < 1000.0) { nb--; b *= 10.0; } while (b >= 10000.0) { nb++; b *= 0.1; } mb = parseInt(b-0.1,10); mb++; a = a*Math.pow(10,-nb); ma = parseInt(a+0.01,10); if (ma >= mb) { // ----- ERROR 2: a === b to 4 significant figures clscal.error = 2; if (!f) return; // If f is false return with error code 2, otherwise repeat smallDiff = true; // the do-while loop one more time with a set to zero and b b = q - p; // set to the original difference b-a stored in p and q. a = 0; // Keep the error code 2 regardless of the later outcome. continue; } for (var i=0; i<12; i++) { n2 = parseInt(mb/ivs[i],10); if (n2*ivs[i] != mb) n2++; n1 = parseInt(ma/ivs[i],10); if (n1*10 < n2) n1=0; dxs[i] = ivs[i]*Math.pow(10,nb); ndxs[i] = n2-n1; xs[i] = n1*dxs[i]; if (l === 2) xs[i] = -n2*dxs[i]; } } else { if (-a < b) { m = 2; xx = b; yy = -a; } else { m = 1; xx = -a; yy = b; } nx = 0; while (xx < 1000.0) { nx--; xx *= 10.0; } while (xx >= 10000.0) { nx++; xx *= 0.1; } mx = parseInt(xx-0.01,10); mx++; for (var i=0; i<12; i++) { n1 = parseInt(mx/ivs[i],10); if (n1*ivs[i] != mx) n1++; dxs[i]=ivs[i]*Math.pow(10,nx); n2 = parseInt(yy/dxs[i],10); if (n2*dxs[i] < yy) n2++; ndxs[i] = n1+n2; xs[i] = -n1*dxs[i]; if (m === 2) xs[i] = -n2*dxs[i]; } } for (var i=0; i<10; i++) { for (var j=0; j<12; j++) { if (ndxs[j] === npref[i]) { clscal.x = rnd(xs[j],z); clscal.dx = rnd(dxs[j],z); clscal.ndx = ndxs[j]; clscal.y = rnd(clscal.x + clscal.ndx*clscal.dx, z); clscal.error = 0; return; // ----- ERROR 0: No error - the values of x, dx and ndx were found } } } if (!smallDiff) clscal.error = 3; // ----- ERROR 3: Unable to find suitable values of x, dx & ndx return; } while (true); // End of do-while loop which is never executed more than twice } /** ----- rnd() ----- * This is called by clscal() and can be called elsewhere to round a number to a given number of * decimal places, and fixes the problem in JavaScript due to the approximate representation of * some floating point numbers, causing a large number of trailing "9"s or "0"s with a non-zero * digit at the end of the number. Currently it is only implemented for numbers that are not * in the exponential notation containing an "e" or an "E". * x - The input number to be processed. * d - The number of digits after the decimal point to round, and must be less than about 16, * provided the number is not in exponential notation. * return - This returns the rounded number if it is not in exponential notation, otherwise it * returns the original number unchanged. */ function rnd(x,d) { var s = x.toString(); if (s.indexOf("e") >= 0 || s.indexOf("E") >=0) return x; return Number(Math.round(x+"e"+d)+"e-"+d); }

After invoking `clscal(a,b,z,f)`

with `a`

being the lower limit in the
range to be plotted, `b`

being the upper limit in the range to be plotted, and
`z`

being the number of digits after the decimal point to round to (values between
4 and 6 are preferred), the returned values are as follows:

`clscal.error === 0 - Provided clscal() has executed correctly.`

`clscal.x <= a - If necessary the new lower limit is rounded down below a.`

`clscal.y >= b - If necessary the new upper limit is rounded up above b.`

`clscal.dx > 0 - The interval that can be used between major plot markings.`

`clscal.ndx > 0 - The number of intervals, thus there are clscal.ndx+1 major plot markings.`

If the error code is anything other than 0, the other returned values are meaningless. The flag
`f`

is only relevant for error code 2. If it is `false`

, the returned values
have no meanings, as with the other non-zero codes. If it is `true`

, the returned values
are as follows:

`clscal.error === 0 - If clscal() has been executed successfully for a second pass.`

`clscal.x === 0 - This is always returned.`

`clscal.y >= b-a - If necessary the new upper limit is rounded up above b-a.`

`clscal.dx > 0 - The interval that can be used between major plot markings.`

`clscal.ndx > 0 - The number of intervals, thus there are clscal.ndx+1 major plot markings.`

If `clscal()`

still returns with an error code of 2 on the second pass, it has failed
again and cannot be used with the present input values.

Click here to return to the diatomic page.