emath
Version:
This is a module for math.
554 lines (550 loc) • 19.6 kB
JavaScript
/**
* @method
* @file number.js
* @desc Perform common expression operations and provide fractional classes.
* @createDate 2018.7.11.
* @author yhzheng
*/
"use strict";
// require
var dataStruct = require("./dataStruct");
/**
* @var inf
* @desc This is for Express infinity
*/
// set default the value of inf
var inf = 100;
/**
* @class fractions
* @classdesc This is for Provides a fractional class object so that fractions can be computed.
* @desc It's for create object and init object.
*/
class fractions
{
constructor(info){
var denominator = info.denominator;
var numerator = info.numerator;
this.denominator = denominator;
this.numerator = numerator;
if (this.denominator === 0){
var err = new Error("Denominator can't is 0!");
throw err;
}
}
/**
* @method
* @returns number The value of this fractions
* @desc For get value of this fractions
*/
value(){
return (this.numerator / this.denominator);
}
/**
* @method
* @returns {fractions} This is the reduction fraction of this fraction
* @desc For get the reduction fraction of this fraction
*/
reduction(){
var newFractions = new fractions({
denominator: (this.denominator / maximum(this.denominator,this.numerator)),
numerator: (this.numerator / maximum(this.denominator,this.numerator))
});
return newFractions;
}
/**
* @method
* @desc For Set this fraction to he reduction fraction of this fraction
*/
toReduction(){
var reductionNumber = this.reduction();
this.denominator = reductionNumber.denominator;
this.numerator = reductionNumber.numerator;
}
}
/**
* @method
* @param {string} exp The expression of the string arithmetic.
* @returns number This is the result of your expression
* @desc For parse the expression of the string arithmetic and get the result.
*/
function expression(exp) {
var lines = exp.split("\n");
var exps = exp.split(/={5,}/g);
if (exps.length > 1){// many expressions
var reses = [];
for (var i = 0 ; i < exps.length ; i++){
reses.push(expression(exps[i]));
}
return reses;
} else {// just one expressions
if (exp.search(/[_\\]/g) === -1 && exp.search(/[a-zA-z]\s*\([\s\S]*\)\s*=/g) === -1 && exp.search(/={2,}/g) === -1 && exp.search(/-{2,}/g) === -1){// four arithmetic operation
/*
* {
* opt: "xx",
* priority: xx
* }
*/
exp = exp.replace(/\(\s*(-\d+\.{0,1}\d*\s*)\)/g,"0" + "$1");
var optArr = [
{opt: '+',priority: 1},
{opt: '-',priority: 1},
{opt: '*',priority: 2},
{opt: '/',priority: 2},
{opt: '%',priority: 2},
];
function priority(opt){
for(var i = 0 ; i < 5 ; i++)
if(opt == optArr[i].opt)
return optArr[i].priority;
return -1;
}
function isNum(c){
return c == '√' || (c >= '0' && c <= '9') || (c >= "a" && c <= "z");
}
function toNum(str,pos) {
var sztmp = "";
do {
sztmp += str.charAt(pos);
pos++;
} while((str.charAt(pos) >= "a" && str.charAt(pos) <= "z") || (str.charAt(pos) >='0' && str.charAt(pos) <='9') || str.charAt(pos) == '.' || str.charAt(pos) == "^");
var num = "";
if (sztmp.charAt(0) == "√"){
for (var i = 1 ; i < sztmp.length ; i++){
if (sztmp.charAt(i) == "^"){
break;
}
num += sztmp.charAt(i);
}
num = Math.sqrt(num);
var sztmpArr_ = sztmp.split("^");
sztmpArr_[0] = num + "";
sztmp = "";
for (var i = 0 ; i < sztmpArr_.length ; i++){
sztmp += sztmpArr_[i] + "^";
}
}
var sztmpArr = sztmp.split("^");
if (sztmpArr.length >= 2){
var tmpFun = "";
if (sztmp.search(/[a-zA-z]/) !== -1){
var end = sztmp.search(/\d/);
for (var i = 0 ; i < end ; i++){
tmpFun += sztmp.charAt(i);
}
sztmp = sztmp.replace(tmpFun,"");
sztmpArr = sztmp.split("^");
}
sztmp = sztmpArr[sztmpArr.length - 1];
for (var i = sztmpArr.length - 2 ; i >= 0 ; i--){
sztmp = Math.pow(sztmpArr[i] * 1,sztmp * 1);
}
sztmp = tmpFun + sztmp;
}
var start = 0;
while (start > -1){
start = sztmp.search(/sin\s*\d+/g) + 3;
if (start == 2){
break;
}
var i = start;
num = "";
while (i < sztmp.length && (sztmp.charAt(i) == " " || (sztmp.charAt(i) >= "0" && sztmp.charAt(i) <= "9"))){
if (sztmp.charAt(i) == " ") continue;
num += sztmp.charAt(i);
i++;
}
num = num * 1;
var tmpnum = Math.sin(num);
sztmp = sztmp.replace(new RegExp("sin\\s*" + num,"g"),tmpnum);
}
start = 0;
while (start > -1){
start = sztmp.search(/cos\s*\d+/g) + 3;
if (start == 2){
break;
}
var i = start;
num = "";
while (i < sztmp.length && (sztmp.charAt(i) == " " || (sztmp.charAt(i) >= "0" && sztmp.charAt(i) <= "9"))){
if (sztmp.charAt(i) == " ") continue;
num += sztmp.charAt(i);
i++;
}
num = num * 1;
var tmpnum = Math.cos(num);
sztmp = sztmp.replace(new RegExp("cos\\s*" + num,"g"),tmpnum);
}
start = 0;
while (start > -1){
start = sztmp.search(/tan\s*\d+/g) + 3;
if (start == 2){
break;
}
var i = start;
num = "";
while (i < sztmp.length && (sztmp.charAt(i) == " " || (sztmp.charAt(i) >= "0" && sztmp.charAt(i) <= "9"))){
if (sztmp.charAt(i) == " ") continue;
num += sztmp.charAt(i);
i++;
}
num = num * 1;
var tmpnum = Math.tan(num);
sztmp = sztmp.replace(new RegExp("tan\\s*" + num,"g"),tmpnum);
}
start = 0;
while (start > -1){
start = sztmp.search(/asin\s*\d+/g) + 3;
if (start == 2){
break;
}
var i = start;
num = "";
while (i < sztmp.length && (sztmp.charAt(i) == " " || (sztmp.charAt(i) >= "0" && sztmp.charAt(i) <= "9"))){
if (sztmp.charAt(i) == " ") continue;
num += sztmp.charAt(i);
i++;
}
num = num * 1;
var tmpnum = Math.asin(num);
sztmp = sztmp.replace(new RegExp("asin\\s*" + num,"g"),tmpnum);
}
start = 0;
while (start > -1){
start = sztmp.search(/acos\s*\d+/g) + 3;
if (start == 2){
break;
}
var i = start;
num = "";
while (i < sztmp.length && (sztmp.charAt(i) == " " || (sztmp.charAt(i) >= "0" && sztmp.charAt(i) <= "9"))){
if (sztmp.charAt(i) == " ") continue;
num += sztmp.charAt(i);
i++;
}
num = num * 1;
var tmpnum = Math.acos(num);
sztmp = sztmp.replace(new RegExp("acos\\s*" + num,"g"),tmpnum);
}
start = 0;
while (start > -1){
start = sztmp.search(/atan\s*\d+/g) + 3;
if (start == 2){
break;
}
var i = start;
num = "";
while (i < sztmp.length && (sztmp.charAt(i) == " " || (sztmp.charAt(i) >= "0" && sztmp.charAt(i) <= "9"))){
if (sztmp.charAt(i) == " ") continue;
num += sztmp.charAt(i);
i++;
}
num = num * 1;
var tmpnum = Math.atan(num);
sztmp = sztmp.replace(new RegExp("atan\\s*" + num,"g"),tmpnum);
}
return {num: sztmp * 1,index: pos};
}
var num = new dataStruct.stack();
var opt = new dataStruct.stack();
var i = 0;
while (true){
if (exp.charAt(i).search(/\s/g) !== -1){
i++;
} else if (isNum(exp.charAt(i))){
var tmp = toNum(exp,i);
num.push(tmp.num);
i = tmp.index;
} else {
if (exp.length <= i && opt.empty()){
break;
}
if (opt.empty()){
opt.push(exp.charAt(i));
i++;
} else {
if (exp.charAt(i) == "(" || priority(exp.charAt(i)) > priority(opt.top())){
opt.push(exp.charAt(i));
i++;
} else if (exp.charAt(i) == ")" && opt.top() == "("){
opt.pop();
i++;
} else {
var opttmp = opt.top();
opt.pop();
var numa = num.top();
num.pop();
var numb = num.top();
num.pop();
var res;
switch (opttmp){
case "+":
res = numb + numa;
break;
case "-":
res = numb - numa;
break;
case "*":
res = numb * numa;
break;
case "/":
res = numb / numa;
break;
case "%":
res = numb % numa;
break;
default:
var err = new Error("Don't have this operator!");
throw err;
break;
}
num.push(res);
}
}
}
}
return num.top();
} else if (exp.search(/==/g) !== -1) {// sigma
/*
* style of sigma:
* z
* ==
* \
* | expression
* /
* ==
* x=y
*/
if (lines[1] != "==") {
var index;
var fills = [];
var tmp;
for (var i = 0; i < lines.length; i++) {
if (lines[i].search(/\s*==\s*/) !== -1) {
index = i - 1;
break;
}
}
for (var i = 0; i < index; i++) {
if (lines[i].search(/^\s*$/) !== -1)
continue;
tmp = lines[i].replace(/\s*(\S)\s*=\s*(\S)\s*/g, "$1=$2").split("=");
fills.push({
name: tmp[0],
value: tmp[1]
});
}
var count = lines[index];
if (count.search(/inf/g) !== -1 || count.search(/∞/g) !== -1) {
count = inf;
} else {
count *= 1;
}
var expression_ = "";
for (var i = (index + 3); i < (lines.length - 3); i++) {
expression_ += lines[i].replace(/^\s\|\s*([\s\S]*)/g, "$1");
if ((i + 1) < (lines.length - 3)) {
expression_ += "\n";
}
}
for (var i = 0 ; i < fills.length ; i++){
expression_ = expression.replace(new RegExp(fills[i].name),fills[i].value);
}
var lastLine = lines[lines.length - 1].split(/\s*=\s*/g);
return sigma(expression_, count, {
name: lastLine[0],
value: lastLine[1]
});
} else {
var count = lines[0];
if (count.search(/inf/g) !== -1 || count.search(/∞/g) !== -1) {
count = inf;
} else {
count *= 1;
}
var expression_ = "";
for (var i = 3; i < (lines.length - 3); i++) {
expression_ += lines[i].replace(/^\s\|\s*([\s\S]*)/g, "$1");
if ((i + 1) < (lines.length - 3)) {
expression_ += "\n";
}
}
var lastLine = lines[lines.length - 1].split(/\s*=\s*/g);
count++;
return sigma(expression_, count, {
name: lastLine[0],
value: lastLine[1]
});
}
} else if (exp.search(/-{3,}/g) !== -1){
var maxLine = "";
for (var i = 0 ; i < lines.length ; i++){
if (lines[i].search(/^-+$/g) !== -1){
if (lines[i].length > maxLine.length){
maxLine = lines[i];
}
}
}
var tmp = exp.split(maxLine);
var up = tmp[0],down = tmp[1];
return expression(up) / expression(down);
} else {
console.log("Now that this method is not available, you can send a brief introduction of the detailed information of this method to zhengyh2018@gmail.com by email, and we will understand the message as soon as possible and make improvements (please set the title to [emath add methods).)");
}
}
}
/**
* @method
* @param {number} num The value of inf
* @desc Set the value of inf
*/
function setInf(num) {
inf = num;
}
/**
* @method
* @param {string} exp The string expression of sigma
* @param {number} count The while count
* @param {object} init The information for init.
* @returns The sum of sigma
* @desc The sigma function<br/>
* Demo: sigma("i^2",3,{
* name: "i",
* value: 0
* });// return: 7
*/
function sigma(exp,count,init) {
var sum = 0;
var newExp;
for (var i = 0 ; i < count ; i++){
newExp = exp.replace(new RegExp(init.name),init.value);
sum += expression(newExp);
init.value++;
}
return sum;
}
/**
* @method
* @param {number} a First number
* @param {number} b Second number
* @returns The maximum common factor of a and b
* @desc To get the maximum common factor of a and b
*/
function MCF(a,b) {
var primeOfA = primeFact(a);
var primeOfB = primeFact(b);
var commonFactors = commonFactor(primeOfA,primeOfB);
var max = commonFactors[0];
for (var i = 1 ; i < commonFactors.length ; i++){
if (max < commonFactors[i]){
max = commonFactors[i];
}
}
return max;
}
/**
* @method
* @param {number} a First number
* @param {number} b Second number
* @returns The least common multiple of a and b
* @desc To get the least common multiple of a and b
*/
function LCM(a,b) {
var MCFA = MCF(a,b);
a /= MCFA;
b /= MCFA;
return (a * b * MCFA);
}
/**
* @method
* @param {number} a First number
* @param {number} b Second number
* @returns The common factors of a and b
* @desc To get the common factors of a and b
*/
function commonFactor(a,b) {
var commonFactors = [];
for (var i in a){
for (var j in b){
if (a[i] == b[j]){
commonFactors.push(a[i]);
break;
}
}
}
return commonFactors;
}
/**
* @method
* @param {number} n Number
* @returns The primes factor of number
* @desc To get the primes factor of number
*/
function primeFact(n) {
var primeNumbers = [];
var arr = prime(Math.sqrt(n));
for (var i in arr){
if (n % i == 0){
primeNumbers.push(arr[i]);
n /= i;
}
}
if (n != 1){
primeNumbers.push(n);
}
return primeNumbers;
}
/**
* @method
* @param {number} max Number
* @returns The primes(2~max)
* @desc To get the primes(2~max)
*/
function prime(max) {
var primes = [];
for (var i = 2 ; i < max ; i++){
if (isPrime(i)){
primes.push(i);
}
}
return primes;
}
/**
* @method
* @param {number} n Number
* @returns bool the number is prime
* @desc To get the number is prime
*/
function isPrime(n) {
var yes = true;
for (var i = 2 ; i < Math.sqrt(n) ; i++){
if (n % i == 0){
yes = false;
break;
}
}
return yes;
}
module.exports.fractions = fractions;
module.exports.expression = expression;
module.exports.setInf = setInf;
module.exports.sigma = sigma;
module.exports.MCF = MCF;
module.exports.LCM = LCM;
module.exports.commonFactor = commonFactor;
module.exports.primeFact = primeFact;
module.exports.prime = prime;
module.exports.isPrime = isPrime;
module.exports.e = 2.7182818284590452;
module.exports.PI = 3.141592653589793;
module.exports.gamma = 3.141592653589793;
module.exports.phi = 1.618033988749894848;
module.exports.gamma = 3.141592653589793;
module.exports.gamma = 3.141592653589793;
module.exports.gamma = 3.141592653589793;
module.exports.gamma = 3.141592653589793;
module.exports.gamma = 3.141592653589793;
module.exports.C = 299792458;
module.exports.G = 6.671999999999999e-11;
module.exports.k = 1.3806620000000002e-23;
module.exports.F = 9.648456e4;
module.exports.k = 6.626176e-34;