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

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

  1. JackKirk

    JackKirk Active Member Licensed User

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

    Erel Administrator Staff Member Licensed User

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

    ac9ts Active Member Licensed User

    Code:
    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
     
  4. OliverA

    OliverA Well-Known Member Licensed 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
    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 * 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.
     
    Peter Simpson, ac9ts, jimmyF and 2 others like this.
  5. Erel

    Erel Administrator Staff Member Licensed 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.
     
    jimmyF likes this.
  6. OliverA

    OliverA Well-Known Member Licensed User

    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 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:
    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.
  7. OliverA

    OliverA Well-Known Member Licensed User

    An example
    Code:
    Private junk As Long
    junk = 
    259200000 * 100
    Log(junk)
    junk = 
    2592000000 * 10
    Log(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.
  8. JackKirk

    JackKirk Active Member Licensed 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?
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice