@@ -51,21 +51,22 @@ else if (elemCount == 2) {
5151 step = args [2 ];
5252 }
5353
54- if (step .equals (BigInteger .ZERO )) {
54+ int stepSignum = step .signum ();
55+ if (stepSignum == 0 ) {
5556 throw new IllegalArgumentException (String .format ("Range element constructed with zero step size!" ));
5657 }
5758
5859 BigInteger diff = stop .subtract (start );
59- int diffComp = diff .compareTo ( BigInteger . ZERO ), stepComp = step . compareTo ( BigInteger . ZERO );
60- if ((diffComp > 0 && stepComp < 0 ) || (diffComp < 0 && stepComp > 0 )) {
60+ int diffSignum = diff .signum ( );
61+ if ((stepSignum < 0 && diffSignum > 0 ) || (stepSignum > 0 && diffSignum < 0 )) {
6162 throw new IllegalArgumentException (String .format ("Range element constructed with invalid arguments start = %s, stop = %s, step = %s!" , start , stop , step ));
6263 }
6364
6465 this .start = start ;
6566 this .stop = stop ;
6667 this .step = step ;
6768
68- size = diff .abs ().subtract (BigInteger .ONE ).divide (step .abs ()).add (BigInteger .ONE ).longValueExact ();
69+ size = diffSignum == 0 ? 0L : diff .abs ().subtract (BigInteger .ONE ).divide (step .abs ()).add (BigInteger .ONE ).longValueExact ();
6970 }
7071
7172 public RangeElement (Interpreter interpreter , @ NonNull BigInteger start , @ NonNull BigInteger stop , @ NonNull BigInteger step , long size ) {
@@ -154,10 +155,17 @@ public boolean contains(TokenExecutor exec, @NonNull Element elem) {
154155 }
155156
156157 @ NonNull BigInteger intValue = intElem .value .raw ;
157- if (intValue .compareTo (start ) < 0 || intValue .compareTo (stop ) >= 0 ) {
158- return false ;
158+ if (step .signum () > 0 ) {
159+ if (intValue .compareTo (start ) < 0 || intValue .compareTo (stop ) >= 0 ) {
160+ return false ;
161+ }
159162 }
160- return intValue .subtract (start ).mod (step ).equals (BigInteger .ZERO );
163+ else {
164+ if (intValue .compareTo (start ) > 0 || intValue .compareTo (stop ) <= 0 ) {
165+ return false ;
166+ }
167+ }
168+ return intValue .subtract (start ).remainder (step ).equals (BigInteger .ZERO );
161169 }
162170
163171 @ Override
@@ -219,8 +227,15 @@ public boolean containsAll(TokenExecutor exec, @NonNull Element elem) {
219227 }
220228
221229 @ NonNull BigInteger intValue = intElem .value .raw ;
222- if (intValue .compareTo (start ) < 0 || intValue .compareTo (stop ) >= 0 ) {
223- return interpreter .builtIn .nullElement ;
230+ if (step .signum () > 0 ) {
231+ if (intValue .compareTo (start ) < 0 || intValue .compareTo (stop ) >= 0 ) {
232+ return interpreter .builtIn .nullElement ;
233+ }
234+ }
235+ else {
236+ if (intValue .compareTo (start ) > 0 || intValue .compareTo (stop ) <= 0 ) {
237+ return interpreter .builtIn .nullElement ;
238+ }
224239 }
225240
226241 BigInteger [] divRem = intValue .subtract (start ).divideAndRemainder (step );
@@ -232,7 +247,7 @@ protected BigInteger at(long index) {
232247 }
233248
234249 protected void methodIndexBoundsCheck (long index , String name ) {
235- if (index >= size ) {
250+ if (index < 0 || index >= size ) {
236251 throw new IndexOutOfBoundsException (String .format ("Built-in method \" %s\" (index: %s, size: %s)" , name , index , size ));
237252 }
238253 }
@@ -255,7 +270,7 @@ public int hashCode() {
255270 @ Override
256271 public boolean equals (Object obj ) {
257272 if (obj instanceof RangeElement other ) {
258- return start == other .start && stop == other .stop && step == other .step ;
273+ return start . equals ( other .start ) && stop . equals ( other .stop ) && step . equals ( other .step ) ;
259274 }
260275 return false ;
261276 }
0 commit comments