History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: GROOVY-2814
Type: Bug Bug
Status: Resolved Resolved
Resolution: Not A Bug
Priority: Major Major
Assignee: Unassigned
Reporter: James King
Votes: 0
Watchers: 1
Operations

If you were logged in you would be able to see more operations.
groovy

Groovy arithmetic errors

Created: 07/May/08 07:08 PM   Updated: Today 09:26 AM
Component/s: None
Affects Version/s: 1.5.6
Fix Version/s: 1.5.7, 1.6-beta-2

Time Tracking:
Not Specified

Environment: Windows Server 2003

Testcase included: yes


 Description  « Hide
Certain equations when evaluated in groovy return incorrect results. Here are some examples:

100000000000*1000000*10*10 returns -8446744073709551616

100000000000*1000000*1000000 returns 200376420520689664



 All   Comments   Work Log   Change History      Sort Order: Ascending order - Click to sort in descending order
Jochen Theodorou - 08/May/08 01:22 PM
in Groovy 100000000000 is interpreted as long. If you do the calculation 100000000000*1000000*10*10 with longs, then Java will as well return -8446744073709551616. The second case be explained along with that. So the result is not wrong

Paul King - 12/May/08 01:26 AM
This is current behavior. Groovy doesn't currently overflow up into the next larger numeric type. There has been some debate on this topic, but currently we have opted to behave like Java:
println 1000 * 1000 * 2000 // 2000000000 (subexpressions all Integer's, result < Integer.MAX_VALUE)
println 1000 * 1000 * 3000 // -1294967296 (subexpressions all Integer's, result > Integer.MAX_VALUE, therefore overflows)
println 1000 * 1000L * 3000 // 3000000000 (one subexpressions is a Long, Integer.MAX_VALUE < result < Long.MAX_VALUE)

println 20000000000 * 200000 * 2000 // 8000000000000000000 (one subexpression is a Long, result < Long.MAX_VALUE)
println 20000000000 * 200000 * 3000 // -6446744073709551616 (one subexpression is a Long, result > Long.MAX_VALUE, therefore overflows)
println 20000000000 * 200000G * 3000 // 12000000000000000000 (one subexpression is a BigInteger, result > Long.MAX_VALUE)

Paul King - 12/May/08 01:35 AM - edited
There is a minor inconsistency here though. For Character, we do not overflow but instead change to the next biggest numeric type, Integer:
int max = Character.MAX_VALUE
println max // => 65535

char x = 30000
def y = x + x + x
println y // => 90000

There is an outstanding bug for this though: GROOVY-1131


Jochen Theodorou - 12/May/08 04:50 AM
as for char... Groovy behaves here exactly like Java. That means even if I do char+char or short+short or byte+byte I still get int. In other words, the result is exactly the same as in Java. So I wouldn't see this as bug too. I only assigned this issue to 1.6-beta2, so we don't forget to close this before the next release. Well, unless James King has something against it.

Paul King - 12/May/08 04:58 AM
Well maybe we should close GROOVY-1131 too.

Jochen Theodorou - 12/May/08 05:14 AM
I think it is reasonable to expect 'c'++ to return a char and not an int.

Paul King - 12/May/08 05:20 AM
So you would expect 'c + 1' to be different to c++?

Jochen Theodorou - 12/May/08 05:37 AM
well, yes, this is difficult. But 1 is an int... if you do 1+1l, you get an long, not an int... well you should at last. So the idea is to expand to the greater scope. From this view it makes perfect sense to let 'c'1 return an int. If I test 'c'+1 in Java I can see that it will return int as well. Now for c, we have two cases here. One is c being types, meaning that if c+ is equal to c=c+1 it will behave exactly the same as in Java. If c is not typed, then we are out of what Java does... and it is quite difficult. That's also the reason GROOVY-1131 is still open.... anyway... I think we should discuss this in GROOVY-1131, not here. But if we say that c++ should be always equal to c=c+1, then we probably should keep it like it is. On the other hand it makes sense to have ++ and-- acting closed under their scope... meaning not to leave the values provided by char.... So yes, I would probably suggest to change next and previous for char, byte and short to return char, byte, short and not int, while still keeping c+1 being an int

Paul King - 17/May/08 09:26 AM
I think the consensus is that this isn't a bug. The character case will be fixed in another issue.