bigarith.js
Version:
Do very large math to precision!
1,297 lines (1,174 loc) • 112 kB
JavaScript
/**
* bigarith.js - Written by Oso Oluwafemi Ebenezer
* The constructor for BigArith
* @param {string|number|null|BigArith} n Accepts no parameter, or number within the safe integer limit or string in "-123.456" form or
* "negative one hundred and twenty three point four five six" form or a constant "PI" form or a BigArith object
* Dependent on verify(), getter name()
*/
var BigArith=function(n){
//version
Object.defineProperty(this, 'version', {
enumerable: true,
writable: false,
value: "v0.0.8",
});
//Object name
Object.defineProperty(this, 'name', {
enumerable: true,
writable: false,
value: "BigArith"
});
//Word length support
Object.defineProperty(this, 'wordSupport', {
writable: false,
value: 1002 //up to (1x10^1,005) - 0.0{199}1
});
//Word decimal length support
Object.defineProperty(this, 'decimalSupport', {
writable: false,
value: 200 //200 decimal characters when using toWords()
});
//assign this.value
if(n == null) this.value = "0"
else if(typeof n == "object" && n.name == "BigArith") this.value = n.toString();
else if(typeof n == "undefined" /*null*/ || n == "") this.value = "0";
else if(n == "PI") this.value = "3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196";
else if(n == "E") this.value = "2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642742746639193200305992181741359662904357290033429526059563073813232862794349076323382988075319525101901";
/*else if(n == "LN2") this.value = "0.6931471805599453";
else if(n == "LN10") this.value = "2.302585092994046";
else if(n == "LOG2E") this.value = "1.4426950408889634";
else if(n == "LOG10E") this.value = "0.4342944819032518";*/
else if(n == "SQRT1_2") this.value = "0.70710678118654752440084436210484903928483593768847403658833986899536623923105351942519376716382078636750692311545614851246241802792536860632206074854996791570661133296375279637789997525057639103028574";
else if(n == "SQRT2") this.value = "1.41421356237309504880168872420969807856967187537694807317667973799073247846210703885038753432764157273501384623091229702492483605585073721264412149709993583141322266592750559275579995050115278206057147";
else this.value = this.verify(n);
};
/**
* Verify input evaluate to a valid number
* function verify
* @param {string|number|BigArth} n Number within the safe integer limit or string in "-123.456" or
* "negative one hundred and twenty three point four five six" form or a BigArith object
* @returns {string|NaN} - A string representation of @param in form "-123.456" or NaN if @param is not valid,
* or throws a RangeError if input is in number form but not within safe limits.
* Dependent on w_Dict()
*/
BigArith.prototype.verify = function(n){
//Can be an already verified BigArith object
if(typeof(n) == "object" && n.name == "BigArith") return n.toString();
//Can be a number in form of 1000 or 1e3
//Number must be within the safe integer range
if(typeof(n) == 'number' && n <= Number.MAX_SAFE_INTEGER && n >= Number.MIN_SAFE_INTEGER) return n.toString();
if(typeof(n) == 'number' && (n > Number.MAX_SAFE_INTEGER || n < Number.MIN_SAFE_INTEGER)) throw new RangeError("The number you entered in typeof 'number' form is not within the safe limit. Please enter the number as a string.");
//It can be string in form "-123.89"
if(typeof(n) == 'string' && /\d/.test(n)/*This just test if it contains any digit, real test in below*/){
n = n.replace(/^\s|\s$/g, "");
var sign = false;
if(n[0] == "-"){
sign = true;
n = n.slice(1, n.length);
}
else if(n[0] == "+"){
n = n.slice(1, n.length);
}
n = n.split(".");
if(n.length > 2) return NaN;
if(n[0] == "") n[0] = "0";
if(typeof(n[1]) == 'undefined') n[1] = "0";
if(/^\d+$/.test(n[0]) && /^\d+$/.test(n[1])/*Test that it contains only digits*/){
//Remove unnecessary zeroes
n[0] = n[0].replace(/^[0]+/g, "");
n[1] = n[1].replace(/[0]+$/g, "");
return ((sign)?"-":"") + ((n[0] == "")?"0":n[0]) + ((n[1] == "")?"":"."+n[1]);
}
else
return NaN;
}
//It can be string in form of "negative one thousand point one two"
if(typeof(n) == 'string'){
n = n.toLowerCase();
n = n.replace(/^\s|\s$/g, "").replace(/\s+/g, " ");
n = n.replace(/\s(and)\s/g, " ");
var fNum, dNum = fNum = "";
//Is Negative or Positive?
var sign = false;
n = n.split(" ");
if(n[0] == "negative"){
sign = true;
n.shift();
}
else if(n[0] == "positive"){
n.shift();
}
//The Mantissa part
if(n.indexOf("point") >= 0){
var decimal = n.splice(n.indexOf("point"), n.length - n.indexOf("point")); decimal.shift();
dNum = decimal.map(a=>{return typeof this.w_Dict(a) != "undefined"&&this.w_Dict(a).length<2&&this.w_Dict(a).length>0?this.w_Dict(a):NaN}).join("");
}
else dNum = "0";
//The Characteristic part
if(n.includes("zero") && n.lastIndexOf("zero") != 0) return NaN;
var subArray = [];
var subString = "";
var prevSuffix = "0".repeat(this.wordSupport);
var prevHSuffix = false; //To check have we gotten an hundred earlier?
var prevValue = false;
for(var i = 0; i < n.length; i++){
if(typeof(this.w_Dict(n[i])) == 'undefined')return NaN; //Spelling errors and what-nots
if(this.w_Dict(n[i]).length >= 3/*thousand and above*/){
if(prevSuffix.length < this.w_Dict(n[i]).length) return NaN; //"one million three billion" is wrong
if(!prevValue) return NaN; //"one million thousnad" is wrong
subString += this.w_Dict(n[i]);
subArray.push(subString);
subString = "";
prevSuffix = this.w_Dict(n[i]);
prevValue = false;
prevHSuffix = false;
}
else if(n[i] == "hundred"){
if(prevHSuffix) return NaN; // "one hundred two hundred" is wrong
if(typeof this.w_Dict(n[i-1]) == 'undefined') return NaN; //"hundred thousand" is wrong
if(this.w_Dict(n[i-1]).length > 1) return NaN;
subString += this.w_Dict(n[i]);
prevHSuffix = true;
}
else{
if(typeof this.w_Dict(n[i-1])!='undefined'&&(this.w_Dict(n[i]).length>this.w_Dict(n[i-1]).length||(this.w_Dict(n[i]).length==1&&this.w_Dict(n[i-1]).length==1))) return NaN; //one ninety is wrong, eight hundred and six three is wrong
subString = subString.substr(0, subString.length - this.w_Dict(n[i]).length) + this.w_Dict(n[i]);
prevValue = true;
}
}
subArray.push(subString);
for(var i = 0; i < subArray.length; i++){
fNum = fNum.substr(0, fNum.length - subArray[i].length) + subArray[i];
}
if(fNum == "") fNum = "0";
//output
if(/^\d+$/.test(fNum) && /^\d+$/.test(dNum)/*Test that it contains only digits*/){
//Remove unnecessary zeros
fNum = fNum.replace(/^[0]+/g, "");
dNum = dNum.replace(/[0]+$/g, "");
return (sign?"-":"") + ((fNum == "")?"0":fNum) + ((dNum == "")?"":"."+dNum);
}
else return NaN;
}
//That's all we support
return NaN;
};
/**
* Returns the this.value as a number
* @return {number} - this.value
*/
BigArith.prototype.valueOf=function(){
return this.value*1;
};
/**
* Returns the this.value as a string
* @return {string} - this.value
*/
BigArith.prototype.toString=function(){
return this.value;
};
/**
* Returns true if this.value is negative, false otherwise
* @return {boolean} - this.value is less than positive zero
*/
BigArith.prototype.isNegative=function(){
if(isNaN(this.value)) return NaN;
if(this.value[0] == "-") return true;
return false;
}
/**
* Returns true if this.value is positive, false otherwise
* @return {boolean} - this.value is greater than negative zero
*/
BigArith.prototype.isPositive=function(){
if(isNaN(this.value)) return NaN;
if(this.value[0] == "-") return false;
return true;
}
/**
* Returns true if this.value is integer, false otherwise
* @return {boolean} - this.value is integer?
*/
BigArith.prototype.isInteger=function(){
if(isNaN(this.value)) return NaN;
if(this.value.indexOf(".") == -1) return true;
return false;
}
/**
* Returns true if this.value is even, false otherwise
* @return {boolean} - this.value is even?
* Dependent on floor(), static divide(), isInteger(), static compare()
*/
BigArith.prototype.isEven=function(){
if(isNaN(this.value)) return NaN;
var d = new BigArith(this.value);
if(!d.isInteger()) return false;
d = BigArith.divide(this.value[this.value.length-1], 2);
if(BigArith.compare(d, d.floor()) == 0) return true;
return false;
}
/**
* Returns true if this.value is NOT even and is an integer, false otherwise
* @return {boolean} - this.value is NOT even and is an integer?
* Dependent on isEven(), isInteger()
*/
BigArith.prototype.isOdd=function(){
if(isNaN(this.value)) return NaN;
var d = new BigArith(this.value);
if(!d.isEven() && d.isInteger()) return true;
return false;
}
/**
* Returns square of this.value
* function square
* @return {BigArith} - product of this.value and this.value
* Dependent on static multiply()
*/
BigArith.prototype.square=function(){
return BigArith.multiply(this.value, this.value);
}
/** [NEEDS OPTIMIZATION - n tends to gets very large within few calculations and this slows down calculation speed. Takes 9105ms to calculate sqrt 2 to 200 decimal place]
* Returns square root of this.value
* function squareRoot
* @return {BigArith} - root of this.value
*/
BigArith.prototype.squareRoot=function(){
var n = this.value;
if(isNaN(n) || new BigArith(n).isNegative()) return NaN;
//Find the perfect square just less than or equal to n
var ps = BigArith.perfectSq(n);
var result = ps;
var quotient = ps;
n = BigArith.subtract(n, BigArith.multiply(ps, ps));
//If reminder (n) is 0, return result we have reached the end of calculation
if(BigArith.compare(n, 0) == 0) return new BigArith(result);
//If we got here that means we have reminders
n = BigArith.multiply(n, 100); //multiply reminder by 100
result += ".";
for(var count = 0; count <= new BigArith().decimalSupport+1; count++){
// take quotient double it and multiply by 10
var j = BigArith.multiply(quotient, 20);
//Find a number bewteen j+1 and j+9 such that (j+i)*i will just be less than or equal to n
var i = 1;
for(; i <= 9; i++){
var g = BigArith.multiply(BigArith.add(j,i), i); //(j+i)*i
if(BigArith.compare(g, n) >= 0 || BigArith.compare(n, 0) == 0) break;
}
//If (j+i)*i > n or i == 10, reduce i by 1
var ji = BigArith.multiply(BigArith.add(j,i), i); //(j+i)*i
if(i == 10 || BigArith.compare(BigArith.multiply(BigArith.add(j,i), i), n) == 1) i--;
n = BigArith.multiply(BigArith.subtract(n, BigArith.multiply(BigArith.add(j,i), i)),100);//(n-(j+i)*i)*100;
result += i;
quotient += i.toString();
//If reminder is 0, break we have reached the end of calculation
if(BigArith.compare(n, 0) == 0) break;
}
return new BigArith(new BigArith(result).toFixed(new BigArith().decimalSupport));
}
/** [NEEDS OPTIMIZATION - incase n is very large]
* Returns the square root of the perfect square just below or equals to n
* function perfectSq
* @param - {string|number|BigArth} n The number to find the perfect square before
* @return {string} - the perfect square just less than n or n if it is a perfect square
*/
BigArith.perfectSq=function(n){
var n = new BigArith(n).toString();
//start counting from 1 to we get to i*i<=n
//This is not the best idea if n is very large
var i = new BigArith(1);
while(true){
if(BigArith.compare(new BigArith(i).square(), n) >= 0) break;
i = BigArith.add(i, 1);
}
return (BigArith.compare(BigArith.multiply(i, i), n) == 0)?i.toString():i.subtract(1).toString();
}
/**
* Return the absolute value of this.value
* function abs
* @returns {BigArith} - Absolute value of this.value
* Dependent on static abs()
*/
BigArith.prototype.abs=function(){
return BigArith.abs(this.value);
}
/**
* Return the absolute value of n
* function abs
* @param {string|number|BigArth} n value to find absolute of.
* @returns {BigArith} - Absolute value of n
* Dependent on isNegative(), negate(), isNaN() (native)
*/
BigArith.abs=function(n){
var n=new BigArith(n);
if(isNaN(n)) return NaN;
return (n.isNegative())?n.negate():n;
}
/**
* Returns a number with it sign changed
* function negate
* @returns {BigArith} - this.value with the sign changed
* Dependent on static negate()
*/
BigArith.prototype.negate=function(){
return BigArith.negate(this.value);
}
/**
* Returns a number with it sign changed
* function negate
* @param {string|number|BigArth} n number to negate
* @returns {BigArith} - number with the sign changed
* Dependent toString()
*/
BigArith.negate=function(n){
var n = new BigArith(n);
if(isNaN(n)) return NaN;
return (n.toString()[0] == "-")?new BigArith(n.toString().substr(1)):new BigArith("-"+n);
}
/**
* Returns the characteristic part (part before the decimal point) of a number
* function truncate
* @returns {BigArith} - characteristic part of the number
* Dependent static truncate()
*/
BigArith.prototype.truncate=function(){
return BigArith.truncate(this.value);
}
/**
* Returns the characteristic part (part before the decimal point) of a number
* function truncate
* @param {string|number|BigArth} n number to truncate
* @returns {BigArith} - characteristic part of the number
* Dependent isNaN(), toString(), indexOf()
*/
BigArith.truncate=function(n){
var n = new BigArith(n);
if(isNaN(n)) return NaN;
if(n.toString().indexOf(".") == -1) return n;
return new BigArith(n.toString().split(".")[0]);
}
/**
* Comparing this.value to n
* function compare
* @param {string|number|BigArth} n the number this.value is to be compared to. Can be negative and fractional
* @returns {number} (-1 if this.value < n), (0 if this.value == n), (1 if this.value > n)
* Dependent on static compare()
*/
BigArith.prototype.compare=function(n){
return BigArith.compare(this.value, n);
}
/**
* Comparing a to b
* function compare
* @param {string|number|BigArth} a number to be compared. Can be negative and fractional
* @param {string|number|BigArth} b number to be compared. Can be negative and fractional
* @returns {number} - (-1 if a < b), (0 if a == b), (1 if a > b)
* Dependent on toString(), isNegative(), isPositive(), abs(), Math.max() (can't use BigArith.max, it's dependent on compare)
*/
BigArith.compare=function(a, b){
var a = new BigArith(a);
var b = new BigArith(b);
if(isNaN(a) || isNaN(b)) return NaN;
//Check for signs
var cSign = false, c = "";
var dSign = false, d = "";
if(a.isNegative()){
cSign = true;
c = a.abs().toString();
}else c=a.toString();
if(b.isNegative()){
dSign = true;
d = b.abs().toString();
}else d=b.toString();
c = c.split("."); d = d.split(".");
(typeof c[1] == 'undefined')?c[1]='0':0;
(typeof d[1] == 'undefined')?d[1]='0':0;
c[1]=c[1].replace(/[0]*$/g,""); if(c[1] == "") c[1] ="0";
d[1]=d[1].replace(/[0]*$/g,""); if(d[1] == "") d[1] ="0";
var max = Math.max(c[1].length, d[1].length);
c[1] += "0".repeat(max - c[1].length);
d[1] += "0".repeat(max - d[1].length);
if(cSign && dSign==false) return -1;
if(dSign && cSign==false) return 1;
if(c[0].length < d[0].length) return (cSign && dSign)?1:-1;
if(c[0].length > d[0].length) return (cSign && dSign)?-1:1;
//check characteristic
for(var i = 0; i < c[0].length/*Length is equal so pick one*/; i++){
if(c[0][i] > d[0][i]) return (cSign && dSign)?-1:1;
if(c[0][i] < d[0][i]) return (cSign && dSign)?1:-1;
}
//check mantissa
for(var i = 0; i < Math.max(c[1].length, d[1].length); i++){
if(c[1][i] > d[1][i]) return (cSign && dSign)?-1:1;
if(c[1][i] < d[1][i]) return (cSign && dSign)?1:-1;
}
return 0;
}
/**
* Comparing absolute value of this.value to absolute value of n
* function compareAbs
* @param {string|number|BigArth} n value to be comapared with this.value
* @returns {string} - (-1 if abs(a) < abs(b)) - (0 if abs(a) == abs(b)) - (1 if abs(a) > abs(b))
* Dependent on static compareAbs()
*/
BigArith.prototype.compareAbs=function(n){
return BigArith.compareAbs(this.value, n);
}
/**
* Comparing absolute value of a to absolute value of b
* function compareAbs
* @param {string|number|BigArth} a value to be compare
* @param {string|number|BigArth} b value to be compare
* @returns {string} - (-1 if abs(a) < abs(b)) - (0 if abs(a) == abs(b)) - (1 if abs(a) > abs(b))
* Dependent on static compare(), abs()
*/
BigArith.compareAbs=function(a, b){
return BigArith.compare(new BigArith(a).abs(), new BigArith(b).abs());
}
/**
* Returns the minimum between this.value and n
* function min
* @param {string|number|BigArth} - optional - zero or more parameters
* @returns {BigArith} - The smallest number between this.value and parameters
* Dependent on static min()
*/
BigArith.prototype.min=function(){
return BigArith.min(this.value, ...arguments);
}
/**
* Returns the minimum between a and b
* function min
* @param {string|number|BigArth|Array} - optional - zero or more parameters
* @returns {BigArith} - The smallest number between parameters
* Dependent on static compare(), valueOf()
*/
BigArith.min=function(){
var args = BigArith.extract(arguments);
var result = new BigArith(args[0]);
for(var i = 0; i < args.length; i++){
if(isNaN(new BigArith(args[i]).valueOf())) return NaN;
result = (BigArith.compare(result, args[i]) == -1)?result:new BigArith(args[i]);
}
return result;
}
/**
* Returns the maximum between this.value and n
* function max
* @param {string|number|BigArth} - optional - zero or more parameters
* @returns {BigArith} - The largest number between this.value and parameters
* Dependent on static max()
*/
BigArith.prototype.max=function(){
return BigArith.max(this.value, ...arguments);
}
/**
* Returns the maximum between a and b
* function max
* @param {string|number|BigArth|Array} - optional - zero or more parameters
* @returns {BigArith} - The largest number between parameters
* Dependent on static compare(), valueOf()
*/
BigArith.max=function(){
var args = BigArith.extract(arguments);
var result = new BigArith(args[0]);
for(var i = 0; i < args.length; i++){
if(isNaN(new BigArith(args[i]).valueOf())) return NaN;
result = (BigArith.compare(result, args[i]) == 1)?result:new BigArith(args[i]);
}
return result;
}
//TODO
BigArith.extract=function(a){
var args = [];
for(var k in a){
if(typeof a[k] == "number" || typeof a[k] == "string"){args.push(a[k]);}
else if(typeof a[k] == "object" && a[k].name == "BigArith"){args.push(a[k].toString());}
else if(typeof a[k] == "object"){args.push(...BigArith.extract(a[k]));}
}
return args;
}
/**
* Returns largest integer less than or equal to this.value
* function floor
* @returns {BigArith} - floored value of this.value
* Dependent on static floor()
*/
BigArith.prototype.floor=function(){
return BigArith.floor(this.value);
}
/**
* Returns largest integer less than or equal to n
* function floor
* @param {string|number|BigArth} n number to floor
* @returns {BigArith} - floored number
* Dependent of subtract(), isNegative(), isInteger(), truncate()
*/
BigArith.floor=function(n){
var n = new BigArith(n);
if(isNaN(n)) return NaN;
if(!n.isInteger()){
n = n.truncate();
if(n.isNegative()){
n = BigArith.subtract(n, "1");
}
}
return n;
}
/**
* Ceil this.value
* function ceil
* @returns {BigArith} - ceiled value of this.value
* Dependent on static ceil()
*/
BigArith.prototype.ceil=function(){
return BigArith.ceil(this.value);
}
/**
* Returns smallest integer greater than or equals to number
* function ceil
* @param {string|number|BigArth} n number to ceil
* @returns {BigArith} - ceiled number
* Dependent of static add(), isNegative(), isPositive(), isInteger(), truncate()
*/
BigArith.ceil=function(n){
var n = new BigArith(n);
if(isNaN(n)) return NaN;
if(!n.isInteger()){
if(n.isPositive())
n = BigArith.add(n.truncate(), "1");
else if(n.isNegative())
n = n.truncate();
}
return n;
}
/**
* Round this.value to the nearest integer
* function round
* @returns {BigArith} - this.value rounded to nearest whole number e.g "1"
* Dependent on static round()
*/
BigArith.prototype.round=function(){
return BigArith.round(this.value);
}
/**
* Round n to the nearest integer
* function round
* @param {string|number|BigArith} n number to round e.g "0.5"
* @returns {BigArith} - n rounded to nearest whole number e.g "1"
* Dependent on toString(), static compare(), isPositive(), add(), subtract()
*/
BigArith.round=function(n){
var n = new BigArith(n);
if(isNaN(n)) return NaN;
n = n.toString();
if(n.indexOf(".")>-1){
n = n.split(".");
if(BigArith.compare(n[1][0], "5") >= 0){
if(new BigArith(n[0]).isPositive())
n[0] = BigArith.add(n[0], "1").toString();
else
n[0] = BigArith.subtract(n[0], "1").toString();
}
n = n[0];
}
return new BigArith(n);
}
/**
* Format a number to a number of decimal places
* function toFixed
* @param {string|number|BigArith} d number of decimal place to return this.value in.
* @returns {string} - this.value to a number of decimal places
* Dependent on static toFixed()
*/
BigArith.prototype.toFixed=function(d=0){
return BigArith.toFixed(this.value, d);
}
/**
* Round n to the nearest integer
* function round
* @param {string|number|BigArith} n number to format
* @param {string|number|BigArith} d number of decimal place to return n in.
* @returns {string} - n rounded to nearest whole number e.g "1"
* Dependent on toString(), static compare(), isInteger(), add(), subtract()
*/
BigArith.toFixed=function(n, d=0){
var e = new BigArith(d).floor().toString();
if(isNaN(n) || isNaN(e)) return NaN;
//if(BigArith.compare(e, 0) == -1 || BigArith.compare(e, new BigArith.decimalSupport) == 1 || isNaN(e)) throw new Error("Argument must be between 0 and "+ new BigArith.decimalSupport +"! " + e + " supplied.");
var n = new BigArith(n);
var sign = n.isNegative();
if(!n.isInteger()){
n = n.toString().split(".");
if(BigArith.compare(e, "0") == 0){
if(BigArith.compare(n[1][0], "5") >= 0){
if(!sign){
n[0] = BigArith.add(n[0], "1").toString();
}
else{
n[0] = BigArith.subtract(n[0], "1").toString();
}
n[1] = "0";
}
else n[1] = "0";
}
else if(BigArith.compare(n[1].length.toString(), e) == -1){ n[1] += "0".repeat(e - Number(n[1].length));}
else if(BigArith.compare(n[1].length.toString(), e) == 1){
if(BigArith.compare(n[1][e], "5") >= 0){
var z0 = n[1].slice(0, e).length;
var z1 = BigArith.add(n[1].slice(0, e), "0").toString().length; //To check if it have leading zeros hence 0.00456 can become 0.456
n[1] = BigArith.add(n[1].slice(0, e), "1").toString();
var z2 = n[1].length;
if(z0 != z1){//Has leading zero
n[1] = "0".repeat(z0-z1) + n[1];
}
if(z2 > z1){
if(n[1][0] != "0"){
n[0] = BigArith.add(n[0], "1").toString();
n[1] = "0".repeat(e);
}
else{
n[1] = n[1].substr(1);
}
}
}
else n[1] = n[1].slice(0, e);
}
n = n[0]+((n[1]!="0")?("."+n[1]):"");
}
else n=n.toString()+((BigArith.compare(e, "0") == 1)?("."+"0".repeat(e)):"");
return n;
}
/**
* Random number between 0 and 1 (1 exclusive)
* function random
* @returns {BigArith} - any number between 0 and 1 (1 exclusive)
* Dependent on Math.random(), floor(), toString(), valueOf()
*/
BigArith.random=function(){
var len = new BigArith(Math.random()*new BigArith().decimalSupport).floor().valueOf();
var n = "0";
for(var i = 0; i < len; i++){
n += new BigArith(Math.random()*10).floor().toString();
}
return (n == "0")?new BigArith(n):(new BigArith("0."+n.slice(1)));
}
/**
* Random integer between min and max (min inclusive, max exclusive)
* function randomInt
* @param {number|string|BigArith} min minimum integer that can be returned (inclusive)
* @param {number|string|BigArith} max maximum integer that can be returned (exclusive)
* @returns {BigArith} - any integer between min and max
* Dependent on static random(), floor(), toString(), multiply(), subtract(), add(), ceil()
*/
BigArith.randomInt=function(min, max){
var min = new BigArith(min).floor();
var max = new BigArith (max).ceil();
if(isNaN(min) || isNaN(max)) return NaN;
return (BigArith.random().multiply(BigArith.subtract(max, min)).add(min)).floor(); // floor((ran()*(max-min))+min)
}
/**
* Word representation of this.value
* @return {string} - this.value in English short scale naming system words e.g "one billion" for "1000000000".
* Throw error if value of this.value is higher than 1x10^124 - (0.0{199}1)
* Dependent on w_Dict2()
*/
BigArith.prototype.toWords = function(){
var n = this.value, sign = false;
if(this.value[0] == "-"){
n = this.value.substr(1);
sign = true;
}
else n=this.value;
n = n.split(".");
if(typeof n[0] == 'undefined') n[0] = "0";
if(typeof n[1] == 'undefined') n[1] = "0";
n[0] = n[0].replace(/^[0]*/g,""); if(n[0] == '') n[0] = "0";
n[1] = n[1].replace(/[0]*$/g,"");
if(n[0].length > this.wordSupport+3) throw new RangeError("Value higher than the recently supported range");
if(n[1].length > this.decimalSupport) throw new RangeError("Length of mantissa value greater than supported length");
//Characteristic part
//Break into chunks of 3 digits e.g. ["1","000"] for "1000"
var chunk = [], c = n[0];
for(var i = c.length; i > -1; i-=3){
chunk.unshift(c.slice((i-3>0)?i-3:0, i));
}(chunk[0] == "")?chunk.shift():0;
var word = "";
for(var i = 0; i < chunk.length; i++){
var m = chunk[i];
if(m =="000") continue;
if(m.length == 3){
if(m[0] != "0"){
word += this.w_Dict2(m[0]) + " hundred ";
if(m[1] + m[2] != "00") word += "and "
}
if(m[1] == "1") word += " "+this.w_Dict2(m[1]+m[2]);
else if(m[1] > "1") word += " "+this.w_Dict2(m[1]+"0");
if(m[2] != "0" && m[1] != "1") word += " "+this.w_Dict2(m[2]);
}
if(m.length == 2){
if(m[0] == "1")
{
word += " "+this.w_Dict2(m[0]+m[1]);
}
else{
if(m[0] != "0")
word += " "+this.w_Dict2(m[0]+"0");
if(m[1] != "0")
word += " "+this.w_Dict2(m[1]);
}
}
if(m.length == 1){
if(m[0] != "0")
word += " "+this.w_Dict2(m[0]);
else
word = this.w_Dict2(m[0]);
}
word += " "+this.w_Dict2("0".repeat(3*(chunk.length-i-1))) + " ";
}
//Mantissa part
if(n[1] != "") word += " point";
for(var i = 0; i < n[1].length; i++){
word += " "+this.w_Dict2(n[1][i]);
}
return (sign?"negative ":"") + word.replace(/\s+/g," ").trim();
}
/**
* Add n to this.value
* function add
* @param {number|string|BigArith} The summand with this.value as the second summand
* @returns {BigArith} - sum of this.value and @param
* Dependent of the static add()
*/
BigArith.prototype.add = function(n){
return BigArith.add(this.value, n);
}
/**
* Add two numbers together
* function add
* @param {number|string|BigArith} A summand.
* @param {number|string|BigArith} A summand.
* @returns {BigArith} - sum of a and b
* Dependent on toString(), floor(), substract(), abs(), max(), valueOf()
*/
BigArith.add = function(a, b){
var a = new BigArith(a);
var b = new BigArith(b);
var signFlag = "";
if(isNaN(a) || isNaN(b))
return NaN;
if(a.isNegative() && b.isPositive())
return BigArith.subtract(b, a.abs());
if(a.isPositive() && b.isNegative())
return BigArith.subtract(a, b.abs());
if(a.isNegative() && b.isNegative()){
signFlag = "-";
a = a.abs();
b = b.abs();
}
a = a.toString().split(".");
b = b.toString().split(".");
(typeof(a[1]) == 'undefined')?a[1]="0":0;
(typeof(b[1]) == 'undefined')?b[1]="0":0;
var max = BigArith.max(a[1].length, b[1].length).valueOf();
a[1] += "0".repeat(max - a[1].length);
b[1] += "0".repeat(max - b[1].length);
a = a[0] + a[1];
b = b[0] + b[1];
var result = "";
var flag = 0;
for(var i = a.length-1, j = b.length-1; i >= 0 || j >= 0; i--, j--)
{
var z = a.charAt(i)*1 + b.charAt(j)*1 + flag;
if(z>9 && (i>0 || j>0))
{
flag = new BigArith(z/10).floor().valueOf();
result = (z-flag*10)+result;
}
else
{
result = z+result;
flag = 0;
}
}
result = result.slice(0, result.length - max) + "." + result.slice(result.length - max);
result = result.replace(/^0+/g,"")/*Remove front zeros*/.replace(/\.0+$/g,"")/*Remove zeros after decimal point zeros*/;
if(result[0] == ".") result = "0" + result;
return ((result == "")? new BigArith("0") : new BigArith(((signFlag=="")?"":"-")+result));
}
/**
* Subtract n from this.value
* function subtract
* @param {number|string|BigArith} The subtrahend with this.value as the minuend
* @returns {BigArith} - difference of this.value and @param
* Dependent on static subtract
*/
BigArith.prototype.subtract=function(n){
return BigArith.subtract(this.value, n);
}
/**
* Subtract b from a
* function subtract
* @param {number|string|BigArith} The Minuend
* @param {number|string|BigArith} The subtrahend
* @returns {BigArith} - difference of a and b
* Dependent on add(), abs(), toString(), compare(), max(), valueOf()
*/
BigArith.subtract=function(a, b){
var a = new BigArith(a);
var b = new BigArith(b);
if(isNaN(a) || isNaN(b))
return NaN;
if(a.isNegative() && b.isPositive())
return BigArith.add(a, "-"+b.toString());
if(a.isPositive() && b.isNegative())
return BigArith.add(a, b.abs());
if(a.isNegative() && b.isNegative()){
//swap the absolute parameters
var temp = a.abs();
a = b.abs();
b = temp;
}
a = a.toString().split(".");
b = b.toString().split(".");
(typeof(a[1]) == 'undefined')?a[1]="0":0;
(typeof(b[1]) == 'undefined')?b[1]="0":0;
var max = BigArith.max(a[1].length, b[1].length).valueOf();
a[1] += "0".repeat(max - a[1].length);
b[1] += "0".repeat(max - b[1].length);
var signFlag = "";
if(BigArith.compare(a[0]+"."+a[1], b[0]+"."+b[1]) >= 0){
a = a[0]+a[1];
b = b[0]+b[1];
}
else{
//swap the parameters
var temp = a[0]+a[1];
a = b[0]+b[1];
b = temp;
signFlag = "-";
}
a = a.split("");
b = b.split("");
var result = "";
for(var i = a.length-1, j = b.length-1; i >= 0 || j >= 0; i--, j--){
if(isNaN(parseInt(b[j]))) b[j] = "0";
if(parseInt(a[i]) >= parseInt(b[j])){
result = (parseInt(a[i]) - parseInt(b[j])).toString() + result;
}
else if(parseInt(a[i]) < parseInt(b[j])){
if(i == 0)
result = (parseInt(a[i]) - parseInt(b[j])).toString() + result;
else{
result = (parseInt(a[i])+10 - parseInt(b[j])).toString() + result;
a[i-1] = parseInt(a[i-1])-1;
}
}
}
result = result.slice(0, result.length - max) + "." + result.slice(result.length - max);
result = result.replace(/^0+/g,"")/*Remove front zeros*/.replace(/\.0+$/g,"")/*Remove zeros after decimal point zeros*/;
if(result[0] == ".") result = "0" + result;
return ((result == "")? new BigArith("0") : new BigArith((signFlag+result)));
}
/**
* Multiplies n and this.value
* function multiply
* @param {number|string|BigArith} - the multiplier with this.value as the multiplicand
* @returns {BigArith} - product of this.value and @param
* Dependent on static multiply
*/
BigArith.prototype.multiply=function(n){
return BigArith.multiply(this.value, n);
}
/**
* Multiplies a and b
* function multiply
* @param {number|string|BigArith} - the multiplicand
* @param {number|string|BigArith} - the multiplier
* @returns {BigArith} - product of a and b
* Dependent on toString(), abs(), max(), static add(), valueOf()
*/
BigArith.multiply=function(a, b){
var a = new BigArith(a);
var b = new BigArith(b);
var signFlag = "";
if(isNaN(a) || isNaN(b)) return NaN;
if((a.isNegative() || b.isNegative()) && !(a.isNegative() && b.isNegative())) signFlag = "-";
a = a.abs().toString().split(".");
b = b.abs().toString().split(".");
(typeof(a[1]) == 'undefined')?a[1]="0":0;
(typeof(b[1]) == 'undefined')?b[1]="0":0;
var max = BigArith.max(a[1].length, b[1].length).valueOf();
a[1] += "0".repeat(max - a[1].length);
b[1] += "0".repeat(max - b[1].length);
a = a[0] + a[1];
b = b[0] + b[1];
var results = [];
for(var i = a.length-1; i >= 0; i--){
var subSum = "";
var flag = 0;
if(i < a.lastIndexOf(a.charAt(i))){ /* Do not need to compute already computed values, just copy answer from previous computation*/
results.push(results[a.length-1-a.lastIndexOf(a.charAt(i))]);
continue;
}
else{
for(var j = b.length-1; j >= 0; j--){
var z = a.charAt(i)*b.charAt(j)+flag;
if(z>9 && j>0){
flag = new BigArith(z/10).floor().valueOf();
subSum = (z-flag*10)+subSum;
}
else{
subSum = z+subSum;
flag = 0;
}
}
}
results.push(subSum);
}
// Sum all the answers
var result = "0";
for(var i = 0; i < results.length; i++) result = BigArith.add(result, results[i]+"0".repeat(i));
//Put the decimal point in the apropriate place
result = result.toString(); //It's a BigArith
if(max*2 > result.length) result = "0".repeat(max*2 - result.length) + result; //Problem with slice if result is shorter than max*2
result = result.slice(0, result.length - max*2) + "." + result.slice(result.length - max*2);
return ((BigArith.compare(new BigArith(result),0) == 0)?new BigArith("0"):new BigArith(signFlag+result));
}
/**
* Return this.value%n (reminder of this.value/n)
* function modulus
* @param {string|number|BigArth} n The divisor with this.value as the dividend
* @returns {BigArith} reminder of this.value/n
* Dependent on static modulus
*/
BigArith.prototype.modulus=function(n){
return BigArith.modulus(this.value, n);
}
/**
* Return a%b (reminder of a/b)
* function modulus
* @param {string|number|BigArth} a the dividend
* @param {string|number|BigArth} b the divisor.
* @returns {BigArith} - reminder of a/b
* Dependent on static compare, isInteger, isNegative, divWithRem, abs, static multiply, static subtract, static divide, toString
*/
BigArith.modulus=function(a, b){
var a = new BigArith(a);
var b = new BigArith(b);
if(BigArith.compare(b, "0") == 0 || isNaN(a) || isNaN(b)) return NaN;
if(a.isInteger() && b.isInteger())
return new BigArith(((a.isNegative())?"-":"")+BigArith.divWithRem(a, b)[1]);
else
return new BigArith(((a.isNegative())?"-":"")+BigArith.subtract(a.abs(), BigArith.multiply(BigArith.divide(a.abs(), b.abs()).toString().split(".")[0], b.abs())));
}
/**
* Return this.valus/n (division of this.valus and n)
* function divide
* @param {string|number|BigArth} The divisor with this.value as the dividend.
* @returns {BigArith} - The quotient to "decimalSupport" decimal places when necessary.
*/
BigArith.prototype.divide=function(n){
return BigArith.divide(this.value, n);
}
/**
* Return a/b (division of a/b)
* function divide
* @param {string|number|BigArth} The dividend.
* @param {string|number|BigArth} The divisor.
* @returns {BigArith} - The quotient to "decimalSupport" decimal places when necessary.
*/
BigArith.divide=function(a, b){
return BigArith.div(a, b, new BigArith().decimalSupport);
}
/**Helper**/
BigArith.div=function(a, b, d){
var a = new BigArith(a).toString().split(".");
var b = new BigArith(b).toString().split(".");
//Note where the decimal points are and remove them
var numeratorIndex = 0;
var denominatorIndex = 0;
if(typeof a[1] != "undefined")
numeratorIndex = a[1].length;
if(typeof b[1] != "undefined")
denominatorIndex = b[1].length;
a = a[0] + ((typeof a[1] != "undefined")?a[1]:"");
b = b[0] + ((typeof b[1] != "undefined")?b[1]:"");
var result = BigArith.divWithRem(a, b);
var rem = result[1];
var remResult = "0.";
/* If the decimal place index of denominator - numerator is positive,
we are likely going to encroach into the 200 decimal result
when shifting the decimal pointto the left. The best is to start count from -(denominator-numerator)
instead of 0 in this case.
*/
var count = (denominatorIndex-numeratorIndex>0)?(-1*(denominatorIndex-numeratorIndex)):0, c = 0;
var flag = false;
while(BigArith.compare(rem, "0") == 1 && BigArith.compare(count, d+1) == -1){
rem += "0";
var j = BigArith.divWithRem(rem, b);
remResult += j[0];
rem = j[1];
/*Don't count yet if quotient is still all 0's
This takes care of (x/x.y) returning (x.x) instead of (x.y)
where x is any single digit, and y is any 200 digits*/
if(j[0] > 0) flag = true; if(!flag) c++;
if(c > 201) break; //if we have gotten 0.00{199 more 0's}, no need to continue
if(flag)count++;
}
remResult = remResult.replace(/\-/g,"");
if(remResult == "0.") remResult = "0.0";
result = result[0] + "." + remResult.split(".")[1];
var dPosition = (result.indexOf(".") == -1)?result.length : result.indexOf("."); // decimal position in answer
//Numerator decimal point means we shift the decimal point in answer forward
//Denominator decimal point means we shift the decimal point in answer backward
dPosition = dPosition+denominatorIndex-numeratorIndex;
result = result.split(".");
if(dPosition < 0){
result = "0." + "0".repeat(-1*dPosition) + result[0] + result[1];
}
else if(dPosition == 0){
result = "0." + result[0] + result[1];
}
else if(dPosition > 0){
if(dPosition <= result[0].length){
result = result[0].slice(0, dPosition) + "." + result[0].slice(dPosition) + result[1];
}
else{
dPosition -= result[0].length;
result = result[0] + result[1].slice(0, dPosition) +
((dPosition-result[1].length>0)?"0".repeat(dPosition-result[1].length):"") + "." +
result[1].substr(dPosition)+ "0";
}
}
return new BigArith(new BigArith(result.replace(/^0+/,"")).toFixed(d));
};
/**
* Return a/b (division of a/b)
* function divWithRem
* @param {string|number|BigArth} a The dividend. Must always be integers.
* @param {String|Number|BigArth} b The divisor. Must always be integers.
* @returns {Array of "strings of digits" (integer)} - [quotient, reminder]
*/
BigArith.divWithRem=function(a, b){
var a = new BigArith(a);
var b = new BigArith(b);
if(isNaN(a) || isNaN(b))
return NaN;
if(!a.isInteger() || !b.isInteger()) throw new TypeError("divWithRem accepts only integers. Non integers passed in");
if(BigArith.compare(b, 0) == 0) throw new RangeError("Division by zero");
var signFlag = false;
if((a.isNegative() || b.isNegative()) && !(a.isNegative() && b.isNegative())) signFlag = true; //Only one of the parameters is negative
a = a.abs().toString();
b = b.abs().toString();
var aLen = a.length;
var aSub = "";
var result = "0";
var hold = a;
for(var i = 0; i < aLen; i++){
aSub += a[i];
if(BigArith.compare(aSub, "0") == 0){result += "0";}
else if(BigArith.compare(b, aSub) == 1){result += "0"; continue;}
else{
var count = 0;
hold = aSub;
while(BigArith.compare(hold, b) != -1){
hold = BigArith.subtract(hold, b);
count++;
}
result += count;
}
aSub = hold.toString();
}
hold = new BigArith(aSub).toString();
result = result.replace(/^0*/g,"");
result = (result == "")? "0" : result;
return [((signFlag)?"-":"")+result, hold.toString()];
};
/* [UNSTABLE - Takes a lot of computation time]
* Returns the sine of an angle (in degree)
* function sin
* @param {string|number|BigArth} n The angle in degree
* @returns {BigArith} - sine of n
* x - x^3/3! + x^5/5! - x^7/7! + x^9/9! - ... (x in radian)
*/
BigArith.sin=function(n){
//Have to use PI to atleast 203 decimal places so new BigArith("PI") won't work here as it is to 200 decimal place
var x = BigArith.div(new BigArith("3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975"), 180, new BigArith().decimalSupport+3).multiply(n);
var tolerance = new BigArith("0." + "0".repeat(new BigArith().decimalSupport+3) + "1");
var sin = new BigArith("0");
var i = 1;
var term = x.toString(), _x = x.toString();
var sign = true;
while(BigArith.compare(term, tolerance) == 1){
if(i > 1){
_x = BigArith.multiply(_x, x.square()).toString().split(".");
//only the first 203 decimal digit is needed as _x gets very large quickly
_x = _x[0] + "." +_x[1].substr(0, new BigArith().decimalSupport+3);
term = BigArith.div(_x, BigArith.factorial(i), new BigArith().decimalSupport+3).toString();
}
if(sign)
sin = BigArith.add(sin, term);
else
sin = BigArith.subtract(sin, term);
sign = !sign;
i += 2;
}
return new BigArith(sin.toFixed(new BigArith().decimalSupport));
}
/* [UNSTABLE - Takes a lot of computation time]
* Returns the cosine of an angle (when angle is in degrees)
* function cos
* @param {string|number|BigArth} n The angle in degrees
* @returns {BigArith} - cosine of n
* 1 - x^2/2! + x^4/4! - x^6/6! + x8/8! - ... (x in radian)
*/
BigArith.cos=function(n){
//Have to use PI to atleast 203 decimal places so new BigArith("PI") won't work here as it is to 200 decimal place
var x = BigArith.div(new BigArith("3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975"), 180, new BigArith().decimalSupport+3).multiply(n);
var tolerance = new BigArith("0." + "0".repeat(new BigArith().decimalSupport+3) + "1");
var cos = new BigArith("0");
var i = 0;
var term = "1", _x = "1";
var sign = true;
while(term == "1" || BigArith.compare(term, tolerance) == 1){
if(i > 1){
_x = BigArith.multiply(_x, x.square());
if(BigArith.compare(_x, "0") == 0) break;
_x = _x.toString().split(".");
//the first 203 decimal digit is needed as _x gets very large quickly
_x = _x[0] + "." +_x[1].substr(0, new BigArith().decimalSupport+3);
term = BigArith.div(_x, BigArith.factorial(i), new BigArith().decimalSupport+3).toString();
}
if(sign)
cos = BigArith.add(cos, term);
else
cos = BigArith.subtract(cos, term);
sign = !sign;
i += 2;
}
return new BigArith(cos.toFixed(new BigArith().decimalSupport));
}
/* [UNSTABLE - Takes a lot of computation time]
* Returns the tangent of an angle (when angle is in degrees)
* function cos
* @param {string|number|BigArth} n The angle in degrees
* @returns {BigArith} - tangent of n
* tan = sin/cos
*/
BigArith.tan=function(n){
var sin = BigArith.sin(n);
var cos = BigArith.cos(n);
return BigArith.divide(sin, cos);
}
/**
* Word Dictionary
* function w_Dict
* @param {string} - Word value for numbers e.g "one"
* @returns {string} - String value of @param e.g "1"
*/
BigArith.prototype.w_Dict=function(w){
/*Word Dictionary*/
var w_Dict = [];
w_Dict["zero"] = "0"; w_Dict["one"] = "1"; w_Dict["two"] = "2"; w_Dict["three"] = "3"; w_Dict["four"] = "4"; w_Dict["five"] = "5"; w_Dict["six"] = "6"; w_Dict["seven"] = "7"; w_Dict["eight"] = "8"; w_Dict["nine"] = "9"; w_Dict["ten"] = "10";
w_Dict["eleven"] = "11"; w_Dict["twelve"] = "12"; w_Dict["thirteen"] = "13"; w_Dict["fourteen"] = "14"; w_Dict["fifteen"] = "15"; w_Dict["sixteen"] = "16"; w_Dict["seventeen"] = "17"; w_Dict["eighteen"] = "18"; w_Dict["nineteen"] = "19"; w_Dict["twenty"] = "20";
w_Dict["thirty"] = "30"; w_Dict["forty"] = "40"; w_Dict["fifty"] = "50"; w_Dict["sixty"] = "60"; w_Dict["seventy"] = "70"; w_Dict["eighty"] = "80"; w_Dict["ninety"] = "90"; w_Dict["hundred"] = "0".repeat(2);
w_Dict["thousand"] = "0".repeat(3); w_Dict["million"]="0".repeat(6);w_Dict["billion"]="0".repeat(9);w_Dict["trillion"]="0".repeat(12);w_Dict["quadrillion"]="0".repeat(15);w_Dict["quintillion"]="0".repeat(18);w_Dict["sextillion"]="0".repeat(21);w_Dict["septillion"]="0".repeat(24);w_Dict["octillion"]="0".repeat(27);w_Dict["nonillion"]="0".repeat(30);w_Dict["decillion"]="0".repeat(33);w_Dict["undecillion"]="0".repeat(36);w_Dict["duodecillion"]="0".repeat(39);w_Dict["tredecillion"]="0".repeat(42);w_Dict["quattuordecillion"]="0".repeat(45);w_Dict["quindecillion"]="0".repeat(48);w_Dict["sexdecillion"]="0".repeat(51);w_Dict["septendecillion"]="0".repeat(54);w_Dict["octodecillion"]="0".repeat(57);w_Dict["novemdecillion"]="0".repeat(60);w_Dict["vigintillion"]="0".repeat(63);w_Dict["unvigintillion"]="0".repeat(66);w_Dict["duovigintillion"]="0".repeat(69);w_Dict["trevigintillion"]="0".repeat(72);w_Dict["quattuorvigintillion"]="0".repeat(75);w_Dict["quinvigintillion"]="0".repeat(78);w_Dict["sexvigintillion"]="0".repeat(81);w_Dict["septenvigintillion"]="0".repeat(84);w_Dict["octavigintillion"]="0".repeat(87);w_Dict["novemvigintillion"]="0".repeat(90);w_Dict["trigintillion"]="0".repeat(93);w_Dict["untrigintillion"]="0".repeat(96);w_Dict["duotrigintillion"]="0".repeat(99);w_Dict["tretrigintillion"]="0".repeat(102);w_Dict["quattuortrigintillion"]="0".repeat(105);w_Dict["quintrigintillion"]="0".repeat(108);w_Dict["sextrigintillion"]="0".repeat(111);w_Dict["septentrigintillion"]="0".repeat(114);w_Dict["octotrigintillion"]="0".repeat(117);w_Dict["novemtrigintillion"]="0".repeat(120);w_Dict["quadragintillion"]="0".repeat(123);w_Dict["unquadragintillion"]="0".repeat(126);w_Dict["duoquadragintillion"]="0".repeat(129);w_Dict["trequadragintillion"]="0".repeat(132);w_Dict["quattuorquadragintillion"]="0".repeat(135);w_Dict["quinquadragintillion"]="0".repeat(138);w_Dict["sexquadragintillion"]="0".repeat(141);w_Dict["septenquadragintillion"]="0".repeat(144);w_Dict["octaquadragintillion"]="0".repeat(147);w_Dict["novemquadragintillion"]="0".repeat(150);w_Dict["quinquagintillion"]="0".repeat(153);w_Dict["unquinquagintillion"]="0".repeat(156);w_Dict["duoquinquagintillion"]="0".repeat(159);w_Dict["trequinquagintillion"]="0".repeat(162);w_Dict["quattuorquinquagintillion"]="0".repeat(165);w_Dict["quinquinquagintillion"]="0".repeat(168);w_Dict["sexquinquagintillion"]="0".repeat(171);w_Dict["septenquinquagintillion"]="0".repeat(174);w_Dict["octaquinquagintillion"]="0".repeat(177);w_Dict["novemquinquagintillion"]="0".repeat(180);w_Dict["sexagintillion"]="0".repeat(183);w_Dict["unsexagintillion"]="0".repeat(186);w_Dict["duosexagintillion"]="0".repeat(189);w_Dict["tresexagintillion"]="0".repeat(192);w_Dict["quattuorsexagintillion"]="0".repeat(195);w_Dict["quinsexagintillion"]="0".repeat(198);w_Dict["sexsexagintillion"]="0".repeat(201);w_Dict["septensexagintillion"]="0".repeat(204);w_Dict["octasexagintillion"]="0".repeat(207);w_Dict["novemsexagintillion"]="0".repeat(210);w_Dict["septuagintillion"]="0".repeat(213);w_Dict["unseptuagintillion"]="0".repeat(216);w_Dict["duoseptuagintillion"]="0".repeat(219);w_Dict["treseptuagintillion"]="0".repeat(222);w_Dict["quattuorseptuagintillion"]="0".repeat(225);w_Dict["quinseptuagintillion"]="0".repeat(228);w_Dict["sexseptuagintillion"]="0".repeat(231);w_Dict["septenseptuagintillion"]="0".repeat(234);w_Dict["octaseptuagintillion"]="0".repeat(237);w_Dict["novemseptuagintillion"]="0".repeat(240);w_Dict["octagintillion"]="0".repeat(243);w_Dict["unoctogintillion"]="0".repeat(246);w_Dict["duooctogintillion"]="0".repeat(249);w_Dict["treoctogintillion"]="0".repeat(252);w_Dict["quattuoroctogintillion"]="0".repeat(255);w_Dict["quinoctogintillion"]="0".repeat(258);w_Dict["sexoctogintillion"]="0".repeat(261);w_Dict["septenoctogintillion"]="0".repeat(264);w_Dict["octaoctogintillion"]="0".repeat(267);w_Dict["novemoctogintillion"]="0".repeat(270);w_Dict["nonagintillion"]="0".repeat(273);w_Dict["unnonagintillion"]="0".repeat(276);w_Dict["duononagintillion"]="0".repeat(279);w_Dict["trenonagintillion"]="0".repeat(282);w_Dict["quattuornonagintillion"]="0".repeat(285);w_Dict["quinnonagintillion"]="0".repeat(288);w_Dict["sexnonagintillion"]="0".repeat(291);w_Dict["septennonagintillion"]="0".repeat(294);w_Dict["octanonagintillion"]="0".repeat(297);w_Dict["novemnonagintillion"]="0".repeat(300);w_Dict["centillion"]="0".repeat(303);w_Dict["cenuntillion"]="0".repeat(306);w_Dict["cendotillion"]="0".repeat(309);w_Dict["centretillion"]="0".repeat(312);w_Dict["cenquattuortillion"]="0".repeat(315);w_Dict["cenquintillion"]="0".repeat(318);w_Dict["censextillion"]="0".repeat(321);w_Dict["censeptentillion"]="0".repeat(324);w_Dict["cenoctotillion"]="0".repeat(327);w_Dict["cennovemtillion"]="0".repeat(330);w_Dict["cendecillion"]="0".repeat(333);w_Dict["cenundecillion"]="0".repeat(336);w_Dict["cendodecillion"]="0".repeat(339);w_Dict["centredecillion"]="0".repeat(342);w_Dict["cenquattuordecillion"]="0".repeat(345);w_Dict["cenquindecillion"]="0".repeat(348);w_Dict["censexdecillion"]="0".repeat(351);w_Dict["censeptendecillion"]="0".repeat(354);w_Dict["cenoctodecillion"]="0".repeat(357);w_Dict["cennovemdecillion"]="0".repeat(360);w_Dict["cenvigintillion"]="0".repeat(363);w_Dict["cenunvigintillion"]="0".repeat(366);w_Dict["cendovigintillion"]="0".repeat(369);w_Dict["centrevigintillion"]="0".repeat(372);w_Dict["cenquattuorvigintillion"]="0".repeat(375);w_Dict["cenquinvigintillion"]="0".repeat(378);w_Dict["censexvigintillion"]="0".repeat(381);w_Dict["censeptenvigintillion"]="0".repeat(384);w_Dict["cenoct