Yea, using the snippet provided by Robert, this can easily be fixed in NumberHelper. It only affects div, right?
Cheers, Daniel On Tue, Jul 25, 2017 at 3:41 PM, Marko Rodriguez <[email protected]> wrote: > Hi, > > Does Kuppitz’ NumberHelper come into play here? > > https://github.com/apache/tinkerpop/blob/master/gremlin- > core/src/main/java/org/apache/tinkerpop/gremlin/util/NumberHelper.java < > https://github.com/apache/tinkerpop/blob/master/gremlin- > core/src/main/java/org/apache/tinkerpop/gremlin/util/NumberHelper.java> > > Marko. > > http://markorodriguez.com > > > > > On Jul 25, 2017, at 6:08 AM, Robert Dale <[email protected]> wrote: > > > > I think gremlin should handle this case. It's a matter of setting the > > MathContext precision. I was trying to reproduce this in the shell but > > couldn't. Here's why and what groovy does: > > > > public Number divideImpl(Number left, Number right) { > > BigDecimal bigLeft = toBigDecimal(left); > > BigDecimal bigRight = toBigDecimal(right); > > try { > > return bigLeft.divide(bigRight); > > } catch (ArithmeticException e) { > > // set a DEFAULT precision if otherwise non-terminating > > int precision = Math.max(bigLeft.precision(), > > bigRight.precision()) + DIVISION_EXTRA_PRECISION; > > BigDecimal result = bigLeft.divide(bigRight, new > > MathContext(precision)); > > int scale = Math.max(Math.max(bigLeft.scale(), > > bigRight.scale()), DIVISION_MIN_SCALE); > > if (result.scale() > scale) result = result.setScale(scale, > > BigDecimal.ROUND_HALF_UP); > > return result; > > } > > } > > > > > > Robert Dale > > > > On Tue, Jul 25, 2017 at 7:48 AM, Stephen Mallette <[email protected]> > > wrote: > > > >> Dan "The Stroke" LaRocque gave me some gory details on groovy's > handling of > >> decimals/numbers which can make sack() do this: > >> > >> gremlin> g.withSack(2).V().sack(div).by(constant(3.0)).sack() > >> Non-terminating decimal expansion; no exact representable decimal > result. > >> Type ':help' or ':h' for help. > >> Display stack trace? [yN]y > >> java.lang.ArithmeticException: Non-terminating decimal expansion; no > exact > >> representable decimal result. > >> at java.math.BigDecimal.divide(BigDecimal.java:1690) > >> at > >> org.apache.tinkerpop.gremlin.process.traversal. > >> NumberHelper.lambda$static$45(NumberHelper.java:132) > >> at > >> org.apache.tinkerpop.gremlin.process.traversal. > >> NumberHelper.div(NumberHelper.java:219) > >> at > >> org.apache.tinkerpop.gremlin.process.traversal. > >> NumberHelper.div(NumberHelper.java:214) > >> at > >> org.apache.tinkerpop.gremlin.process.traversal.Operator$4. > >> apply(Operator.java:47) > >> at > >> org.apache.tinkerpop.gremlin.process.traversal.step. > >> sideEffect.SackValueStep.sideEffect(SackValueStep.java:60) > >> at > >> org.apache.tinkerpop.gremlin.process.traversal.step. > >> sideEffect.SideEffectStep.processNextStart(SideEffectStep.java:39) > >> at > >> org.apache.tinkerpop.gremlin.process.traversal.step.util. > >> AbstractStep.hasNext(AbstractStep.java:143) > >> at > >> org.apache.tinkerpop.gremlin.process.traversal.step.util. > >> ExpandableStepIterator.next(ExpandableStepIterator.java:50) > >> at > >> org.apache.tinkerpop.gremlin.process.traversal.step.map. > >> MapStep.processNextStart(MapStep.java:36) > >> at > >> org.apache.tinkerpop.gremlin.process.traversal.step.util. > >> AbstractStep.hasNext(AbstractStep.java:143) > >> at > >> org.apache.tinkerpop.gremlin.process.traversal.util. > >> DefaultTraversal.hasNext(DefaultTraversal.java:184) > >> at > >> org.apache.tinkerpop.gremlin.console.Console$_closure3. > >> doCall(Console.groovy:237) > >> at sun.reflect.GeneratedMethodAccessor39.invoke(Unknown Source) > >> ... > >> at > >> org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodOnSuperN( > >> ScriptBytecodeAdapter.java:132) > >> at > >> org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodOnSuper0( > >> ScriptBytecodeAdapter.java:152) > >> at > >> org.codehaus.groovy.tools.shell.InteractiveShellRunner. > >> run(InteractiveShellRunner.groovy:83) > >> at > >> org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod( > >> IndyInterface.java:232) > >> at org.apache.tinkerpop.gremlin.console.Console.<init>( > Console.groovy:169) > >> at > >> org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod( > >> IndyInterface.java:232) > >> at org.apache.tinkerpop.gremlin.console.Console.main(Console. > groovy:478) > >> > >> this does work well if the Gremlin has more explicit typing: > >> > >> gremlin> g.withSack(2).V().sack(div).by(constant(3.0d)).sack() > >> ==>0.6666666666666666 > >> ==>0.6666666666666666 > >> ==>0.6666666666666666 > >> ==>0.6666666666666666 > >> ==>0.6666666666666666 > >> ==>0.6666666666666666 > >> gremlin> g.withSack(2d).V().sack(div).by(constant(3)).sack() > >> ==>0.6666666666666666 > >> ==>0.6666666666666666 > >> ==>0.6666666666666666 > >> ==>0.6666666666666666 > >> ==>0.6666666666666666 > >> ==>0.6666666666666666 > >> gremlin> g.withSack(2).V().sack(div).by(constant(3)).sack() > >> ==>0 > >> ==>0 > >> ==>0 > >> ==>0 > >> ==>0 > >> ==>0 > >> > >> Is this something we can make nicer? Create a ticket? > >> > >
