DIM A AS _UNSIGNED LONG
DIM b AS _UNSIGNED INTEGER
DIM c AS _UNSIGNED INTEGER
DIM E AS _UNSIGNED _INTEGER64
DIM F AS _UNSIGNED LONG
DIM G AS _UNSIGNED LONG
b = 40000
c = 40000
A = b * c
PRINT A
F = 4000000000
G = 4000000000
E = F * G
PRINT E
E prints out as 1983905792, it should be 16000000000 (16 billion)
Indeed in some cases it would be impossible to make such as inference, e.g. PRINT F * G.
Any number bigger than the largest number representable by the type simply “wraps around” (sometimes called “modulo wrapping”, or more obscurely, “saturation”)
In C, unsigned integer overflow is defined to wrap around, while signed integer overflow causes undefined behavior
There's definetly something wrong with _UNSIGNED _INTEGER64, I already noticed it 2 years back here https://www.qb64.org/forum/index.php?topic=1084.msg102794#msg102794
I did also stumble over it when making the &B additions to the last two realease versions, but didn't change anything on it, as the problem seems to be scattered across several functions and not easy to spot entirely.
In some situations, and only with _INTEGER64, the _UNSIGNED condition seemes to be simply ignored and so it will only allow the signed range, loosing half of the possible unsigned values.
And honestly, I don't understand this... I can see why floating point math is affected the way it is, but INTEGER math? This one was a total shock to me, when STx first showcased code which highlighted the issue. Now, there might be some simple trick like making that a 2~&& ^ 55~&&, or such, but at the end of the day, just changing from normal precision to double precision can make a large difference, as shown above.
I have changed it to use the fldcw instruction directly.
This should fix a lot of the precision issues which people like jack have highlighted several times in his work.I was hoping for that, but the problem with _Float is still there