# Bug? Is this a bug or am I going stark raving mad?

Discussion in 'Bugs & wishlist' started by JackKirk, Nov 1, 2018.

Code:
`Private junk As Long = 30 * 24 * 3600junk = junk * 1000Log(junk) 'get 2592000000junk = 30 * 24 * 3600 * 1000Log(junk) 'get -1702967296`

This is not a bug. When you multiply int values you get an int result.

Code:
`Private junk As Long = 30 * 24 * 3600Log(junk) ' get 2592000junk = junk * 1000Log(junk) 'get 2592000000junk = 30 * 24 * 3600 * 1000Log(junk) 'get -1702967296`
I'm confused too.

Multiply the first 3 values:
30 * 24 * 3600 = 2592000

Multiply the result by the 4th value:
2592000 * 1000 = 2592000000

When multiplying the same 4 values but all on one line:
30 * 24 * 3600 * 1000 = -1702967296

When you write an integer number as a literal, integers from -2 147 483 648 to +2 147 483 647 are cast to an Int in B4A/B4J (did not test B4i). Integers literals outside the Int range are cast to a Long, which has a range of -9 223 372 036 854 775 808 to +9 223 372 036 854 775 807. Any integer literals outside the Long range will just overflow and remain a Long.

When you write
Code:
`junk = 30 * 24 * 3600 * 1000`
All four integer literals are converted to Int (they are in that range). 30 is multiplied by 24, giving an Int of 720. 720 is multiplied by 3600, resulting in an Int of 2592000. 2592000 is multiplied by 1000, which then produces an overflow (the result is larger than the max Int size), resulting in -1702967296 which then is cast to a Long.
When you write
Code:
`Private junk As Long = 30 * 24 * 3600Log(junk) ' get 2592000junk = junk * 1000`
Then 30*24*3600 produces an Int of 2592000, which then is cast to a Long. Then you multiply that Long by an Int, the Long does not overflow (in this case), producing your expected result of 2592000000.

Moral of this story, when mixing Long and Int multiplication, make sure that the first number (be it a variable or be it an integer literal) is a Long or you may experience an unexpected result (due to overflow).

Note: In Java, you can add a L to your integer literal (such as 100L) to designate that number as a Long, but that does not seem to work in B4A (nor B4J), where Int or Long are solely determined by the range the integer literal falls into.

Peter Simpson, ac9ts, jimmyF and 2 others like this.

The bottom line is: if you want to make a calculation with long values then make sure that at least one of the values is a long variable.

jimmyF likes this.

More accurately, the Long variable/integer literal must be in a position where Int calculations have no chance to overflow. For me, that would mean first position. Let the code speak:
Code:
`Private junk As Longjunk = 30junk = junk * 24 * 3600 * 1000 * 100 * 10Log(junk)junk = 30junk = 24 * junk * 3600 * 1000 * 100 * 10Log(junk)junk = 30junk = 24 * 3600 * junk * 1000 * 100 * 10Log(junk)junk = 30junk = 24 * 3600 * 1000 * junk * 100 * 10Log(junk)junk = 30junk = 24 * 3600 * 1000 * 100 * junk * 10Log (junk)junk = 30junk = 24 * 3600 * 1000 * 100 * 10 * junkLog (junk)`
And the output:
As can be seen, the last two do not produce the expected result. The position of the Long variable is important.

moster67, mindful, ac9ts and 3 others like this.

An example
Code:
`Private junk As Longjunk = 259200000 * 100Log(junk)junk = 2592000000 * 10Log(junk)`
Results
In the first calculation, two Int's are multiplied (both literals fall into the Int range), resulting in an overflow and producing an unexpected result. In the second calculation, the first literal is cast to a Long and the result is as expected.

mindful likes this.