# int64 returning 0?

I have a simple program -

dim number as int64
number=(102410241024)*20
if number =0 then
msgbox “Number is zero?”+str(number)
else
msgbox "Number is "+str(number)
end if

When I run it it returns 0
The result of number is no where near the documents defined int64 size

Int64 8 -2^63 to 2^63-1 (+/-9,223,372,036,854,775,807)

Is this a bug?

all numbers are integers, so you probably run into some kind of overflow…

The generic integer expression on the right should fit on the left container, int64. So, for me, it’s a bug.
21474836480 fits in a int64

```Dim number As Int64 number = Int64(1024 * 1024 * 1024 * 20)```
… doesn’t compile with the error: Type mismatch error. Expected Int64, but got Int32.
Seems to be a bug.

Seems to be a matter of internal Integer math…

because this DOES work

``````Dim number As Int64
number = 1024. * 1024. * 1024. * 20.``````

double math into an int64

This code gives the correct answer, so Dave’s (and Eli’s) posts must be getting toward the right problem - I guess it’s doing smaller integer math when you string it together.

``````  dim number as int64
number=1024
number = number * 1024
number = number * 1024
number = number * 20

msgbox str(number)``````

[quote=89244:@Bill Gookin][/quote]You are right.
It’s not a bug.

Actually… .I would say it is a bug…

Bill’s code works because it is directly multiplying a INT64 by and INT32 and the result is always the the higher datatype.

The original was all INT32 math (hence the overflow). My example worked becuase it was all DOUBLE math.

It SHOULD (my opinion) do math using the largest datatype between the operators(64) and the result (int64)
but what I think it is doing is using the highest default datatype of the OS (which is currently only 32bit), and if so, the problem will “go away” when a 64bit compiler comes online.

FYI… the result is a 36bit number (0x500000000)

Well, Xojo is strongly typed, so in my opinion it shouldn’t.

I agree with Eli just because it matches how I think of my own world.

I’m only human as probably a less-smart one, I can’t for the life of me remember operator precedence, so I avoid the topic entirely and use parentheses so there’s never any argument.

Same with “maths” - I (try to) never expose a “lesser” type to handicap another one. Since I code just as much (if not more) in C++ as Basic, I’m always casting when I divide and “upping” to INT64 when there’s even the slightest chance of overflowing the 32-bit scale.

Dave S. may be right, but one thing I learned much in reading computer books like Code Complete and others was to “make and enforce your own rules” and not depend on others, no matter if they are “the way everyone does it”. By that I mean be explicit with your coding, not make it so you have to have the “rulebook” sitting by you to understand the code. And for me, since I code in different languages, if I used my memory, that’s would be a huge conduit for bugs.

When I saw the OP’s code, I knew instantly there was an overflow math problem just because I could see the disconnect between the literals and the type, not because I pulled out a calculator and tried to figure it out.

Boring code is Good code.

[quote=89250:@Garth Hjelte]Boring code is Good code.[/quote]I first read:
Boring code is God code.

Well, it IS Sunday. =)

It’s using the highest type in the expression 102410241024*20 which are all Int32s. Insert an Int64 in there and it doesn’t overflow.

[code]dim x as Int64 = Ctype(1024, Int64) * 1024 * 1024 * 20

//or

dim a As Int64 = 1024
dim y As Int64 = a * 1024 * 1024 * 20[/code]

Can someone explain why this works:

``dim number as int64 = 1024 * 1024 * 1024 * 20. 'Gives the correct answer``

And this works:

``dim number as int64 = 1024 * 1024 * 1024 * 10. * 2 'Correct``

But this doesn’t:

``dim number as int64 = 1024 * 1024 * 1024 * 10 * 2. 'Gives a big negative number``

And this one gives a positive number but the wrong one.

``dim number as int64 = 1024 * 1024 * 1024 * 5 * 4. 'Gives a positive number, but the wrong one``

