ParserNG icon indicating copy to clipboard operation
ParserNG copied to clipboard

ParserNG should use `BigDecimal` instead of `double`

Open JellyBrick opened this issue 3 years ago • 16 comments

Test code

class MathTest {
    @Test
    fun testMathExpression() {
        println(MathExpression("239081204214*1247981247912749").solve())
    }
}

Expect

298368859587470504923124286

Result

298368859587470500000000000

JellyBrick avatar Feb 06 '23 10:02 JellyBrick

The parserng works by default in doubles. What you see is max precision double can get:

jshell> double a = 239081204214d
a ==> 2.39081204214E11
jshell> double b=1247981247912749d
b ==> 1.247981247912749E15
jshell> a*b
$3 ==> 2.983688595874705E26

What you see would be achieved moving whole parserng to bigdecimal:

jshell> BigInteger ba = new BigInteger("239081204214");
ba ==> 239081204214
jshell> BigInteger bb = new BigInteger("1247981247912749");
bb ==> 1247981247912749
jshell> BigInteger bc =ba.multiply(bb)
bc ==> 298368859587470504923124286

and big decimal

jshell> BigDecimal ba = new BigDecimal("239081204214");
ba ==> 239081204214
jshell> BigDecimal bb = new BigDecimal("1247981247912749");
bb ==> 1247981247912749
jshell> ba.multiply(bb)
$3 ==> 298368859587470504923124286

Where the cost performance will be notable, I would vote for moveing parserng from double to BigInteger. Still it is very huge step.

judovana avatar Feb 06 '23 10:02 judovana

I would probably recommend to change subject of this issue: "parserng shoud use bigdecimal instead of doubles" , but still, I think its not going to be solved anytime soon.

judovana avatar Feb 06 '23 10:02 judovana

btw, future 0.1.9 (pom is not yet bumped) have sum and gsum rewritten to biginteger:

java -jar target/parser-ng-0.1.8.jar  "gsum(239081204214,1247981247912749)"
298368859587470504923124286

(prod is still in double):

java -jar target/parser-ng-0.1.8.jar  "prod(239081204214,1247981247912749)"
2.983688595874705E26

So gsum/summ can help you to workaroudn this problem.. somehow...

judovana avatar Feb 06 '23 10:02 judovana

I hope to draft readme.md changes for 0.1.9 during this week, so @gbenroscience could release.

judovana avatar Feb 06 '23 10:02 judovana

The parserng works by default in doubles. What you see is max precission double can get:

jshell> double a = 239081204214d
a ==> 2.39081204214E11
jshell> double b=1247981247912749d
b ==> 1.247981247912749E15
jshell> a*b
$3 ==> 2.983688595874705E26

What you see would be achieved moving whole parserng to bigdecimal:

jshell> BigInteger ba = new BigInteger("239081204214");
ba ==> 239081204214
jshell> BigInteger bb = new BigInteger("1247981247912749");
bb ==> 1247981247912749
jshell> BigInteger bc =ba.multiply(bb)
bc ==> 298368859587470504923124286

Where the cost performance will be notable, I would vote for moveing parserng from double to BigInteger. Still it is very huge step.

https://github.com/ezylang/EvalEx-big-math

How about delegating BigDecimal operations to other extension libraries? (e.g. EvalEx <-> EvalEx-big-math)

JellyBrick avatar Feb 06 '23 11:02 JellyBrick

https://github.com/ezylang/EvalEx-big-math

How about delegating BigDecimal operations to other extension libraries? (e.g. EvalEx <-> EvalEx-big-math)

Well there is plenty of math libraries, each with its pros and cons. Some ar fast, some ar not, some have some functins, some dont, some are double, some are bigdecimal.... I like pareserng for its strightforward approach and easy extendability. To have math library(parserng) calling another math library (evalex-bigmath) would be very weird step.

judovana avatar Feb 06 '23 12:02 judovana

Thanx for fixing me to BigDecimal. My typo. Had BigDecimal in mind.

