|
Java precision four operations (without brackets limit)
package cn.skyatom.common;
import java.math.BigDecimal;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/ **
* Basic four arithmetic
*
* /
public class Arithmetic {
private static String getUUID () {
.. Return java.util.UUID.randomUUID () toString () replaceAll ( "-", "");
}
public static void main (String [] args) throws Exception {
java.util.Map < String, BigDecimal> values = new java.util.HashMap < String, BigDecimal> ();
BigDecimal AAF = new BigDecimal (5.5);
BigDecimal BCCC = new BigDecimal (8);
BigDecimal QQC = new BigDecimal (-8.33);
BigDecimal DCC = new BigDecimal (2);
BigDecimal EE = new BigDecimal (23);
BigDecimal BF = new BigDecimal (2.5);
BigDecimal A1 = new BigDecimal (12);
BigDecimal A2 = new BigDecimal (4);
BigDecimal A3 = new BigDecimal (5);
BigDecimal A4 = new BigDecimal (15);
values.put ( "AAF", AAF);
values.put ( "BCCC", BCCC);
values.put ( "QQC", QQC);
values.put ( "DCC", DCC);
values.put ( "EE", EE);
values.put ( "BF", BF);
values.put ( "A1", A1);
values.put ( "A2", A2);
values.put ( "A3", A3);
values.put ( "A4", A4);
//
// Values.put ( "B1", 4F);
// Values.put ( "B2", 15f);
// Values.put ( "B3", 55f);
// Values.put ( "B4", 2f);
// Values.put ( "B5", 5f);
String str = "AAF * BCCC + QQC / DCC-EE * BF + (A1 * (A2 / (A3 + A4)))"; // 5.5 * 8 + (-8.33) / 2 - 23 * 2.5 + (12 * (4 / (15 + 5)))
// String str = "B1 * B2 + B3 -B4 / B5"; // go blank
// BigDecimal v = getArithmeticValue (str, values);
System.out.println ( "the result is:" + getArithmeticFloatValue (str, values));
}
/ **
* Operation is executed to obtain the result of the expression. float value
*
* @param Str
* @param Values
* @return
* @throws Exception
* /
public static float getArithmeticFloatValue (String str, java.util.Map < String, BigDecimal> values) throws Exception {
return getArithmeticValue (str, values) .floatValue ();
}
public static int getArithmeticIntValue (String str, java.util.Map < String, BigDecimal> values) throws Exception {
return getArithmeticValue (str, values) .intValue ();
}
public static long getArithmeticLongValue (String str, java.util.Map < String, BigDecimal> values) throws Exception {
return getArithmeticValue (str, values) .longValue ();
}
/ **
* Replace the brackets
*
* @param Str
* @param Values
* @return All alternatives when completed, null, and vice versa to return the replacement string
* /
private static String replaceBrackets (String str, java.util.Map < String, BigDecimal> values) {
String v = "";
String tmp = null; // temporary string value
Pattern patt = Pattern.compile ( "\\ (([A-Za-z0-9 \\ \\ * \\ + \\ - /.] *) \\)?", Pattern.DOTALL);
Matcher mat = patt.matcher (str);
if (mat.find ()) {
tmp = mat.group (1);
}
if (tmp! = null) {
String uuid = getUUID ();
BigDecimal value = getBasicArithmeticValue (tmp, values);
str = str.replace ( "(" + tmp + ")", uuid);
values.put (uuid, value);
v = str;
v = replaceBrackets (v, values);
} Else {
v = str;
}
return v;
}
/ **
* Results perform an operation to obtain the expression
*
* @param Str String expression
* @param Values value storage table
* @return Return value calculation
* @throws Java.lang.Exception operation when malformed thrown
* /
public static BigDecimal getArithmeticValue (String str, java.util.Map < String, BigDecimal> values) throws Exception {
str = str.replaceAll ( "\\ s *", ""); // go blank
String s = replaceBrackets (str, values);
if (s! = null ||! s.trim (). equals ( "")) {
str = s;
}
return getBasicArithmeticValue (str, values);
}
/ **
* Four basic arithmetic
*
* @param Str the basis of four operations
* @param Values value storage table
* @return
* /
private static BigDecimal getBasicArithmeticValue (String str, java.util.Map < String, BigDecimal> values) {
str = multiReg (str, values);
str = divReg (str, values);
java.util.List < Boolean> signs = getPlusReduceSign (str); // Get the symbol
java.util.List < String> valuesign = getValueSign (str); // replace symbols
BigDecimal v = getValue (valuesign, signs, values);
return v;
}
/ **
* Get Results
*
* @param Valuesign value replaces the symbol
* @param Signs symbol
* @param Values value storage table
* @return
* /
private static BigDecimal getValue (java.util.List < String> valuesign, java.util.List < Boolean> signs, java.util.Map < String, BigDecimal> values) {
BigDecimal value = values.get (valuesign.get (0));
for (int i = 0; i < signs.size (); i ++) {
if (signs.get (i)) {
value = value.add (values.get (valuesign.get (i + 1)));
// Value + = values.get (valuesign.get (i + 1));
} Else {
value = value.subtract (values.get (valuesign.get (i + 1)));
// Value - = values.get (valuesign.get (i + 1));
}
}
return value;
}
/ **
* Obtain a replacement symbol
*
* @param Str the string to be matched
* @return Return value to replace symbols
* /
private static java.util.List < String> getValueSign (String str) {
java.util.List < String> list = new java.util.ArrayList < String> ();
Pattern patt = Pattern.compile ( "([a-zA-Z0-9] * {1})", Pattern.DOTALL);
Matcher mat = patt.matcher (str);
while (mat.find ()) {
if (mat.group (1) .trim (). equals ( "")) {
continue;
}
list.add (mat.group (1));
}
return list;
}
/ **
* Get the plus and minus signs
*
* @param Str the string to be matched
* @return Return symbol sequence, plus true, the minus sign is false
* /
private static java.util.List < Boolean> getPlusReduceSign (String str) {
java.util.List < Boolean> list = new java.util.ArrayList < Boolean> ();
Pattern patt = Pattern.compile ( "([a-zA-Z0-9] * {1} ([+ | -]) [a-zA-Z0-9] * {1})", Pattern.DOTALL);
Matcher mat = patt.matcher (str);
while (mat.find ()) {
if (mat.group (2) .trim (). equals ( "+")) {
list.add (true);
} Else {
list.add (false);
}
}
return list;
}
/ **
* Multiplication regular
*
* @param Str arithmetic expression string
* @param Values value storage table
* @return String returned after reconstruction
* /
private static String multiReg (String str, java.util.Map < String, BigDecimal> values) {
Pattern patt = Pattern.compile ( "([a-zA-Z0-9] * {1} \\ * [a-zA-Z0-9] * {1})", Pattern.DOTALL);
Matcher mat = patt.matcher (str);
while (mat.find ()) {
str = excMultiplication (str, mat.group (1), values);
}
return str;
}
/ **
* Regular division
*
* @param Str arithmetic expression string
* @param Values value storage table
* @return String returned after reconstruction
* /
private static String divReg (String str, java.util.Map < String, BigDecimal> values) {
Pattern patt = Pattern.compile ( "([a-zA-Z0-9] * {1} \\ / [a-zA-Z0-9] * {1})", Pattern.DOTALL);
Matcher mat = patt.matcher (str);
while (mat.find ()) {
str = excDivsion (str, mat.group (1), values);
}
return str;
}
/ **
* Calculate the multiplication
*
* @param Str the entire operation string
* @param Value calculated string multiplication
* @param Map value storage table
* @return String returned after reconstruction
* /
private static String excMultiplication (String str, String value, java.util.Map < String, BigDecimal> map) {
String vs [] = value.split ( "\\ *");
BigDecimal v1 = map.get (vs [0]);
BigDecimal v2 = map.get (vs [1]);
BigDecimal x = v1.multiply (v2);
map.remove (vs [0]);
map.remove (vs [1]);
String uuid = getUUID ();
map.put (uuid, x);
str = str.replace (value, uuid);
return str;
}
/ **
* Calculation departure
*
* @param Str the entire operation string
* @param Value calculated string multiplication
* @param Map value storage table
* @return String returned after reconstruction
* /
private static String excDivsion (String str, String value, java.util.Map < String, BigDecimal> map) {
String vs [] = value.split ( "\\ /");
BigDecimal v1 = map.get (vs [0]);
BigDecimal v2 = map.get (vs [1]);
BigDecimal x = v1.divide (v2);
map.remove (vs [0]);
map.remove (vs [1]);
String uuid = getUUID ();
map.put (uuid, x);
str = str.replace (value, uuid);
return str;
}
}
These are the JAVA code, the idea is a formula word as a string parameter to look at, and not as a purely digital. When each operation, only binary operation after operation to save the data, then delete the original data in the data table. This cycle, without the need to consider limiting the brackets.
When implementing the code, consider the direct use of float or double type, but the final result is displayed, will produce two types of precision loss in accuracy, so eventually consider using BigDecimal types, can be considered for long-term operation to consider it. |
|
|
|