Bug? [SOLVED a bit embarrassing] Is this a bug or am I going stark raving mad?

JackKirk

Well-Known Member
Licensed User
Longtime User
B4X:
 Private junk As Long = 30 * 24 * 3600
junk = junk * 1000
Log(junk) 'get 2592000000
junk = 30 * 24 * 3600 * 1000
Log(junk) 'get -1702967296
 

ac9ts

Active Member
Licensed User
Longtime User
B4X:
Private junk As Long = 30 * 24 * 3600
Log(junk) ' get 2592000
junk = junk * 1000
Log(junk) 'get 2592000000
junk = 30 * 24 * 3600 * 1000
Log(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
 

OliverA

Expert
Licensed User
Longtime User
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
B4X:
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
B4X:
Private junk As Long = 30 * 24 * 3600
Log(junk) ' get 2592000
junk = 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.
 

OliverA

Expert
Licensed User
Longtime User
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.
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:
B4X:
Private junk As Long
junk = 30
junk = junk * 24 * 3600 * 1000 * 100 * 10
Log(junk)
junk = 30
junk = 24 * junk * 3600 * 1000 * 100 * 10
Log(junk)
junk = 30
junk = 24 * 3600 * junk * 1000 * 100 * 10
Log(junk)
junk = 30
junk = 24 * 3600 * 1000 * junk * 100 * 10
Log(junk)
junk = 30
junk = 24 * 3600 * 1000 * 100 * junk * 10
Log (junk)
junk = 30
junk = 24 * 3600 * 1000 * 100 * 10 * junk
Log (junk)
And the output:
2592000000000
2592000000000
2592000000000
2592000000000
15019622400
15019622400
As can be seen, the last two do not produce the expected result. The position of the Long variable is important.
 

OliverA

Expert
Licensed User
Longtime User
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.
An example
B4X:
Private junk As Long
junk = 259200000 * 100
Log(junk)
junk = 2592000000 * 10
Log(junk)
Results
150196224
25920000000
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.
 

JackKirk

Well-Known Member
Licensed User
Longtime User
OK I understand all this but would make the following comment.

B4X is supposed to be RAD - rapid application development.

I don't know if there is a formal definition of RAD but I would suggest it would/should include measures to remote a developer from this low level stuff.

Even just an error message or somesuch when an overflow occurs?
 
Top