judovana avatar Feb 06 '23 12:02 judovana

ezylang/EvalEx-big-math How about delegating BigDecimal operations to other extension libraries? (e.g. EvalEx <-> EvalEx-big-math)

Well there is plenty of math libraries, each with its pros and cons. Some ar fast, some ar not, some have some functins, some dont, some are double, some are bigdecimal.... I like pareserng for its strightforward approach and easy extendability. To have math library(parserng) calling another math library (evalex-bigmath) would be very weird step.

What I'm saying is that there are cases like EvalEx-big-math. I'm not saying that ParserNG should include EvalEx-big-math.

JellyBrick avatar Feb 06 '23 14:02 JellyBrick

Hello @JellyBrick , thanks for using ParserNG! Thanks @judovana for responding.

@JellyBrick , BigDecimal computations would definitely slow down the parser and this is why we use double precision instead!

However, we can define a limited BigMathExpression class that handles no functions, just algebraic expressions. This would bring limited support of your functionality to ParserNG.

Many important classes are based on MathExpression and we don't want something like this to break something higher up in the chain.

With time, then we can contribute functions that efficiently and accurately compute the trig functions, the log functions etc in BigDecimal format.

Once this is achieved, we can then allow BigMathExpression support functions also.

What do you think, @judovana and @JellyBrick ?

gbenroscience avatar Feb 07 '23 13:02 gbenroscience

Actually, there is a class PolynomialExpression that does this already, buried somewhere in the heart of ParserNG. It is used mainly by numerical methods for integral calculus and some other functionality, I think, in the parser. If you are cool with it, we can base this functionality on it and move ahead.

gbenroscience avatar Feb 07 '23 13:02 gbenroscience

Can you provide examples of PolynomialExpression please?

The BigMathExpression is interesting idea. Maybe MathExpression can have as parameter factory method, which will be responsible for sting->number convertions? like T toNumber(String) which in MathExpression will return Double, and otherwise BigDecimal. The mian issue here is the Double x double. In all cases this will get rid of primitives, whcih you do not want I guess. Still having BigDecimal at elast semi optional, sounds exceptionally god.

Before actuallys tarting anything, would be nice to have performance comparsion double x Double x BigDecimal. Maybe the difference will bs super trivial.

judovana avatar Feb 07 '23 14:02 judovana

PolynomialExpression

So sorry. I took a look at PolynomialExpression and its not what I had in mind that it does. Its quite old code but it contains a lot of things that can be reused in an hypothetical BigMathExpression class.

Before actually starting anything, would be nice to have performance comparison double x Double x BigDecimal. Maybe the difference will be super trivial.

Did some research online though, it seems the general consensus is that BigDecimal would be much slower versus primitives. One such article is this

gbenroscience avatar Feb 07 '23 15:02 gbenroscience

I have bigger concerns about double x Double. Which is killing the idea of generic MathExpression. Still worthy to investigate in future. I personally would like to see whole ParserNG on BigDecimal. But that would be tremendous work with sporadic result. generic MathExpression would be incredible solution. It would allow also predictable default length of fractional part of number.

judovana avatar Feb 07 '23 15:02 judovana

Considering the fact that I pray God that a time would come when I would have enough time on my hands to do a speed optimized refactor of ParserNG, moving all of ParserNG to BigDecimal is definitely not attractive to me. But I do not mind having robust BigDecimal support via inheritance(extension...e.g BigMathExpression, preferable) or via setting modes(e.g. DOUBLE or BIGDECIMAL) on the MathExpression class(not so attractive).

I have bigger concerns about double x Double.

Double would benchmark slower than double also; that is the popular opinion since Double is an object. But you could run some tests to convince us of this.

gbenroscience avatar Feb 07 '23 16:02 gbenroscience

Yup. Sure. Crossing fingers for you, and agreeing on double x Double.

judovana avatar Feb 07 '23 16:02 judovana

Hi @judovana and @JellyBrick, here is PR #32

gbenroscience avatar Feb 13 '23 01:02 gbenroscience