views:

371

answers:

5

The problem im facing with BigInteger when i try computing a string like "7+3" and then storing the result in a BigInteger variable, it throws a NumberFormat exception. Any pointers on how this can worked on? Eg:

    String ist="7+2";
    java.math.BigInteger a = new java.math.BigInteger(ist);
+6  A: 

BigInteger cannot evaluate expressions. In fact, I don't know of any solution in Java to do evaluation of arbitrary arithmetic expressions - you could try Groovy instead or parse the expression yourself.

If you're considering parsing, the simplest way is probably to convert from infix notation to polish notation and then evaluate the polish form one operator at a time. Look up the shunting yard algorithm.

diciu
+2  A: 

BigInteger will only understand that, when you pass a numeric value like new java.math.BigInteger("9"). It can not parse what you provide.

Peter Lang
+2  A: 

As diciu and Peter Lang have stated, BigInteger cannot evaluate expressions. If you need numbers that, when evaluated, would overflow some primitive like an Integer, you can create two BigIntegers and then evaluate the result. For instance:

java.math.BigInteger a = new java.math.BigInteger("7").add(new java.math.BigInteger("2"));
faran
+8  A: 

BigInteger sum = (new BigInteger(7)).add(new BigInteger(3))

JepLite, Jeks, JbcParser, MESP, and JEP are all libraries can parse expressions like "7+3"

jspcal
Warning - JEP is not free software. You'll need to pay for a license.
Stephen C
v2.4.1 is free. and the commercial version has many excellent enhancements and new features.
jspcal
+1  A: 

If you really want to evaluate strings and you don't mind using s-expressions then you could use Clojure:

Clojure 1.0.0-
user=> (def s "(+ 7 3)")
#'user/s
user=> (load-string s)
10
user=>

Here are instructions for invoking Clojure from Java

If you take this route be careful to sanitize the strings before you evaluate them or you could leave yourself open to injection attacks.

BTW when Clojure evaluates the expression it will use a BigInteger if needed, for instance:

user=> (def s "(+ 1 2)")
#'user/s
user=> (def r (load-string s))
#'user/r
user=> (. r getClass)
java.lang.Integer
user=> (def s "(+ 1000000000000000000000000 20000000000000000000000)")
#'user/s
user=> (def r (load-string s))
#'user/r
user=> (. r getClass)
java.math.BigInteger
user=>
Nathan Hughes
Can this not lead to some type of injection attack? The string could be originating from some random client who replaces the (+ 7 3) with some sort of system call
adi92