Xojo Math badly broken: 32bit problems in a 64bit environment

:+1:t2: We should have reaction emojis here instead of this stupid heart for everything. :laughing:

2 Likes

We did.

Maybe some people got downvoted too often :wink:

3 Likes

What others exactly? This may have big impacts on an almost finished part of our code relying on dates (a major piece) depending.

Okay, seems there is evidence on this topics and Markus’ (and others’) observations.
I would like to see any statement by Xojo to this ā€œExcel is working wrongā€ Moment… or shall I better say Mars Orbiter Moment?

I am curious how other languages tackling this?

Has anybody tested Floor, Ceil & Round?

I know Min & Max have a similar problem with Int64 / UInt64 values because those functions only accept doubles.

integer div is also affected:

Dim d As Double = 3000000002.0

Dim n1 As Integer = d Mod 3
Dim n2 As Integer = d \ 3

Dim r1 As Integer = CType(d, Int64) Mod 3
Dim r2 As Integer = CType(d, Int64) \ 3

Break

In 64-bit app, those n1 and n2 will be wrong values.

1 Like

and as I love to look on the assembler for

Dim n1 As Integer = d Mod 3

I get this:

0x10012d466 <+150>: movb   $0x1, %al
0x10012d468 <+152>: movq   -0x60(%rbp), %rcx // load self
0x10012d46c <+156>: cvttsd2si -0xe0(%rcx), %edx // take double at address and convert to integer 32-bit!
0x10012d474 <+164>: movl   %edx, -0x10(%rbp) // store it
0x10012d477 <+167>: testb  $0x1, %al // always true!?
0x10012d479 <+169>: movl   %edx, -0x64(%rbp) // store integer in temp variable
0x10012d47c <+172>: jne    0x10012d480               ; <+176>
0x10012d47e <+174>: jmp    0x10012d498               ; <+200>
0x10012d480 <+176>: movl   $0x3, %eax // value 3
0x10012d485 <+181>: movl   -0x64(%rbp), %ecx 
0x10012d488 <+184>: movl   %eax, -0x68(%rbp) // value 3 stored
0x10012d48b <+187>: movl   %ecx, %eax
0x10012d48d <+189>: cltd   // convert 32-bit EAX to 64-bit EDX:EAX!?
0x10012d48e <+190>: movl   -0x68(%rbp), %esi // value 3 read
0x10012d491 <+193>: idivl  %esi // divide by 3
0x10012d493 <+195>: movl   %edx, -0xc(%rbp) // store mod result
0x10012d496 <+198>: jmp    0x10012d49b               ; <+203>
0x10012d498 <+200>: movl   %eax, -0xc(%rbp)

I added a few comments. And it looks like double conversion uses EDX as target instead of RDX for 64-bit. And later the 32-bit number is extended to 64-bit as division needs that as input.

3 Likes

Yes. In writing my xDev article I needed to use both Mod and Integer division, and both have the problem.

1 Like

Maybe if people who have a few minutes could grab a function and test it, and post the code showing the problem?

The whole auto-type conversion/promotion for numbers should be rechecked. This part of the compiler is less safe than Fortran compilers I used more than 40 years ago. Puzzling.

Better documenting the rules of auto-type conversion/promotion could help (with examples : constants, functions, etc.). But fundamentally, the compiler should do a better job. CType is not the answer plus it is costly.

2 Likes

I had to read up a bit on EDX and RDX.

I would have expected a conversion to Double to Integer to use Int64 or at least the system integer type.

Do I get this right that the integer conversion as seen on a 64bit system seems to be hardcoded to convert to Int32 (via EDX), and is not using the system integer type?

Or is that reading too much into it?

As far as I see, it’s hard coded to use Int32 independent of CPU architecture.

I wonder how many times people have run into this and didn’t know it. I know I’ve had issues with things in the past that could have been affected by this sort of thing. I remember one particular project where I went through and manually setup a bunch of things to 64bit integers to try and work around a problem I thought was caused by integer overflow, but it may have been more than that. I also had some strange issues with an iOS project I built several years ago now I think, and I’m wondering if this issue wasn’t related to that as well. It used quite a bit of math to calculate speeds, distance, and time and it never seemed to work consistently. I eventually gave up on that project and haven’t revisitied iOS on Xojo since.

Xojo needs to fix this. I am not going to use a development environment that doesn’t handle basic match properly. This is not something I should need to deal with in a high level language.

2 Likes

In feedback case 11536 got implemented by Paul. Great if he can do that and I hope they verified it’s working better now.

@Paul_Lefebvre, did you also do change for \ operator?

4 Likes

WOOHOO!

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

:+1:

1 Like

You have more cases to look into?

1 Like

Oh THIS one they fix, but comparisons suffering the same problem is vehemently not a bug? Come on…

#11935 and #2218. Both closed because Xojo doesn’t want to fix it.

I have a blog post about the issue, but I’m not going to link it due to forum rules.

4 Likes

A small step for man, a giant leap for humanity. Let’s see if they can take another step. :wink:

2 Likes

This is one of the MOST SERIOUS things that could ever happen, we’ve had it before and moved on. Since then we have had this issue over 100’s of times and changed trough the use of the debugger to get the correct if… end if to happen. It’s a major waste of time, not knowing what to expect from the compiler while your brain says the value is for example:

// In a 32-bit app the following happens:
Var Value As UInt32 = 4294967295
If Value > 100 Then
// Won't Reach Here 
End If

My brains where exploding almost… We use Xojo always with sockets, binary streams etc. We have had these kind of min-blowing pain points alot. Never know what was the true problem. Moved on… Now it’s clearly showing what the actual problem is. Let’s just fix this Xojo… before this gets out of hand.

We have NEVER before used CType(…) and don’t expect to have 100’s of lines of code (if not more) to be changed to add CType to it… slowing things down and making things much more complex (and therefore more unclear).

I truely hope Xojo fixes this, even if it may break some projects. Don’t the right thing is MORE important than doing the WRONG thing and walking away from it.

Thanks to this amazing community we find such serious issues, so we should be able to expect a fix for these kind of time wasting bugs…

5 Likes

Yes, the fix applies to both the Mod and Integer Division operators.

3 Likes