Need reviewer: JDK 8 CR for Support Integer overflow
There is a need for arithmetic operations that throw exceptions when the results overflow the representation of int or long. The CR is 6708398: Support integer overflow <http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6708398> Please review this webrev <http://cr.openjdk.java.net/%7Erriggs/CR6708398/webrev/> to add static methods in java.lang.Math to support addExact(), subtractExact(), negateExact(), multiplyExact(), and toIntExact() for int and long primitive types. Thanks, Roger Riggs
* Roger Riggs:
to support addExact(), subtractExact(), negateExact(), multiplyExact(), and toIntExact() for int and long primitive types.
Would it make sense to replace (x ^ r) < 0 && (x ^ y) >= 0 in + public static int addExact(int x, int y) { + int r = x + y; + if ((x ^ r) < 0 && (x ^ y) >= 0) { + throw new ArithmeticException("Addition overflows an int"); + } + return r; + } with (x ^ y ^ r) < 0? For substraction, you could use ((x ^ r) & (x ^ y)) < 0. Will Hotspot be able to optimize away the string construction on the exception path in multiplyExact() if the exception is caught locally? -- Florian Weimer <fweimer@bfk.de> BFK edv-consulting GmbH http://www.bfk.de/ Kriegsstraße 100 tel: +49-721-96201-1 D-76133 Karlsruhe fax: +49-721-96201-99
Hi Florian, On Fri, Feb 3, 2012 at 4:11 PM, Florian Weimer <fweimer@bfk.de> wrote:
Will Hotspot be able to optimize away the string construction on the exception path in multiplyExact() if the exception is caught locally?
At least -XX:+OptimizeStringConcat should remove the need to construct a StringBuilder instance, in multiplyExact()'s case.
Cc'ing hotspot-compiler-dev for confirmation. - Kris
On Feb 3, 2012, at 12:38 AM, Krystal Mok wrote:
Hi Florian,
On Fri, Feb 3, 2012 at 4:11 PM, Florian Weimer <fweimer@bfk.de> wrote: Will Hotspot be able to optimize away the string construction on the exception path in multiplyExact() if the exception is caught locally?
At least -XX:+OptimizeStringConcat should remove the need to construct a StringBuilder instance, in multiplyExact()'s case.
Cc'ing hotspot-compiler-dev for confirmation.
Could we have some context? tom
- Kris
Hi Tom, Yes, I'm sorry for not including enough context when cc'ing. The original discussion thread starts from [1]. The webrev is at [2]. For the string concats in multiplyExact(): * the StringBuilder doesn't escape * it's only concatenating Strings and ints which should meet the requirements for OptimizeStringConcat to work, Regards, Kris Mok [1]: http://mail.openjdk.java.net/pipermail/core-libs-dev/2012-February/009128.ht... [2]: http://cr.openjdk.java.net/~rriggs/CR6708398/webrev/ On Sat, Feb 4, 2012 at 1:47 AM, Tom Rodriguez <tom.rodriguez@oracle.com>wrote:
On Feb 3, 2012, at 12:38 AM, Krystal Mok wrote:
Hi Florian,
On Fri, Feb 3, 2012 at 4:11 PM, Florian Weimer <fweimer@bfk.de> wrote: Will Hotspot be able to optimize away the string construction on the exception path in multiplyExact() if the exception is caught locally?
At least -XX:+OptimizeStringConcat should remove the need to construct a StringBuilder instance, in multiplyExact()'s case.
Cc'ing hotspot-compiler-dev for confirmation.
Could we have some context?
tom
- Kris
On Feb 3, 2012, at 8:37 PM, Krystal Mok wrote:
Hi Tom,
Yes, I'm sorry for not including enough context when cc'ing.
The original discussion thread starts from [1]. The webrev is at [2].
For the string concats in multiplyExact(): * the StringBuilder doesn't escape * it's only concatenating Strings and ints
which should meet the requirements for OptimizeStringConcat to work,
That's right. I believe it would be able to optimize away the string construction work in this case. tom
Regards, Kris Mok
[1]: http://mail.openjdk.java.net/pipermail/core-libs-dev/2012-February/009128.ht... [2]: http://cr.openjdk.java.net/~rriggs/CR6708398/webrev/
On Sat, Feb 4, 2012 at 1:47 AM, Tom Rodriguez <tom.rodriguez@oracle.com> wrote:
On Feb 3, 2012, at 12:38 AM, Krystal Mok wrote:
Hi Florian,
On Fri, Feb 3, 2012 at 4:11 PM, Florian Weimer <fweimer@bfk.de> wrote: Will Hotspot be able to optimize away the string construction on the exception path in multiplyExact() if the exception is caught locally?
At least -XX:+OptimizeStringConcat should remove the need to construct a StringBuilder instance, in multiplyExact()'s case.
Cc'ing hotspot-compiler-dev for confirmation.
Could we have some context?
tom
- Kris
On 3 February 2012 00:11, Florian Weimer <fweimer@bfk.de> wrote:
Would it make sense to replace (x ^ r) < 0 && (x ^ y) >= 0 with (x ^ y ^ r) < 0?
That would not be correct. For example, it would signal overflow for -1 + 1. Éamonn On 3 February 2012 00:11, Florian Weimer <fweimer@bfk.de> wrote:
* Roger Riggs:
to support addExact(), subtractExact(), negateExact(), multiplyExact(), and toIntExact() for int and long primitive types.
Would it make sense to replace (x ^ r) < 0 && (x ^ y) >= 0 in
+ public static int addExact(int x, int y) { + int r = x + y; + if ((x ^ r) < 0 && (x ^ y) >= 0) { + throw new ArithmeticException("Addition overflows an int"); + } + return r; + }
with (x ^ y ^ r) < 0?
For substraction, you could use ((x ^ r) & (x ^ y)) < 0.
Will Hotspot be able to optimize away the string construction on the exception path in multiplyExact() if the exception is caught locally?
-- Florian Weimer <fweimer@bfk.de> BFK edv-consulting GmbH http://www.bfk.de/ Kriegsstraße 100 tel: +49-721-96201-1 D-76133 Karlsruhe fax: +49-721-96201-99
* Eamonn McManus:
On 3 February 2012 00:11, Florian Weimer <fweimer@bfk.de> wrote:
Would it make sense to replace (x ^ r) < 0 && (x ^ y) >= 0 with (x ^ y ^ r) < 0?
That would not be correct. For example, it would signal overflow for -1 + 1.
Oops. But there has to be a way to implement this using just one comparison. -- Florian Weimer <fweimer@bfk.de> BFK edv-consulting GmbH http://www.bfk.de/ Kriegsstraße 100 tel: +49-721-96201-1 D-76133 Karlsruhe fax: +49-721-96201-99
The boolean expression can be refactored. (Only bit-31 is significant). But it becomes pretty inscrutable. (x ^ r)< 0&& (x ^ y)>= 0 becomes (x ^ r)< 0&& (~(x ^ y))< 0 becomes ((x ^ r)& ~(x ^ y))< 0 Roger On 02/03/2012 07:12 AM, Florian Weimer wrote:
* Eamonn McManus:
On 3 February 2012 00:11, Florian Weimer<fweimer@bfk.de> wrote:
Would it make sense to replace (x ^ r)< 0&& (x ^ y)>= 0 with (x ^ y ^ r)< 0? That would not be correct. For example, it would signal overflow for -1 + 1. Oops. But there has to be a way to implement this using just one comparison.
* Roger Riggs:
The boolean expression can be refactored. (Only bit-31 is significant). But it becomes pretty inscrutable.
(x ^ r)< 0&& (x ^ y)>= 0 becomes
(x ^ r)< 0&& (~(x ^ y))< 0 becomes
((x ^ r)& ~(x ^ y))< 0
That's what I got in my second attempt, too. It doesn't result in a longer dependency chain because the left side of the & is two operations deep, too. Therefore, this version should be faster (at least after compilation), independent of the input arguments. -- Florian Weimer <fweimer@bfk.de> BFK edv-consulting GmbH http://www.bfk.de/ Kriegsstraße 100 tel: +49-721-96201-1 D-76133 Karlsruhe fax: +49-721-96201-99
On 02/03/2012 06:44 AM, Florian Weimer wrote:
* Roger Riggs:
The boolean expression can be refactored. (Only bit-31 is significant). But it becomes pretty inscrutable.
(x ^ r)< 0&& (x ^ y)>= 0 becomes
(x ^ r)< 0&& (~(x ^ y))< 0 becomes
((x ^ r)& ~(x ^ y))< 0 That's what I got in my second attempt, too. It doesn't result in a longer dependency chain because the left side of the& is two operations deep, too. Therefore, this version should be faster (at least after compilation), independent of the input arguments.
These sorts of concerns and lovingly (and laboriously!) detailed to Hank Warren's bit-twiddling tome "Hacker's Delight" (http://www.hackersdelight.org/). Roger's initial code used one of the recommend idioms from that source. We should stick with those idioms unless there is a good reason not to. -Joe
Hacker's Delight gives a formula equivalent to this one on page 27: ((x ^ r) & (y ^ r)) < 0 Having said that, I think Florian's assertion that such a rewrite will be faster needs proof. In the original form... (x ^ r) < 0 && (x ^ y) >= 0 ...the first condition will be false half the time for random inputs and (hand-waving) probably a lot more than half the time for typical inputs. To the extent that the difference is measurable at all, I would not like to have to bet on which alternative is faster, and the original form is definitely easier to read as "both arguments have the same sign and the result has the opposite sign." Éamonn On 3 February 2012 09:07, Joe Darcy <joe.darcy@oracle.com> wrote:
On 02/03/2012 06:44 AM, Florian Weimer wrote:
* Roger Riggs:
The boolean expression can be refactored. (Only bit-31 is significant).
But it becomes pretty inscrutable.
(x ^ r)< 0&& (x ^ y)>= 0 becomes
(x ^ r)< 0&& (~(x ^ y))< 0 becomes
((x ^ r)& ~(x ^ y))< 0
That's what I got in my second attempt, too. It doesn't result in a longer dependency chain because the left side of the& is two operations
deep, too. Therefore, this version should be faster (at least after compilation), independent of the input arguments.
These sorts of concerns and lovingly (and laboriously!) detailed to Hank Warren's bit-twiddling tome "Hacker's Delight" (http://www.hackersdelight. **org/ <http://www.hackersdelight.org/>).
Roger's initial code used one of the recommend idioms from that source. We should stick with those idioms unless there is a good reason not to.
-Joe
I prefer the method naming safeAdd/safeNegate/safeMultiply (I think they are a lot clearer), but can live with the ones proposed (which are somewhat linked to BigInteger/BigDecimal). I would like to see source code comments explaining why the algorithm works in the final version in OpenJDK. Thats because OpenJDK code is used by everyone to read and understand what is good Java code, and for debugging. Being given a clue to understand the algorithm is highly desirable. It would be desirable to see safe increment and decrement methods as well. These are faster than just an add/subtract (simpler implementation). Most of the methods do not specify the arguments in the exception, but the multiply methods do. It should be consistent one way or the other. It may be worth considering (by testing) if methods taking one long and one int are worthwhile. More efficient implementations of the algorithms may be possible, but at the expense of additional API size. Separately but related, there are missing methods in BigInteger, longValueExact() and intValueExact() Also see here if you haven't already: http://blogs.oracle.com/darcy/entry/jvmlang_numbers Stephen On 2 February 2012 20:15, Roger Riggs <Roger.Riggs@oracle.com> wrote:
There is a need for arithmetic operations that throw exceptions when the results overflow the representation of int or long.
The CR is 6708398: Support integer overflow <http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6708398>
Please review this webrev <http://cr.openjdk.java.net/%7Erriggs/CR6708398/webrev/> to add static methods in java.lang.Math to support addExact(), subtractExact(), negateExact(), multiplyExact(), and toIntExact() for int and long primitive types.
Thanks, Roger Riggs
On 02/03/2012 10:23 AM, Stephen Colebourne wrote:
I prefer the method naming safeAdd/safeNegate/safeMultiply (I think they are a lot clearer), but can live with the ones proposed (which are somewhat linked to BigInteger/BigDecimal). The method names should start with the operation. I would like to see source code comments explaining why the algorithm works in the final version in OpenJDK. Thats because OpenJDK code is used by everyone to read and understand what is good Java code, and for debugging. Being given a clue to understand the algorithm is highly desirable. yes, I will add comments to describe the implementation and refer to Hackers Delight Section 2-12
Most of the methods do not specify the arguments in the exception, but the multiply methods do. It should be consistent one way or the other. Simplify the exception arguments; if these exceptions occur debugging will be required by examining the source code or using a debugger so the message content is not a significant factor in debugging.
It may be worth considering (by testing) if methods taking one long and one int are worthwhile. More efficient implementations of the algorithms may be possible, but at the expense of additional API size. Since there is no support in the bytecode for combinations of int and long handcoding the mixing would make it harder to optimize the code to the hardware operations. Widening to long enables optimizations for those operations to be used. Separately but related, there are missing methods in BigInteger, longValueExact() and intValueExact()
BigInteger provides a bitLength method than be tested to see if the result would overflow. That's a better API than an ArithmeticException and is easier for the developer to work with. Thanks, Roger
On 6 February 2012 21:15, Roger Riggs <Roger.Riggs@oracle.com> wrote:
Separately but related, there are missing methods in BigInteger, longValueExact() and intValueExact()
BigInteger provides a bitLength method than be tested to see if the result would overflow. That's a better API than an ArithmeticException and is easier for the developer to work with.
As a user, I wouldn't think to use bitLength, and the readability of the resulting code would be far lower. With BigDecimal, int and long now having these "exact" methods, not providing the equivalent on BigInteger should be raising some red flags. Stephen
My initial remarks: In negateExact, the condition x == -x should be faster to evaluate than x == Integer.MIN_VALUE and reflects the intent just as well. In addExact and subtractExact, I would be inclined to implement the int versions using long arithmetic, like this: long lr = x + y; int r = (int) lr; if (r == lr) { return r; } else { throw... } I would use this technique of cast-and-compare in the int multiplyExact instead of comparing against MIN_VALUE and MAX_VALUE, and especially in toIntExact(long). I agree with Stephen Colebourne that brief implementation comments would be useful. But I disagree with his proposed further methods in Math (increment, decrement, int+long variants), which I don't think would pull their weight. Éamonn On 2 February 2012 12:15, Roger Riggs <Roger.Riggs@oracle.com> wrote:
There is a need for arithmetic operations that throw exceptions when the results overflow the representation of int or long.
The CR is 6708398: Support integer overflow <http://bugs.sun.com/** bugdatabase/view_bug.do?bug_**id=6708398<http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6708398>
Please review this webrev <http://cr.openjdk.java.net/%** 7Erriggs/CR6708398/webrev/<http://cr.openjdk.java.net/%7Erriggs/CR6708398/webrev/>> to add static methods in java.lang.Math to support addExact(), subtractExact(), negateExact(), multiplyExact(), and toIntExact() for int and long primitive types.
Thanks, Roger Riggs
On 3 February 2012 17:52, Eamonn McManus <eamonn@mcmanus.net> wrote:
I agree with Stephen Colebourne that brief implementation comments would be useful. But I disagree with his proposed further methods in Math (increment, decrement, int+long variants), which I don't think would pull their weight.
FWIW, JSR-310 currently has 18 non-test usages of increment/decrement, vs 42 uses of add. Less, but certainly used. The real value in increment/decrement is that it becomes a simple mapping from operator to method a++ = increment(a) a-- = decrement(a) a + b = add(a, b) This makes it easier to see what the intent would have been were the real operators safe. Stephen
The methods for increment, decrement, and also negation test for exactly one value at the extremities of the value range. The verbosity of method calls in the source code and the overhead in the execution make these a poor choice for developers. If the code must really operate correctly at the extremities then the developer needs to carefully implement and check where appropriate. The checking for overflow in addition, subtraction, and multiplication are subtle or complex enough to warrant support in the runtime. Roger On 02/03/2012 01:00 PM, Stephen Colebourne wrote:
On 3 February 2012 17:52, Eamonn McManus<eamonn@mcmanus.net> wrote:
I agree with Stephen Colebourne that brief implementation comments would be useful. But I disagree with his proposed further methods in Math (increment, decrement, int+long variants), which I don't think would pull their weight. FWIW, JSR-310 currently has 18 non-test usages of increment/decrement, vs 42 uses of add. Less, but certainly used.
The real value in increment/decrement is that it becomes a simple mapping from operator to method a++ = increment(a) a-- = decrement(a) a + b = add(a, b) This makes it easier to see what the intent would have been were the real operators safe.
Stephen
Concerning the long multiplyExactly, I have a number of comments. public static long multiplyExact(long x, long y) { long r = x * y; long ax = Math.abs(x); long ay = Math.abs(y); if (((ax | ay) >>> 31 == 0) || (x == 1) || (y == 1)) { return r; } if (((y != 0) && r / y != x) || (r == Long.MIN_VALUE )) { throw new ArithmeticException("Multiplication overflows a long: " + x + " * " + y); } return r; } I believe that the (ax | ay) condition is an optimization, but I wonder if it is worthwhile. Presumably the intent is to avoid the division if possible, but is division really more expensive than all these extra operations (abs, abs, or, shift, compare) that we are doing? In addition to returning when x == 1 or y == 1, we could return when y == 0, since we're going to be making that check anyway to avoid divide-by-zero. The final check (r == Long.MIN_VALUE) is incorrect. I presume the intent is to detect overflow when we multiply Long.MIN_VALUE by -1 (and obtain Long.MIN_VALUE), but Long.MIN_VALUE can be the result of a non-overflowing multiplication, for example ((Long.MIN_VALUE / 2) * 2). The division check will catch the case of x=-1,y=Long.MIN_VALUE, so we could just check for the other case x=Long.MIN_VALUE,y=-1 explicitly. Éamonn On 4 February 2012 10:51, Roger Riggs <Roger.Riggs@oracle.com> wrote:
The methods for increment, decrement, and also negation test for exactly one value at the extremities of the value range.
The verbosity of method calls in the source code and the overhead in the execution make these a poor choice for developers. If the code must really operate correctly at the extremities then the developer needs to carefully implement and check where appropriate.
The checking for overflow in addition, subtraction, and multiplication are subtle or complex enough to warrant support in the runtime.
Roger
On 02/03/2012 01:00 PM, Stephen Colebourne wrote:
On 3 February 2012 17:52, Eamonn McManus<eamonn@mcmanus.net> wrote:
I agree with Stephen Colebourne that brief implementation comments would be useful. But I disagree with his proposed further methods in Math (increment, decrement, int+long variants), which I don't think would pull their weight.
FWIW, JSR-310 currently has 18 non-test usages of increment/decrement, vs 42 uses of add. Less, but certainly used.
The real value in increment/decrement is that it becomes a simple mapping from operator to method a++ = increment(a) a-- = decrement(a) a + b = add(a, b) This makes it easier to see what the intent would have been were the real operators safe.
Stephen
Éamonn, Thanks for the detailed review. I did some simple performance tests with and without the optimization test. With the optimization, performance was nearly doubled. The individual tests for x or y ==1 did not improve performance. Those cases are likely optimized inside the divide operation. Special casing the simple arguments and return values seems to slow down the non-special cases and it isn't important to speed them up. I will correct for the multiplyExact case for Long.MIN_VALUE * -1. Roger On 02/04/2012 07:40 PM, Eamonn McManus wrote:
Concerning the long multiplyExactly, I have a number of comments.
public static long multiplyExact(long x, long y) { long r = x * y; long ax = Math.abs(x); long ay = Math.abs(y); if (((ax | ay)>>> 31 == 0) || (x == 1) || (y == 1)) { return r; } if (((y != 0)&& r / y != x) || (r == Long.MIN_VALUE )) { throw new ArithmeticException("Multiplication overflows a long: " + x + " * " + y); } return r; }
I believe that the (ax | ay) condition is an optimization, but I wonder if it is worthwhile. Presumably the intent is to avoid the division if possible, but is division really more expensive than all these extra operations (abs, abs, or, shift, compare) that we are doing?
In addition to returning when x == 1 or y == 1, we could return when y == 0, since we're going to be making that check anyway to avoid divide-by-zero.
The final check (r == Long.MIN_VALUE) is incorrect. I presume the intent is to detect overflow when we multiply Long.MIN_VALUE by -1 (and obtain Long.MIN_VALUE), but Long.MIN_VALUE can be the result of a non-overflowing multiplication, for example ((Long.MIN_VALUE / 2) * 2). The division check will catch the case of x=-1,y=Long.MIN_VALUE, so we could just check for the other case x=Long.MIN_VALUE,y=-1 explicitly.
Éamonn
On 4 February 2012 10:51, Roger Riggs<Roger.Riggs@oracle.com> wrote:
The methods for increment, decrement, and also negation test for exactly one value at the extremities of the value range.
The verbosity of method calls in the source code and the overhead in the execution make these a poor choice for developers. If the code must really operate correctly at the extremities then the developer needs to carefully implement and check where appropriate.
The checking for overflow in addition, subtraction, and multiplication are subtle or complex enough to warrant support in the runtime.
Roger
On 02/03/2012 01:00 PM, Stephen Colebourne wrote:
On 3 February 2012 17:52, Eamonn McManus<eamonn@mcmanus.net> wrote:
I agree with Stephen Colebourne that brief implementation comments would be useful. But I disagree with his proposed further methods in Math (increment, decrement, int+long variants), which I don't think would pull their weight. FWIW, JSR-310 currently has 18 non-test usages of increment/decrement, vs 42 uses of add. Less, but certainly used.
The real value in increment/decrement is that it becomes a simple mapping from operator to method a++ = increment(a) a-- = decrement(a) a + b = add(a, b) This makes it easier to see what the intent would have been were the real operators safe.
Stephen
x == Integer.MIN_VALUE should be faster than x == -x as it's a cmp against a constant whereas the latter requires negating x (that's a dependency too), tying up a register to store the negation, and then doing the cmp. Sent from my phone On Feb 3, 2012 12:53 PM, "Eamonn McManus" <eamonn@mcmanus.net> wrote:
My initial remarks:
In negateExact, the condition x == -x should be faster to evaluate than x == Integer.MIN_VALUE and reflects the intent just as well.
In addExact and subtractExact, I would be inclined to implement the int versions using long arithmetic, like this:
long lr = x + y; int r = (int) lr; if (r == lr) { return r; } else { throw... }
I would use this technique of cast-and-compare in the int multiplyExact instead of comparing against MIN_VALUE and MAX_VALUE, and especially in toIntExact(long).
I agree with Stephen Colebourne that brief implementation comments would be useful. But I disagree with his proposed further methods in Math (increment, decrement, int+long variants), which I don't think would pull their weight.
Éamonn
On 2 February 2012 12:15, Roger Riggs <Roger.Riggs@oracle.com> wrote:
There is a need for arithmetic operations that throw exceptions when the results overflow the representation of int or long.
The CR is 6708398: Support integer overflow <http://bugs.sun.com/** bugdatabase/view_bug.do?bug_**id=6708398< http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6708398>
Please review this webrev <http://cr.openjdk.java.net/%** 7Erriggs/CR6708398/webrev/< http://cr.openjdk.java.net/%7Erriggs/CR6708398/webrev/>> to add static methods in java.lang.Math to support addExact(), subtractExact(), negateExact(), multiplyExact(), and toIntExact() for int and long primitive types.
Thanks, Roger Riggs
On 3 February 2012 10:22, Vitaly Davidovich <vitalyd@gmail.com> wrote:
x == Integer.MIN_VALUE should be faster than x == -x as it's a cmp against a constant whereas the latter requires negating x (that's a dependency too), tying up a register to store the negation, and then doing the cmp.
The value -x is needed anyway since it's the return value. But a more important reason why my idea is a bad one is that the condition is true for x == 0! Writing x == -x && x != 0 is definitely not an improvement. Éamonn On 3 February 2012 10:22, Vitaly Davidovich <vitalyd@gmail.com> wrote:
x == Integer.MIN_VALUE should be faster than x == -x as it's a cmp against a constant whereas the latter requires negating x (that's a dependency too), tying up a register to store the negation, and then doing the cmp.
Sent from my phone
On Feb 3, 2012 12:53 PM, "Eamonn McManus" <eamonn@mcmanus.net> wrote:
My initial remarks:
In negateExact, the condition x == -x should be faster to evaluate than x == Integer.MIN_VALUE and reflects the intent just as well.
In addExact and subtractExact, I would be inclined to implement the int versions using long arithmetic, like this:
long lr = x + y; int r = (int) lr; if (r == lr) { return r; } else { throw... }
I would use this technique of cast-and-compare in the int multiplyExact instead of comparing against MIN_VALUE and MAX_VALUE, and especially in toIntExact(long).
I agree with Stephen Colebourne that brief implementation comments would be useful. But I disagree with his proposed further methods in Math (increment, decrement, int+long variants), which I don't think would pull their weight.
Éamonn
On 2 February 2012 12:15, Roger Riggs <Roger.Riggs@oracle.com> wrote:
There is a need for arithmetic operations that throw exceptions when the results overflow the representation of int or long.
The CR is 6708398: Support integer overflow <http://bugs.sun.com/** bugdatabase/view_bug.do?bug_**id=6708398<http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6708398>
Please review this webrev <http://cr.openjdk.java.net/%** 7Erriggs/CR6708398/webrev/<http://cr.openjdk.java.net/%7Erriggs/CR6708398/webrev/>>
to add static methods in java.lang.Math to support addExact(), subtractExact(), negateExact(), multiplyExact(), and toIntExact() for int and long primitive types.
Thanks, Roger Riggs
Yeah my comment was more general - I didn't look at the entire context, just wasn't sure why you thought that comparison would be faster (nevermind that it's wrong as you mention :)). Sent from my phone On Feb 3, 2012 1:58 PM, "Eamonn McManus" <eamonn@mcmanus.net> wrote:
On 3 February 2012 10:22, Vitaly Davidovich <vitalyd@gmail.com> wrote:
x == Integer.MIN_VALUE should be faster than x == -x as it's a cmp against a constant whereas the latter requires negating x (that's a dependency too), tying up a register to store the negation, and then doing the cmp.
The value -x is needed anyway since it's the return value. But a more important reason why my idea is a bad one is that the condition is true for x == 0! Writing x == -x && x != 0 is definitely not an improvement.
Éamonn
On 3 February 2012 10:22, Vitaly Davidovich <vitalyd@gmail.com> wrote:
x == Integer.MIN_VALUE should be faster than x == -x as it's a cmp
against a constant whereas the latter requires negating x (that's a dependency too), tying up a register to store the negation, and then doing the cmp.
Sent from my phone
On Feb 3, 2012 12:53 PM, "Eamonn McManus" <eamonn@mcmanus.net> wrote:
My initial remarks:
In negateExact, the condition x == -x should be faster to evaluate than
x
== Integer.MIN_VALUE and reflects the intent just as well.
In addExact and subtractExact, I would be inclined to implement the int versions using long arithmetic, like this:
long lr = x + y; int r = (int) lr; if (r == lr) { return r; } else { throw... }
I would use this technique of cast-and-compare in the int multiplyExact instead of comparing against MIN_VALUE and MAX_VALUE, and especially in toIntExact(long).
I agree with Stephen Colebourne that brief implementation comments would be useful. But I disagree with his proposed further methods in Math (increment, decrement, int+long variants), which I don't think would pull their weight.
Éamonn
On 2 February 2012 12:15, Roger Riggs <Roger.Riggs@oracle.com> wrote:
There is a need for arithmetic operations that throw exceptions when the results overflow the representation of int or long.
The CR is 6708398: Support integer overflow <http://bugs.sun.com/** bugdatabase/view_bug.do?bug_**id=6708398< http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6708398>
Please review this webrev <http://cr.openjdk.java.net/%** 7Erriggs/CR6708398/webrev/< http://cr.openjdk.java.net/%7Erriggs/CR6708398/webrev/>>
to add static methods in java.lang.Math to support addExact(), subtractExact(), negateExact(), multiplyExact(), and toIntExact() for int and long primitive types.
Thanks, Roger Riggs
participants (8)
-
Eamonn McManus
-
Florian Weimer
-
Joe Darcy
-
Krystal Mok
-
Roger Riggs
-
Stephen Colebourne
-
Tom Rodriguez
-
Vitaly Davidovich