Hmm. This is not simple, particularly if you mean that you want to
- take an expression as a string of characters
- parse out the numbers and operators
- hold the numbers as arbitrary-precision big integers
- evaluate the expression respecting the bodmas/pedmas rules
I mean - let's say someone wants to evaluate 1/3. How many decimals will you want? Or do you want to hold all the values as exact fractions - using a bigger denominator when necessary? But do you want exponentation? If so, using fractions is not an option, because 2^(1/2) does not have an exact fractional representation. Best you could do, if you want exact numbers, is to reduce the expression to its simplest exact form? For the general case, AFAIK the result would be the sum of a number of terms each of the form a/b * c/d ^ (e/f), eg: 3 + 2 * 5^(7/13)
So, your first question is representation. What do you really, really want? (Shout out to the Spice Girls).
The other difficult problem is the pedmas. To do that, you need a proper parser - google "LALR(1) parser" for a taster of what's involved. The parser builds an in-memory tree of the structure of the expression, then the nodes of the tree are solved from the leaves to the root. Early calculators solved this problem by using reverse polish notation - google "reverse polish notation".
So, assuming that we are not trying to do exponentation you'd parse the expresssion. Each number would be converted to an exact fraction - decimal places handled by multiplying by 10 until you had integers. The parser would build a tree of operators, and then you'd implement +-*/ to work over the fractions and produce a fraction as a result. For the output, you'd either print out the fractional result, or do it as a decimal - working out where the reapeating section starts. 97/70 would be rendered 1.3[857142], or something like that.
If you want to do exponentation, then the values would be a list of those basic expressions - the sum of which is the value - and the +-/^ operations would have to be able to work with lists like that. eg, you 'd have to write something to express 35^(1/2) + 5*3^(1/5) exponentiated by 2^(1/3)-7^(15/13) as a sum of terms.
If you really want it exact.
It's do-able, but this is not a simple ask. You could certainly use a library if there is one, but the question of how to go about doing that really depends on the library.
Or, or, you could just use 64-bit floating-point numbers, which are more than accurate enough for most practical purposes.
Perhaps the take-away from this is that you young whipper-snappers don't really get just how much these convenient high-level interpreted languages do for you. One of the useful things about programming for the arduino is that it gives you a taste of what is going on under the hood, that being: a lot.