| JScript Example - Calculating 2^4194304 |
I tried to estimate the value of 2^332 power by hand without actually running through 332 iterations. Therefore, I tried two techniques resulting in a number that was relatively close to the estimation given by Google and the Windows calculator. Then I decided to actually calculate the exact value. Finally, I decided to change the problem so that I could get an extremely long number. Therefore I wrote JScript code to calculate 2^(2^22) which should result in a number that is more than 1,000,000 digits long. This code can be found below or in this file:
/*!
Author: Chris West
Created: March 12, 2010
Revised: March 14, 2010
Purpose: Use JScript to calculate a power of 2 which is at least one million
digits in length.
*/
// Parameters:
// n = The number of characters that should be in the string.
// c = Optional. The character that may be used for padding to the left of n.
String.prototype.padLeft = function(n, c)
{
n = Math.max(n - this.length, 0);
return (new Array(n + 1)).join((c && c.length) ? c.charAt(0) : " ") + this;
};
// Converts the given milliseconds to a string in the following format:
// d days hh:mm:ss.nnn
Date.getTimeValue = function(ms)
{
var n = ms % 1000;
ms = parseInt(ms / 1000);
var s = ms % 60;
ms = parseInt(ms / 60);
var m = ms % 60;
ms = parseInt(ms / 60);
var h = ms % 24;
ms = parseInt(ms / 24);
return ms + " day" + (ms == 1 ? "" : "s") + " " + (h + ":").padLeft(3, "0")
+ (m + ":").padLeft(3, "0") + (s + ".").padLeft(3, "0")
+ (n + "").padLeft(3, "0");
}
// Provides access to a beefed up version of the alert function.
// This function provides all of the features available for VBScript's MsgBox.
function alert(message, title, options, timeout)
{
if(message == null)
message = "";
if(!title)
title = WScript.ScriptName;
if(options == null)
options = alert.OKOnly + alert.Exclamation;
if(timeout == null)
timeout = 0;
return (new ActiveXObject("WScript.Shell")).Popup(message, timeout, title, options);
}
// Define the option constants for the alert function.
(function(a)
{
for(var i in a)
alert[i]=a[i];
})({Critical : 16, Question : 32, Exclamation : 48, Information : 64,
OKOnly : 0, OKCancel : 1, AbortRetryIgnore : 2, YesNoCancel : 3, YesNo : 4,
RetryCancel : 5, Timeout : -1, OK : 1, Cancel : 2, Abort : 3, Retry : 4,
Ignore : 5, Yes : 6, No : 7});
// Squares the positive string integer passed in.
function square(strNum)
{
// The maximum number of digits stored in one element of the digits array.
var DIGITS_PER_GROUP = 7;
// One more than the maximum number that will be allowed to stay in one
// element of the digits array.
var CUT_OFF = Math.pow(10, DIGITS_PER_GROUP);
// The regular expression used to split strNum into groups of
// DIGITS_PER_GROUP digits, starting from the right-most digits.
var re = new RegExp(".{1," + DIGITS_PER_GROUP + "}(?=(.{" + DIGITS_PER_GROUP + "})*$)", "g");
// Split strNum into the groups and reverse them.
var inGroup = strNum.match(re).reverse();
// The length of the groups of digits.
var len1 = inGroup.length;
// Convert each digit grouping into a decimal integer.
for(var i = 0; i < len1; i++)
inGroup[i] = parseInt(inGroup[i], 10);
// Find the product of all of the groups. Make sure that any product that is
// longer than DIGITS_PER_GROUP are carried over to the next digit grouping.
// This process is based on the one that children are taught when multiplying
// two or three digit numbers together.
var dIndex, outGroup = [];
for(var carryOver, j, prod, i = 0; i < len1; i++)
{
dIndex = i;
carryOver = 0;
for(j = 0; j < len1; j++)
{
prod = inGroup[i] * inGroup[j];
outGroup[dIndex] = carryOver + (outGroup[dIndex] || 0) + prod;
currentDigits = outGroup[dIndex] % CUT_OFF;
carryOver = parseInt((outGroup[dIndex] - currentDigits) / CUT_OFF, 10);
outGroup[dIndex] = currentDigits;
dIndex++;
}
// Make sure that no digit grouping exceeds the CUT_OFF.
while(carryOver)
{
outGroup[dIndex] = (outGroup[dIndex] || 0) + carryOver;
currentDigits = outGroup[dIndex] % CUT_OFF;
carryOver = parseInt((outGroup[dIndex] - currentDigits) / CUT_OFF, 10);
outGroup[dIndex] = currentDigits;
dIndex++;
}
}
// Make sure that each grouping has as many digits as specified by
// DIGITS_PER_GROUP.
for(var i = 0; i < outGroup.length; i++)
outGroup[i] = (outGroup[i] + "").padLeft(DIGITS_PER_GROUP, "0");
// Reverse the order of the groupings to undo the original reversal.
// Return the number as a string.
outGroup = outGroup.reverse().join("").replace(/^0+/, "");
return outGroup || "0";
}
// Find strNum ^ (2 ^ intPower).
function powSquare(startNum, intPower)
{
// Record the starting number.
var strNum = startNum;
// Create a blank text file naed after this script.
ts = (new ActiveXObject("Scripting.FileSystemObject")).createTextFile(WScript.ScriptFullName + ".log");
// Write the resulting square of each number.
for(var time1, time2, i = 0; i < intPower; i++)
{
// Record the starting time.
time1 = new Date();
// Square the number.
strNum = square(strNum);
// Record the ending time.
time2 = new Date();
// Write the results to the file.
ts.WriteLine("Milliseconds Taken: " + Date.getTimeValue(time2.getTime()
- time1.getTime()));
ts.WriteLine("Problem: " + startNum + " ^ (2 ^ " + (i + 1) + ")");
ts.WriteLine("Answer: " + strNum);
ts.WriteBlankLines(5);
}
// Close the text stream (file).
ts.Quit();
}
// Find 2^(2^22) and record the results in a log file named after this script.
powSquare("2", 22);
// Inform the user when the script is done.
alert("This script is finally done.", null, alert.Information);
© 2010 Christopher West. Powered by jPaq.