JavaScript – Cube Root & Beyond

Lately, I have been in a math oriented mood.  Yesterday, I was thinking about how the fact that you can take the square root of a number in JavaScript, but not the cube root, 4th root, etc..  Naturally, I looked to Wikipedia to find the algorithm to find the nth root of a number.  I developed the following unnecessary function:

function bad_nthroot(x, n) {
  // If an error occurs, don't return anything.
  try {
    // If an error occurs
    // Loop through the nth root algorithm until no difference is found.
    var x2, A = x, n1 = n - 1, itersLeft = 99;
    do {
      x2 = x;
      x = (n1 * x2 + A / Math.pow(x2, n1)) / n;
    } while(x != x2 && itersLeft--);
    
    // If less than 100 iterations were done or if the difference between the
    // previous approximation and the current one is acceptable, return the
    // current one.
    if((itersLeft || (Math.abs(x - x2) < 1 && (x < 0) == (x2 < 0))) && isFinite(x))
      return x;
  } catch(e){}
}

After testing out the function a bit and taking a look at an online example, I realized that I could have done it with the Math.pow(). After all, the cube root of a number is the same thing as that number to the power of 1/3. With this in mind, I redeveloped the function and came up with the following, more accurate function:

function nthroot(x, n) {
  try {
    var negate = n % 2 == 1 && x < 0;
    if(negate)
      x = -x;
    var possible = Math.pow(x, 1 / n);
    n = Math.pow(possible, n);
    if(Math.abs(x - n) < 1 && (x > 0 == n > 0))
      return negate ? -possible : possible;
  } catch(e){}
}

One notable difference is the fact that calling bad_nthroot(8, 1/2) results in 63.99999999999999. On the other hand, nthroot(8, 1/2) results in 64. There are many other differences as well.

The reason I created this function instead of using Math.pow(x, 1 / n) is because of examples such as Math.pow(-8, 1 / 3). Even though the cube root of -8 is -2, Math.pow(-8, 1 / 3) results in NaN. On the other hand, nthroot(-8, 3) results in the expected value of -2.

If you find something wrong with my nthroot function, please let me know.

Excel – Batch Convert XLS To CSV

Update!!!

A newer HTML application (HTA) has just been created which accomplishes the same thing but in a more customizable manner. Click here to read the post.

Original Post

A few days ago, someone asked me to help them convert a large number of XLS files to CSV. Since, while working for Bristol-Myers Squibb, I became very familiar with writing macros and JScripts to work with Excel, I decided to write a JScript to accomplish the task. Basically, all you have to do is put the script inside of the same folder as all of the Excel files and double-click it to run it. The script uses Excel to open all of the files and convert each worksheet of each XLS file to a CSV. The naming convention for the CSV files is as follows:
{file_name}-{worksheet_name}.csv

Here is the script:
Excel – XLS To CSV Converter

If you examine the script, you will notice that it uses jPaq for user interaction.  All of the code, except for the jPaq because it is the minifieid version, is pretty well documented.  You may do whatever you want to the script. All I ask is that, if you re-use the code, you give credit where it is due. 🙂

Convert Anything To A Number

There are many times in JavaScript when you need to scrub the input and give output of a specific type. Today, I will cover how you can convert anything into a number. The function to do so is as follows:

// Converts any object into a number.
function parseNumber(obj) {
  return parseFloat(obj)||+obj||0;
}

Now the question is, what happens under different circumstances. Look at (or even try out) the following to find out:

// Convert any empty string into a number:
var a = "";
var b = parseNumber(a);  // 0
alert(JSON.stringify(a) + "\n" + b);

// Convert a string version of a number into a number:
var a = "9563.49";
var b = parseNumber(a);  // 9563.49
alert(JSON.stringify(a) + "\n" + b);

// Convert a string starting with space and then a number with extra decimal points into a number:
var a = "    9563.49.2";
var b = parseNumber(a);  // 9563.49
alert(JSON.stringify(a) + "\n" + b);

// Convert a sentence into a number:
var a = "I am 23.";
var b = parseNumber(a);  // 0
alert(JSON.stringify(a) + "\n" + b);

// Convert an array of numbers into a number:
var a = [129,84,7];
var b = parseNumber(a);  // 129
alert(JSON.stringify(a) + "\n" + b);

// Convert a date into a number:
var a = new Date();
var b = parseNumber(a);  // milliseconds since January 1, 1970
alert(JSON.stringify(a) + "\n" + b);

// Convert an object literal into a number:
var a = {};
var b = parseNumber(a);  // 0
alert(JSON.stringify(a) + "\n" + b);

The most interesting of the above test are probably the parsing of dates and arrays. For dates, the number will be the amount of milliseconds since January 1, 1970. For arrays, the number will be the numeric value of the number in the first position of the array.