From the docs:

Please remember that such examples are just examples. Don’t tell me someone would actually code such things.

I’ll tell you want works better:

```Const THIS_FACTOR As Int64 = 1024 Const NUM_MULTIPLER As Int64 = 3 Const NUM_ITEMS As Int64 = 20 Dim ThisNumber As Int64 = (THIS_FACTOR * NUM_MULTIPLER) * NUM_ITEMS ```

I know the examples are just for “figuring the internal logic of Xojo” but know it’s getting where these examples seem like you are actually coding like that. Real coding is going to serve you better, where you’ll find that logically types start serving YOU, like they are supposed to, as opposed to torpedoing your calculations because you are making irresponsible assumptions.

Don’t use literals if you don’t have to. That isn’t to say literals aren’t common, but try as a habit to push things into constants or variables. Literals are also called “magic numbers”.

It’s the literals that make this confusing, but the normal human mind thinks they are super types with minds of their own. In truth internally they take on types and now your code is becoming non-self-documenting. Don’t program by magic, be intentional.

[quote=89270:@Bill Gookin]Can someone explain why this works:

``dim number as int64 = 1024 * 1024 * 1024 * 20. 'Gives the correct answer``

And this works:

``dim number as int64 = 1024 * 1024 * 1024 * 10. * 2 'Correct``

But this doesn’t:

``dim number as int64 = 1024 * 1024 * 1024 * 10 * 2. 'Gives a big negative number``

And this one gives a positive number but the wrong one.

``` dim number as int64 = 1024 * 1024 * 1024 * 5 * 4. 'Gives a positive number, but the wrong one ```[/quote]
Joe would have to comment BUT I’m pretty sure it has to do with the order the expression is evaluated
Basically things are normally evaluated from left to right since there is not other precedence imposed by ()
So in the first couple of examples that work
works because 1024 * 1024 * 1024 does not overflow a 32 bit integer
then the last part of the expression uses a double so everything is promoted to a double then assigned to the int64

The last two example DO overflow a 32 bit int

``````dim number as int64 = 1024 * 1024 * 1024 * 10
dim number as int64 = 1024 * 1024 * 1024 * 5``````

and the rest of the calculation uses that overflowed value before a double is involved

Number literals are EITHER integer or double regardless of the final destination type
So you have

``````dim number as int64 = 1024 * 1024 * 1024 * 20.
dim number as int64 = integer * integer * integer * double``````

with resulting overflows etc when you evaluate from left to right
The reason I’m sure this is the issue is as soon as you insert a set of ( ) to group things you get different answers
For instance

``````dim number4 as int64 = 1024 * 1024 * 1024 * 5 * 4.
dim number4a as int64 = 1024 * 1024 * (1024 * (5 * 4.))``````

Thank you Norman, that makes perfect sense. Also, I’m mad at myself for not thinking of the order of operations. LOL

The Xojo coercion detection (auto casting the members to the highest result container type) is not taking result container (int64) on the left side of the expression ( dim container as int64 = expression) in account when doing the evaluation.

Seems it’s analyzing like this:
result(is int64)=1024(is int32)*1024(is int32)*1024(is int32)*20(is int8) -> so highest = int32 then it makes:
result=int32(1024)*int32(1024)*int32(1024)*int32(20)

Should do:
result(is int64)=1024(is int32)*1024(is int32)*1024(is int32)*20(is int8) -> so highest = int64, and then:
result=int64(1024)*int64(1024)*int64(1024)*int64(20)

[quote=89291:@Rick Araujo]The Xojo coercion detection (auto casting the members to the highest result container type) is not taking result container (int64) on the left side of the expression ( dim container as int64 = expression) in account when doing the evaluation.
[/quote]
Never has
The expression is computed (in this case at compile time) using the types inferred from the literals (integer and double)
And then assigned to what ever type the declared variable is

Changing that design might silently induce some unexpected behavior