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.
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)
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.
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.
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.))
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