RPG Maker MV
CXJ Core - BigInt v1.0.1
Sometimes you need larger numbers, and sometimes you need really big numbers. And sometimes, you need enough numbers to make any computer crash. Well, this script gives you the option to create really big numbers, and do simple calculations with.
The BigInt object is now part of the CXJCore line of scripts. Even though it is part of it, it's still a stand-alone script, and can even be used outside of RPG Maker MV.
Download (31.41 kB, 871 times downloaded)
This is a simple helper plugin, meant for those with a little bit more programming experience. As such, the end-user is supposed to place this as high as possible. As it doesn't touch any JavaScript class, you can freely use it as you want.
Of course, developers are fully authorized to integrate the code into their own scripts, no strings attached.
You can use this BigInt
object by creating a new CXJScripts.CXJCore.BigInt
instance. If CXJ Core is installed and the Namespace
parameter is set, you
can also call this object from the chosen namespace.
The BigInt
object uses an array to store the big numbers, and each row is
stored as a string. As such, doing simple additions and subtractions isn't
a simple task, which is why it has several new methods that do the job for
you. Do know that because of this, the BigInt
object might be a bit slower
than regular integers.
When creating a new BigInt
object, you can set a default value. From there,
you can use add
, sub
, multiply
, divide
and mod
to modify the current object.
Note that it doesn't create a new object, but it does return the current
object each time, so you can chain commands. This also does mean that every
time you do a modification, the original object does get modified, so if
you want to keep the original, you'll have to clone the current object.
Finally, you can output the current BigInt
as a string using toString
.
Methods
CXJScripts.CXJCore.BigInt(value)
Constructor
This creates a BigInt object, allowing you to create really big integers.
Arguments:
value | optional The value to set this BigInt with |
CXJCore.BigInt.prototype.add(value)
Adds the value the current BigInt
Arguments:
value | The value to modify this BigInt with |
Returns: The current BigInt object
CXJCore.BigInt.prototype.sub(value)
Subtracts the value from the current BigInt
Arguments:
value | The value to modify this BigInt with |
Returns: The current BigInt object
CXJCore.BigInt.prototype.multiply(value)
Multiplies the current BigInt with a value
Arguments:
value | The value to modify this BigInt with |
Returns: The current BigInt object
CXJCore.BigInt.prototype.divide(value)
Divides the current BigInt with a value
Arguments:
value | The value to modify this BigInt with |
Returns: The current BigInt object
CXJCore.BigInt.prototype.mod(value)
Gets the modulus of the current object
Arguments:
value | The value to modify this BigInt with |
Returns: The current BigInt object
CXJCore.BigInt.prototype.compare(value)
Compares two values
Arguments:
value | The value to compare this BigInt with |
Returns: 1 if the current object is bigger than the value, -1 if smaller, and 0 if equal
CXJCore.BigInt.prototype.clone()
Returns: A BigInt object
CXJCore.BigInt.prototype.toString()
Converts the object to a string
Returns: A string with the value of the current object
Download CXJ Core - BigInt v1.0.0 (30.53 kB, 843 times downloaded)
/****************************************************************************** * CXJ_CXJCoreBigInt.js * ****************************************************************************** * CXJ Core - BigInt v1.0.1 * * By G.A.M. Kertopermono, a.k.a. GaryCXJk * ****************************************************************************** * License: ISC * ****************************************************************************** * Copyright (c) 2017, G.A.M. Kertopermono * * * * Permission to use, copy, modify, and/or distribute this software for any * * purpose with or without fee is hereby granted, provided that the above * * copyright notice and this permission notice appear in all copies. * * * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR * * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * ******************************************************************************/ /*: * @plugindesc A JavaScript object that allows for big numbers * @author G.A.M. Kertopermono * * @help * ============================================================================ * = About = * ============================================================================ * * Sometimes you need larger numbers, and sometimes you need really big * numbers. And sometimes, you need enough numbers to make any computer crash. * Well, this script gives you the option to create really big numbers, and * do simple calculations with. * * The BigInt object is now part of the CXJCore line of scripts. Even though * it is part of it, it's still a stand-alone script, and can even be used * outside of RPG Maker MV. * * ============================================================================ * = Usage = * ============================================================================ * * This is a simple helper plugin, meant for those with a little bit more * programming experience. As such, the end-user is supposed to place this as * high as possible. As it doesn't touch any JavaScript class, you can freely * use it as you want. * * Of course, developers are fully authorized to integrate the code into their * own scripts, no strings attached. * * You can use this BigInt object by creating a new CXJScripts.CXJCore.BigInt * instance. If CXJCore is installed and the Namespace parameter is set, you * can also call this object from the chosen namespace. * * The BigInt object uses an array to store the big numbers, and each row is * stored as a string. As such, doing simple additions and subtractions isn't * a simple task, which is why it has several new methods that do the job for * you. Do know that because of this, the BigInt object might be a bit slower * than regular integers. * * When creating a new BigInt object, you can set a default value. From there, * you can use add, sub, multiply, divide and mod to modify the current object. * Note that it doesn't create a new object, but it does return the current * object each time, so you can chain commands. This also does mean that every * time you do a modification, the original object does get modified, so if * you want to keep the original, you'll have to clone the current object. * * Finally, you can output the current BigInt as a string using toString. * * ---------------------------------------------------------------------------- * - Methods - * ---------------------------------------------------------------------------- * * CXJScripts.CXJCore.BigInt(value) * * Constructor. * This creates a BigInt object, allowing you to create really big integers. * * Arguments: * * value - (optional) The value to set this BigInt with * * --- * * CXJCore.BigInt.prototype.add(value) * * Adds the value the current BigInt * * Arguments: * * value - The value to modify this BigInt with * * Returns: The current BigInt object * * --- * * CXJCore.BigInt.prototype.sub(value) * * Subtracts the value from the current BigInt * * Arguments: * * value - The value to modify this BigInt with * * Returns: The current BigInt object * * --- * * CXJCore.BigInt.prototype.multiply(value) * * Multiplies the current BigInt with a value * * Arguments: * * value - The value to modify this BigInt with * * Returns: The current BigInt object * * --- * * CXJCore.BigInt.prototype.divide(value) * * Divides the current BigInt with a value * * Arguments: * * value - The value to modify this BigInt with * * Returns: The current BigInt object * * --- * * CXJCore.BigInt.prototype.mod(value) * * Gets the modulus of the current object * * Arguments: * * value - The value to modify this BigInt with * * Returns: The current BigInt object * * --- * * CXJCore.BigInt.prototype.compare(value) * * Compares two values * * Arguments: * * value - The value to compare this BigInt with * * Returns: 1 if the current object is bigger than the value, -1 if smaller, and 0 if equal * * --- * * CXJCore.BigInt.prototype.clone() * * Clones the current object * * Returns: A BigInt object * * --- * * CXJCore.BigInt.prototype.toString() * * Converts the object to a string * * Returns: A string with the value of the current object * * ============================================================================ * = Compatibility = * ============================================================================ * * This plugin does not overwrite default functionality. * * ============================================================================ * = Changelog = * ============================================================================ * * 1.0.1 (2017-08-29) * * * Fix: Positive integers get stripped of a character * * 1.0.0 (2017-07-17) * ------------------ * * * Initial release * * ============================================================================ * = License = * ============================================================================ * * Copyright (c) 2017, G.A.M. Kertopermono * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * ============================================================================ */ // If it doesn't already exist, create a new CXJScripts object. /** @namespace */ var CXJScripts = CXJScripts || {}; +function(_) { // Creates the CXJCore object and attaches it to the main CXJScripts object var CXJCore = {}; _.CXJCore = CXJCore; var NaNException = function() { this.name = 'BigIntNaN'; this.message = 'Value is not an integer'; } var DivideByZeroException = function() { this.name = 'BigIntDivideByZero'; this.message = 'Divided by zero'; } /** * @constructor * This creates a BigInt object, allowing you to create really big integers. * * @param {int|string|Array|CXJScript.CXJCore.BigInt} The value to set this BigInt with * @return {CXJScript.CXJCore.BigInt} the current BigInt object */ CXJCore.BigInt = function(value) { // Sets the initial values this._isPositive = true; // Whether the BigInt is a positive integer this._intVals = ['0']; // The value of the BigInt in an array // If the value is given, initializes the value if(value) { this._initValue(value); } } /** * Sets the initial value * @param {int|string|Array|CXJScript.CXJCore.BigInt} The value to set the BigInt to * @return {CXJScript.CXJCore.BigInt} the current BigInt object */ CXJCore.BigInt.prototype._initValue = function(value) { // If the value is a BigInt, just clone the values if(value instanceof CXJCore.BigInt) { this._intVals = value._intVals.slice(0); this._isPositive = value._isPositive; return this; } // If the value is not an array, check if it at least is a numeric (string) if(!Array.isArray(value)) { // If it's not a number, throw an error if(isNaN(value)) { throw new NaNException(); } value = value + ''; // If it's not an integer, throw an error if(!/^\-?\d+$/.test(value)) { throw new NaNException(); } // If it's a negative number, make it a positive, // then set the _isPositive flag if(/^\-\d+$/.test(value)) { this._isPositive = false; value = (value + '').slice(1); } // Slices the string into chunks of nine, starting from the end var tempValue = []; while(value.length > 9) { tempValue.push(value.slice(-9)); value = value.slice(0, -9); } // Places the remaining value in the temporary array, // then sets the array as a value tempValue.push(value); value = tempValue; } // Does a check to see if the array only contains integers for(var idx = 0; idx < value.length; idx++) { // It first checks if it's the last row and if it's a negative number. // If that's the case, this BigInt is a negative number. if(idx == (value.length - 1) && /^\-\d+$/.test(value[idx])) { value[idx] = value[idx].slice(1); this._isPositive = false; } /* Throws an array if the string is: * - Not a number; * - Larger than nine characters; * - Not an integer. */ if(isNaN(value[idx]) || value[idx].length > 9 || !/^\d+$/.test(value[idx])) { throw new NaNException(); } } // Sets the value this._intVals = value; return this; } /** * Adds the value the current BigInt * @param {int|string|Array|CXJScript.CXJCore.BigInt} The value to modify this BigInt with * @return {CXJScript.CXJCore.BigInt} the current BigInt object */ CXJCore.BigInt.prototype.add = function(value) { // If the value isn't a BigInt, convert it to a BigInt if(!(value instanceof CXJCore.BigInt)) { value = new CXJCore.BigInt(value); } // If either one but not the other is a negative number, call the subtraction // method instead if(value._isPositive != this._isPositive) { value._isPositive = this._isPositive; return this.sub(value); } var rem = 0; // Remainder var smallIntVals = value._intVals; // Smaller value var bigIntVals = this._intVals; // Larger value var newIntVals = []; // Result array // If the array of the smaller value is bigger than the array of // the larger value, swap these values if(smallIntVals.length > bigIntVals.length) { var tempIntVals = bigIntVals; bigIntVals = smallIntVals; smallIntVals = tempIntVals; } // Iterate over each row and make calculations for(var idx = 0; idx < bigIntVals.length; idx++) { // Set the new value for the current row var newVal = bigIntVals[idx] * 1; // If the smaller value still has rows left, do the addition if(idx < smallIntVals.length) { // Set the added value var addVal = smallIntVals[idx] * 1 + rem; // Set the remainder to zero rem = 0; // Add the two values var newVal = (newVal + addVal) + ''; /* If the new value is bigger than nine characters, set the * remainder to the excess characters, and shorten the new * value to nine characters. */ if(newVal.length > 9) { rem = newVal.slice(0, -9) * 1; newVal = newVal.slice(-9); } } else { // If there are no more rows in the smaller value, add any // remaining larger value rows with any possible remainder newVal+= rem; rem = 0; newVal+= ''; } // Push the new value to the resulting array newIntVals.push(newVal); } // If there's still a remainder, push that to the results if(rem > 0) { newIntVals.push(rem + ''); } //Set the results to the current object, then return this object this._intVals = newIntVals; return this; } /** * Subtracts the value from the current BigInt * @param {int|string|Array|CXJScript.CXJCore.BigInt} The value to modify this BigInt with * @return {CXJScript.CXJCore.BigInt} the current BigInt object */ CXJCore.BigInt.prototype.sub = function(value) { // If the value isn't a BigInt, convert it to a BigInt if(!(value instanceof CXJCore.BigInt)) { value = new CXJCore.BigInt(value); } // If either one but not the other is a negative number, call the addition // method instead if(value._isPositive != this._isPositive) { value._isPositive = this._isPositive; return this.add(value); } var oldVals = this._intVals; // The old value var subVals = value._intVals; // The subtraction value var newVals = []; // The resulting value var isPositive = this._isPositive; // Whether the result is a positive integer if(subVals.length > oldVals.length) { /* If the subtraction value is bigger than the old value, swap the * two values, and reverses the isPositive flag */ isPositive = !isPositive; var tempVals = subVals; subVals = oldVals; oldVals = tempVals; } else if(oldVals.length == subVals.length) { /* If both values are of equal lengths, make sure the old value is still * smaller than the subtraction value, otherwise, swap both and reverse * the isPositive flag */ /* This will check if both values are equal */ var sameCheck = true; for(var idx = oldVals.length - 1; idx >= 0; idx--) { // This will get the current values and compares the two var oldVal = oldVals[idx] * 1; var subVal = subVals[idx] * 1; // In case both values are the same, just skip to the next iteration if(oldVal == subVal) { continue; } /* If the substraction value is bigger than the old value, do the * switch */ if(subVal > oldVal) { isPositive = !isPositive; var tempVals = subVals; subVals = oldVals; oldVals = tempVals; } // In either case, the values are not the same, so this flag will // be set to false, and the loop is aborted sameCheck = false; break; } // If both values are the same, set the current value to zero, since // one value minus an equal value results in zero anyway if(sameCheck) { this._intVals = ['0']; this._isPositive = true; return this; } } // Set the remainder to zero var rem = 0; // Now let's do the subtraction for(var idx = 0; idx < oldVals.length; idx++) { // First set the old value for this row var oldVal = oldVals[idx] * 1; // Set the subtraction value to zero var subVal = 0; // If there is still a row left for the subtraction value, // set this value instead if(idx < subVals.length) { subVal = subVals[idx] * 1; } // Let's subtract the subtraction value plus the remainder from // the old value, then set the remainder to zero var newVal = oldVal - (subVal + rem); rem = 0; // While the new value is smaller than zero, add one to the remainder // and add 1000000000 to the new value while(newVal < 0) { rem++; newVal+= 1000000000; } // Push the new value to the result newVals.push(newVal + ''); } // Finally, set the current value this._isPositive = isPositive; this._intVals = newVals; return this; } /** * Multiplies the current BigInt with a value * @param {int|string|Array|CXJScript.CXJCore.BigInt} The value to modify this BigInt with * @return {CXJScript.CXJCore.BigInt} the current BigInt object */ CXJCore.BigInt.prototype.multiply = function(value) { // If the value isn't a BigInt, convert it to a BigInt if(!(value instanceof CXJCore.BigInt)) { value = new CXJCore.BigInt(value); } // Sets the isPositive to positive if this object and the value are either both // positive or negative var isPositive = this._isPositive == value._isPositive; // Set both values to positive this._isPositive = true; value._isPositive = true; // Turn both values to string var val1 = this.toString(); // This object var val2 = value.toString(); // The multiplication value // If either value is a zero, just return zero, since 0 * x = 0 if(val1 == '0' || val1 == '-0' || val2 == '0' || val2 == '-0') { this._intVals = ['0']; return this; } // If value 1 has more characters than value 2, swap the two values if(val1.length > val2.length) { var tempVal = val1; val1 = val2; val2 = tempVal; } /* Set an array that stores the results * This array will contain strings that essentially are results of * sub-multiplications. For example, for 12 * 34, it will store: * ['34', '680'] * All values will later be added together. */ var multi = []; for(var idx = 0; idx < val1.length; idx++) { // Sets the current value to an empty string var mVal = ''; // Add a zero for each character's position, for example, if it was // the character second to the right, it would add one zero for(var idx2 = 0; idx2 < idx; idx2++) { mVal+= '0'; } // Take a number at a certain position from the end from value 1 // This number will be used to multiply value 2 with var num = val1.slice(-(idx + 1)).slice(0, 1) * 1; // Set the modification number to 0 // Essentially this could be seen as the remainder, since we're only // going to store one character at a time var mod = 0; for(var idx2 = 0; idx2 < val2.length; idx2++) { // Take one character from value 2 to multiply with var mNum = val2.slice(-(idx2 + 1)).slice(0, 1) * 1; // Multiply number 1 with number 2, then add the modification number var newNum = ((num * mNum) + mod) + ''; // Set the modification number to 0 mod = 0; // If the new number has more than one character, slice all but the // last one and place that part into the modification number if(newNum.length > 1) { mod = newNum.slice(0, -1) * 1; newNum = newNum.slice(-1); } // Prepend the new number to the string set at the beginning of // the first for-loop mVal = newNum + mVal; } // Prepend the remaining numbers to the value, and add that value to the // array if(mod > 0) { mVal = mod + '' + mVal; } multi.push(mVal); } // Add all values together this._intVals = ['0']; for(var idx = 0; idx < multi.length; idx++) { this.add(multi[idx]); } // Set the isPositive flag this._isPositive = isPositive; return this; } /** * Divides the current BigInt with a value * @param {int|string|Array|CXJScript.CXJCore.BigInt} The value to modify this BigInt with * @return {CXJScript.CXJCore.BigInt} the current BigInt object */ CXJCore.BigInt.prototype.divide = function(value) { // If the value isn't a BigInt, convert it to a BigInt if(!(value instanceof CXJCore.BigInt)) { value = new CXJCore.BigInt(value); } // Sets the isPositive to positive if this object and the value are either both // positive or negative var isPositive = this._isPositive == value._isPositive; // Stores the old isPositive value for this object var oldIsPositive = this._isPositive; // Sets both isPositive values to positive this._isPositive = true; value._isPositive = true; // Modulus mode is false var mod = false; // If the second argument is true, set modulus mode to true if(arguments.length > 1) { mod = arguments[1]; } // If modulus mode, just set the isPositive value to the old isPositive value if(mod) { isPositive = oldIsPositive; } // Compare the two values var cmp = this.compare(value); if(cmp == 0) { // If both values are equal, set isPositive to the stored isPositive value this._isPositive = isPositive; // If modulus mode, set this to 0, otherwise to 1 if(mod) { this._intVals = ['0']; } else { this._intVals = ['1']; } return this; } // Set the division value var divVal = value.toString(); // If the division value is 0, return a divide by zero error if(divVal == '0' || divVal == '-0') { this._isPositive = oldIsPositive; return new DivideByZeroException(); } // If this object is smaller than the division value... if(cmp == -1) { /* If modulus mode, just return the current object unaltered, * otherwise, set it to zero * Since it's an integer, we'll treat the value as rounded down, * and since a small number divided by a big number is always * smaller than one, it's rounded to zero */ if(mod) { this._isPositive = isPositive; } else { this._intVals = ['0']; } return this; } // Set the old value var oldVal = this.toString(); var mults = []; // Store multiples of the dividing value for(var idx = 0; idx < 9; idx++) { var dV = new CXJCore.BigInt(divVal); dV.multiply(idx + 1); mults.unshift(dV); } var val = ''; // The resulting value var dN = ''; // A buffer to store the number being processed // Repeat until the old value is an empty string while(oldVal != '') { // Add one character to the buffer dN+= oldVal.slice(0, 1); // Conver the buffer to a BigInt var dNVal = new CXJCore.BigInt(dN); // Chop the first character off the old value oldVal = oldVal.slice(1); // If the dividing value is still bigger than the buffer, add a // zero and continue with the next iteration if(value.compare(dNVal) > 0) { val+= '0'; continue; } // Go through the multiples of the dividing value, starting with // the highest (9 * dividing value) for(var idx = 0; idx < mults.length; idx++) { // Go to the next iteration if the multiple is bigger than the // buffer if(mults[idx].compare(dNVal) > 0) { continue; } // Subtract the multiple from the buffer, then set the buffer // back as a string, and finally add the multiplier to the value dNVal.sub(mults[idx]); dN = dNVal.toString(); val+= (9 - idx) + ''; break; } } // If modulus mode, set the buffer as the value if(mod) { val = dN; } else { // Removes any leading zeroes, then adds a zero if the string is empty val = val.replace(/^0+/,''); if(!val) { val = '0'; } } // Reinitialize the value, then set the isPositive to the correct value this._initValue(val); this._isPositive = isPositive; return this; } /** * Gets the modulus of the current object * @param {int|string|Array|CXJScript.CXJCore.BigInt} The value to modify this BigInt with * @return {CXJScript.CXJCore.BigInt} the current BigInt object */ CXJCore.BigInt.prototype.mod = function(value) { // This will just call the divide method with the extra argument that // basically just uses the modulus instead of the regular divide return this.divide(value, true); } /** * Compares two values * @param {int|string|Array|CXJScript.CXJCore.BigInt} The value to compare this BigInt with * @return {int} 1 if the current object is bigger than the value, -1 if smaller, and 0 if equal */ CXJCore.BigInt.prototype.compare = function(value) { // If the value isn't a BigInt, convert it to a BigInt if(!(value instanceof CXJCore.BigInt)) { value = new CXJCore.BigInt(value); } // If one is positive and the other don't, return if the current value is bigger or not if(this._isPositive != value._isPositive) { return this._isPositive ? 1 : -1; } // Get the string value of each, removing the leading minus sign var valA = this.toString().replace(/^\-/,''); var valB = value.toString().replace(/^\-/,''); // If both values are equal, return zero if(valA == valB) { return 0; } // If the lengths are not equal, return 1 if this object is bigger, or -1 if it isn't if(valA.length != valB.length) { return valA.length > valB.length ? 1 : -1; } // Do the same check for each character for(var idx = 0; idx < valA.length; idx++) { var cA = valA.slice(idx, idx + 1) * 1; var cB = valB.slice(idx, idx + 1) * 1; if(cA == cB) { continue; } return cA > cB ? 1 : -1; } return 0; } /** * Clones the current object * @return {CXJScript.CXJCore.BigInt} A BigInt object */ CXJCore.BigInt.prototype.clone = function() { return new CXJCore.BigInt(this); } /** * Converts the object to a string * @return {string} a string with the value of the current object */ CXJCore.BigInt.prototype.toString = function() { // Sets an empty string var str = ''; // Iterates through each row for(var idx = 0; idx < this._intVals.length; idx++) { // First retrieves the length of the string, then pads it with zeroes to make its length exactly 9 var strLength = this._intVals[idx]; var strPad = '000000000'.slice(0, -strLength.length); str = strPad + this._intVals[idx] + str; } // Removes any leading zeroes, then adds a zero if the string is empty str = str.replace(/^0+/,''); if(!str) { str = '0'; } // Adds a minus sign if it's a negative number if(str != '0' && !this._isPositive) { str = '-' + str; } // Returns the string return str; } }(CXJScripts);
Creator: GaryCXJk
Release date: 2017-07-17
Downloads: 871
Optional compatibility: