FIXED: Mod and \ - running into 32 bit Math problems on a 64 bit system 🤦‍♂️

For a forthcoming article in xDev I had to use the Mod function and came across an interesting problem:

From the Xojo documentation:

result = number1 Mod number2

The Mod operator divides number1 by number2 and returns the remainder as result. If either number1 or number2 is a floating-point type, it is first coerced to Int32. If either number1 or number2 is an Int64, then both values are promoted to Int64.

Result is an Integer, and should be a 64 bit integer on a 64 bit system. Testing revealed that the coercing to 32bit Integer rule takes precedence over promoting to 64bit Integer.

But why would the double be coerced into a 32bit integer on 64 bit systems? That just screams overflow error!

Basically you are running into a 32 bit limitation on a 64 bit system.

Have Xojo forgotten to update this when they moved to 64 bit?

And now don’t have a compiler guy anymore to fix it?

:man_shrugging:

Min & Max have a similar problem as they expect doubles rather than being overloaded for Int64 / UInt64.

Case logged in Feedback but I would be surprised if it got fixed.

I bet this is just a documentation issue as the CPUs can easily do mod for 64-bit.

Dim n As Int64 = 300000000002

Dim x As Int64 = n Mod 3
Dim y As Int64 = n \ 3
Break

Works well here.

Sorry, Christian, you are missing the point: try it with a double and you’ll see the problem.

You are right. Double is converted to int32 and doing the mod and div operation. How bad.

Feedback case 11536: mod fails for doubles with divisors greater than [ ( 2 ^ 31 ) - 2 ]

is already 10 years old :roll_eyes:

1 Like

Thanks for digging that one out.

They do most stuff themselves. e.g. William does a few things. And I bet they have the staff to find the conversion from double to Int32 in the code generating the Intermediate Representation for LLVM for a MOD operation and change it to Int64.

by the way, I don’t use mod often. And even less often with double as input. This is not an issue affecting a lot of people.

i do use MOD occasionally but never with float/double… always with whole number

now WHY would you say that ? :stuck_out_tongue:

How about since geoff says they dont have a dedicated compiler guy ?
(from https://forum.xojo.com/t/something-funky-about-uint32-comparisons/57447/163)

Which flat out says “we dont have a dedicated compiler guy”

so we know the issue, although as others mentioned, I use MOD a lot but never with FP or doubles (old embedded code habit of making EVERYTHING integer).

what is a simple work around, turn everything to int64 first and then convert back?

Integers should work.

Just don’t do MOD with double or single data types.

The basic problem is that under a 32 bit system a Double can represent a MUCH larger range of integers accurately than an Integer can. So a LOT of code used Double instead of Integer to avoid integer overflows:

The maximum value of “whole numbers” that can be accurately represented:

32 bit 64 bit
Integer 2,147,483,647 9,223,372,036,854,775,807
Double 9,007,199,254,740,992 9,007,199,254,740,992
unsigned Integer 4,294,967,295 18,446,744,073,709,551,615

On 32 bit systems it made some sense to cast to a 32 bit integer even though I would argue it would have been better (and more future proof) to cast to a 64 bit integer (and yes, you CAN use 64 bit integers on 32 bit systems though it will probably slow down the calculation).

However on 64 bit systems it is simply not acceptable to cast a Double to 32 bit Integers.

Btw the two Boeings that fell out of the air because their engines stalled? That was due to a 32bit Integer overflow error.

probably a long standing issue since the sized integer types were added

Alberto brought up a nice example with date intervals where the problem rears it’s ugly head:


That simply should not happen on a 64 bit system.

WOOHOO!

Took 10 years and Christian’s detective work, but good news nonetheless!

:+1:

… and the same bug in Integer Division got fixed too!

:+1:

are they going to fix thoms bug too where the comparison fails ?
seems pointless to only fix some of them