Why is this broken?

from TOF

ok so WHY is it “broken” ?
in this line

resultd = 24 * 60 * 60 * 180 * 1000

the TYPE of the result is IRRELEVANT until the computation is completed and needs to be put into the destination
The compiler looks at each operand and sees that each fits an integer
Not sure it opts for 32 vs 64 bit integers internally based on what target you’re compiling for
However that the first gets the wrong result I suspect it opts for a 32 bit one
And so uses that to do the work
The result overflows 32 bits & is then assigned to the double

In the second

resultd = 24 * 60 * 60 * 180 * 1000.0

it sees that at least one operand is a floating point value and so uses doubles for everything
And then eventually assigns the floating point value to the result

feel free to cross post this

Compiling for 32 bit (Windows) gives the “wrong” answers, compiling for 64 gives right ones. So I guess it’s opting for the biggest it has available?

FYI: Because the OP in TOF is not allowed to mention from which forum the original question came, here is the original post: Product of 24*60*60*180*1000 is negative and incorrect | B4X Programming Forum

1 Like

Quite possible as I’m not sure about these sorts of details about the internals of the compiler and what types it assumes things are
It may well opt for using an int64 - and if compiling for 64 bit does give the right answer for the first test then that makes sense as no overflow is experienced

thats funny !

It just means this really is a cross-language/cross-tool forum! :wink:

I’d say an open cross platform forum
0 posts deleted by moderators/admins
0 banned users
so many “we dont do that shit here” things

fwiw java seem to get this weird too

class jTest {

    public static void main(String args[]) {
    
               double resultd ;
		resultd = 24 * 60 * 60 * 180 * 1000 ;
		
		System.out.printf( "%14.0f\n", resultd ) ;
		
	}
	
}

npalardy@server jTest % javac jTest.java
npalardy@server jTest % java jTest
-1627869184
npalardy@server jTest %

Change the original calc to have one literal as a double and its suddenly right as well

class jTest {

    public static void main(String args[]) {
    
    	double resultd ;
		resultd = 24.0 * 60 * 60 * 180 * 1000 ;
		
		System.out.printf( "%14.0f\n", resultd ) ;
		
	}
	
}

npalardy@server jTest % javac jTest.java
npalardy@server jTest % java jTest
15552000000
npalardy@server jTest %

FWIW : NOTE I’m not saying Xojo has this uniquely wrong
Java does the same
When no type is stated or hinted then the compiler has to assume something about the literals
In both java and Xojo it appears to assume numerics are implicitly int32

And then when you multiply enough int32’s together you eventually overflow the type

Possibly the compiler(s) could be altered to do something like

      // resultd = 24 * 60 * 60 * 180 * 1000 ;
      dim temp1 as int32 = 24
      dim temp2 as int32 = 60
      dim temp3 as INT64  = temp1 * temp2 // because int32 * int32 can overflow an int32
      dim temp4 as int32 = 60
      dim temp5 as int64 = temp3 * temp4 // int64 * int32 will give an int64
      dim temp6 as int32 = 180
      dim temp7 as int64 = temp5 * temp6 // int64 * int32 will give an int64
      dim temp8 as int32 = 1000
      dim temp9 as int64 = temp7 * temp8

      dim resultd as double = temp9

there is still a way to overflow int64
and an fr to add int128 :slight_smile:

var resultD : Double =  24 * 60 * 60 * 180 * 1000
print(resultD)
15552000000.0

yeah
some compilers DO use the result type to infer the size of intermediate results

it certainly seems more intuitive :slight_smile:

1 Like

I use MPLABX for my embedded stuff and if you try to use literal with 32 bit calculations it completely fecks up and seemingly has no idea what to do.
fine on other types.

to use a literal it has to be declared as the same 32 bit type and given the value you wish to represent by that literal:-

uint32 literal_x100 = 100;

cant say I have evener used MPLABX
I have run into compilers that are very touchy about assumptions
BUT being that way also means they are VERY explicit
ie/ no literals in expressions means EVERYTHING has to be explicitly typed before used and that can help with several things like optimizations and even overflow checking

it seems a pain but depending on what kind of code you’re writing can also be much safer

that is the goal of lots of new langs like swift go rust etc
to reduce the things that constantly & perpetually get done that create bugs

Remamber that REALbasic 1 was released with REALbasic and Java…

This may explain why Xojo behave like it do.

I do not know which was added first.

Not sure that really matters since the compiler has been rewritten twice since 1.0 shipped

Maybe we should go back to using hand calculators since every one I tried, from the one in my iPhone to an ancient Casio EL-386L, came up with the correct answer.
:grinning_face_with_smiling_eyes:

but then most hand calculators don’t embrace the concept of Integer datatypes… and all calculations are done as Double/Float values.

I suspect all typeless languages will handle this with ease…

For what it’s worth, in LiveCode this works correctly:
put 24*60*60*180*1000
15552000000