Fix loops over progressions near to MAX_VALUE/MIN_VALUE

#KT-492 Fixed

For Byte, Char and Short ranges, promote the type of the loop parameter to int
to avoid overflows. For Int and Long ranges at the end of the loop over a
progression we now check if the new (incremented) value of the loop parameter
is greater than the old value iff increment > 0
This commit is contained in:
Alexander Udalov
2013-06-18 19:41:38 +04:00
parent 33d6347876
commit ee80e0b8ca
25 changed files with 1148 additions and 36 deletions
+3 -3
View File
@@ -17,7 +17,7 @@
package jet;
class ByteProgressionIterator extends ByteIterator {
private byte next;
private int next;
private final byte end;
private final int increment;
@@ -34,8 +34,8 @@ class ByteProgressionIterator extends ByteIterator {
@Override
public byte nextByte() {
byte value = next;
int value = next;
next += increment;
return value;
return (byte) value;
}
}
+3 -3
View File
@@ -17,7 +17,7 @@
package jet;
class CharProgressionIterator extends CharIterator {
private char next;
private int next;
private final char end;
private final int increment;
@@ -34,8 +34,8 @@ class CharProgressionIterator extends CharIterator {
@Override
public char nextChar() {
char value = next;
int value = next;
next += increment;
return value;
return (char) value;
}
}
+5 -1
View File
@@ -20,6 +20,7 @@ class IntProgressionIterator extends IntIterator {
private int next;
private final int end;
private final int increment;
private boolean overflowHappened = false;
public IntProgressionIterator(int start, int end, int increment) {
this.next = start;
@@ -29,13 +30,16 @@ class IntProgressionIterator extends IntIterator {
@Override
public boolean hasNext() {
return increment > 0 ? next <= end : next >= end;
return !overflowHappened && (increment > 0 ? next <= end : next >= end);
}
@Override
public int nextInt() {
int value = next;
next += increment;
if ((increment > 0) != (next > value)) {
overflowHappened = true;
}
return value;
}
}
+5 -1
View File
@@ -20,6 +20,7 @@ class LongProgressionIterator extends LongIterator {
private long next;
private final long end;
private final long increment;
private boolean overflowHappened = false;
public LongProgressionIterator(long start, long end, long increment) {
this.next = start;
@@ -29,13 +30,16 @@ class LongProgressionIterator extends LongIterator {
@Override
public boolean hasNext() {
return increment > 0 ? next <= end : next >= end;
return !overflowHappened && (increment > 0 ? next <= end : next >= end);
}
@Override
public long nextLong() {
long value = next;
next += increment;
if ((increment > 0) != (next > value)) {
overflowHappened = true;
}
return value;
}
}
@@ -17,7 +17,7 @@
package jet;
class ShortProgressionIterator extends ShortIterator {
private short next;
private int next;
private final short end;
private final int increment;
@@ -34,8 +34,8 @@ class ShortProgressionIterator extends ShortIterator {
@Override
public short nextShort() {
short value = next;
int value = next;
next += increment;
return value;
return (short) value;
}
}