2016-02-16 20:07:51 +01:00
|
|
|
|
package fr.pandacube.java.util;
|
|
|
|
|
|
|
|
|
|
//******************************************************************************
|
|
|
|
|
//***
|
|
|
|
|
//*** INTERPRETEUR ARITHMETIQUE version 2.1 Version Java
|
|
|
|
|
//***
|
|
|
|
|
//***
|
|
|
|
|
//***
|
|
|
|
|
//******************************************************************************
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
Historique:
|
|
|
|
|
|
|
|
|
|
2.1:
|
|
|
|
|
- Version Java disponible:
|
|
|
|
|
# les operateurs mathematiques disponibles sont ceux de Java donc certains manquent.
|
|
|
|
|
|
2016-07-14 14:22:23 +02:00
|
|
|
|
2.0:
|
2016-02-16 20:07:51 +01:00
|
|
|
|
- Portage en C++ et debut en Java
|
|
|
|
|
|
|
|
|
|
Version C++:
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
2016-02-16 20:07:51 +01:00
|
|
|
|
- Meilleure gestion memoire lors de la construction de l'expression.
|
|
|
|
|
- Acceleration de certaines operations.
|
|
|
|
|
|
|
|
|
|
Version Java:
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
2016-02-16 20:07:51 +01:00
|
|
|
|
- Premiere version. Normalement ca doit marcher
|
|
|
|
|
|
|
|
|
|
1.3b: ajoute les fonctions suivantes: (NON DISTRIBUEE)
|
|
|
|
|
- reconnaissance du symbole <EFBFBD>
|
|
|
|
|
- ecriture formatee d'expression (<EFBFBD> ameliorer)
|
|
|
|
|
|
|
|
|
|
1.2: corrige les bugs suivants:
|
|
|
|
|
- erreur sur l'interpretation de fonctions unaires imbriquees telles que ln(exp(x)).
|
|
|
|
|
- la fonction puissance (pour les puissances entieres).
|
|
|
|
|
ajoute:
|
|
|
|
|
- la verification de la chaine entree (voir code d'erreur)
|
|
|
|
|
- la verification de l'existence de l'evaluation (voir code d'erreur)
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
2016-02-16 20:07:51 +01:00
|
|
|
|
|
|
|
|
|
1.1: corrige un bug au niveau de l'interpretation des fonctions du type:
|
|
|
|
|
|
|
|
|
|
exp(-(x+y))
|
|
|
|
|
|
|
|
|
|
1.0: premiere version
|
|
|
|
|
|
|
|
|
|
Le code source peut etre librement modifie et distribue.
|
|
|
|
|
|
|
|
|
|
Puisqu'il s'agit d'un essai en Java, le code ne doit pas etre super genial et merite sans doute
|
|
|
|
|
quelques modifications.En particulier, il serait interessant de rajouter le support des Exceptions
|
|
|
|
|
pour les calculs (division par zero, etc...).
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
2016-02-16 20:07:51 +01:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
// Classe servant <20> palier l'absence de passage par variables ou reference
|
|
|
|
|
|
|
|
|
|
class VariableInt {
|
|
|
|
|
public int mValue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Classe principale
|
|
|
|
|
|
|
|
|
|
public class JArithmeticInterpreter {
|
|
|
|
|
|
|
|
|
|
// Variables
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
|
|
|
|
int mOperator;
|
|
|
|
|
double mValue;
|
|
|
|
|
JArithmeticInterpreter fg, fd;
|
|
|
|
|
|
2016-02-16 20:07:51 +01:00
|
|
|
|
// Methods
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
|
|
|
|
// ....................................................................................
|
|
|
|
|
// Node
|
|
|
|
|
|
2016-02-16 20:07:51 +01:00
|
|
|
|
private JArithmeticInterpreter() {
|
|
|
|
|
this(0, 0, null, null);
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
|
|
|
|
// ....................................................................................
|
|
|
|
|
// Node
|
|
|
|
|
|
|
|
|
|
private JArithmeticInterpreter(int Operator, double Value, JArithmeticInterpreter Fg, JArithmeticInterpreter Fd) {
|
|
|
|
|
mOperator = Operator;
|
|
|
|
|
mValue = Value;
|
|
|
|
|
fg = Fg;
|
|
|
|
|
fd = Fd;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
|
|
|
|
private JArithmeticInterpreter(int Operator, double Value) {
|
2016-02-16 20:07:51 +01:00
|
|
|
|
this(Operator, Value, null, null);
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
|
|
|
|
// ....................................................................................
|
|
|
|
|
// Construct_Tree
|
|
|
|
|
|
|
|
|
|
private static JArithmeticInterpreter constructTree(StringBuffer string, int length, int error) {
|
|
|
|
|
int imbric, Bimbric;
|
|
|
|
|
int priorite, ope;
|
|
|
|
|
int position, positionv, i, j;
|
|
|
|
|
int opetemp = 0;
|
|
|
|
|
int espa = 0, espat = 0;
|
|
|
|
|
int caspp = 0;
|
|
|
|
|
|
|
|
|
|
JArithmeticInterpreter node;
|
|
|
|
|
|
2016-02-16 20:07:51 +01:00
|
|
|
|
// Initialisation des variables
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
|
|
|
|
if (length <= 0) {
|
|
|
|
|
error = 3;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
return null;
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
|
|
|
|
ope = 0;
|
|
|
|
|
imbric = 0;
|
|
|
|
|
Bimbric = 128;
|
|
|
|
|
priorite = 6;
|
|
|
|
|
i = 0;
|
|
|
|
|
positionv = position = 0;
|
|
|
|
|
|
2016-02-16 20:07:51 +01:00
|
|
|
|
// Mise en place des donnees sur le morceau de chaine
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
|
|
|
|
while (i < length)
|
|
|
|
|
if (((string.charAt(i) > 47) && (string.charAt(i) < 58)) || (string.charAt(i) == '<27>')) {
|
|
|
|
|
if (priorite > 5) {
|
|
|
|
|
priorite = 5;
|
|
|
|
|
positionv = i;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
}
|
|
|
|
|
i++;
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
else if ((string.charAt(i) > 96) && (string.charAt(i) < 117)) {
|
|
|
|
|
VariableInt Vopetemp, Vespat;
|
|
|
|
|
|
|
|
|
|
Vopetemp = new VariableInt();
|
|
|
|
|
Vespat = new VariableInt();
|
|
|
|
|
|
|
|
|
|
Vopetemp.mValue = opetemp;
|
|
|
|
|
Vespat.mValue = espat;
|
|
|
|
|
|
|
|
|
|
FindOperator(Vopetemp, Vespat, string, i);
|
|
|
|
|
|
|
|
|
|
opetemp = Vopetemp.mValue;
|
|
|
|
|
espat = Vespat.mValue;
|
|
|
|
|
|
|
|
|
|
if (opetemp >= 0) {
|
|
|
|
|
if (imbric < Bimbric) {
|
|
|
|
|
Bimbric = imbric;
|
|
|
|
|
ope = opetemp;
|
|
|
|
|
position = i;
|
|
|
|
|
priorite = 4;
|
|
|
|
|
espa = espat;
|
|
|
|
|
}
|
|
|
|
|
else if ((imbric == Bimbric) && (priorite >= 4)) {
|
|
|
|
|
ope = opetemp;
|
|
|
|
|
position = i;
|
|
|
|
|
priorite = 4;
|
|
|
|
|
espa = espat;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
j = i + 1;
|
|
|
|
|
i += espat;
|
|
|
|
|
while (j < i)
|
2016-02-16 20:07:51 +01:00
|
|
|
|
j++;
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
2016-02-16 20:07:51 +01:00
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
else if (string.charAt(i) == 't') {
|
|
|
|
|
if (priorite == 6) ope = -1;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
i++;
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
else if (string.charAt(i) == 'p') {
|
|
|
|
|
if (priorite == 6) ope = -2;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
i++;
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
else if (string.charAt(i) == 'r') {
|
|
|
|
|
if (priorite == 6) ope = -2;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
i++;
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
else if (string.charAt(i) == 'n') {
|
|
|
|
|
if (priorite == 6) ope = -1;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
else {
|
2016-07-14 14:22:23 +02:00
|
|
|
|
error = 2; // symbole non reconnu
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2016-02-16 20:07:51 +01:00
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
else
|
|
|
|
|
switch (string.charAt(i)) {
|
|
|
|
|
case '(':
|
|
|
|
|
imbric++;
|
|
|
|
|
i++;
|
|
|
|
|
break;
|
|
|
|
|
case ')':
|
|
|
|
|
imbric--;
|
|
|
|
|
i++;
|
|
|
|
|
break;
|
|
|
|
|
case '+':
|
|
|
|
|
if (imbric < Bimbric) {
|
|
|
|
|
Bimbric = imbric;
|
|
|
|
|
priorite = 1;
|
|
|
|
|
ope = 1;
|
|
|
|
|
position = i;
|
|
|
|
|
caspp = 0;
|
|
|
|
|
}
|
|
|
|
|
else if ((imbric == Bimbric) && (priorite >= 1)) {
|
|
|
|
|
priorite = 1;
|
|
|
|
|
ope = 1;
|
|
|
|
|
position = i;
|
|
|
|
|
caspp = 0;
|
|
|
|
|
}
|
|
|
|
|
i++;
|
|
|
|
|
break;
|
|
|
|
|
case '-':
|
|
|
|
|
if (imbric < Bimbric) {
|
|
|
|
|
if ((i - 1) < 0) {
|
|
|
|
|
if (priorite > 5) {
|
|
|
|
|
priorite = 1;
|
|
|
|
|
position = i;
|
|
|
|
|
ope = 2;
|
|
|
|
|
Bimbric = imbric;
|
|
|
|
|
caspp = 1;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
else if (string.charAt(i - 1) == '(') {
|
|
|
|
|
if (priorite > 1) {
|
|
|
|
|
priorite = 1;
|
|
|
|
|
position = i;
|
|
|
|
|
Bimbric = imbric;
|
|
|
|
|
caspp = 1;
|
|
|
|
|
ope = 2;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
else {
|
|
|
|
|
Bimbric = imbric;
|
|
|
|
|
priorite = 1;
|
|
|
|
|
ope = 2;
|
|
|
|
|
position = i;
|
|
|
|
|
caspp = 0;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
}
|
|
|
|
|
else if ((imbric == Bimbric) && (priorite >= 1)) if ((i - 1) < 0) {
|
|
|
|
|
if (priorite > 5) {
|
|
|
|
|
priorite = 1;
|
|
|
|
|
position = i;
|
|
|
|
|
ope = 2;
|
|
|
|
|
caspp = 1;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
}
|
|
|
|
|
else if (string.charAt(i - 1) == '(') {
|
|
|
|
|
if (priorite > 1) {
|
|
|
|
|
priorite = 1;
|
|
|
|
|
position = i;
|
|
|
|
|
caspp = 1;
|
|
|
|
|
ope = 2;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
else {
|
|
|
|
|
priorite = 1;
|
|
|
|
|
ope = 2;
|
|
|
|
|
position = i;
|
|
|
|
|
caspp = 0;
|
|
|
|
|
}
|
|
|
|
|
i++;
|
|
|
|
|
break;
|
|
|
|
|
case '*':
|
|
|
|
|
if (imbric < Bimbric) {
|
|
|
|
|
Bimbric = imbric;
|
|
|
|
|
priorite = 2;
|
|
|
|
|
ope = 3;
|
|
|
|
|
position = i;
|
|
|
|
|
}
|
|
|
|
|
else if ((imbric == Bimbric) && (priorite >= 2)) {
|
|
|
|
|
priorite = 2;
|
|
|
|
|
ope = 3;
|
|
|
|
|
position = i;
|
|
|
|
|
}
|
|
|
|
|
i++;
|
|
|
|
|
break;
|
|
|
|
|
case '/':
|
|
|
|
|
if (imbric < Bimbric) {
|
|
|
|
|
Bimbric = imbric;
|
|
|
|
|
priorite = 2;
|
|
|
|
|
ope = 4;
|
|
|
|
|
position = i;
|
|
|
|
|
}
|
|
|
|
|
else if ((imbric == Bimbric) && (priorite >= 2)) {
|
|
|
|
|
priorite = 2;
|
|
|
|
|
ope = 4;
|
|
|
|
|
position = i;
|
|
|
|
|
}
|
|
|
|
|
i++;
|
|
|
|
|
break;
|
|
|
|
|
case '^':
|
|
|
|
|
if (imbric < Bimbric) {
|
|
|
|
|
Bimbric = imbric;
|
|
|
|
|
priorite = 3;
|
|
|
|
|
ope = 5;
|
|
|
|
|
position = i;
|
|
|
|
|
}
|
|
|
|
|
else if ((imbric == Bimbric) && (priorite >= 3)) {
|
|
|
|
|
priorite = 3;
|
|
|
|
|
ope = 5;
|
|
|
|
|
position = i;
|
|
|
|
|
}
|
|
|
|
|
i++;
|
|
|
|
|
break;
|
|
|
|
|
case '.':
|
|
|
|
|
i++;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
error = 2; // symbole non reconnu
|
|
|
|
|
return null;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
|
|
|
|
if (imbric != 0) {
|
|
|
|
|
error = 1; // erreur de "parenthesage"
|
2016-02-16 20:07:51 +01:00
|
|
|
|
return null;
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
|
|
|
|
// Traitement des donnees
|
|
|
|
|
|
|
|
|
|
if (priorite == 6) {
|
|
|
|
|
node = new JArithmeticInterpreter(ope, 0.0);
|
2016-02-16 20:07:51 +01:00
|
|
|
|
return node;
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
else if (caspp == 1) {
|
|
|
|
|
node = new JArithmeticInterpreter(2, 0);
|
|
|
|
|
|
|
|
|
|
node.fg = new JArithmeticInterpreter(0, 0);
|
|
|
|
|
node.fd = new JArithmeticInterpreter();
|
|
|
|
|
|
|
|
|
|
if ((length - position - 1 - Bimbric) == 0) { // argument absent
|
|
|
|
|
error = 3;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
return null;
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
StringBuffer temp = CopyPartialString(string, (position + 1), (length - 1 - Bimbric));
|
|
|
|
|
node.fd = constructTree(temp, (length - position - 1 - Bimbric), error);
|
|
|
|
|
|
|
|
|
|
return node;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else if (priorite == 5) {
|
|
|
|
|
node = new JArithmeticInterpreter(0, calc_const(string, positionv), null, null);
|
|
|
|
|
|
2016-02-16 20:07:51 +01:00
|
|
|
|
return node;
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
else if (ope > 5) {
|
|
|
|
|
node = new JArithmeticInterpreter(ope, 0, null, null);
|
|
|
|
|
|
|
|
|
|
if ((length - position - espa - Bimbric) == 0) { // argument absent
|
|
|
|
|
error = 3;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
return null;
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
StringBuffer temp = CopyPartialString(string, (position + espa), (length - 1));
|
|
|
|
|
node.fg = constructTree(temp, (length - position - espa - Bimbric), error);
|
2016-02-16 20:07:51 +01:00
|
|
|
|
return node;
|
2016-07-14 14:22:23 +02:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
node = new JArithmeticInterpreter(ope, 0, null, null);
|
|
|
|
|
|
|
|
|
|
if ((position - Bimbric) == 0) { // argument absent
|
|
|
|
|
error = 3;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
return null;
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
StringBuffer temp = CopyPartialString(string, Bimbric, (position - 1));
|
|
|
|
|
node.fg = constructTree(temp, (position - Bimbric), error);
|
|
|
|
|
if ((length - position - 1 - Bimbric) == 0) { // argument absent
|
|
|
|
|
error = 3;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
return null;
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
temp = CopyPartialString(string, (position + 1), (length - 1 - Bimbric));
|
|
|
|
|
node.fd = constructTree(temp, (length - position - 1 - Bimbric), error);
|
2016-02-16 20:07:51 +01:00
|
|
|
|
return node;
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
|
|
|
|
// ....................................................................................
|
|
|
|
|
|
2016-02-16 20:07:51 +01:00
|
|
|
|
private double computeTree() {
|
2016-07-14 14:22:23 +02:00
|
|
|
|
if (mOperator == 0) return mValue;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
int error = 0;
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
|
|
|
|
double valueL = fg.computeTree();
|
|
|
|
|
|
|
|
|
|
if (error != 0) return 0;
|
|
|
|
|
double valueR = 0;
|
|
|
|
|
|
|
|
|
|
if (fd != null) valueR = fd.computeTree();
|
|
|
|
|
if (error != 0) return 0;
|
|
|
|
|
|
|
|
|
|
switch (mOperator) {
|
|
|
|
|
case 1: // +
|
|
|
|
|
return (valueL + valueR);
|
|
|
|
|
case 2: // -
|
|
|
|
|
return (valueL - valueR);
|
|
|
|
|
case 3: // *
|
|
|
|
|
return (valueL * valueR);
|
|
|
|
|
case 4: // -
|
|
|
|
|
if (valueR == 0) {
|
|
|
|
|
error = 1;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
return 0;
|
2016-07-14 14:22:23 +02:00
|
|
|
|
}
|
|
|
|
|
return (valueL / valueR);
|
|
|
|
|
case 5: // ^
|
|
|
|
|
return Math.pow(valueL, valueR);
|
|
|
|
|
case 6: // exp
|
|
|
|
|
return Math.exp(valueL);
|
|
|
|
|
case 7: // ln
|
|
|
|
|
if (valueL <= 0) {
|
|
|
|
|
if (valueL < 0) error = 2;
|
|
|
|
|
else
|
|
|
|
|
error = 1;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return (Math.log(valueL) / Math.log(2));
|
|
|
|
|
case 8: // log
|
|
|
|
|
if (valueL <= 0) {
|
|
|
|
|
if (valueL < 0) error = 2;
|
|
|
|
|
else
|
|
|
|
|
error = 1;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return Math.log(valueL);
|
|
|
|
|
case 9: // sqrt
|
|
|
|
|
if (valueL < 0) {
|
|
|
|
|
error = 2;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return Math.sqrt(valueL);
|
|
|
|
|
case 10: // abs
|
|
|
|
|
return Math.abs(valueL);
|
|
|
|
|
case 11:
|
|
|
|
|
return Math.sin(valueL); // sin
|
|
|
|
|
case 12:
|
|
|
|
|
return Math.cos(valueL); // cos
|
|
|
|
|
case 13:
|
|
|
|
|
return Math.tan(valueL); // tan
|
|
|
|
|
case 14:
|
|
|
|
|
return Math.asin(valueL); // asin
|
|
|
|
|
case 15:
|
|
|
|
|
return Math.acos(valueL); // acos
|
|
|
|
|
case 16:
|
|
|
|
|
return Math.atan(valueL); // atan
|
|
|
|
|
default:
|
|
|
|
|
return 0;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
|
|
|
|
// ....................................................................................
|
|
|
|
|
// Write_Tree
|
|
|
|
|
|
2016-02-16 20:07:51 +01:00
|
|
|
|
private void writeTree(StringBuffer string) {
|
2016-07-14 14:22:23 +02:00
|
|
|
|
boolean parenthese = false;
|
|
|
|
|
|
|
|
|
|
switch (mOperator) {
|
|
|
|
|
case 0:
|
|
|
|
|
string.append(StringUtil.formatDouble(mValue));
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
fg.writeTree(string);
|
|
|
|
|
string.append('+');
|
|
|
|
|
fd.writeTree(string);
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
if ((fg.mOperator == 0) && (fg.mValue == 0)) ;
|
|
|
|
|
else
|
2016-02-16 20:07:51 +01:00
|
|
|
|
fg.writeTree(string);
|
2016-07-14 14:22:23 +02:00
|
|
|
|
string.append('-');
|
|
|
|
|
if ((fd.mOperator == 1) || (fd.mOperator == 2)) {
|
|
|
|
|
parenthese = true;
|
|
|
|
|
string.append('(');
|
|
|
|
|
}
|
|
|
|
|
fd.writeTree(string);
|
|
|
|
|
if (parenthese == true) string.append(')');
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
if ((fg.mOperator == 1) || (fg.mOperator == 2)) {
|
|
|
|
|
parenthese = true;
|
|
|
|
|
string.append('(');
|
|
|
|
|
}
|
|
|
|
|
fg.writeTree(string);
|
|
|
|
|
if (parenthese == true) string.append(')');
|
|
|
|
|
parenthese = false;
|
|
|
|
|
string.append('*');
|
|
|
|
|
if ((fd.mOperator == 1) || (fd.mOperator == 2)) {
|
|
|
|
|
parenthese = true;
|
|
|
|
|
string.append('(');
|
|
|
|
|
}
|
|
|
|
|
fd.writeTree(string);
|
|
|
|
|
if (parenthese == true) string.append(')');
|
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
if ((fg.mOperator == 1) || (fg.mOperator == 2)) {
|
|
|
|
|
parenthese = true;
|
|
|
|
|
string.append('(');
|
|
|
|
|
}
|
|
|
|
|
fg.writeTree(string);
|
|
|
|
|
if (parenthese == true) string.append(')');
|
|
|
|
|
parenthese = false;
|
|
|
|
|
string.append('/');
|
|
|
|
|
if ((fd.mOperator > 0) && (fd.mOperator < 5)) {
|
|
|
|
|
parenthese = true;
|
|
|
|
|
string.append('(');
|
|
|
|
|
}
|
|
|
|
|
fd.writeTree(string);
|
|
|
|
|
if (parenthese == true) string.append(')');
|
|
|
|
|
break;
|
|
|
|
|
case 5:
|
|
|
|
|
if ((fg.mOperator > 0) && (fg.mOperator < 5)) {
|
|
|
|
|
parenthese = true;
|
|
|
|
|
string.append('(');
|
|
|
|
|
}
|
|
|
|
|
fg.writeTree(string);
|
|
|
|
|
if (parenthese == true) string.append(')');
|
|
|
|
|
parenthese = false;
|
|
|
|
|
string.append('^');
|
|
|
|
|
if ((fd.mOperator > 0) && (fd.mOperator < 5)) {
|
|
|
|
|
parenthese = true;
|
|
|
|
|
string.append('(');
|
|
|
|
|
}
|
|
|
|
|
fd.writeTree(string);
|
|
|
|
|
if (parenthese == true) string.append(')');
|
|
|
|
|
break;
|
|
|
|
|
case 6:
|
|
|
|
|
string.append("exp(");
|
|
|
|
|
fg.writeTree(string);
|
|
|
|
|
string.append(')');
|
|
|
|
|
break;
|
|
|
|
|
case 7:
|
|
|
|
|
string.append("log(");
|
|
|
|
|
fg.writeTree(string);
|
|
|
|
|
string.append(')');
|
|
|
|
|
break;
|
|
|
|
|
case 8:
|
|
|
|
|
string.append("ln(");
|
|
|
|
|
fg.writeTree(string);
|
|
|
|
|
string.append(')');
|
|
|
|
|
break;
|
|
|
|
|
case 9:
|
|
|
|
|
string.append("sqrt(");
|
|
|
|
|
fg.writeTree(string);
|
|
|
|
|
string.append(')');
|
|
|
|
|
break;
|
|
|
|
|
case 10:
|
|
|
|
|
string.append("|");
|
|
|
|
|
fg.writeTree(string);
|
|
|
|
|
string.append('|');
|
|
|
|
|
break;
|
|
|
|
|
case 11:
|
|
|
|
|
string.append("sin(");
|
|
|
|
|
fg.writeTree(string);
|
|
|
|
|
string.append(')');
|
|
|
|
|
break;
|
|
|
|
|
case 12:
|
|
|
|
|
string.append("cos(");
|
|
|
|
|
fg.writeTree(string);
|
|
|
|
|
string.append(')');
|
|
|
|
|
break;
|
|
|
|
|
case 13:
|
|
|
|
|
string.append("tan(");
|
|
|
|
|
fg.writeTree(string);
|
|
|
|
|
string.append(')');
|
|
|
|
|
break;
|
|
|
|
|
case 14:
|
|
|
|
|
string.append("asin(");
|
|
|
|
|
fg.writeTree(string);
|
|
|
|
|
string.append(')');
|
|
|
|
|
break;
|
|
|
|
|
case 15:
|
|
|
|
|
string.append("acos(");
|
|
|
|
|
fg.writeTree(string);
|
|
|
|
|
string.append(')');
|
|
|
|
|
break;
|
|
|
|
|
case 16:
|
|
|
|
|
string.append("atan(");
|
|
|
|
|
fg.writeTree(string);
|
|
|
|
|
string.append(')');
|
|
|
|
|
break;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
|
|
|
|
// ....................................................................................
|
|
|
|
|
// calc_const
|
|
|
|
|
|
|
|
|
|
private static double calc_const(StringBuffer chaine, int pos) {
|
|
|
|
|
int i = pos, j;
|
|
|
|
|
double temp = 0;
|
|
|
|
|
int signe = 1;
|
|
|
|
|
int longueur = chaine.length();
|
|
|
|
|
|
|
|
|
|
if (chaine.charAt(i) == '-') {
|
|
|
|
|
signe = -1;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
i++;
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
if (chaine.charAt(i) == 'π') return signe * Math.PI;
|
|
|
|
|
|
|
|
|
|
while (i < longueur && chaine.charAt(i) > 47 && chaine.charAt(i) < 58) {
|
|
|
|
|
temp = temp * 10 + (chaine.charAt(i) - 48);
|
2016-02-16 20:07:51 +01:00
|
|
|
|
i++;
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
if (i < longueur && chaine.charAt(i) == '.') {
|
2016-02-16 20:07:51 +01:00
|
|
|
|
i++;
|
2016-07-14 14:22:23 +02:00
|
|
|
|
j = 1;
|
|
|
|
|
while (i < longueur && chaine.charAt(i) > 47 && chaine.charAt(i) < 58) {
|
|
|
|
|
temp = temp + (chaine.charAt(i) - 48) * Math.exp(-j * 2.30258509);
|
2016-02-16 20:07:51 +01:00
|
|
|
|
i++;
|
|
|
|
|
j++;
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
return (signe * temp);
|
2016-02-16 20:07:51 +01:00
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
|
|
|
|
// ....................................................................................
|
|
|
|
|
// FindOperator
|
|
|
|
|
|
|
|
|
|
private static void FindOperator(VariableInt oper, VariableInt esp, StringBuffer chaine, int pos) {
|
|
|
|
|
switch (chaine.charAt(pos)) {
|
2016-02-16 20:07:51 +01:00
|
|
|
|
case 'a':
|
2016-07-14 14:22:23 +02:00
|
|
|
|
switch (chaine.charAt(pos + 1)) {
|
|
|
|
|
case 'b':
|
|
|
|
|
esp.mValue = 3;
|
|
|
|
|
oper.mValue = 10;
|
|
|
|
|
break;
|
|
|
|
|
case 'c':
|
|
|
|
|
esp.mValue = 4;
|
|
|
|
|
oper.mValue = 15;
|
|
|
|
|
break;
|
|
|
|
|
case 's':
|
|
|
|
|
esp.mValue = 4;
|
|
|
|
|
oper.mValue = 14;
|
|
|
|
|
break;
|
|
|
|
|
case 't':
|
|
|
|
|
esp.mValue = 4;
|
|
|
|
|
oper.mValue = 16;
|
|
|
|
|
break;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 'c':
|
2016-07-14 14:22:23 +02:00
|
|
|
|
if (chaine.charAt(pos + 1) == 'h') {
|
|
|
|
|
esp.mValue = 2;
|
|
|
|
|
oper.mValue = 18;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
else if ((chaine.charAt(pos + 1) == 'o') && (chaine.charAt(pos + 2) == 's'))
|
|
|
|
|
if (chaine.charAt(pos + 3) == 'h') {
|
|
|
|
|
esp.mValue = 4;
|
|
|
|
|
oper.mValue = 18;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
esp.mValue = 3;
|
|
|
|
|
oper.mValue = 12;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 'e':
|
2016-07-14 14:22:23 +02:00
|
|
|
|
if ((chaine.charAt(pos + 1) == 'x') && (chaine.charAt(pos + 2) == 'p')) {
|
|
|
|
|
esp.mValue = 3;
|
|
|
|
|
oper.mValue = 6;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
else
|
|
|
|
|
oper.mValue = -10;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
break;
|
|
|
|
|
case 'l':
|
2016-07-14 14:22:23 +02:00
|
|
|
|
if (chaine.charAt(pos + 1) == 'n') {
|
|
|
|
|
esp.mValue = 2;
|
|
|
|
|
oper.mValue = 7;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
else if ((chaine.charAt(pos + 1) == 'o') && (chaine.charAt(pos + 2) == 'g')) {
|
|
|
|
|
esp.mValue = 3;
|
|
|
|
|
oper.mValue = 8;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
oper.mValue = -10;
|
|
|
|
|
break;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
case 's':
|
2016-07-14 14:22:23 +02:00
|
|
|
|
if (chaine.charAt(pos + 1) == 'h') {
|
|
|
|
|
esp.mValue = 2;
|
|
|
|
|
oper.mValue = 17;
|
|
|
|
|
}
|
|
|
|
|
else if (chaine.charAt(pos + 1) == 'q') {
|
|
|
|
|
esp.mValue = 4;
|
|
|
|
|
oper.mValue = 9;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
else if (chaine.charAt(pos + 3) == 'h') {
|
|
|
|
|
esp.mValue = 4;
|
|
|
|
|
oper.mValue = 17;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
}
|
|
|
|
|
else {
|
2016-07-14 14:22:23 +02:00
|
|
|
|
esp.mValue = 3;
|
|
|
|
|
oper.mValue = 11;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 't':
|
2016-07-14 14:22:23 +02:00
|
|
|
|
if (chaine.charAt(pos + 1) == 'h') {
|
|
|
|
|
esp.mValue = 2;
|
|
|
|
|
oper.mValue = 19;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
else if ((chaine.charAt(pos + 1) == 'a') && (chaine.charAt(pos + 2) == 'n')) {
|
|
|
|
|
if (chaine.charAt(pos + 3) == 'h') {
|
|
|
|
|
esp.mValue = 4;
|
|
|
|
|
oper.mValue = 19;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
}
|
|
|
|
|
else {
|
2016-07-14 14:22:23 +02:00
|
|
|
|
esp.mValue = 3;
|
|
|
|
|
oper.mValue = 13;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
else
|
|
|
|
|
oper.mValue = -10;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
break;
|
|
|
|
|
default:
|
2016-07-14 14:22:23 +02:00
|
|
|
|
oper.mValue = -10;
|
2016-02-16 20:07:51 +01:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
|
|
|
|
// ....................................................................................
|
|
|
|
|
// CopyPartialString
|
|
|
|
|
|
|
|
|
|
private static StringBuffer CopyPartialString(StringBuffer chaine, int debut, int fin) {
|
|
|
|
|
StringBuffer chartemp;
|
|
|
|
|
int a = fin - debut + 1;
|
|
|
|
|
chartemp = new StringBuffer(a + 1);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < a; i++)
|
|
|
|
|
chartemp.append(chaine.charAt(debut + i));
|
|
|
|
|
|
2016-02-16 20:07:51 +01:00
|
|
|
|
return chartemp;
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
|
|
|
|
public static double getResultFromExpression(String expr, StringBuffer writeTree) {
|
2016-02-16 20:07:51 +01:00
|
|
|
|
StringBuffer input = new StringBuffer(expr);
|
|
|
|
|
|
|
|
|
|
JArithmeticInterpreter jai = null;
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
2016-02-16 20:07:51 +01:00
|
|
|
|
try {
|
2016-07-14 14:22:23 +02:00
|
|
|
|
jai = JArithmeticInterpreter.constructTree(input, input.length(), 0);
|
|
|
|
|
} catch (Exception e) {}
|
|
|
|
|
|
|
|
|
|
if (jai == null) throw new IllegalArgumentException("Le calcul passé en paramètre est invalide");
|
|
|
|
|
|
|
|
|
|
if (writeTree != null) {
|
2016-02-16 20:07:51 +01:00
|
|
|
|
writeTree.setLength(0);
|
|
|
|
|
jai.writeTree(writeTree);
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
2016-02-16 20:07:51 +01:00
|
|
|
|
return jai.computeTree();
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
|
|
|
|
public static double getResultFromExpression(String expr) {
|
2016-02-16 20:07:51 +01:00
|
|
|
|
return getResultFromExpression(expr, null);
|
|
|
|
|
}
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
2016-02-16 20:07:51 +01:00
|
|
|
|
public static void main(String args[]) {
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
2016-02-16 20:07:51 +01:00
|
|
|
|
StringBuffer b = new StringBuffer(0);
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
2016-02-16 20:07:51 +01:00
|
|
|
|
String disp_res = StringUtil.formatDouble(JArithmeticInterpreter.getResultFromExpression("1245.25*2", b));
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
2016-02-16 20:07:51 +01:00
|
|
|
|
System.out.println(disp_res);
|
|
|
|
|
System.out.println(b);
|
|
|
|
|
} // */
|
2016-07-14 14:22:23 +02:00
|
|
|
|
|
2016-02-16 20:07:51 +01:00
|
|
|
|
}
|